diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 65cbea01b1..057689a8ee 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -17,6 +17,7 @@ use Utopia\Database\Exception\Duplicate; use Utopia\Database\Validator\UID; use DeviceDetector\DeviceDetector; use Appwrite\Database\Validator\CustomId; +use Utopia\Database\Query; App::post('/v1/users') ->desc('Create User') @@ -376,6 +377,131 @@ 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('dbForInternal') + ->inject('audits') + ->action(function ($userId, $name, $response, $dbForInternal, $audits) { + /** @var Appwrite\Utopia\Response $response */ + /** @var Utopia\Database\Database $dbForInternal */ + /** @var Appwrite\Event\Event $audits */ + + $user = $dbForInternal->getDocument('users', $userId); + + if ($user->isEmpty()) { + throw new Exception('User not found', 404); + } + + $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('name', $name)); + + $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('dbForInternal') + ->inject('audits') + ->action(function ($userId, $password, $response, $dbForInternal, $audits) { + /** @var Appwrite\Utopia\Response $response */ + /** @var Utopia\Database\Database $dbForInternal */ + /** @var Appwrite\Event\Event $audits */ + + $user = $dbForInternal->getDocument('users', $userId); + + if ($user->isEmpty()) { + throw new Exception('User not found', 404); + } + + $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('password', Auth::passwordHash($password)) + ->setAttribute('passwordUpdate', \time())); + + $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('dbForInternal') + ->inject('audits') + ->action(function ($userId, $email, $response, $dbForInternal, $audits) { + /** @var Appwrite\Utopia\Response $response */ + /** @var Utopia\Database\Database $dbForInternal */ + /** @var Appwrite\Event\Event $audits */ + + $user = $dbForInternal->getDocument('users', $userId); + + if ($user->isEmpty()) { + throw new Exception('User not found', 404); + } + + $email = \strtolower($email); + $profile = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [\strtolower($email)])]); // Get user by email address + + if ($profile) { + throw new Exception('Email already exists', 409); + } + + $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('email', $email)); + + $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/app/views/console/users/user.phtml b/app/views/console/users/user.phtml index 391f86cc36..f01b382cce 100644 --- a/app/views/console/users/user.phtml +++ b/app/views/console/users/user.phtml @@ -17,6 +17,108 @@ + + + + + +