diff --git a/app/config/collections.php b/app/config/collections.php index afe5a963f5..606cae782a 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4177,17 +4177,6 @@ $consoleCollections = array_merge([ 'array' => false, 'filters' => [], ], - [ - '$id' => ID::custom('minFactors'), - 'type' => Database::VAR_INTEGER, - 'format' => '', - 'size' => 0, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], [ '$id' => ID::custom('services'), 'type' => Database::VAR_STRING, diff --git a/app/console b/app/console index ab5a7e673e..0a007a3b1b 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit ab5a7e673e92ebc2ebdcd9bc23e5c8fd57ff6db1 +Subproject commit 0a007a3b1b6eafc39dc19b7129f41643102f9676 diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index f3af74a551..4244c6d2f8 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -3499,7 +3499,7 @@ App::get('/v1/account/mfa/providers') App::post('/v1/account/mfa/:provider') ->desc('Add Authenticator') - ->groups(['api', 'account', 'mfa']) + ->groups(['api', 'account']) ->label('event', 'users.[userId].update.mfa') ->label('scope', 'accounts.write') ->label('audits.event', 'user.update') @@ -3559,7 +3559,7 @@ App::post('/v1/account/mfa/:provider') App::put('/v1/account/mfa/:provider') ->desc('Verify Authenticator') - ->groups(['api', 'account', 'mfa']) + ->groups(['api', 'account']) ->label('event', 'users.[userId].update.mfa') ->label('scope', 'accounts.write') ->label('audits.event', 'user.update') @@ -3697,11 +3697,13 @@ App::post('/v1/account/mfa/challenge') ->action(function (string $provider, Response $response, Database $dbForProject, Document $user, Document $project, Event $queueForEvents, Messaging $queueForMessaging, Mail $queueForMails, Locale $locale) { $expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_CONFIRM); + $code = Auth::codeGenerator(); $challenge = new Document([ 'userId' => $user->getId(), 'userInternalId' => $user->getInternalId(), 'provider' => $provider, 'token' => Auth::tokenGenerator(), + 'code' => $code, 'expire' => $expire, '$permissions' => [ Permission::read(Role::user($user->getId())), @@ -3710,6 +3712,8 @@ App::post('/v1/account/mfa/challenge') ], ]); + $challenge = $dbForProject->createDocument('challenges', $challenge); + switch ($provider) { case 'phone': if (empty(App::getEnv('_APP_SMS_PROVIDER'))) { @@ -3722,11 +3726,14 @@ App::post('/v1/account/mfa/challenge') throw new Exception(Exception::USER_PHONE_NOT_VERIFIED); } - $code = Auth::codeGenerator(); - $challenge->setAttribute('code', $code); - $messaging - ->setRecipient($user->getAttribute('phone')) - ->setMessage($code) + $queueForMessaging + ->setMessage(new Document([ + '$id' => $challenge->getId(), + 'data' => [ + 'content' => $code, + ], + ])) + ->setRecipients([$user->getAttribute('phone')]) ->trigger(); break; case 'email': @@ -3740,21 +3747,14 @@ App::post('/v1/account/mfa/challenge') throw new Exception(Exception::USER_EMAIL_NOT_VERIFIED); } - $code = Auth::codeGenerator(); - $challenge->setAttribute('code', $code); - $from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $project->getAttribute('name')); - - $mails - ->setSubject('mfa challenge') + $queueForMails + ->setSubject("{$code} is your 6-digit code") ->setBody($code) - ->setFrom($from) ->setRecipient($user->getAttribute('email')) ->trigger(); break; } - $challenge = $dbForProject->createDocument('challenges', $challenge); - $queueForEvents ->setParam('userId', $user->getId()) ->setParam('challengeId', $challenge->getId()); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index e7ca9bed99..01a7c26e77 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -166,7 +166,6 @@ App::post('/v1/projects') 'webhooks' => null, 'keys' => null, 'auths' => $auths, - 'minFactors' => 1, 'search' => implode(' ', [$projectId, $name]), 'database' => $database ])); @@ -741,36 +740,6 @@ App::patch('/v1/projects/:projectId/auth/max-sessions') $response->dynamic($project, Response::MODEL_PROJECT); }); -App::patch('/v1/projects/:projectId/auth/mfa/factors') - ->desc('Update Project user minimum sessions factors') - ->groups(['api', 'projects']) - ->label('scope', 'projects.write') - ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) - ->label('sdk.namespace', 'projects') - ->label('sdk.method', 'updateAuthMfaFactors') - ->label('sdk.response.code', Response::STATUS_CODE_OK) - ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) - ->label('sdk.response.model', Response::MODEL_PROJECT) - ->param('projectId', '', new UID(), 'Project unique ID.') - ->param('factors', false, new Range(1, 4), '') - ->inject('response') - ->inject('dbForConsole') - ->action(function (string $projectId, int $factors, Response $response, Database $dbForConsole) { - - $project = $dbForConsole->getDocument('projects', $projectId); - - if ($project->isEmpty()) { - throw new Exception(Exception::PROJECT_NOT_FOUND); - } - - $auths = $project->getAttribute('auths', []); - $auths['minFactors'] = $factors; - - $dbForConsole->updateDocument('projects', $project->getId(), $project->setAttribute('auths', $auths)); - - $response->dynamic($project, Response::MODEL_PROJECT); - }); - App::delete('/v1/projects/:projectId') ->desc('Delete project') ->groups(['api', 'projects']) diff --git a/app/controllers/general.php b/app/controllers/general.php index 0291281349..ebb2a31891 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -564,17 +564,15 @@ App::init() } if ($mode !== APP_MODE_ADMIN) { - $minFactors = $project->getAttribute('minFactors') ?? 1; $mfaEnabled = $user->getAttribute('mfa', false); $hasVerifiedAuthenticator = $user->getAttribute('totpVerification', false); $hasVerifiedEmail = $user->getAttribute('emailVerification', false); $hasVerifiedPhone = $user->getAttribute('phoneVerification', false); $hasMoreFactors = $hasVerifiedEmail || $hasVerifiedPhone || $hasVerifiedAuthenticator; - if ($mfaEnabled && $hasMoreFactors && $minFactors === 1) { - $minFactors = 2; - } + $minimumFactors = ($mfaEnabled && $hasMoreFactors) ? 2 : 1; + if (!in_array('mfa', $route->getGroups())) { - if ($session && \count($session->getAttribute('factors')) < $minFactors) { + if ($session && \count($session->getAttribute('factors')) < $minimumFactors) { throw new AppwriteException(AppwriteException::USER_MORE_FACTORS_REQUIRED); } }