diff --git a/CHANGES.md b/CHANGES.md index 59a7b09e3..91e6e4dbe 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ - Added new environment variables to the `telegraf` service: (#1202) - _APP_INFLUXDB_HOST - _APP_INFLUXDB_PORT +- Added new endpoint to get a session based on it's ID (#1294) ## Breaking Changes (Read before upgrading!) - Renamed `env` param on `/v1/functions` to `runtime` (#1314) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 1801a26e3..38a1ad118 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -254,9 +254,13 @@ App::post('/v1/account/sessions') $countries = $locale->getText('countries'); + $countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))])) + ? $countries[strtoupper($session->getAttribute('countryCode'))] + : $locale->getText('locale.country.unknown'); + $session ->setAttribute('current', true) - ->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))])) ? $countries[strtoupper($session->getAttribute('countryCode'))] : $locale->getText('locale.country.unknown')) + ->setAttribute('countryName', $countryName) ; $response->dynamic($session, Response::MODEL_SESSION); @@ -753,9 +757,13 @@ App::post('/v1/account/sessions/anonymous') ->setStatusCode(Response::STATUS_CODE_CREATED) ; + $countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))])) + ? $countries[strtoupper($session->getAttribute('countryCode'))] + : $locale->getText('locale.country.unknown'); + $session ->setAttribute('current', true) - ->setAttribute('countryName', (isset($countries[$session->getAttribute('countryCode')])) ? $countries[$session->getAttribute('countryCode')] : $locale->getText('locale.country.unknown')) + ->setAttribute('countryName', $countryName) ; $response->dynamic($session, Response::MODEL_SESSION); @@ -878,9 +886,11 @@ App::get('/v1/account/sessions') foreach ($sessions as $key => $session) { /** @var Document $session */ - $session->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))])) - ? $countries[strtoupper($session->getAttribute('countryCode'))] - : $locale->getText('locale.country.unknown')); + $countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))])) + ? $countries[strtoupper($session->getAttribute('countryCode'))] + : $locale->getText('locale.country.unknown'); + + $session->setAttribute('countryName', $countryName); $session->setAttribute('current', ($current == $session->getId()) ? true : false); $sessions[$key] = $session; @@ -968,6 +978,47 @@ App::get('/v1/account/logs') $response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST); }); +App::get('/v1/account/sessions/:sessionId') + ->desc('Get Session By ID') + ->groups(['api', 'account']) + ->label('scope', 'account') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'account') + ->label('sdk.method', 'getSession') + ->label('sdk.description', '/docs/references/account/get-session.md') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_SESSION) + ->param('sessionId', null, new UID(), 'Session unique ID. Use the string \'current\' to get the current device session.') + ->inject('response') + ->inject('user') + ->inject('locale') + ->inject('projectDB') + ->action(function ($sessionId, $response, $user, $locale, $projectDB) { + /** @var Appwrite\Utopia\Response $response */ + /** @var Appwrite\Database\Document $user */ + /** @var Utopia\Locale\Locale $locale */ + /** @var Appwrite\Database\Database $projectDB */ + + $sessionId = ($sessionId === 'current') + ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) + : $sessionId; + + $session = $projectDB->getDocument($sessionId); // get user by session ID + + if ($session->isEmpty() || Database::SYSTEM_COLLECTION_SESSIONS != $session->getCollection()) { + throw new Exception('Session not found', 404); + }; + + $countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))])) + ? $countries[strtoupper($session->getAttribute('countryCode'))] + : $locale->getText('locale.country.unknown'); + + $session->setAttribute('countryName', $countryName); + + $response->dynamic($session, Response::MODEL_SESSION); + }); + App::patch('/v1/account/name') ->desc('Update Account Name') ->groups(['api', 'account']) diff --git a/docs/references/account/get-session.md b/docs/references/account/get-session.md new file mode 100644 index 000000000..91b58fa48 --- /dev/null +++ b/docs/references/account/get-session.md @@ -0,0 +1 @@ +Use this endpoint to get a logged in user's session using a Session ID. Inputting 'current' will return the current session being used. \ No newline at end of file diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 77a4f9368..e3d5587d5 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -424,4 +424,39 @@ class AccountCustomClientTest extends Scope return []; } + + public function testGetSessionByID() { + $session = $this->testCreateAnonymousAccount(); + + $response = $this->client->call(Client::METHOD_GET, '/account/sessions/current', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ])); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertEquals($response['body']['provider'], 'anonymous'); + + $sessionID = $response['body']['$id']; + + $response = $this->client->call(Client::METHOD_GET, '/account/sessions/'.$sessionID, array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ])); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertEquals($response['body']['provider'], 'anonymous'); + + $response = $this->client->call(Client::METHOD_GET, '/account/sessions/97823askjdkasd80921371980', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ])); + + $this->assertEquals($response['headers']['status-code'], 404); + } } \ No newline at end of file