mirror of
https://github.com/appwrite/appwrite
synced 2026-05-22 16:38:32 +00:00
Merge branch '1.5.x' into feat-add-version-header
This commit is contained in:
commit
8ff98bcb41
6 changed files with 65 additions and 46 deletions
|
|
@ -5,7 +5,7 @@
|
|||
<table border="0" cellspacing="0" cellpadding="0" style="padding-top: 10px; padding-bottom: 10px; display: inline-block;">
|
||||
<tr>
|
||||
<td align="center" style="border-radius: 8px; background-color: #ffffff;">
|
||||
<p style="font-size: 24px; text-indent: 18px; letter-spacing: 18px; font-family: Inter; color: #414146; text-decoration: none; border-radius: 8px; padding: 24px 12px; border: 1px solid #EDEDF0; display: inline-block; font-weight: bold; ">{{otp}}</p>
|
||||
<p style="font-size: 24px; text-indent: 18px; letter-spacing: 18px; font-family: 'Inter', sans-serif; color: #414146; text-decoration: none; border-radius: 8px; padding: 24px 12px; border: 1px solid #EDEDF0; display: inline-block; font-weight: bold; ">{{otp}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -1069,17 +1069,15 @@ App::get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
|||
$domain = $request->getHostname();
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$params = $request->getParams();
|
||||
$params['project'] = $projectId;
|
||||
unset($params['projectId']);
|
||||
|
||||
$response
|
||||
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->addHeader('Pragma', 'no-cache')
|
||||
->redirect($protocol . '://' . $domain . '/v1/account/sessions/oauth2/' . $provider . '/redirect?'
|
||||
. \http_build_query([
|
||||
'project' => $projectId,
|
||||
'code' => $code,
|
||||
'state' => $state,
|
||||
'error' => $error,
|
||||
'error_description' => $error_description
|
||||
]));
|
||||
. \http_build_query($params));
|
||||
});
|
||||
|
||||
App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
||||
|
|
@ -1102,17 +1100,15 @@ App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
|||
$domain = $request->getHostname();
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$params = $request->getParams();
|
||||
$params['project'] = $projectId;
|
||||
unset($params['projectId']);
|
||||
|
||||
$response
|
||||
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->addHeader('Pragma', 'no-cache')
|
||||
->redirect($protocol . '://' . $domain . '/v1/account/sessions/oauth2/' . $provider . '/redirect?'
|
||||
. \http_build_query([
|
||||
'project' => $projectId,
|
||||
'code' => $code,
|
||||
'state' => $state,
|
||||
'error' => $error,
|
||||
'error_description' => $error_description
|
||||
]));
|
||||
. \http_build_query($params));
|
||||
});
|
||||
|
||||
App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
|
|
@ -1239,7 +1235,17 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
$failureRedirect(Exception::USER_MISSING_ID);
|
||||
}
|
||||
|
||||
$name = $oauth2->getUserName($accessToken);
|
||||
$name = '';
|
||||
$nameOAuth = $oauth2->getUserName($accessToken);
|
||||
$userParam = \json_decode($request->getParam('user'), true);
|
||||
if (!empty($nameOAuth)) {
|
||||
$name = $nameOAuth;
|
||||
} elseif (is_array($userParam)) {
|
||||
$nameParam = $userParam['name'];
|
||||
if (is_array($nameParam) && isset($nameParam['firstName']) && isset($nameParam['lastName'])) {
|
||||
$name = $nameParam['firstName'] . ' ' . $nameParam['lastName'];
|
||||
}
|
||||
}
|
||||
$email = $oauth2->getUserEmail($accessToken);
|
||||
|
||||
// Check if this identity is connected to a different user
|
||||
|
|
@ -3495,14 +3501,33 @@ App::patch('/v1/account/mfa')
|
|||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('session')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->action(function (bool $mfa, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) {
|
||||
->action(function (bool $mfa, ?\DateTime $requestTimestamp, Response $response, Document $user, Document $session, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$user->setAttribute('mfa', $mfa);
|
||||
|
||||
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
|
||||
|
||||
if ($mfa) {
|
||||
$factors = $session->getAttribute('factors', []);
|
||||
$totp = TOTP::getAuthenticatorFromUser($user);
|
||||
if ($totp !== null && $totp->getAttribute('verified', false)) {
|
||||
$factors[] = Type::TOTP;
|
||||
}
|
||||
if ($user->getAttribute('email', false) && $user->getAttribute('emailVerification', false)) {
|
||||
$factors[] = Type::EMAIL;
|
||||
}
|
||||
if ($user->getAttribute('phone', false) && $user->getAttribute('phoneVerification', false)) {
|
||||
$factors[] = Type::PHONE;
|
||||
}
|
||||
$factors = \array_unique($factors);
|
||||
|
||||
$session->setAttribute('factors', $factors);
|
||||
$dbForProject->updateDocument('sessions', $session->getId(), $session);
|
||||
}
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
|
||||
$response->dynamic($user, Response::MODEL_ACCOUNT);
|
||||
|
|
@ -3633,10 +3658,10 @@ App::put('/v1/account/mfa/authenticators/:type')
|
|||
->param('otp', '', new Text(256), 'Valid verification token.')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('project')
|
||||
->inject('session')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $type, string $otp, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents) {
|
||||
->action(function (string $type, string $otp, Response $response, Document $user, Document $session, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$authenticator = (match ($type) {
|
||||
Type::TOTP => TOTP::getAuthenticatorFromUser($user),
|
||||
|
|
@ -3665,10 +3690,12 @@ App::put('/v1/account/mfa/authenticators/:type')
|
|||
$dbForProject->updateDocument('authenticators', $authenticator->getId(), $authenticator);
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$sessionId = Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $authDuration);
|
||||
$session = $dbForProject->getDocument('sessions', $sessionId);
|
||||
$dbForProject->updateDocument('sessions', $sessionId, $session->setAttribute('factors', $type, Document::SET_TYPE_APPEND));
|
||||
$factors = $session->getAttribute('factors', []);
|
||||
$factors[] = $type;
|
||||
$factors = \array_unique($factors);
|
||||
|
||||
$session->setAttribute('factors', $factors);
|
||||
$dbForProject->updateDocument('sessions', $session->getId(), $session);
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
|
||||
|
|
@ -4057,9 +4084,10 @@ App::put('/v1/account/mfa/challenge')
|
|||
->inject('project')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('session')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $challengeId, string $otp, Document $project, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) {
|
||||
->action(function (string $challengeId, string $otp, Document $project, Response $response, Document $user, Document $session, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$challenge = $dbForProject->getDocument('challenges', $challengeId);
|
||||
|
||||
|
|
@ -4105,15 +4133,15 @@ App::put('/v1/account/mfa/challenge')
|
|||
$dbForProject->deleteDocument('challenges', $challengeId);
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$sessionId = Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $authDuration);
|
||||
$session = $dbForProject->getDocument('sessions', $sessionId);
|
||||
$factors = $session->getAttribute('factors', []);
|
||||
$factors[] = $type;
|
||||
$factors = \array_unique($factors);
|
||||
|
||||
$session = $session
|
||||
->setAttribute('factors', $type, Document::SET_TYPE_APPEND)
|
||||
$session
|
||||
->setAttribute('factors', $factors)
|
||||
->setAttribute('mfaUpdatedAt', DateTime::now());
|
||||
|
||||
$dbForProject->updateDocument('sessions', $sessionId, $session);
|
||||
$dbForProject->updateDocument('sessions', $session->getId(), $session);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ App::get('/v1/project/usage')
|
|||
'1d' => 'Y-m-d\T00:00:00.000P',
|
||||
};
|
||||
|
||||
Authorization::skip(function () use ($dbForProject, $firstDay, $lastDay, $period, $metrics, &$total, &$stats) {
|
||||
Authorization::skip(function () use ($dbForProject, $firstDay, $lastDay, $period, $metrics, $limit, &$total, &$stats) {
|
||||
foreach ($metrics['total'] as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
|
|
@ -85,6 +85,7 @@ App::get('/v1/project/usage')
|
|||
Query::equal('period', [$period]),
|
||||
Query::greaterThanEqual('time', $firstDay),
|
||||
Query::lessThan('time', $lastDay),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -750,12 +750,12 @@ App::error()
|
|||
'file' => $file,
|
||||
'line' => $line,
|
||||
'trace' => \json_encode($trace, JSON_UNESCAPED_UNICODE) === false ? [] : $trace, // check for failing encode
|
||||
'version' => $version,
|
||||
'version' => APP_VERSION_STABLE,
|
||||
'type' => $type,
|
||||
] : [
|
||||
'message' => $message,
|
||||
'code' => $code,
|
||||
'version' => $version,
|
||||
'version' => APP_VERSION_STABLE,
|
||||
'type' => $type,
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1239,14 +1239,13 @@ App::setResource('project', function ($dbForConsole, $request, $console) {
|
|||
return $project;
|
||||
}, ['dbForConsole', 'request', 'console']);
|
||||
|
||||
App::setResource('session', function (Document $user, Document $project) {
|
||||
App::setResource('session', function (Document $user) {
|
||||
if ($user->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sessions = $user->getAttribute('sessions', []);
|
||||
$authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$sessionId = Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret, $authDuration);
|
||||
$sessionId = Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret);
|
||||
|
||||
if (!$sessionId) {
|
||||
return;
|
||||
|
|
@ -1259,7 +1258,7 @@ App::setResource('session', function (Document $user, Document $project) {
|
|||
}
|
||||
|
||||
return;
|
||||
}, ['user', 'project']);
|
||||
}, ['user']);
|
||||
|
||||
App::setResource('console', function () {
|
||||
return new Document([
|
||||
|
|
|
|||
|
|
@ -160,15 +160,6 @@ class Apple extends OAuth2
|
|||
*/
|
||||
public function getUserName(string $accessToken): string
|
||||
{
|
||||
if (
|
||||
isset($this->claims['email']) &&
|
||||
!empty($this->claims['email']) &&
|
||||
isset($this->claims['email_verified']) &&
|
||||
$this->claims['email_verified'] === 'true'
|
||||
) {
|
||||
return $this->claims['email'];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue