first commit
This commit is contained in:
98
src/Identity/UI/Http/AccountController.php
Normal file
98
src/Identity/UI/Http/AccountController.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Netig\Netslim\Identity\UI\Http;
|
||||
|
||||
use Netig\Netslim\Identity\Application\AuthServiceInterface;
|
||||
use Netig\Netslim\Identity\Domain\Exception\WeakPasswordException;
|
||||
use Netig\Netslim\Identity\UI\Http\Request\ChangePasswordRequest;
|
||||
use Netig\Netslim\Kernel\Http\Application\Flash\FlashServiceInterface;
|
||||
use Netig\Netslim\Kernel\Http\Application\Session\SessionManagerInterface;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Slim\Views\Twig;
|
||||
|
||||
/**
|
||||
* Gère les actions liées au compte courant, notamment le changement de mot de passe.
|
||||
*/
|
||||
class AccountController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Twig $view,
|
||||
private readonly AuthServiceInterface $authService,
|
||||
private readonly FlashServiceInterface $flash,
|
||||
private readonly SessionManagerInterface $sessionManager,
|
||||
private readonly ?LoggerInterface $logger = null,
|
||||
) {}
|
||||
|
||||
public function showChangePassword(Request $req, Response $res): Response
|
||||
{
|
||||
$referer = $req->getHeaderLine('Referer');
|
||||
$path = parse_url($referer, PHP_URL_PATH);
|
||||
$path = is_string($path) ? $path : '';
|
||||
$backUrl = (str_starts_with($path, '/') && $path !== '/account/password')
|
||||
? $path
|
||||
: AdminHomePath::resolve();
|
||||
|
||||
return $this->view->render($res, '@Identity/account/password-change.twig', [
|
||||
'error' => $this->flash->get('password_error'),
|
||||
'success' => $this->flash->get('password_success'),
|
||||
'back_url' => $backUrl,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valide puis applique le changement de mot de passe pour l'utilisateur connecté.
|
||||
*/
|
||||
public function changePassword(Request $req, Response $res): Response
|
||||
{
|
||||
$changePasswordRequest = ChangePasswordRequest::fromRequest($req);
|
||||
$userId = $this->sessionManager->getUserId() ?? 0;
|
||||
|
||||
try {
|
||||
$changePasswordRequest->ensureConfirmed();
|
||||
$this->authService->changePassword(
|
||||
$userId,
|
||||
$changePasswordRequest->currentPassword,
|
||||
$changePasswordRequest->newPassword,
|
||||
);
|
||||
$this->flash->set('password_success', 'Mot de passe modifié avec succès');
|
||||
} catch (WeakPasswordException $e) {
|
||||
$this->flash->set('password_error', $e->getMessage());
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
$message = $e->getMessage();
|
||||
if ($message === 'Mot de passe actuel incorrect') {
|
||||
$message = 'Le mot de passe actuel est incorrect';
|
||||
}
|
||||
$this->flash->set('password_error', $message);
|
||||
} catch (\Throwable $e) {
|
||||
$incidentId = $this->logUnexpectedError($req, $e, [
|
||||
'user_id' => $userId,
|
||||
]);
|
||||
$this->flash->set('password_error', "Une erreur inattendue s\'est produite (réf. {$incidentId})");
|
||||
}
|
||||
|
||||
return $res->withHeader('Location', '/account/password')->withStatus(302);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $context
|
||||
*/
|
||||
private function logUnexpectedError(Request $req, \Throwable $e, array $context = []): string
|
||||
{
|
||||
$incidentId = bin2hex(random_bytes(8));
|
||||
|
||||
$this->logger?->error('Account password change failed', $context + [
|
||||
'incident_id' => $incidentId,
|
||||
'route' => (string) $req->getUri()->getPath(),
|
||||
'method' => $req->getMethod(),
|
||||
'exception_class' => $e::class,
|
||||
'exception_message' => $e->getMessage(),
|
||||
'exception' => $e,
|
||||
]);
|
||||
|
||||
return $incidentId;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user