feat: Permettre au super admin de se connecter et accéder à son dashboard

Le super admin (table super_admins, master DB) ne pouvait pas se connecter
via /api/login car ce firewall n'utilisait que le provider tenant. De même,
le JWT n'était pas enrichi pour les super admins, l'endpoint /api/me/roles
les rejetait, et le frontend redirigeait systématiquement vers /dashboard.

Un chain provider (super_admin + tenant) résout l'authentification,
le JwtPayloadEnricher et MyRolesProvider gèrent désormais les deux types
d'utilisateurs, et le frontend redirige selon le rôle après login.
This commit is contained in:
2026-02-17 10:07:10 +01:00
parent c856dfdcda
commit 0951322d71
68 changed files with 4049 additions and 8 deletions

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Administration\Infrastructure\Security;
use App\SuperAdmin\Infrastructure\Security\SecuritySuperAdmin;
use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;
/**
@@ -12,7 +13,8 @@ use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;
* Added claims:
* - sub: User email (Symfony Security identifier)
* - user_id: User UUID (for API consumers)
* - tenant_id: Tenant UUID for multi-tenant isolation
* - tenant_id: Tenant UUID for multi-tenant isolation (regular users only)
* - user_type: "super_admin" for super admins
* - roles: List of Symfony roles for authorization
*
* @see Story 1.4 - User login
@@ -22,13 +24,21 @@ final readonly class JwtPayloadEnricher
public function onJWTCreated(JWTCreatedEvent $event): void
{
$user = $event->getUser();
$payload = $event->getData();
if ($user instanceof SecuritySuperAdmin) {
$payload['user_id'] = $user->superAdminId();
$payload['user_type'] = 'super_admin';
$payload['roles'] = $user->getRoles();
$event->setData($payload);
return;
}
if (!$user instanceof SecurityUser) {
return;
}
$payload = $event->getData();
// Business claims for multi-tenant isolation and authorization
$payload['user_id'] = $user->userId();
$payload['tenant_id'] = $user->tenantId();