From 37cd88544b01bfc9f25437fe30c4c95ed5dad688 Mon Sep 17 00:00:00 2001 From: Sebastiaan Stok Date: Thu, 8 May 2025 20:56:32 +0200 Subject: [PATCH] Fix verifier must be NULL after creation The `create()` method zeroes the verifier after usage but the property didn't allow a null value --- phpstan.neon | 8 +++++--- src/SplitToken.php | 6 +++++- tests/Argon2SplitTokenTest.php | 11 +++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index e20dcf1..711f84f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,8 +10,10 @@ parameters: - ./tests excludePaths: - var/ - - templates/ - - translations/ ignoreErrors: - - '#Attribute class Symfony\\Contracts\\Service\\Attribute\\Required does not exist#' # Not required + # Not required + - '#Attribute class Symfony\\Contracts\\Service\\Attribute\\Required does not exist#' + + # Always set, as it's only NULL after zeroing, which happens later + - '#Parameter \#1 \$verifier of method Rollerworks\\Component\\SplitToken\\SplitToken\:\:hashVerifier\(\) expects string, string\|null given#' diff --git a/src/SplitToken.php b/src/SplitToken.php index fbf42d2..cef2cf6 100644 --- a/src/SplitToken.php +++ b/src/SplitToken.php @@ -94,7 +94,7 @@ abstract class SplitToken protected array $config = []; private HiddenString $token; private string $selector; - private string $verifier; + private ?string $verifier; private ?string $verifierHash = null; private ?\DateTimeImmutable $expiresAt = null; @@ -203,6 +203,10 @@ final public function matches(?SplitTokenValueHolder $token): bool return false; } + if ($this->verifier === null) { + throw new \RuntimeException('matches() does not work with a SplitToken object when created with create(), use fromString() instead.'); + } + return $this->verifyHash($token->verifierHash(), $this->verifier); } diff --git a/tests/Argon2SplitTokenTest.php b/tests/Argon2SplitTokenTest.php index eb92a92..3a487e1 100644 --- a/tests/Argon2SplitTokenTest.php +++ b/tests/Argon2SplitTokenTest.php @@ -166,6 +166,17 @@ public function it_fails_when_creating_holder_with_string_constructed(): void SplitToken::fromString(self::FULL_TOKEN)->toValueHolder(); } + #[Test] + public function it_fails_matches_when_just_created(): void + { + $splitToken = SplitToken::create(self::$randValue); + + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('matches() does not work with a SplitToken object when created with create(), use fromString() instead.'); + + $splitToken->matches($splitToken->toValueHolder()); + } + #[Test] public function it_verifies_split_token(): void {