From 255c0ac866d77061f2e98d73d06e57ef91bb0b69 Mon Sep 17 00:00:00 2001 From: Aditya Oberai Date: Wed, 22 Oct 2025 22:21:56 +0000 Subject: [PATCH] Add provider info to the session data for OAuth2 token auth --- app/controllers/api/account.php | 53 +++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 5563fc6a59..e98cac4e69 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -201,19 +201,48 @@ $createSession = function (string $userId, string $secret, Request $request, Res default => throw new Exception(Exception::USER_INVALID_TOKEN) }); + $sessionData = [ + '$id' => ID::unique(), + 'userId' => $user->getId(), + 'userInternalId' => $user->getSequence(), + 'provider' => Auth::getSessionProviderByTokenType($verifiedToken->getAttribute('type')), + 'secret' => Auth::hash($sessionSecret), // One way hash encryption to protect DB leak + 'userAgent' => $request->getUserAgent('UNKNOWN'), + 'ip' => $request->getIP(), + 'factors' => [$factor], + 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', + 'expire' => DateTime::addSeconds(new \DateTime(), $duration) + ]; + + // For OAuth2 tokens, retrieve and add provider tokens from identity + if ($verifiedToken->getAttribute('type') === Auth::TOKEN_TYPE_OAUTH2) { + // Find the most recently updated identity for this user with an access token + // This will be the identity that was just used in the OAuth2 flow + $identities = $dbForProject->find('identities', [ + Query::equal('userInternalId', [$user->getSequence()]), + Query::orderDesc('$updatedAt'), + Query::limit(100) + ]); + + // Find the first identity with a non-empty access token + $latestIdentity = null; + foreach ($identities as $identity) { + if (!empty($identity->getAttribute('providerAccessToken'))) { + $latestIdentity = $identity; + break; + } + } + + if ($latestIdentity && !$latestIdentity->isEmpty()) { + $sessionData['providerUid'] = $latestIdentity->getAttribute('providerUid', ''); + $sessionData['providerAccessToken'] = $latestIdentity->getAttribute('providerAccessToken', ''); + $sessionData['providerRefreshToken'] = $latestIdentity->getAttribute('providerRefreshToken', ''); + $sessionData['providerAccessTokenExpiry'] = $latestIdentity->getAttribute('providerAccessTokenExpiry', ''); + } + } + $session = new Document(array_merge( - [ - '$id' => ID::unique(), - 'userId' => $user->getId(), - 'userInternalId' => $user->getSequence(), - 'provider' => Auth::getSessionProviderByTokenType($verifiedToken->getAttribute('type')), - 'secret' => Auth::hash($sessionSecret), // One way hash encryption to protect DB leak - 'userAgent' => $request->getUserAgent('UNKNOWN'), - 'ip' => $request->getIP(), - 'factors' => [$factor], - 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', - 'expire' => DateTime::addSeconds(new \DateTime(), $duration) - ], + $sessionData, $detector->getOS(), $detector->getClient(), $detector->getDevice()