1
0
Fork 0
mirror of synced 2024-06-29 19:50:26 +12:00

Alter sessionVerify to remove expire

This commit is contained in:
Bradley Schofield 2022-11-04 09:50:59 +00:00
parent 4b8287c097
commit 94676a6c16
5 changed files with 24 additions and 22 deletions

View file

@ -453,7 +453,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
} }
$sessions = $user->getAttribute('sessions', []); $sessions = $user->getAttribute('sessions', []);
$current = Auth::sessionVerify($sessions, Auth::$secret); $current = Auth::sessionVerify($sessions, Auth::$secret, $project->getAttribute('authDuration', 0));
if ($current) { // Delete current session of new one. if ($current) { // Delete current session of new one.
$currentDocument = $dbForProject->getDocument('sessions', $current); $currentDocument = $dbForProject->getDocument('sessions', $current);
@ -1332,10 +1332,11 @@ App::get('/v1/account/sessions')
->inject('response') ->inject('response')
->inject('user') ->inject('user')
->inject('locale') ->inject('locale')
->action(function (Response $response, Document $user, Locale $locale) { ->inject('project')
->action(function (Response $response, Document $user, Locale $locale, Document $project) {
$sessions = $user->getAttribute('sessions', []); $sessions = $user->getAttribute('sessions', []);
$current = Auth::sessionVerify($sessions, Auth::$secret); $current = Auth::sessionVerify($sessions, Auth::$secret, $project->getAttribute('authDuration', 0));
foreach ($sessions as $key => $session) {/** @var Document $session */ foreach ($sessions as $key => $session) {/** @var Document $session */
$countryName = $locale->getText('countries.' . strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown')); $countryName = $locale->getText('countries.' . strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown'));
@ -1435,7 +1436,7 @@ App::get('/v1/account/sessions/:sessionId')
$sessions = $user->getAttribute('sessions', []); $sessions = $user->getAttribute('sessions', []);
$sessionId = ($sessionId === 'current') $sessionId = ($sessionId === 'current')
? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret, $project->getAttribute('authDuration', 0))
: $sessionId; : $sessionId;
foreach ($sessions as $session) {/** @var Document $session */ foreach ($sessions as $session) {/** @var Document $session */
@ -1445,7 +1446,7 @@ App::get('/v1/account/sessions/:sessionId')
$session $session
->setAttribute('current', ($session->getAttribute('secret') == Auth::hash(Auth::$secret))) ->setAttribute('current', ($session->getAttribute('secret') == Auth::hash(Auth::$secret)))
->setAttribute('countryName', $countryName) ->setAttribute('countryName', $countryName)
->setAttribute('expire', $session->getAttribute('$createdAt', 0) + $project->getAttribute('authDuration', 0)) ->setAttribute('expire', DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $project->getAttribute('authDuration', 0)))
; ;
return $response->dynamic($session, Response::MODEL_SESSION); return $response->dynamic($session, Response::MODEL_SESSION);
@ -1712,11 +1713,12 @@ App::delete('/v1/account/sessions/:sessionId')
->inject('dbForProject') ->inject('dbForProject')
->inject('locale') ->inject('locale')
->inject('events') ->inject('events')
->action(function (?string $sessionId, Request $request, Response $response, Document $user, Database $dbForProject, Locale $locale, Event $events) { ->inject('project')
->action(function (?string $sessionId, Request $request, Response $response, Document $user, Database $dbForProject, Locale $locale, Event $events, Document $project) {
$protocol = $request->getProtocol(); $protocol = $request->getProtocol();
$sessionId = ($sessionId === 'current') $sessionId = ($sessionId === 'current')
? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret, $project->getAttribute('authDuration', 0))
: $sessionId; : $sessionId;
$sessions = $user->getAttribute('sessions', []); $sessions = $user->getAttribute('sessions', []);
@ -1789,7 +1791,7 @@ App::patch('/v1/account/sessions/:sessionId')
->action(function (?string $sessionId, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Event $events) { ->action(function (?string $sessionId, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Event $events) {
$sessionId = ($sessionId === 'current') $sessionId = ($sessionId === 'current')
? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret, $project->getAttribute('authDuration', 0))
: $sessionId; : $sessionId;
$sessions = $user->getAttribute('sessions', []); $sessions = $user->getAttribute('sessions', []);
@ -1830,7 +1832,7 @@ App::patch('/v1/account/sessions/:sessionId')
$dbForProject->deleteCachedDocument('users', $user->getId()); $dbForProject->deleteCachedDocument('users', $user->getId());
$session->setAttribute('expire', $session->getAttribute('$createdAt', 0) + $project->getAttribute('authDuration', 0)); $session->setAttribute('expire', $session->getCreatedAt() + $project->getAttribute('authDuration', 0));
$events $events
->setParam('userId', $user->getId()) ->setParam('userId', $user->getId())

View file

@ -837,7 +837,7 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons
if ( if (
$user->isEmpty() // Check a document has been found in the DB $user->isEmpty() // Check a document has been found in the DB
|| !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret) || !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $project->getAttribute('authDuration', 0))
) { // Validate user has valid login token ) { // Validate user has valid login token
$user = new Document(['$id' => ID::custom(''), '$collection' => 'users']); $user = new Document(['$id' => ID::custom(''), '$collection' => 'users']);
} }

View file

@ -539,7 +539,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
if ( if (
empty($user->getId()) // Check a document has been found in the DB empty($user->getId()) // Check a document has been found in the DB
|| !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret) // Validate user has valid login token || !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $project->getAttribute('authDuration', 0)) // Validate user has valid login token
) { ) {
// cookie not valid // cookie not valid
throw new Exception('Session is not valid.', 1003); throw new Exception('Session is not valid.', 1003);

View file

@ -352,19 +352,19 @@ class Auth
* *
* @param array $sessions * @param array $sessions
* @param string $secret * @param string $secret
* @param string $expires
* *
* @return bool|string * @return bool|string
*/ */
public static function sessionVerify(array $sessions, string $secret) public static function sessionVerify(array $sessions, string $secret, int $expires)
{ {
foreach ($sessions as $session) { foreach ($sessions as $session) {
/** @var Document $session */ /** @var Document $session */
if ( if (
$session->isSet('secret') && $session->isSet('secret') &&
$session->isSet('expire') &&
$session->isSet('provider') && $session->isSet('provider') &&
$session->getAttribute('secret') === self::hash($secret) && $session->getAttribute('secret') === self::hash($secret) &&
DateTime::formatTz($session->getAttribute('expire')) >= DateTime::formatTz(DateTime::now()) DateTime::formatTz(DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $expires)) >= DateTime::formatTz(DateTime::now())
) { ) {
return $session->getId(); return $session->getId();
} }

View file

@ -204,46 +204,46 @@ class AuthTest extends TestCase
public function testSessionVerify(): void public function testSessionVerify(): void
{ {
$expireTime1 = 60 * 60 * 24;
$secret = 'secret1'; $secret = 'secret1';
$hash = Auth::hash($secret); $hash = Auth::hash($secret);
$tokens1 = [ $tokens1 = [
new Document([ new Document([
'$id' => ID::custom('token1'), '$id' => ID::custom('token1'),
'expire' => DateTime::formatTz(DateTime::addSeconds(new \DateTime(), 60 * 60 * 24)),
'secret' => $hash, 'secret' => $hash,
'provider' => Auth::SESSION_PROVIDER_EMAIL, 'provider' => Auth::SESSION_PROVIDER_EMAIL,
'providerUid' => 'test@example.com', 'providerUid' => 'test@example.com',
]), ]),
new Document([ new Document([
'$id' => ID::custom('token2'), '$id' => ID::custom('token2'),
'expire' => DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -60 * 60 * 24)),
'secret' => 'secret2', 'secret' => 'secret2',
'provider' => Auth::SESSION_PROVIDER_EMAIL, 'provider' => Auth::SESSION_PROVIDER_EMAIL,
'providerUid' => 'test@example.com', 'providerUid' => 'test@example.com',
]), ]),
]; ];
$expireTime2 = -60 * 60 * 24;
$tokens2 = [ $tokens2 = [
new Document([ // Correct secret and type time, wrong expire time new Document([ // Correct secret and type time, wrong expire time
'$id' => ID::custom('token1'), '$id' => ID::custom('token1'),
'expire' => DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -60 * 60 * 24)),
'secret' => $hash, 'secret' => $hash,
'provider' => Auth::SESSION_PROVIDER_EMAIL, 'provider' => Auth::SESSION_PROVIDER_EMAIL,
'providerUid' => 'test@example.com', 'providerUid' => 'test@example.com',
]), ]),
new Document([ new Document([
'$id' => ID::custom('token2'), '$id' => ID::custom('token2'),
'expire' => DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -60 * 60 * 24)),
'secret' => 'secret2', 'secret' => 'secret2',
'provider' => Auth::SESSION_PROVIDER_EMAIL, 'provider' => Auth::SESSION_PROVIDER_EMAIL,
'providerUid' => 'test@example.com', 'providerUid' => 'test@example.com',
]), ]),
]; ];
$this->assertEquals(Auth::sessionVerify($tokens1, $secret), 'token1'); $this->assertEquals(Auth::sessionVerify($tokens1, $secret, $expireTime1), 'token1');
$this->assertEquals(Auth::sessionVerify($tokens1, 'false-secret'), false); $this->assertEquals(Auth::sessionVerify($tokens1, 'false-secret', $expireTime1), false);
$this->assertEquals(Auth::sessionVerify($tokens2, $secret), false); $this->assertEquals(Auth::sessionVerify($tokens2, $secret, $expireTime2), false);
$this->assertEquals(Auth::sessionVerify($tokens2, 'false-secret'), false); $this->assertEquals(Auth::sessionVerify($tokens2, 'false-secret', $expireTime2), false);
} }
public function testTokenVerify(): void public function testTokenVerify(): void