Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
SymfonyPasswordHasher
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
3 / 3
3
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hash
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 verify
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace App\Identity\Infrastructure\Security;
6
7use App\Identity\Application\Service\PasswordHasher;
8use App\Identity\Domain\ValueObject\HashedPassword;
9use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface;
10
11final class SymfonyPasswordHasher implements PasswordHasher
12{
13    public function __construct(
14        private readonly PasswordHasherFactoryInterface $hasherFactory,
15    ) {
16    }
17
18    public function hash(string $plainPassword): HashedPassword
19    {
20        // Single source of truth: the same hasher security.yaml configures for
21        // SecurityUser (argon2id), so registration and login verification always
22        // agree on algorithm and parameters.
23        $hasher = $this->hasherFactory->getPasswordHasher(SecurityUser::class);
24
25        return new HashedPassword($hasher->hash($plainPassword));
26    }
27
28    public function verify(HashedPassword $hashedPassword, string $plainPassword): bool
29    {
30        return $this->hasherFactory
31            ->getPasswordHasher(SecurityUser::class)
32            ->verify($hashedPassword->value(), $plainPassword);
33    }
34}