diff --git a/app/main/controller/api/route.php b/app/main/controller/api/route.php index 25272832..b6f875cd 100644 --- a/app/main/controller/api/route.php +++ b/app/main/controller/api/route.php @@ -92,6 +92,9 @@ class Route extends Controller\AccessController { $rows = $this->getDB()->exec($query, null, $this->staticJumpDataCacheTime); if(count($rows) > 0){ + array_walk($rows, function(&$row){ + $row['jumpNodes'] = array_map('intval', explode(':', $row['jumpNodes'])); + }); $this->updateJumpData($rows); } } @@ -172,58 +175,65 @@ class Route extends Controller\AccessController { $whereQuery .= " `connection`.`eolUpdated` IS NULL AND "; } - $query = "SELECT - `system_src`.`systemId` systemId, - ( - SELECT - GROUP_CONCAT( NULLIF(`system_tar`.`systemId`, NULL) SEPARATOR ':') + $query = "SELECT + `system_src`.`systemId` systemSourceId, + `system_tar`.`systemId` systemTargetId FROM `connection` INNER JOIN - `system` system_tar ON - `system_tar`.`id` = `connection`.`source` OR - `system_tar`.`id` = `connection`.`target` + `map` ON + `map`.`id` = `connection`.`mapId` AND + `map`.`active` = 1 INNER JOIN + `system` `system_src` ON + `system_src`.`id` = `connection`.`source` AND + `system_src`.`active` = 1 INNER JOIN + `system` `system_tar` ON + `system_tar`.`id` = `connection`.`target` AND + `system_tar`.`active` = 1 WHERE - `connection`.`mapId` " . $whereMapIdsQuery . " AND - `connection`.`active` = 1 AND - ( - `connection`.`source` = `system_src`.`id` OR - `connection`.`target` = `system_src`.`id` - ) AND - " . $whereQuery . " - `system_tar`.`id` != `system_src`.`id` AND - `system_tar`.`active` = 1 - ) jumpNodes - FROM - `system` `system_src` INNER JOIN - `map` ON - `map`.`id` = `system_src`.`mapId` - WHERE - `system_src`.`mapId` " . $whereMapIdsQuery . " AND - `system_src`.`active` = 1 AND - `map`.`active` = 1 - HAVING - -- skip systems without neighbors (e.g. WHs) - jumpNodes IS NOT NULL - "; + " . $whereQuery . " + `connection`.`active` = 1 AND + `connection`.`mapId` " . $whereMapIdsQuery . " + "; $rows = $this->getDB()->exec($query, null, $this->dynamicJumpDataCacheTime); if(count($rows) > 0){ - // enrich $row data with static system data (from universe DB) + $jumpData = []; $universe = new Universe(); - for($i = 0; $i < count($rows); $i++){ - if($staticData = $universe->getSystemData($rows[$i]['systemId'])){ - $rows[$i]['systemName'] = $staticData->name; - $rows[$i]['constellationId'] = $staticData->constellation->id; - $rows[$i]['regionId'] = $staticData->constellation->region->id; - $rows[$i]['trueSec'] = $staticData->trueSec; + + /** + * enrich dynamic jump data with static system data (from universe DB) + * @param array $row + * @param string $systemSourceKey + * @param string $systemTargetKey + */ + $enrichJumpData = function(array &$row, string $systemSourceKey, string $systemTargetKey) use (&$jumpData, &$universe) { + if( + !array_key_exists($row[$systemSourceKey], $jumpData) && + !is_null($staticData = $universe->getSystemData($row[$systemSourceKey])) + ){ + $jumpData[$row[$systemSourceKey]] = [ + 'systemId' => (int)$row[$systemSourceKey], + 'systemName' => $staticData->name, + 'constellationId' => $staticData->constellation->id, + 'regionId' => $staticData->constellation->region->id, + 'trueSec' => $staticData->trueSec, + ]; } + + if( !in_array($row[$systemTargetKey], (array)$jumpData[$row[$systemSourceKey]]['jumpNodes']) ){ + $jumpData[$row[$systemSourceKey]]['jumpNodes'][] = (int)$row[$systemTargetKey]; + } + }; + + for($i = 0; $i < count($rows); $i++){ + $enrichJumpData($rows[$i], 'systemSourceId', 'systemTargetId'); + $enrichJumpData($rows[$i], 'systemTargetId', 'systemSourceId'); } // update jump data for this instance - $this->updateJumpData($rows); + $this->updateJumpData($jumpData); } - } } } @@ -259,7 +269,7 @@ class Route extends Controller\AccessController { if( !is_array($this->jumpArray[$systemId]) ){ $this->jumpArray[$systemId] = []; } - $this->jumpArray[$systemId] = array_merge(array_map('intval', explode(':', $row['jumpNodes'])), $this->jumpArray[$systemId]); + $this->jumpArray[$systemId] = array_merge($row['jumpNodes'], $this->jumpArray[$systemId]); // add systemName to end (if not already there) if(end($this->jumpArray[$systemId]) != $systemName){ diff --git a/app/main/controller/api/user.php b/app/main/controller/api/user.php index 190f5d98..0425d5c3 100644 --- a/app/main/controller/api/user.php +++ b/app/main/controller/api/user.php @@ -41,23 +41,24 @@ class User extends Controller\Controller{ /** * login a valid character - * @param Model\CharacterModel $characterModel + * @param Model\CharacterModel $character * @return bool * @throws Exception */ - protected function loginByCharacter(Model\CharacterModel &$characterModel){ + protected function loginByCharacter(Model\CharacterModel &$character) : bool { $login = false; - if($user = $characterModel->getUser()){ + if($user = $character->getUser()){ // check if character belongs to current user // -> If there is already a logged in user! (e.g. multi character use) $currentUser = $this->getUser(); + $timezone = $this->getF3()->get('getTimeZone')(); $sessionCharacters = [ [ - 'ID' => $characterModel->_id, - 'NAME' => $characterModel->name, - 'TIME' => (new \DateTime())->getTimestamp(), + 'ID' => $character->_id, + 'NAME' => $character->name, + 'TIME' => (new \DateTime('now', $timezone))->getTimestamp(), 'UPDATE_RETRY' => 0 ] ]; @@ -74,29 +75,29 @@ class User extends Controller\Controller{ ]); }else{ // user has NOT changed ----------------------------------------------------------- - $sessionCharacters = $characterModel::mergeSessionCharacterData($sessionCharacters); + $sessionCharacters = $character::mergeSessionCharacterData($sessionCharacters); } $this->getF3()->set(self::SESSION_KEY_CHARACTERS, $sessionCharacters); // save user login information -------------------------------------------------------- - $characterModel->roleId = $characterModel->requestRole(); - $characterModel->touch('lastLogin'); - $characterModel->save(); + $character->roleId = $character->requestRole(); + $character->touch('lastLogin'); + $character->save(); // write login log -------------------------------------------------------------------- self::getLogger('LOGIN')->write( sprintf(self::LOG_LOGGED_IN, $user->_id, $user->name, - $characterModel->_id, - $characterModel->name + $character->_id, + $character->name ) ); // set temp character data ------------------------------------------------------------ // -> pass character data over for next http request (reroute()) - $this->setTempCharacterData($characterModel->_id); + $this->setTempCharacterData($character->_id); $login = true; } @@ -112,31 +113,30 @@ class User extends Controller\Controller{ */ public function getCookieCharacter(\Base $f3){ $data = $f3->get('POST'); + $cookieName = (string)$data['cookie']; $return = (object) []; $return->error = []; - if( !empty($data['cookie']) ){ - if( !empty($cookieData = $this->getCookieByName($data['cookie']) )){ - // cookie data is valid -> validate data against DB (security check!) - // -> add characters WITHOUT permission to log in too! - if( !empty($characters = $this->getCookieCharacters(array_slice($cookieData, 0, 1, true), false)) ){ - // character is valid and allowed to login - $return->character = reset($characters)->getData(); - // get Session status for character - if($activeCharacter = $this->getCharacter()){ - if($activeUser = $activeCharacter->getUser()){ - if($sessionCharacterData = $activeUser->findSessionCharacterData($return->character->id)){ - $return->character->hasActiveSession = true; - } + if( !empty($cookieData = $this->getCookieByName($cookieName) )){ + // cookie data is valid -> validate data against DB (security check!) + // -> add characters WITHOUT permission to log in too! + if( !empty($characters = $this->getCookieCharacters(array_slice($cookieData, 0, 1, true), false)) ){ + // character is valid and allowed to login + $return->character = reset($characters)->getData(); + // get Session status for character + if($activeCharacter = $this->getCharacter()){ + if($activeUser = $activeCharacter->getUser()){ + if($sessionCharacterData = $activeUser->findSessionCharacterData($return->character->id)){ + $return->character->hasActiveSession = true; } } - }else{ - $characterError = (object) []; - $characterError->type = 'warning'; - $characterError->message = 'This can happen through "invalid cookies(SSO)", "login restrictions", "ESI problems".'; - $return->error[] = $characterError; } + }else{ + $characterError = (object) []; + $characterError->type = 'warning'; + $characterError->message = 'This can happen through "invalid cookies(SSO)", "login restrictions", "ESI problems".'; + $return->error[] = $characterError; } } diff --git a/app/main/controller/ccp/sso.php b/app/main/controller/ccp/sso.php index 7cbd3d5e..36609695 100644 --- a/app/main/controller/ccp/sso.php +++ b/app/main/controller/ccp/sso.php @@ -45,8 +45,7 @@ class Sso extends Api\User{ const ERROR_CHARACTER_DATA = 'Failed to load characterData from ESI'; const ERROR_CHARACTER_FORBIDDEN = 'Character "%s" is not authorized to log in. Reason: %s'; const ERROR_SERVICE_TIMEOUT = 'CCP SSO service timeout (%ss). Try again later'; - const ERROR_COOKIE_LOGIN = 'Login from Cookie failed. Please retry by CCP SSO'; - + const ERROR_COOKIE_LOGIN = 'Login from Cookie failed (data not found). Please retry by CCP SSO'; /** * redirect user to CCP SSO page and request authorization @@ -104,9 +103,7 @@ class Sso extends Api\User{ $character->hasUserCharacter() && ($character->isAuthorized() === 'OK') ){ - $loginCheck = $this->loginByCharacter($character); - - if($loginCheck){ + if($this->loginByCharacter($character)){ // set "login" cookie $this->setLoginCookie($character); @@ -253,9 +250,7 @@ class Sso extends Api\User{ $characterModel = $userCharactersModel->getCharacter(); // login by character - $loginCheck = $this->loginByCharacter($characterModel); - - if($loginCheck){ + if($this->loginByCharacter($characterModel)){ // set "login" cookie $this->setLoginCookie($characterModel); @@ -306,7 +301,7 @@ class Sso extends Api\User{ */ public function login(\Base $f3){ $data = (array)$f3->get('GET'); - $cookieName = empty($data['cookie']) ? '' : $data['cookie']; + $cookieName = (string)$data['cookie']; $character = null; if( !empty($cookieName) ){ @@ -319,17 +314,19 @@ class Sso extends Api\User{ } } - if( is_object($character)){ + if(is_object($character)){ // login by character - $loginCheck = $this->loginByCharacter($character); - if($loginCheck){ + if($this->loginByCharacter($character)){ // route to "map" $f3->reroute(['map', ['*' => '']]); + }else{ + $f3->set(self::SESSION_KEY_SSO_ERROR, sprintf(self::ERROR_LOGIN_FAILED, $character->name)); } + }else{ + $f3->set(self::SESSION_KEY_SSO_ERROR, self::ERROR_COOKIE_LOGIN); } // on error -> route back to login form - $f3->set(self::SESSION_KEY_SSO_ERROR, self::ERROR_COOKIE_LOGIN); $f3->reroute(['login']); } diff --git a/app/main/controller/controller.php b/app/main/controller/controller.php index 1d74f5ab..6d051caf 100644 --- a/app/main/controller/controller.php +++ b/app/main/controller/controller.php @@ -212,7 +212,7 @@ class Controller { $data[$name] = $value; } } - }elseif( isset($cookieData[$cookieName]) ){ + }elseif(isset($cookieData[$cookieName])){ // look for a single cookie $data[$cookieName] = $cookieData[$cookieName]; } @@ -539,6 +539,7 @@ class Controller { /** * get EVE server status from ESI * @param \Base $f3 + * @throws \Exception */ public function getEveServerStatus(\Base $f3){ $cacheKey = 'eve_server_status'; diff --git a/app/main/model/charactermodel.php b/app/main/model/charactermodel.php index a1ed6590..6b85e3e6 100644 --- a/app/main/model/charactermodel.php +++ b/app/main/model/charactermodel.php @@ -1121,7 +1121,7 @@ class CharacterModel extends BasicModel { * @param array $characterDataBase * @return array */ - public static function mergeSessionCharacterData(array $characterDataBase = []){ + public static function mergeSessionCharacterData(array $characterDataBase = []) : array { $addData = []; // get current session characters to be merged with $characterData = (array)self::getF3()->get(User::SESSION_KEY_CHARACTERS);