get('POST'); $return = (object) []; $user = null; if($data['loginData']){ $loginData = $data['loginData']; $user = $this->logUserIn( $loginData['userName'], $loginData['userPassword'] ); } // set "vague" error if(is_null($user)){ $return->error = []; $loginError = (object) []; $loginError->type = 'login'; $return->error[] = $loginError; }else{ // update/check api data $user->updateApiData(); // route user to map app $return->reroute = rtrim(self::getEnvironmentData('URL'), '/') . $f3->alias('map'); } echo json_encode($return); } /** * core function for user login * @param $userName * @param $password * @return Model\UserModel|null */ private function logUserIn($userName, $password){ // try to verify user $user = $this->_verifyUser($userName, $password); if( !is_null($user)){ // user is verified -> ready for login // set Session login $dateTime = new \DateTime(); $this->f3->set('SESSION.user', [ 'time' => $dateTime->getTimestamp(), 'name' => $user->name, 'id' => $user->id ]); // save user login information $user->touch('lastLogin'); $user->save(); // save log $logText = "id: %s, name: %s, ip: %s"; self::getLogger( $this->f3->get('PATHFINDER.LOGFILES.LOGIN') )->write( sprintf($logText, $user->id, $user->name, $this->f3->get('IP')) ); } return $user; } /** * get captcha image and store key to session * @param $f3 */ public function getCaptcha($f3){ $data = $f3->get('POST'); $return = (object) []; $return->error = []; // check if reason for captcha generation is valid if( isset($data['reason']) && in_array( $data['reason'], self::$captchaReason) ){ $reason = $data['reason']; $im = imagecreatetruecolor(1, 1); $colorText = imagecolorallocate($im, 102, 200, 79); $colorBG = imagecolorallocate($im, 49, 51, 53); $img = new \Image(); $imgDump = $img->captcha( 'fonts/oxygen-bold-webfont.ttf', 14, 6, 'SESSION.' . $reason, '', $colorText, $colorBG )->dump(); $return->img = $f3->base64( $imgDump, 'image/png'); }else{ $captchaError = (object) []; $captchaError->type = 'error'; $captchaError->message = 'Could not create captcha image'; $return->error[] = $captchaError; } echo json_encode($return); } /** * delete the character log entry for the current active (main) character * @param $f3 */ public function deleteLog($f3){ $user = $this->_getUser(); if($user){ $activeUserCharacter = $user->getActiveUserCharacter(); if($activeUserCharacter){ $character = $activeUserCharacter->getCharacter(); if($characterLog = $character->getLog()){ $characterLog->erase(); } } } } /** * log the current user out + clear character system log data * @param $f3 */ public function logOut($f3){ $this->deleteLog($f3); parent::logOut($f3); } /** * save/update "map sharing" configurations for all map types * the user has access to * @param $f3 */ public function saveSharingConfig($f3){ $data = $f3->get('POST'); $return = (object) []; $privateSharing = 0; $corporationSharing = 0; $allianceSharing = 0; $user = $this->_getUser(); if($user){ // form values if(isset($data['formData'])){ $formData = $data['formData']; if(isset($formData['privateSharing'])){ $privateSharing = 1; } if(isset($formData['corporationSharing'])){ $corporationSharing = 1; } if(isset($formData['allianceSharing'])){ $allianceSharing = 1; } } $user->sharing = $privateSharing; $user->save(); // update corp/ally --------------------------------------------------------------- $activeUserCharacter = $user->getActiveUserCharacter(); if(is_object($activeUserCharacter)){ $corporation = $activeUserCharacter->getCharacter()->getCorporation(); $alliance = $activeUserCharacter->getCharacter()->getAlliance(); if(is_object($corporation)){ $corporation->sharing = $corporationSharing; $corporation->save(); } if(is_object($alliance)){ $alliance->sharing = $allianceSharing; $alliance->save(); } } $return->userData = $user->getData(); } echo json_encode($return); } /** * search for a registration key model * e.g. for new user registration with "invite" feature enabled * @param $email * @param $registrationKey * @return bool|Model\RegistrationKeyModel * @throws Exception */ protected function getRegistrationKey($email, $registrationKey){ $registrationKeyModel = Model\BasicModel::getNew('RegistrationKeyModel'); $registrationKeyModel->load([ 'registrationKey = :registrationKey AND email = :email AND used = 0 AND active = 1', ':registrationKey' => $registrationKey, ':email' => $email ]); if( $registrationKeyModel->dry() ){ return false; }else{ return $registrationKeyModel; } } /** * check if there is already an active Key for a mail * @param $email * @param bool|false $used * @return bool|null * @throws Exception */ protected function findRegistrationKey($email, $used = false){ $queryPart = 'email = :email AND active = 1'; if(is_int($used)){ $queryPart .= ' AND used = ' . $used; } $registrationKeyModel = Model\BasicModel::getNew('RegistrationKeyModel'); $registrationKeyModels = $registrationKeyModel->find([ $queryPart, ':email' => $email ]); if( is_object($registrationKeyModels) ){ return $registrationKeyModels; }else{ return false; } } /** * save/update user account data * @param $f3 */ public function saveAccount($f3){ $data = $f3->get('POST'); $return = (object) []; $return->error = []; $captcha = $f3->get('SESSION.createAccount'); // reset captcha -> forces user to enter new one $f3->clear('SESSION.createAccount'); $newUserData = null; // check for new user $loginAfterSave = false; // valid registration key Model is required for new registration // if "invite" feature is enabled $registrationKeyModel = false; if( isset($data['settingsData']) ){ $settingsData = $data['settingsData']; try{ $user = $this->_getUser(0); // captcha is send -> check captcha if( isset($settingsData['captcha']) && !empty($settingsData['captcha']) ){ if($settingsData['captcha'] === $captcha){ // change/set sensitive user data requires captcha! if($user === false){ // check if registration key invite function is enabled if($f3->get('PATHFINDER.REGISTRATION.INVITE') === 1 ){ $registrationKeyModel = $this->getRegistrationKey( $settingsData['email'], $settingsData['registrationKey'] ); if($registrationKeyModel === false){ throw new Exception\RegistrationException('Registration key invalid', 'registrationKey'); } } // new user registration $user = $mapType = Model\BasicModel::getNew('UserModel'); $loginAfterSave = true; // set username if( isset($settingsData['name']) && !empty($settingsData['name']) ){ $user->name = $settingsData['name']; } } // change/set email if( isset($settingsData['email']) && isset($settingsData['email_confirm']) && !empty($settingsData['email']) && !empty($settingsData['email_confirm']) && $settingsData['email'] == $settingsData['email_confirm'] ){ $user->email = $settingsData['email']; } // change/set password if( isset($settingsData['password']) && isset($settingsData['password_confirm']) && !empty($settingsData['password']) && !empty($settingsData['password_confirm']) && $settingsData['password'] == $settingsData['password_confirm'] ){ $user->password = $settingsData['password']; } }else{ // captcha was send but not valid -> return error $captchaError = (object) []; $captchaError->type = 'error'; $captchaError->message = 'Captcha does not match'; $return->error[] = $captchaError; } } // saving additional user info requires valid user object (no captcha required) if($user){ // save API data if( isset($settingsData['keyId']) && isset($settingsData['vCode']) && is_array($settingsData['keyId']) && is_array($settingsData['vCode']) ){ // get all existing API models for this user $apiModels = $user->getAPIs(); foreach($settingsData['keyId'] as $i => $keyId){ $api = null; // search for existing API model foreach($apiModels as $key => $apiModel){ if($apiModel->keyId == $keyId){ $api = $apiModel; // make sure model is up2data -> cast() $api->cast(); unset($apiModels[$key]); break; } } if(is_null($api)){ // new API Key $api = Model\BasicModel::getNew('UserApiModel'); $api->userId = $user; } $api->keyId = $keyId; $api->vCode = $settingsData['vCode'][$i]; $api->save(); $characterCount = $api->updateCharacters(); if($characterCount == 0){ // no characters found -> return warning $characterError = (object) []; $characterError->type = 'warning'; $characterError->message = 'API verification failed. No Characters found for KeyId ' . $api->keyId; $return->error[] = $characterError; } } // delete API models that no longer exists foreach($apiModels as $apiModel){ $apiModel->delete(); } // get fresh updated user object (API info may have has changed) $user = $this->_getUser(0); } // set main character if( isset($settingsData['mainCharacterId']) ){ $user->setMainCharacterId((int)$settingsData['mainCharacterId']); } // check if the user already has a main character // if not -> save the next best character as main $mainUserCharacter = $user->getMainUserCharacter(); // set main character if no main character exists if(is_null($mainUserCharacter)){ $user->setMainCharacterId(); } // save/update user model // this will fail if model validation fails! $user->save(); if(is_object($registrationKeyModel)){ $registrationKeyModel->used = 1; $registrationKeyModel->save(); } // log user in (in case he is new if($loginAfterSave){ $this->logUserIn( $user->name, $settingsData['password'] ); // return reroute path $return->reroute = rtrim(self::getEnvironmentData('URL'), '/') . $this->f3->alias('map'); } // get fresh updated user object $user = $this->_getUser(0); $newUserData = $user->getData(); } }catch(Exception\ValidationException $e){ $validationError = (object) []; $validationError->type = 'error'; $validationError->field = $e->getField(); $validationError->message = $e->getMessage(); $return->error[] = $validationError; }catch(Exception\RegistrationException $e){ $registrationError = (object) []; $registrationError->type = 'error'; $registrationError->field = $e->getField(); $registrationError->message = $e->getMessage(); $return->error[] = $registrationError; } // return new/updated user data $return->userData = $newUserData; } echo json_encode($return); } /** * send mail with registration key * -> check INVITE in pathfinder.ini * @param $f3 * @throws Exception */ public function sendInvite($f3){ $data = $f3->get('POST.settingsData'); $return = (object) []; // check invite limit // get handed out key count $tempRegistrationKeyModel = Model\BasicModel::getNew('RegistrationKeyModel'); $tempRegistrationKeyModels = $tempRegistrationKeyModel->find([ ' email != "" AND active = 1' ]); $totalKeys = 0; if(is_object($tempRegistrationKeyModels)){ $totalKeys = $tempRegistrationKeyModels->count(); } if( $f3->get('PATHFINDER.REGISTRATION.INVITE') == 1 && $totalKeys < $f3->get('PATHFINDER.REGISTRATION.INVITE_LIMIT') ){ // key limit not reached if( isset($data['email']) && !empty($data['email']) ){ $email = trim($data['email']); // check if mail is valid if( \Audit::instance()->email($email) ){ // new key for this mail is allowed $registrationKeyModel = $this->findRegistrationKey($email, 0); if($registrationKeyModel === false){ // check for total number of invites (active and inactive) -> prevent spamming $allRegistrationKeysByMail = $this->findRegistrationKey($email); if( $allRegistrationKeysByMail == false || $allRegistrationKeysByMail->count() < 3 ){ // get a fresh key $registrationKeyModel = Model\BasicModel::getNew('RegistrationKeyModel'); $registrationKeyModel->load([' used = 0 AND active = 1 AND email = "" ', ':email' => $email ], ['limit' => 1]); }else{ $validationError = (object) []; $validationError->type = 'warning'; $validationError->message = 'The number of keys is limited by Email. You can not get more keys'; $return->error[] = $validationError; } }else{ $registrationKeyModel = $registrationKeyModel[0]; } // send "old" key again or send a new key if( is_object($registrationKeyModel) ){ $msg = 'Your personal Registration Key: ' . $registrationKeyModel->registrationKey; $mailController = new MailController(); $status = $mailController->sendInviteKey($email, $msg); if( $status ){ $registrationKeyModel->email = $email; $registrationKeyModel->ip = $this->f3->get('IP'); $registrationKeyModel->save(); } } }else{ $validationError = (object) []; $validationError->type = 'error'; $validationError->field = 'email'; $validationError->message = 'Email is not valid'; $return->error[] = $validationError; } } }else{ $validationError = (object) []; $validationError->type = 'warning'; $validationError->message = 'The pool of beta keys has been exhausted, please try again in a few days/weeks'; $return->error[] = $validationError; } echo json_encode($return); } /** * delete current user account from DB * @param $f3 */ public function deleteAccount($f3){ $data = $f3->get('POST.formData'); $return = (object) []; $captcha = $f3->get('SESSION.deleteAccount'); // reset captcha -> forces user to enter new one $f3->clear('SESSION.deleteAccount'); if( isset($data['captcha']) && !empty($data['captcha']) && $data['captcha'] === $captcha ){ $user = $this->_getUser(0); $validUser = $this->_verifyUser( $user->name, $data['password']); if( is_object($validUser) && is_object($user) && $user->id === $validUser->id ){ // send delete account mail $msg = 'Hello ' . $user->name . ',

'; $msg .= 'your account data has been successfully deleted.'; $mailController = new MailController(); $status = $mailController->sendDeleteAccount($user->email, $msg); if($status){ // save log $logText = "id: %s, name: %s, ip: %s"; self::getLogger( $this->f3->get('PATHFINDER.LOGFILES.DELETE_ACCOUNT') )->write( sprintf($logText, $user->id, $user->name, $f3->get('IP')) ); // remove user $user->erase(); $this->logOut($f3); die(); } }else{ // password does not match current user pw $passwordError = (object) []; $passwordError->type = 'error'; $passwordError->message = 'Invalid password'; $return->error[] = $passwordError; } }else{ // captcha not valid -> return error $captchaError = (object) []; $captchaError->type = 'error'; $captchaError->message = 'Captcha does not match'; $return->error[] = $captchaError; } echo json_encode($return); } }