Skip to content

Commit

Permalink
Add API docs and types for changeMyPassword method.
Browse files Browse the repository at this point in the history
  • Loading branch information
BusterNeece committed Feb 25, 2025
1 parent 67a2365 commit 7706d60
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 22 deletions.
67 changes: 45 additions & 22 deletions backend/src/Controller/Api/Frontend/Account/PutPasswordAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,72 @@

use App\Container\EntityManagerAwareTrait;
use App\Controller\SingleActionInterface;
use App\Entity\Api\Error;
use App\Entity\Api\Account\ChangePassword;
use App\Entity\Api\Status;
use App\Exception\ValidationException;
use App\Http\Response;
use App\Http\ServerRequest;
use App\OpenApi;
use InvalidArgumentException;
use OpenApi\Attributes as OA;
use Psr\Http\Message\ResponseInterface;
use Throwable;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Validator\Validator\ValidatorInterface;

#[
OA\Put(
path: '/frontend/account/password',
operationId: 'changeMyPassword',
description: 'Change the password of your account.',
security: OpenApi::API_KEY_SECURITY,
requestBody: new OA\RequestBody(
content: new OA\JsonContent(ref: '#/components/schemas/Api_Account_ChangePassword')
),
tags: ['Accounts'],
responses: [
new OA\Response(ref: OpenApi::REF_RESPONSE_SUCCESS, response: 200),
new OA\Response(ref: OpenApi::REF_RESPONSE_ACCESS_DENIED, response: 403),
new OA\Response(ref: OpenApi::REF_RESPONSE_NOT_FOUND, response: 404),
new OA\Response(ref: OpenApi::REF_RESPONSE_GENERIC_ERROR, response: 500),
]
)
]
final class PutPasswordAction implements SingleActionInterface
{
use EntityManagerAwareTrait;

public function __construct(
protected Serializer $serializer,
protected ValidatorInterface $validator
) {
}

public function __invoke(
ServerRequest $request,
Response $response,
array $params
): ResponseInterface {
$user = $request->getUser();
$body = (array)$request->getParsedBody();

try {
if (empty($body['current_password'])) {
throw new InvalidArgumentException('Current password not provided (current_password).');
}
/** @var ChangePassword $changePassword */
$changePassword = $this->serializer->denormalize($request->getParsedBody(), ChangePassword::class);

$currentPassword = $body['current_password'];
if (!$user->verifyPassword($currentPassword)) {
throw new InvalidArgumentException('Invalid current password.');
}
// Validate the UploadFile API record.
$errors = $this->validator->validate($changePassword);
if (count($errors) > 0) {
throw ValidationException::fromValidationErrors($errors);
}

if (empty($body['new_password'])) {
throw new InvalidArgumentException('New password not provided (new_password).');
}
if (!$user->verifyPassword($changePassword->current_password)) {
throw new InvalidArgumentException('Invalid current password.');
}

$user = $this->em->refetch($user);
$user = $this->em->refetch($user);

$user->setNewPassword($body['new_password']);
$this->em->persist($user);
$this->em->flush();
$user->setNewPassword($changePassword->new_password);
$this->em->persist($user);
$this->em->flush();

return $response->withJson(Status::updated());
} catch (Throwable $e) {
return $response->withStatus(400)->withJson(Error::fromException($e));
}
return $response->withJson(Status::updated());
}
}
33 changes: 33 additions & 0 deletions backend/src/Entity/Api/Account/ChangePassword.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace App\Entity\Api\Account;

use OpenApi\Attributes as OA;
use Symfony\Component\Validator\Constraints as Assert;

#[OA\Schema(
schema: 'Api_Account_ChangePassword',
required: [
'current_password',
'new_password',
],
type: 'object'
)]
final readonly class ChangePassword
{
public function __construct(
#[
OA\Property(description: 'The current account password.'),
Assert\NotBlank,
]
public string $current_password,
#[
OA\Property(description: 'The new account password.'),
Assert\NotBlank
]
public string $new_password
) {
}
}
7 changes: 7 additions & 0 deletions frontend/entities/ApiInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
* ---------------------------------------------------------------
*/

export interface ApiAccountChangePassword {
/** The current account password. */
current_password: string;
/** The new account password. */
new_password: string;
}

export interface ApiAccountNewApiKey {
/** The newly generated API key. */
key: string;
Expand Down
35 changes: 35 additions & 0 deletions web/static/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,29 @@ paths:
security:
-
ApiKey: []
/frontend/account/password:
put:
tags:
- Accounts
description: 'Change the password of your account.'
operationId: changeMyPassword
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Api_Account_ChangePassword'
responses:
'200':
$ref: '#/components/responses/Success'
'403':
$ref: '#/components/responses/AccessDenied'
'404':
$ref: '#/components/responses/RecordNotFound'
'500':
$ref: '#/components/responses/GenericError'
security:
-
ApiKey: []
/status:
get:
tags:
Expand Down Expand Up @@ -3591,6 +3614,18 @@ paths:
ApiKey: []
components:
schemas:
Api_Account_ChangePassword:
required:
- current_password
- new_password
properties:
current_password:
description: 'The current account password.'
type: string
new_password:
description: 'The new account password.'
type: string
type: object
Api_Account_NewApiKey:
required:
- key
Expand Down

0 comments on commit 7706d60

Please sign in to comment.