<?php
namespace MedBrief\MSR\EventListener;
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationFailureEvent;
use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;
use Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationFailureResponse;
use MedBrief\MSR\Service\Security\SecurityTimeDelayHelperService;
class JWTCreatedListener
{
public function __construct(private readonly SecurityTimeDelayHelperService $securityTimeDelayHelper)
{
}
/**
* Handles successful JWT creation.
*
* @param JWTCreatedEvent $event
*/
public function onJWTAuthenticationSuccess(JWTCreatedEvent $event): void
{
$payload = $event->getData();
$userId = $event->getUser()->getId();
$payload['uid'] = $userId;
$event->setData($payload);
}
/**
* Handles authentication failure events.
*
* @param AuthenticationFailureEvent $event
*/
public function onJWTAuthenticationFailed(AuthenticationFailureEvent $event): void
{
// Start time of the request processing
$startTime = microtime(true);
// This is for email enumeration attacks
// Use the SecurityHelper to determine if the user exists
$userExists = $this->securityTimeDelayHelper->determineIfUserExists();
if (!$userExists) {
// Add an extra delay for wrong email to match password timing
usleep(600 * 1000);
}
// Use the SecurityHelper to add a random delay
$this->securityTimeDelayHelper->addRandomDelay($startTime);
$responseMessage = 'Bad credentials, please verify that your username/password are correctly set.';
$response = new JWTAuthenticationFailureResponse($responseMessage);
$event->setResponse($response);
}
}