diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 074fd57761..8832e30614 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -403,6 +403,163 @@ App::patch('/v1/users/:userId/verification') $response->dynamic($user, Response::MODEL_USER); }); +App::patch('/v1/users/:userId/name') + ->desc('Update Name') + ->groups(['api', 'users']) + ->label('event', 'users.update.name') + ->label('scope', 'users.write') + ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) + ->label('sdk.namespace', 'users') + ->label('sdk.method', 'updateName') + ->label('sdk.description', '/docs/references/users/update-user-name.md') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_USER) + ->param('userId', '', new UID(), 'User unique ID.') + ->param('name', '', new Text(128), 'User name. Max length: 128 chars.') + ->inject('response') + ->inject('projectDB') + ->inject('audits') + ->action(function ($userId, $name, $response, $projectDB, $audits) { + /** @var Appwrite\Utopia\Response $response */ + /** @var Appwrite\Database\Database $projectDB */ + /** @var Appwrite\Event\Event $audits */ + + $user = $projectDB->getDocument($userId); + + if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) { + throw new Exception('User not found', 404); + } + + $user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [ + 'name' => $name, + ])); + + if (false === $user) { + throw new Exception('Failed saving user to DB', 500); + } + + $audits + ->setParam('userId', $user->getId()) + ->setParam('event', 'users.update.name') + ->setParam('resource', 'users/'.$user->getId()) + ; + + $response->dynamic($user, Response::MODEL_USER); + }); + +App::patch('/v1/users/:userId/password') + ->desc('Update Password') + ->groups(['api', 'users']) + ->label('event', 'users.update.password') + ->label('scope', 'users.write') + ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) + ->label('sdk.namespace', 'users') + ->label('sdk.method', 'updatePassword') + ->label('sdk.description', '/docs/references/users/update-user-password.md') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_USER) + ->param('userId', '', new UID(), 'User unique ID.') + ->param('password', '', new Password(), 'New user password. Must be between 6 to 32 chars.') + ->inject('response') + ->inject('projectDB') + ->inject('audits') + ->action(function ($userId, $password, $response, $projectDB, $audits) { + /** @var Appwrite\Utopia\Response $response */ + /** @var Appwrite\Database\Database $projectDB */ + /** @var Appwrite\Event\Event $audits */ + + $user = $projectDB->getDocument($userId); + + if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) { + throw new Exception('User not found', 404); + } + + $user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [ + 'password' => Auth::passwordHash($password), + 'passwordUpdate' => \time(), + ])); + + if (false === $user) { + throw new Exception('Failed saving user to DB', 500); + } + + $audits + ->setParam('userId', $user->getId()) + ->setParam('event', 'users.update.password') + ->setParam('resource', 'users/'.$user->getId()) + ; + + $response->dynamic($user, Response::MODEL_USER); + }); + +App::patch('/v1/users/:userId/email') + ->desc('Update Email') + ->groups(['api', 'users']) + ->label('event', 'users.update.email') + ->label('scope', 'users.write') + ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) + ->label('sdk.namespace', 'users') + ->label('sdk.method', 'updateEmail') + ->label('sdk.description', '/docs/references/users/update-user-email.md') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_USER) + ->param('userId', '', new UID(), 'User unique ID.') + ->param('email', '', new Email(), 'User email.') + ->inject('response') + ->inject('projectDB') + ->inject('audits') + ->action(function ($userId, $email, $response, $projectDB, $audits) { + /** @var Appwrite\Utopia\Response $response */ + /** @var Appwrite\Database\Database $projectDB */ + /** @var Appwrite\Event\Event $audits */ + + $user = $projectDB->getDocument($userId); + + if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) { + throw new Exception('User not found', 404); + } + + $isAnonymousUser = is_null($user->getAttribute('email')) && is_null($user->getAttribute('password')); // Check if request is from an anonymous account for converting + $email = \strtolower($email); + $profile = $projectDB->getCollectionFirst([ // Get user by email address + 'limit' => 1, + 'filters' => [ + '$collection='.Database::SYSTEM_COLLECTION_USERS, + 'email='.$email, + ], + ]); + + if (!empty($profile)) { + throw new Exception('User already registered', 400); + } + + if (!$isAnonymousUser) { + // Remove previous unique ID. + $projectDB->deleteUniqueKey(\md5($user->getArrayCopy()['$collection'].':'.'email'.'='.$user->getAttribute('email'))); + } + + $user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [ + 'email' => $email, + ])); + + $projectDB->addUniqueKey(\md5($user['$collection'].':'.'email'.'='.$email)); + + if (false === $user) { + throw new Exception('Failed saving user to DB', 500); + } + + $audits + ->setParam('userId', $user->getId()) + ->setParam('event', 'account.update.email') + ->setParam('resource', 'users/'.$user->getId()) + ; + + $response->dynamic($user, Response::MODEL_USER); + }); + App::patch('/v1/users/:userId/prefs') ->desc('Update User Preferences') ->groups(['api', 'users']) diff --git a/docs/references/users/update-user-email.md b/docs/references/users/update-user-email.md new file mode 100644 index 0000000000..334f726a81 --- /dev/null +++ b/docs/references/users/update-user-email.md @@ -0,0 +1 @@ +Update the user email by its unique ID. \ No newline at end of file diff --git a/docs/references/users/update-user-name.md b/docs/references/users/update-user-name.md new file mode 100644 index 0000000000..9a8fa7b8ad --- /dev/null +++ b/docs/references/users/update-user-name.md @@ -0,0 +1 @@ +Update the user name by its unique ID. \ No newline at end of file diff --git a/docs/references/users/update-user-password.md b/docs/references/users/update-user-password.md new file mode 100644 index 0000000000..cfc8543cf4 --- /dev/null +++ b/docs/references/users/update-user-password.md @@ -0,0 +1 @@ +Update the user password by its unique ID. \ No newline at end of file