diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 6a109ee5c7..12b758f2a1 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -1448,8 +1448,58 @@ App::post('/v1/users/:userId/sessions') ->action(function (string $userId, Request $request, Response $response, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents) { $user = $dbForProject->getDocument('users', $userId); - if ($user->isEmpty()) { - throw new Exception(Exception::USER_NOT_FOUND); + if ($user !== false && !$user->isEmpty()) { + $user->setAttributes($user->getArrayCopy()); + } else { + $limit = $project->getAttribute('auths', [])['limit'] ?? 0; + + if ($limit !== 0) { + $total = $dbForProject->count('users', max: APP_LIMIT_USERS); + + if ($total >= $limit) { + throw new Exception(Exception::USER_COUNT_EXCEEDED); + } + } + + if ($userId !== 'unique()') { + $existingUser = $dbForProject->findOne('users', [ + Query::equal('$id', [$userId]), + ]); + + if ($existingUser !== false && !$existingUser->isEmpty()) { + throw new Exception(Exception::USER_ALREADY_EXISTS); + } + } + + $userId = $userId === 'unique()' ? ID::unique() : $userId; + + + $user->setAttributes([ + '$id' => $userId, + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::user($userId)), + Permission::delete(Role::user($userId)), + ], + 'email' => null, + 'emailVerification' => false, + 'status' => true, + 'password' => null, + 'hash' => Auth::DEFAULT_ALGO, + 'hashOptions' => Auth::DEFAULT_ALGO_OPTIONS, + 'passwordUpdate' => null, + 'registration' => DateTime::now(), + 'reset' => false, + 'prefs' => new \stdClass(), + 'sessions' => null, + 'tokens' => null, + 'memberships' => null, + 'search' => implode(' ', [$userId]), + 'accessedAt' => DateTime::now(), + ]); + + $user->removeAttribute('$internalId'); + Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); } $secret = Auth::codeGenerator();