You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.6 KiB
88 lines
2.6 KiB
<?php |
|
|
|
declare(strict_types=1); |
|
|
|
namespace AutoStore\Infrastructure\Auth; |
|
|
|
use AutoStore\Application\Interfaces\IAuthService; |
|
use Firebase\JWT\JWT; |
|
use Firebase\JWT\Key; |
|
use Firebase\JWT\ExpiredException; |
|
use Firebase\JWT\SignatureInvalidException; |
|
use AutoStore\Application\Exceptions\UserNotFoundException; |
|
use AutoStore\Application\Interfaces\IUserRepository; |
|
use Psr\Log\LoggerInterface; |
|
|
|
class JwtAuthService implements IAuthService |
|
{ |
|
private IUserRepository $userRepository; |
|
private string $secretKey; |
|
private LoggerInterface $logger; |
|
|
|
public function __construct( |
|
IUserRepository $userRepository, |
|
string $secretKey, |
|
LoggerInterface $logger |
|
) { |
|
$this->userRepository = $userRepository; |
|
$this->secretKey = $secretKey; |
|
$this->logger = $logger; |
|
} |
|
|
|
/** |
|
* @note Showcase only, use a proper service |
|
*/ |
|
public function authenticate(string $username, string $password): ?string |
|
{ |
|
$user = $this->userRepository->findByUsername($username); |
|
|
|
if ($user === null) { |
|
$this->logger->warning("User not found: {$username}"); |
|
return null; |
|
} |
|
|
|
// Verify the password against the stored hash |
|
if (password_verify($password, $user->getPasswordHash())) { |
|
$payload = [ |
|
'iss' => 'autostore', |
|
'sub' => $user->getId(), |
|
'iat' => time(), |
|
'exp' => time() + 3600, // 1 hour expiration |
|
'username' => $user->getUsername() |
|
]; |
|
|
|
return JWT::encode($payload, $this->secretKey, 'HS256'); |
|
} |
|
|
|
$this->logger->warning("Invalid password for user: {$username}"); |
|
return null; |
|
} |
|
|
|
public function validateToken(string $token): bool |
|
{ |
|
try { |
|
JWT::decode($token, new Key($this->secretKey, 'HS256')); |
|
return true; |
|
} catch (ExpiredException $e) { |
|
$this->logger->warning('Token expired'); |
|
return false; |
|
} catch (SignatureInvalidException $e) { |
|
$this->logger->warning('Invalid token signature'); |
|
return false; |
|
} catch (\Exception $e) { |
|
$this->logger->error('Token validation error: ' . $e->getMessage()); |
|
return false; |
|
} |
|
} |
|
|
|
public function getUserIdFromToken(string $token): ?string |
|
{ |
|
try { |
|
$decoded = JWT::decode($token, new Key($this->secretKey, 'HS256')); |
|
return $decoded->sub; |
|
} catch (\Exception $e) { |
|
$this->logger->error('Error extracting user ID from token: ' . $e->getMessage()); |
|
return null; |
|
} |
|
} |
|
}
|
|
|