From 6cd0be66e4811e02db40b833dbb2f93f48c9e820 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Fri, 28 Feb 2025 11:51:49 +0100 Subject: [PATCH 1/7] feat: Support Laravel 12 --- .github/workflows/static.yml | 2 +- .github/workflows/tests.yml | 20 ++++++++++++++------ composer.json | 22 +++++++++++----------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 685ed61..02f2978 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -13,4 +13,4 @@ jobs: name: Static analysis uses: monicahq/workflows/.github/workflows/static.yml@v2 with: - php-version: 8.2 + php-version: 8.4 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 63ec6c2..417338d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,9 +16,9 @@ on: workflow_dispatch: env: - default-php-version: '8.3' - default-laravel-version: '11.0' - semantic-node-version: 20 + default-php-version: '8.4' + default-laravel-version: '12.0' + semantic-node-version: 22 concurrency: group: Tests ${{ github.ref }} @@ -32,8 +32,8 @@ jobs: strategy: fail-fast: false matrix: - php-version: ['8.1', '8.2', '8.3'] - laravel-version: ['9.0', '10.0', '11.0'] + php-version: ['8.1', '8.2', '8.3', '8.4'] + laravel-version: ['9.0', '10.0', '11.0', '12.0'] psr7: ['guzzle'] include: - php-version: '8.1' @@ -60,9 +60,17 @@ jobs: - php-version: '8.3' laravel-version: '11.0' psr7: 'discovery' + - php-version: '8.4' + laravel-version: '12.0' + psr7: 'nyholm' + - php-version: '8.4' + laravel-version: '12.0' + psr7: 'discovery' exclude: - php-version: '8.1' laravel-version: '11.0' + - php-version: '8.1' + laravel-version: '12.0' steps: - name: Checkout sources @@ -183,7 +191,7 @@ jobs: - name: SonarCloud Scan if: env.SONAR_TOKEN != '' - uses: SonarSource/sonarqube-scan-action@v4 + uses: SonarSource/sonarqube-scan-action@v5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/composer.json b/composer.json index 1b71ebd..d674305 100644 --- a/composer.json +++ b/composer.json @@ -21,33 +21,33 @@ ], "require": { "php": ">=8.1", - "illuminate/support": "^9.0 || ^10.0 || ^11.0", + "illuminate/support": "^9.0 || ^10.0 || ^11.0 || ^12.0", "phpdocumentor/reflection-docblock": "^5.3", "psr/http-factory-implementation": "1.0", "symfony/property-access": "^6.4 || ^7.0", "symfony/property-info": "^6.4 || ^7.0", "symfony/serializer": "^6.4 || ^7.0", "web-auth/cose-lib": "^4.0", - "web-auth/webauthn-lib": "^4.8", - "web-token/jwt-library": "^3.0" + "web-auth/webauthn-lib": "^4.8 || ^5.0", + "web-token/jwt-library": "^3.0 || ^4.0" }, "conflict": { "web-auth/webauthn-lib": "4.7.0" }, "require-dev": { "ext-sqlite3": "*", + "brainmaestro/composer-git-hooks": "^3.0", "guzzlehttp/psr7": "^2.1", - "jschaedl/composer-git-hooks": "^4.0", - "larastan/larastan": "^2.0", + "larastan/larastan": "^2.0 || ^3.0", "laravel/legacy-factories": "^1.0", "laravel/pint": "^1.13", "ocramius/package-versions": "^2.0", - "orchestra/testbench": "^7.0 || ^8.0 || ^9.0", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5 || ^10.0 || ^11.0", - "psalm/plugin-laravel": "^2.8" + "orchestra/testbench": "^7.0 || ^8.0 || ^9.0 || ^10.0", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.5 || ^10.0 || ^11.0 || ^12.0", + "psalm/plugin-laravel": "^2.8 || ^3.0" }, "suggest": { "guzzlehttp/psr7": "To provide a psr/http-factory-implementation implementation", From 1701d1cc9c02d87a195a5b280ce5f5c48909ba16 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Fri, 28 Feb 2025 12:56:52 +0100 Subject: [PATCH 2/7] fix tests --- .../Webauthn/CreationOptionsFactory.php | 4 +- .../Webauthn/RequestOptionsFactory.php | 4 +- src/WebauthnServiceProvider.php | 26 +++++------- .../AuthenticateControllerTest.php | 2 +- .../Controllers/WebauthnControllerTest.php | 2 +- .../Webauthn/CredentialRepositoryTest.php | 2 +- tests/Unit/Services/WebauthnTest.php | 40 +++++++++---------- 7 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/Services/Webauthn/CreationOptionsFactory.php b/src/Services/Webauthn/CreationOptionsFactory.php index 2edf6d5..3a3658d 100644 --- a/src/Services/Webauthn/CreationOptionsFactory.php +++ b/src/Services/Webauthn/CreationOptionsFactory.php @@ -8,6 +8,7 @@ use Illuminate\Contracts\Config\Repository as Config; use Illuminate\Http\Request; use LaravelWebauthn\Facades\Webauthn; +use Symfony\Component\Serializer\SerializerInterface; use Webauthn\AuthenticatorSelectionCriteria; use Webauthn\PublicKeyCredentialCreationOptions; use Webauthn\PublicKeyCredentialDescriptor; @@ -27,6 +28,7 @@ public function __construct( Cache $cache, Config $config, CredentialRepository $repository, + protected SerializerInterface $loader, protected PublicKeyCredentialRpEntity $publicKeyCredentialRpEntity, protected AuthenticatorSelectionCriteria $authenticatorSelectionCriteria, protected CoseAlgorithmManager $algorithmManager @@ -51,7 +53,7 @@ public function __invoke(User $user): PublicKeyCredentialCreationOptions $this->timeout ); - $value = json_encode($publicKey, flags: JSON_THROW_ON_ERROR); + $value = $this->loader->serialize($publicKey, 'json'); $this->cache->put($this->cacheKey($user), $value, $this->timeout); diff --git a/src/Services/Webauthn/RequestOptionsFactory.php b/src/Services/Webauthn/RequestOptionsFactory.php index c36b271..5f30b72 100644 --- a/src/Services/Webauthn/RequestOptionsFactory.php +++ b/src/Services/Webauthn/RequestOptionsFactory.php @@ -6,6 +6,7 @@ use Illuminate\Contracts\Cache\Repository as Cache; use Illuminate\Contracts\Config\Repository as Config; use Illuminate\Http\Request; +use Symfony\Component\Serializer\SerializerInterface; use Webauthn\PublicKeyCredentialDescriptor; use Webauthn\PublicKeyCredentialRequestOptions; use Webauthn\PublicKeyCredentialRpEntity; @@ -22,6 +23,7 @@ public function __construct( Cache $cache, Config $config, CredentialRepository $repository, + protected SerializerInterface $loader, protected PublicKeyCredentialRpEntity $publicKeyCredentialRpEntity ) { parent::__construct($request, $cache, $config, $repository); @@ -41,7 +43,7 @@ public function __invoke(?User $user): PublicKeyCredentialRequestOptions $this->timeout ); - $value = json_encode($publicKey, flags: JSON_THROW_ON_ERROR); + $value = $this->loader->serialize($publicKey, 'json'); $this->cache->put($this->cacheKey($user), $value, $this->timeout); diff --git a/src/WebauthnServiceProvider.php b/src/WebauthnServiceProvider.php index 9da05ef..4f95108 100644 --- a/src/WebauthnServiceProvider.php +++ b/src/WebauthnServiceProvider.php @@ -126,12 +126,12 @@ protected function bindWebAuthnPackage(): void $this->app->bind( PackedAttestationStatementSupport::class, fn ($app) => new PackedAttestationStatementSupport( - $app[CoseAlgorithmManager::class] + algorithmManager: $app[CoseAlgorithmManager::class] ) ); $this->app->bind( AttestationStatementSupportManager::class, - fn ($app) => tap(new AttestationStatementSupportManager(), function ($manager) use ($app) { + fn ($app) => tap(new AttestationStatementSupportManager, function ($manager) use ($app) { // https://www.w3.org/TR/webauthn/#sctn-none-attestation $manager->add($app[NoneAttestationStatementSupport::class]); @@ -167,8 +167,7 @@ protected function bindWebAuthnPackage(): void $this->app->bind( AuthenticatorAttestationResponseValidator::class, fn ($app) => tap(new AuthenticatorAttestationResponseValidator( - attestationStatementSupportManager: $app[AttestationStatementSupportManager::class], - extensionOutputCheckerHandler: $app[ExtensionOutputCheckerHandler::class] + ceremonyStepManager: ($app[CeremonyStepManagerFactory::class])->creationCeremony(), ), fn (AuthenticatorAttestationResponseValidator $responseValidator) => $responseValidator->setLogger($app['webauthn.log']) ) ); @@ -183,29 +182,24 @@ protected function bindWebAuthnPackage(): void $this->app->bind( AuthenticatorAssertionResponseValidator::class, fn ($app) => tap((new AuthenticatorAssertionResponseValidator( - null, - null, - $app[ExtensionOutputCheckerHandler::class], - $app[CoseAlgorithmManager::class], - null, - ($app[CeremonyStepManagerFactory::class])->requestCeremony() + ceremonyStepManager: ($app[CeremonyStepManagerFactory::class])->requestCeremony() )), fn (AuthenticatorAssertionResponseValidator $responseValidator) => $responseValidator->setLogger($app['webauthn.log']) ) ); $this->app->bind( AuthenticatorSelectionCriteria::class, fn ($app) => new AuthenticatorSelectionCriteria( - $app['config']->get('webauthn.attachment_mode', 'null'), - $app['config']->get('webauthn.user_verification', 'preferred'), - $app['config']->get('webauthn.userless') + authenticatorAttachment: $app['config']->get('webauthn.attachment_mode', 'null'), + userVerification: $app['config']->get('webauthn.user_verification', 'preferred'), + residentKey: $app['config']->get('webauthn.userless') ) ); $this->app->bind( PublicKeyCredentialRpEntity::class, fn ($app) => new PublicKeyCredentialRpEntity( - $app['config']->get('app.name', 'Laravel'), - $app->make('request')->host(), - $app['config']->get('webauthn.icon') + name: $app['config']->get('app.name', 'Laravel'), + id: $app->make('request')->host(), + icon: $app['config']->get('webauthn.icon') ) ); $this->app->bind( diff --git a/tests/Unit/Http/Controllers/AuthenticateControllerTest.php b/tests/Unit/Http/Controllers/AuthenticateControllerTest.php index 0208603..9da2986 100644 --- a/tests/Unit/Http/Controllers/AuthenticateControllerTest.php +++ b/tests/Unit/Http/Controllers/AuthenticateControllerTest.php @@ -60,7 +60,7 @@ public function it_auth_get() $response = $this->get('/webauthn/auth', ['accept' => 'application/json']); $response->assertStatus(200); - $this->assertEquals('Y2hhbGxlbmdl', $response->json('publicKey.challenge')); + $this->assertEquals('challenge', $response->json('publicKey.challenge')); } /** diff --git a/tests/Unit/Http/Controllers/WebauthnControllerTest.php b/tests/Unit/Http/Controllers/WebauthnControllerTest.php index 6c68731..1ffc332 100644 --- a/tests/Unit/Http/Controllers/WebauthnControllerTest.php +++ b/tests/Unit/Http/Controllers/WebauthnControllerTest.php @@ -73,7 +73,7 @@ public function it_register_get_data() $response = $this->post('/webauthn/keys/options', [], ['accept' => 'application/json']); $response->assertStatus(200); - $this->assertEquals('Y2hhbGxlbmdl', $response->json('publicKey.challenge')); + $this->assertEquals('challenge', $response->json('publicKey.challenge')); } /** diff --git a/tests/Unit/Services/Webauthn/CredentialRepositoryTest.php b/tests/Unit/Services/Webauthn/CredentialRepositoryTest.php index 1b633c9..4e425ac 100644 --- a/tests/Unit/Services/Webauthn/CredentialRepositoryTest.php +++ b/tests/Unit/Services/Webauthn/CredentialRepositoryTest.php @@ -35,6 +35,6 @@ public function it_returns_an_array_with_the_keys() $keys = CredentialRepository::getRegisteredKeys($user); $this->assertCount(1, $keys); - $this->assertEquals('{"type":"public-key","id":"MQ"}', json_encode($keys[0], JSON_THROW_ON_ERROR)); + $this->assertEquals('{"type":"public-key","id":"1","transports":[]}', json_encode($keys[0], JSON_THROW_ON_ERROR)); } } diff --git a/tests/Unit/Services/WebauthnTest.php b/tests/Unit/Services/WebauthnTest.php index 7eac887..a22fedd 100644 --- a/tests/Unit/Services/WebauthnTest.php +++ b/tests/Unit/Services/WebauthnTest.php @@ -36,12 +36,12 @@ public function test_get_register_data() $this->assertInstanceOf(\Webauthn\PublicKeyCredentialCreationOptions::class, $publicKey); - $this->assertNotNull($publicKey->getChallenge()); - $this->assertEquals(32, strlen($publicKey->getChallenge())); + $this->assertNotNull($publicKey->challenge); + $this->assertEquals(32, strlen($publicKey->challenge)); - $this->assertInstanceOf(\Webauthn\PublicKeyCredentialUserEntity::class, $publicKey->getUser()); - $this->assertEquals($user->getAuthIdentifier(), $publicKey->getUser()->getId()); - $this->assertEquals($user->email, $publicKey->getUser()->getDisplayName()); + $this->assertInstanceOf(\Webauthn\PublicKeyCredentialUserEntity::class, $publicKey->user); + $this->assertEquals($user->getAuthIdentifier(), $publicKey->user->id); + $this->assertEquals($user->email, $publicKey->user->displayName); } /** @@ -65,7 +65,7 @@ public function test_do_register_data() 'type' => 'public-key', 'transports' => '[]', 'attestationType' => 'none', - 'trustPath' => '{"type":"Webauthn\\\\TrustPath\\\\EmptyTrustPath"}', + 'trustPath' => '{}', 'aaguid' => '30303030-3030-3030-3030-303030303030', 'credentialPublicKey' => 'omExZXZhbHVlYTMm', 'counter' => '1', @@ -86,13 +86,13 @@ public function test_get_authenticate_data() $this->assertInstanceOf(\Webauthn\PublicKeyCredentialRequestOptions::class, $publicKey); - $this->assertNotNull($publicKey->getChallenge()); - $this->assertEquals(32, strlen($publicKey->getChallenge())); + $this->assertNotNull($publicKey->challenge); + $this->assertEquals(32, strlen($publicKey->challenge)); - $this->assertEquals('preferred', $publicKey->getUserVerification()); - $this->assertEquals('localhost', $publicKey->getRpId()); - $this->assertEquals(60000, $publicKey->getTimeout()); - $this->assertCount(0, $publicKey->getExtensions()); + $this->assertEquals('preferred', $publicKey->userVerification); + $this->assertEquals('localhost', $publicKey->rpId); + $this->assertEquals(60000, $publicKey->timeout); + $this->assertCount(0, $publicKey->extensions); } /** @@ -124,7 +124,7 @@ private function getAttestationData($publicKey) 'response' => [ 'clientDataJSON' => Base64UrlSafe::encodeUnpadded(json_encode([ 'type' => 'webauthn.create', - 'challenge' => Base64UrlSafe::encodeUnpadded($publicKey->getChallenge()), + 'challenge' => Base64UrlSafe::encodeUnpadded($publicKey->challenge), 'origin' => 'https://localhost', 'tokenBinding' => [ 'status' => 'supported', @@ -192,7 +192,7 @@ public function test_enabled() */ public function test_aaguid_null() { - $webauthnKey = new WebauthnKey(); + $webauthnKey = new WebauthnKey; $webauthnKey->aaguid = null; $this->assertNull($webauthnKey->getAttributeValue('aaguid')); @@ -204,7 +204,7 @@ public function test_aaguid_null() */ public function test_aaguid_empty() { - $webauthnKey = new WebauthnKey(); + $webauthnKey = new WebauthnKey; $webauthnKey->aaguid = ''; $this->assertEquals('', $webauthnKey->getAttributeValue('aaguid')); @@ -216,7 +216,7 @@ public function test_aaguid_empty() */ public function test_aaguid_string() { - $webauthnKey = new WebauthnKey(); + $webauthnKey = new WebauthnKey; $webauthnKey->aaguid = '38195f59-0e5b-4ebf-be46-75664177eeee'; $this->assertEquals('38195f59-0e5b-4ebf-be46-75664177eeee', $webauthnKey->getAttributeValue('aaguid')); @@ -227,9 +227,9 @@ public function test_aaguid_string() /** * @test */ - public function test_aaguid_Uuid() + public function test_aaguid_uuid() { - $webauthnKey = new WebauthnKey(); + $webauthnKey = new WebauthnKey; $webauthnKey->aaguid = Uuid::fromString('38195f59-0e5b-4ebf-be46-75664177eeee'); $this->assertEquals('38195f59-0e5b-4ebf-be46-75664177eeee', $webauthnKey->getAttributeValue('aaguid')); @@ -252,7 +252,7 @@ public function it_creates_model() [], 'attestationType', new \Webauthn\TrustPath\EmptyTrustPath, - new NilUuid(), + new NilUuid, 'credentialPublicKey', $user->id, 0 @@ -278,7 +278,7 @@ public function it_creates_model_anyway() [], 'attestationType', new \Webauthn\TrustPath\EmptyTrustPath, - new NilUuid(), + new NilUuid, 'credentialPublicKey', $user->id, 0 From d2670130ba9ec58c3363c4bee3267472f3c2fc32 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Fri, 28 Feb 2025 13:07:13 +0100 Subject: [PATCH 3/7] fix --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index d674305..438f758 100644 --- a/composer.json +++ b/composer.json @@ -43,9 +43,9 @@ "laravel/pint": "^1.13", "ocramius/package-versions": "^2.0", "orchestra/testbench": "^7.0 || ^8.0 || ^9.0 || ^10.0", - "phpstan/phpstan-deprecation-rules": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpstan/phpstan-strict-rules": "^2.0", + "phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0", + "phpstan/phpstan-phpunit": "^1.0 || ^2.0", + "phpstan/phpstan-strict-rules": "^1.0 || ^2.0", "phpunit/phpunit": "^9.5 || ^10.0 || ^11.0 || ^12.0", "psalm/plugin-laravel": "^2.8 || ^3.0" }, From d308953dd6ece729672fc281007bdf5d9b0ea418 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Sun, 2 Mar 2025 20:40:22 +0100 Subject: [PATCH 4/7] fixes --- .../migrations/2019_03_29_163611_add_webauthn.php | 2 +- phpstan.neon | 2 -- psalm.xml | 4 ++++ src/Actions/UpdateKey.php | 2 ++ src/Auth/EloquentWebAuthnProvider.php | 12 ++++-------- src/Events/WebauthnLogin.php | 3 +++ src/Events/WebauthnLoginData.php | 3 +++ src/Events/WebauthnRegister.php | 5 +++++ src/Events/WebauthnRegisterData.php | 5 +++++ src/Events/WebauthnRegisterFailed.php | 5 +++++ src/Facades/Webauthn.php | 1 + src/Http/Controllers/AuthenticateController.php | 4 ++-- src/Http/Middleware/WebauthnMiddleware.php | 3 +++ src/Http/Responses/DestroyResponse.php | 1 + src/Http/Responses/LockoutResponse.php | 4 ++++ src/Http/Responses/LoginSuccessResponse.php | 1 + src/Http/Responses/LoginViewResponse.php | 2 ++ src/Http/Responses/RegisterSuccessResponse.php | 2 ++ src/Http/Responses/RegisterViewResponse.php | 2 ++ src/Http/Responses/UpdateResponse.php | 1 + src/Listeners/LoginViaRemember.php | 5 +++++ src/Models/Casts/Base64.php | 2 ++ src/Models/Casts/TrustPath.php | 2 ++ src/Models/Casts/Uuid.php | 2 ++ src/Models/WebauthnKey.php | 8 ++++---- src/Services/LoginRateLimiter.php | 2 ++ src/Services/Webauthn.php | 2 +- src/Services/Webauthn/CreationOptionsFactory.php | 13 +++++-------- src/Services/Webauthn/OptionsFactory.php | 3 +-- src/Services/Webauthn/RequestOptionsFactory.php | 3 +-- src/WebauthnAuthenticatable.php | 5 +++++ src/WebauthnServiceProvider.php | 8 ++++++-- tests/Unit/Auth/EloquentWebAuthnProviderTest.php | 6 ------ tests/Unit/Http/Middleware/MiddlewareTest.php | 4 ++-- tests/Unit/Models/Casts/Base64Test.php | 4 ++-- tests/Unit/Models/WebauthnKeyTest.php | 8 ++++---- .../Services/Webauthn/CredentialRepositoryTest.php | 2 +- 37 files changed, 96 insertions(+), 47 deletions(-) diff --git a/database/migrations/2019_03_29_163611_add_webauthn.php b/database/migrations/2019_03_29_163611_add_webauthn.php index 1b47b6f..c6cf8ab 100644 --- a/database/migrations/2019_03_29_163611_add_webauthn.php +++ b/database/migrations/2019_03_29_163611_add_webauthn.php @@ -6,7 +6,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class() extends Migration +return new class extends Migration { /** * Run the migrations. diff --git a/phpstan.neon b/phpstan.neon index 3d9ed46..9c9f133 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -16,5 +16,3 @@ parameters: paths: - */Actions/AttemptToAuthenticate.php - */Services/Webauthn/CreationOptionsFactory.php - - excludes_analyse: diff --git a/psalm.xml b/psalm.xml index c8b6116..ed1314e 100644 --- a/psalm.xml +++ b/psalm.xml @@ -17,4 +17,8 @@ + + + + diff --git a/src/Actions/UpdateKey.php b/src/Actions/UpdateKey.php index cad6923..3b0dfe6 100644 --- a/src/Actions/UpdateKey.php +++ b/src/Actions/UpdateKey.php @@ -10,6 +10,8 @@ class UpdateKey { /** * Update a key. + * + * @psalm-suppress PossiblyUnusedReturnValue */ public function __invoke(User $user, int $webauthnKeyId, string $keyName): Model { diff --git a/src/Auth/EloquentWebAuthnProvider.php b/src/Auth/EloquentWebAuthnProvider.php index 052955c..a20babc 100644 --- a/src/Auth/EloquentWebAuthnProvider.php +++ b/src/Auth/EloquentWebAuthnProvider.php @@ -9,7 +9,6 @@ use Illuminate\Database\Eloquent\ModelNotFoundException; use LaravelWebauthn\Events\WebauthnLogin; use LaravelWebauthn\Facades\Webauthn; -use LaravelWebauthn\Services\Webauthn\CredentialAssertionValidator; use ParagonIE\ConstantTime\Base64UrlSafe; use Webauthn\Util\Base64; @@ -20,18 +19,12 @@ class EloquentWebAuthnProvider extends EloquentUserProvider */ protected bool $fallback; - /** - * WebAuthn assertion validator. - */ - protected CredentialAssertionValidator $validator; - /** * Create a new database user provider. */ - public function __construct(Config $config, CredentialAssertionValidator $validator, Hasher $hasher, string $model) + public function __construct(Config $config, Hasher $hasher, string $model) { $this->fallback = (bool) $config->get('webauthn.fallback', true); - $this->validator = $validator; parent::__construct($hasher, $model); } @@ -39,6 +32,7 @@ public function __construct(Config $config, CredentialAssertionValidator $valida /** * Retrieve a user by the given credentials. */ + #[\Override] public function retrieveByCredentials(array $credentials): ?User { if ($this->isSignedChallenge($credentials)) { @@ -68,6 +62,7 @@ protected function isSignedChallenge(array $credentials): bool /** * Validate a user against the given credentials. */ + #[\Override] public function validateCredentials(User $user, array $credentials): bool { if ($this->isSignedChallenge($credentials) @@ -88,6 +83,7 @@ public function validateCredentials(User $user, array $credentials): bool /** * Rehash the user's password if required and supported. */ + #[\Override] public function rehashPasswordIfRequired(User $user, array $credentials, bool $force = false): void { if ($this->isSignedChallenge($credentials)) { diff --git a/src/Events/WebauthnLogin.php b/src/Events/WebauthnLogin.php index 922f705..eb15533 100644 --- a/src/Events/WebauthnLogin.php +++ b/src/Events/WebauthnLogin.php @@ -6,6 +6,9 @@ use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; +/** + * @psalm-suppress PossiblyUnusedProperty + */ class WebauthnLogin { use Dispatchable, SerializesModels; diff --git a/src/Events/WebauthnLoginData.php b/src/Events/WebauthnLoginData.php index c553ba7..51e371f 100644 --- a/src/Events/WebauthnLoginData.php +++ b/src/Events/WebauthnLoginData.php @@ -7,6 +7,9 @@ use Illuminate\Queue\SerializesModels; use Webauthn\PublicKeyCredentialRequestOptions; +/** + * @psalm-suppress PossiblyUnusedProperty + */ class WebauthnLoginData { use Dispatchable, SerializesModels; diff --git a/src/Events/WebauthnRegister.php b/src/Events/WebauthnRegister.php index ad87ed6..01a5a3d 100644 --- a/src/Events/WebauthnRegister.php +++ b/src/Events/WebauthnRegister.php @@ -6,6 +6,9 @@ use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; +/** + * @psalm-suppress PossiblyUnusedProperty + */ class WebauthnRegister { use Dispatchable, SerializesModels; @@ -14,6 +17,8 @@ class WebauthnRegister * Create a new event instance. * * @param \Illuminate\Database\Eloquent\Model $webauthnKey The new WebauthnKey. + * + * @psalm-suppress PossiblyUnusedProperty */ public function __construct( public Model $webauthnKey diff --git a/src/Events/WebauthnRegisterData.php b/src/Events/WebauthnRegisterData.php index 15a3517..512922f 100644 --- a/src/Events/WebauthnRegisterData.php +++ b/src/Events/WebauthnRegisterData.php @@ -7,6 +7,9 @@ use Illuminate\Queue\SerializesModels; use Webauthn\PublicKeyCredentialCreationOptions; +/** + * @psalm-suppress PossiblyUnusedProperty + */ class WebauthnRegisterData { use Dispatchable, SerializesModels; @@ -16,6 +19,8 @@ class WebauthnRegisterData * * @param \Illuminate\Contracts\Auth\Authenticatable $user The authenticated user. * @param PublicKeyCredentialCreationOptions $publicKey The register data. + * + * @psalm-suppress PossiblyUnusedProperty */ public function __construct( public User $user, diff --git a/src/Events/WebauthnRegisterFailed.php b/src/Events/WebauthnRegisterFailed.php index a3b527b..4d36a44 100644 --- a/src/Events/WebauthnRegisterFailed.php +++ b/src/Events/WebauthnRegisterFailed.php @@ -7,6 +7,9 @@ use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; +/** + * @psalm-suppress PossiblyUnusedProperty + */ class WebauthnRegisterFailed { use Dispatchable, SerializesModels; @@ -16,6 +19,8 @@ class WebauthnRegisterFailed * * @param \Illuminate\Contracts\Auth\Authenticatable $user The authenticated user. * @param Exception|null $exception Exception throwned. + * + * @psalm-suppress PossiblyUnusedProperty */ public function __construct( public User $user, diff --git a/src/Facades/Webauthn.php b/src/Facades/Webauthn.php index c28038a..17e3372 100644 --- a/src/Facades/Webauthn.php +++ b/src/Facades/Webauthn.php @@ -27,6 +27,7 @@ class Webauthn extends Facade /** * Get the registered name of the component. */ + #[\Override] protected static function getFacadeAccessor(): string { return \LaravelWebauthn\Services\Webauthn::class; diff --git a/src/Http/Controllers/AuthenticateController.php b/src/Http/Controllers/AuthenticateController.php index ff1b35d..926b784 100644 --- a/src/Http/Controllers/AuthenticateController.php +++ b/src/Http/Controllers/AuthenticateController.php @@ -62,13 +62,13 @@ public function store(WebauthnLoginRequest $request): LoginSuccessResponse protected function loginPipeline(WebauthnLoginRequest $request): Pipeline { if (Webauthn::$authenticateThroughCallback !== null) { - return (new Pipeline(app()))->send($request)->through(array_filter( + return (new Pipeline(app()))->send($request)->through(array_filter( // @phpstan-ignore arrayFilter.strict call_user_func(Webauthn::$authenticateThroughCallback, $request) )); } if (is_array($pipelines = config('webauthn.pipelines.login'))) { - return (new Pipeline(app()))->send($request)->through(array_filter( + return (new Pipeline(app()))->send($request)->through(array_filter( // @phpstan-ignore arrayFilter.strict $pipelines )); } diff --git a/src/Http/Middleware/WebauthnMiddleware.php b/src/Http/Middleware/WebauthnMiddleware.php index 7c1d79c..53909b7 100644 --- a/src/Http/Middleware/WebauthnMiddleware.php +++ b/src/Http/Middleware/WebauthnMiddleware.php @@ -8,6 +8,9 @@ use Illuminate\Support\Facades\Redirect; use LaravelWebauthn\Facades\Webauthn; +/** + * @psalm-suppress UnusedClass + */ class WebauthnMiddleware { /** diff --git a/src/Http/Responses/DestroyResponse.php b/src/Http/Responses/DestroyResponse.php index 59fce21..8ca57ef 100644 --- a/src/Http/Responses/DestroyResponse.php +++ b/src/Http/Responses/DestroyResponse.php @@ -13,6 +13,7 @@ class DestroyResponse implements DestroyResponseContract * @param \Illuminate\Http\Request $request * @return \Symfony\Component\HttpFoundation\Response */ + #[\Override] public function toResponse($request) { return $request->wantsJson() diff --git a/src/Http/Responses/LockoutResponse.php b/src/Http/Responses/LockoutResponse.php index 4668142..e57cb2d 100644 --- a/src/Http/Responses/LockoutResponse.php +++ b/src/Http/Responses/LockoutResponse.php @@ -8,6 +8,9 @@ use LaravelWebauthn\Services\LoginRateLimiter; use LaravelWebauthn\Services\Webauthn; +/** + * @psalm-suppress UnusedClass + */ class LockoutResponse implements LockoutResponseContract { /** @@ -23,6 +26,7 @@ public function __construct( * @param \Illuminate\Http\Request $request * @return \Symfony\Component\HttpFoundation\Response */ + #[\Override] public function toResponse($request) { $seconds = $this->limiter->availableIn($request); diff --git a/src/Http/Responses/LoginSuccessResponse.php b/src/Http/Responses/LoginSuccessResponse.php index 21709f8..eac71b0 100644 --- a/src/Http/Responses/LoginSuccessResponse.php +++ b/src/Http/Responses/LoginSuccessResponse.php @@ -16,6 +16,7 @@ class LoginSuccessResponse implements LoginSuccessResponseContract * @param \Illuminate\Http\Request $request * @return \Symfony\Component\HttpFoundation\Response */ + #[\Override] public function toResponse($request) { return $request->wantsJson() diff --git a/src/Http/Responses/LoginViewResponse.php b/src/Http/Responses/LoginViewResponse.php index 1e28814..27efc48 100644 --- a/src/Http/Responses/LoginViewResponse.php +++ b/src/Http/Responses/LoginViewResponse.php @@ -20,6 +20,7 @@ class LoginViewResponse implements LoginViewResponseContract * @param \Illuminate\Http\Request $request * @return \Symfony\Component\HttpFoundation\Response */ + #[\Override] public function toResponse($request) { $view = config('webauthn.views.authenticate', ''); @@ -32,6 +33,7 @@ public function toResponse($request) /** * Set public key request data. */ + #[\Override] public function setPublicKey(Request $request, PublicKeyCredentialRequestOptions $publicKey): self { $this->publicKey = $publicKey; diff --git a/src/Http/Responses/RegisterSuccessResponse.php b/src/Http/Responses/RegisterSuccessResponse.php index 8aa3783..eafb574 100644 --- a/src/Http/Responses/RegisterSuccessResponse.php +++ b/src/Http/Responses/RegisterSuccessResponse.php @@ -22,6 +22,7 @@ class RegisterSuccessResponse implements RegisterSuccessResponseContract * @param \Illuminate\Http\Request $request * @return \Symfony\Component\HttpFoundation\Response */ + #[\Override] public function toResponse($request) { return $request->wantsJson() @@ -45,6 +46,7 @@ protected function jsonResponse(Request $request): \Symfony\Component\HttpFounda /** * Set the new Webauthn key. */ + #[\Override] public function setWebauthnKey(Request $request, Model $webauthnKey): self { $this->webauthnKey = $webauthnKey; diff --git a/src/Http/Responses/RegisterViewResponse.php b/src/Http/Responses/RegisterViewResponse.php index efb542f..54067f4 100644 --- a/src/Http/Responses/RegisterViewResponse.php +++ b/src/Http/Responses/RegisterViewResponse.php @@ -20,6 +20,7 @@ class RegisterViewResponse implements RegisterViewResponseContract * @param \Illuminate\Http\Request $request * @return \Symfony\Component\HttpFoundation\Response */ + #[\Override] public function toResponse($request) { $view = config('webauthn.views.register', ''); @@ -32,6 +33,7 @@ public function toResponse($request) /** * Set public key request data. */ + #[\Override] public function setPublicKey(Request $request, PublicKeyCredentialCreationOptions $publicKey): self { $this->publicKey = $publicKey; diff --git a/src/Http/Responses/UpdateResponse.php b/src/Http/Responses/UpdateResponse.php index d453d66..36ba90b 100644 --- a/src/Http/Responses/UpdateResponse.php +++ b/src/Http/Responses/UpdateResponse.php @@ -13,6 +13,7 @@ class UpdateResponse implements UpdateResponseContract * @param \Illuminate\Http\Request $request * @return \Symfony\Component\HttpFoundation\Response */ + #[\Override] public function toResponse($request) { return $request->wantsJson() diff --git a/src/Listeners/LoginViaRemember.php b/src/Listeners/LoginViaRemember.php index 5a7330e..4c65f50 100644 --- a/src/Listeners/LoginViaRemember.php +++ b/src/Listeners/LoginViaRemember.php @@ -8,6 +8,9 @@ use Illuminate\Support\Facades\Auth; use LaravelWebauthn\Facades\Webauthn; +/** + * @psalm-suppress UnusedClass + */ class LoginViaRemember { /** @@ -34,6 +37,8 @@ private function registerWebauthn(User $user) * Register the listeners for the subscriber. * * @return array + * + * @psalm-suppress PossiblyUnusedParam */ public function subscribe(Dispatcher $events): array { diff --git a/src/Models/Casts/Base64.php b/src/Models/Casts/Base64.php index dd24354..0378b8f 100644 --- a/src/Models/Casts/Base64.php +++ b/src/Models/Casts/Base64.php @@ -17,6 +17,7 @@ class Base64 implements CastsAttributes * @param \Illuminate\Database\Eloquent\Model $model * @param mixed $value */ + #[\Override] public function get($model, string $key, $value, array $attributes): ?string { return $value !== null ? Base64Webauthn::decode($value) : null; @@ -28,6 +29,7 @@ public function get($model, string $key, $value, array $attributes): ?string * @param \Illuminate\Database\Eloquent\Model $model * @param string|null $value */ + #[\Override] public function set($model, string $key, mixed $value, array $attributes): ?string { return $value !== null ? Base64UrlSafe::encode($value) : null; diff --git a/src/Models/Casts/TrustPath.php b/src/Models/Casts/TrustPath.php index cf2862c..3746fdf 100644 --- a/src/Models/Casts/TrustPath.php +++ b/src/Models/Casts/TrustPath.php @@ -17,6 +17,7 @@ class TrustPath implements CastsAttributes * @param \Illuminate\Database\Eloquent\Model $model * @param mixed $value */ + #[\Override] public function get($model, string $key, $value, array $attributes): ?TrustPathLib { return $value !== null ? app(SerializerInterface::class)->deserialize($value, TrustPathLib::class, 'json') : null; @@ -28,6 +29,7 @@ public function get($model, string $key, $value, array $attributes): ?TrustPathL * @param \Illuminate\Database\Eloquent\Model $model * @param string|null $value */ + #[\Override] public function set($model, string $key, mixed $value, array $attributes): ?string { return json_encode($value, flags: JSON_THROW_ON_ERROR); diff --git a/src/Models/Casts/Uuid.php b/src/Models/Casts/Uuid.php index 302386d..28a6d97 100644 --- a/src/Models/Casts/Uuid.php +++ b/src/Models/Casts/Uuid.php @@ -17,6 +17,7 @@ class Uuid implements CastsAttributes * @param \Illuminate\Database\Eloquent\Model $model * @param mixed $value */ + #[\Override] public function get($model, string $key, $value, array $attributes): ?AbstractUid { if ($value !== null && UuidConvert::isValid($value)) { @@ -32,6 +33,7 @@ public function get($model, string $key, $value, array $attributes): ?AbstractUi * @param \Illuminate\Database\Eloquent\Model $model * @param string|null $value */ + #[\Override] public function set($model, string $key, mixed $value, array $attributes): ?string { return (string) $value; diff --git a/src/Models/WebauthnKey.php b/src/Models/WebauthnKey.php index 8cb54fd..5b8c6f7 100644 --- a/src/Models/WebauthnKey.php +++ b/src/Models/WebauthnKey.php @@ -26,7 +26,7 @@ class WebauthnKey extends Model /** * The attributes that are mass assignable. * - * @var array + * @var list */ protected $fillable = [ 'user_id', @@ -45,7 +45,7 @@ class WebauthnKey extends Model /** * The attributes that should be visible in serialization. * - * @var array + * @var list */ protected $visible = [ 'id', @@ -84,14 +84,14 @@ public function publicKeyCredentialSource(): Attribute $this->transports, $this->attestationType, $this->trustPath, - $this->aaguid ?? new NilUuid(), + $this->aaguid ?? new NilUuid, $this->credentialPublicKey, (string) $this->user_id, $this->counter ), set: function (PublicKeyCredentialSource $value, ?array $attributes = null): array { if (((string) Arr::get($attributes, 'user_id')) !== $value->userHandle) { - throw new WrongUserHandleException(); + throw new WrongUserHandleException; } // Set value to attributes using casts diff --git a/src/Services/LoginRateLimiter.php b/src/Services/LoginRateLimiter.php index ab5c31a..4b51950 100644 --- a/src/Services/LoginRateLimiter.php +++ b/src/Services/LoginRateLimiter.php @@ -33,6 +33,8 @@ public function tooManyAttempts(Request $request): bool /** * Increment the login attempts for the user. + * + * @psalm-suppress PossiblyUnusedReturnValue */ public function increment(Request $request): int { diff --git a/src/Services/Webauthn.php b/src/Services/Webauthn.php index c1e3ed2..59b1f29 100644 --- a/src/Services/Webauthn.php +++ b/src/Services/Webauthn.php @@ -72,7 +72,7 @@ public static function login(?User $user): void */ public static function logout(): void { - session()->forget(static::sessionName()); + session()->forget(static::sessionName()); // @phpstan-ignore staticMethod.dynamicCall } /** diff --git a/src/Services/Webauthn/CreationOptionsFactory.php b/src/Services/Webauthn/CreationOptionsFactory.php index 3a3658d..f2b8ee9 100644 --- a/src/Services/Webauthn/CreationOptionsFactory.php +++ b/src/Services/Webauthn/CreationOptionsFactory.php @@ -27,13 +27,12 @@ public function __construct( Request $request, Cache $cache, Config $config, - CredentialRepository $repository, protected SerializerInterface $loader, protected PublicKeyCredentialRpEntity $publicKeyCredentialRpEntity, protected AuthenticatorSelectionCriteria $authenticatorSelectionCriteria, protected CoseAlgorithmManager $algorithmManager ) { - parent::__construct($request, $cache, $config, $repository); + parent::__construct($request, $cache, $config); $this->attestationConveyance = $config->get('webauthn.attestation_conveyance', 'none'); } @@ -79,12 +78,10 @@ private function getUserEntity(User $user): PublicKeyCredentialUserEntity private function createCredentialParameters(): array { return collect($this->algorithmManager->list()) - ->map(function ($algorithm): PublicKeyCredentialParameters { - return new PublicKeyCredentialParameters( - PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, - $algorithm - ); - }) + ->map(fn ($algorithm): PublicKeyCredentialParameters => new PublicKeyCredentialParameters( + PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, + $algorithm + )) ->toArray(); } diff --git a/src/Services/Webauthn/OptionsFactory.php b/src/Services/Webauthn/OptionsFactory.php index ae9b8c7..ac3d838 100644 --- a/src/Services/Webauthn/OptionsFactory.php +++ b/src/Services/Webauthn/OptionsFactory.php @@ -21,8 +21,7 @@ abstract class OptionsFactory extends CredentialValidator public function __construct( Request $request, Cache $cache, - Config $config, - protected CredentialRepository $repository + Config $config ) { parent::__construct($request, $cache); diff --git a/src/Services/Webauthn/RequestOptionsFactory.php b/src/Services/Webauthn/RequestOptionsFactory.php index 5f30b72..74d147a 100644 --- a/src/Services/Webauthn/RequestOptionsFactory.php +++ b/src/Services/Webauthn/RequestOptionsFactory.php @@ -22,11 +22,10 @@ public function __construct( Request $request, Cache $cache, Config $config, - CredentialRepository $repository, protected SerializerInterface $loader, protected PublicKeyCredentialRpEntity $publicKeyCredentialRpEntity ) { - parent::__construct($request, $cache, $config, $repository); + parent::__construct($request, $cache, $config); $this->userVerification = self::getUserVerification($config); } diff --git a/src/WebauthnAuthenticatable.php b/src/WebauthnAuthenticatable.php index 91baea6..8ce9acf 100644 --- a/src/WebauthnAuthenticatable.php +++ b/src/WebauthnAuthenticatable.php @@ -5,6 +5,11 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use LaravelWebauthn\Models\WebauthnKey; +/** + * Trait to add Webauthn authenticatable to a user model. + * + * @phpstan-ignore trait.unused + */ trait WebauthnAuthenticatable { /** diff --git a/src/WebauthnServiceProvider.php b/src/WebauthnServiceProvider.php index 4f95108..a339fe8 100644 --- a/src/WebauthnServiceProvider.php +++ b/src/WebauthnServiceProvider.php @@ -30,7 +30,6 @@ use LaravelWebauthn\Http\Responses\RegisterViewResponse; use LaravelWebauthn\Http\Responses\UpdateResponse; use LaravelWebauthn\Services\Webauthn; -use LaravelWebauthn\Services\Webauthn\CredentialAssertionValidator; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\ResponseFactoryInterface; @@ -57,6 +56,9 @@ use Webauthn\Counter\ThrowExceptionIfInvalid; use Webauthn\PublicKeyCredentialRpEntity; +/** + * @psalm-suppress UnusedClass + */ class WebauthnServiceProvider extends ServiceProvider { /** @@ -73,6 +75,7 @@ public function boot(): void /** * Register any application services. */ + #[\Override] public function register(): void { $this->app->singleton(WebauthnFacade::class, Webauthn::class); @@ -294,6 +297,8 @@ protected function bindPsrInterfaces(): void if (class_exists(\Nyholm\Psr7\Factory\Psr17Factory::class) && class_exists(PsrHttpFactory::class)) { /** * @var ServerRequestFactoryInterface|StreamFactoryInterface|UploadedFileFactoryInterface|ResponseFactoryInterface + * + * @phpstan-ignore varTag.nativeType */ $psr17Factory = new \Nyholm\Psr7\Factory\Psr17Factory; @@ -324,7 +329,6 @@ private function passwordLessWebauthn(): void { $this->app['auth']->provider('webauthn', fn ($app, array $config) => new EloquentWebAuthnProvider( $app['config'], - $app[CredentialAssertionValidator::class], $app[Hasher::class], $config['model'] ) diff --git a/tests/Unit/Auth/EloquentWebAuthnProviderTest.php b/tests/Unit/Auth/EloquentWebAuthnProviderTest.php index 65388a7..aff675c 100644 --- a/tests/Unit/Auth/EloquentWebAuthnProviderTest.php +++ b/tests/Unit/Auth/EloquentWebAuthnProviderTest.php @@ -7,7 +7,6 @@ use LaravelWebauthn\Auth\EloquentWebAuthnProvider; use LaravelWebauthn\Facades\Webauthn; use LaravelWebauthn\Models\WebauthnKey; -use LaravelWebauthn\Services\Webauthn\CredentialAssertionValidator; use LaravelWebauthn\Tests\FeatureTestCase; use LaravelWebauthn\Tests\User; use ParagonIE\ConstantTime\Base64UrlSafe; @@ -27,7 +26,6 @@ public function it_validate_credentials() $provider = new EloquentWebAuthnProvider( app('config'), - app(CredentialAssertionValidator::class), app(Hasher::class), '' ); @@ -59,7 +57,6 @@ public function it_retrieve_user() $provider = new EloquentWebAuthnProvider( app('config'), - app(CredentialAssertionValidator::class), app(Hasher::class), User::class, ); @@ -92,7 +89,6 @@ public function it_retrieve_user_old_format() $provider = new EloquentWebAuthnProvider( app('config'), - app(CredentialAssertionValidator::class), app(Hasher::class), User::class, ); @@ -127,7 +123,6 @@ public function it_retrieve_user_new_format() $provider = new EloquentWebAuthnProvider( app('config'), - app(CredentialAssertionValidator::class), app(Hasher::class), User::class, ); @@ -153,7 +148,6 @@ public function it_does_not_fail_when_retrieving_user() $provider = new EloquentWebAuthnProvider( app('config'), - app(CredentialAssertionValidator::class), app(Hasher::class), User::class, ); diff --git a/tests/Unit/Http/Middleware/MiddlewareTest.php b/tests/Unit/Http/Middleware/MiddlewareTest.php index 69c5719..fb689a4 100644 --- a/tests/Unit/Http/Middleware/MiddlewareTest.php +++ b/tests/Unit/Http/Middleware/MiddlewareTest.php @@ -12,7 +12,7 @@ class MiddlewareTest extends FeatureTestCase { public function test_middleware_guest() { - $request = new Request(); + $request = new Request; $this->expectException(\Symfony\Component\HttpKernel\Exception\HttpException::class); $this->app[WebauthnMiddleware::class]->handle($request, fn () => null); @@ -56,7 +56,7 @@ public function test_middleware_user_enabled() private function getRequest($user) { - return (new Request()) + return (new Request) ->setUserResolver(fn () => $user); } } diff --git a/tests/Unit/Models/Casts/Base64Test.php b/tests/Unit/Models/Casts/Base64Test.php index d5e697a..bc75946 100644 --- a/tests/Unit/Models/Casts/Base64Test.php +++ b/tests/Unit/Models/Casts/Base64Test.php @@ -13,9 +13,9 @@ class Base64Test extends FeatureTestCase * * @dataProvider dataProvider */ - public function it_deserialize_credentialId($credentialId, $expected) + public function it_deserialize_credential_id($credentialId, $expected) { - $webauthnKey = new WebauthnKey(); + $webauthnKey = new WebauthnKey; $bin = (new Base64)->get($webauthnKey, 'credentialId', $credentialId, []); diff --git a/tests/Unit/Models/WebauthnKeyTest.php b/tests/Unit/Models/WebauthnKeyTest.php index 94dee32..03e1cd9 100644 --- a/tests/Unit/Models/WebauthnKeyTest.php +++ b/tests/Unit/Models/WebauthnKeyTest.php @@ -11,9 +11,9 @@ class WebauthnKeyTest extends FeatureTestCase { public function test_serialize_data() { - $webauthnKey = new WebauthnKey(); + $webauthnKey = new WebauthnKey; $webauthnKey->user_id = 0; - $webauthnKey->publicKeyCredentialSource = new PublicKeyCredentialSource('a', 'b', [], 'c', new \Webauthn\TrustPath\EmptyTrustPath(), Uuid::fromString('38195f59-0e5b-4ebf-be46-75664177eeee'), 'e', '0', 1); + $webauthnKey->publicKeyCredentialSource = new PublicKeyCredentialSource('a', 'b', [], 'c', new \Webauthn\TrustPath\EmptyTrustPath, Uuid::fromString('38195f59-0e5b-4ebf-be46-75664177eeee'), 'e', '0', 1); $this->assertEquals(0, $webauthnKey->user_id); $this->assertEquals('a', $webauthnKey->credentialId); @@ -28,7 +28,7 @@ public function test_serialize_data() public function test_deserialize_data() { - $webauthnKey = new WebauthnKey(); + $webauthnKey = new WebauthnKey; $webauthnKey->user_id = 0; $webauthnKey->credentialId = 'a'; @@ -38,7 +38,7 @@ public function test_deserialize_data() $webauthnKey->credentialPublicKey = 'e'; $webauthnKey->counter = 0; $webauthnKey->attestationType = 'c'; - $webauthnKey->trustPath = new \Webauthn\TrustPath\EmptyTrustPath(); + $webauthnKey->trustPath = new \Webauthn\TrustPath\EmptyTrustPath; $publicKeyCredentialSource = $webauthnKey->publicKeyCredentialSource; diff --git a/tests/Unit/Services/Webauthn/CredentialRepositoryTest.php b/tests/Unit/Services/Webauthn/CredentialRepositoryTest.php index 4e425ac..d802add 100644 --- a/tests/Unit/Services/Webauthn/CredentialRepositoryTest.php +++ b/tests/Unit/Services/Webauthn/CredentialRepositoryTest.php @@ -28,7 +28,7 @@ public function it_returns_an_array_with_the_keys() $this->assertEmpty(WebauthnKey::all()); - $webauthnKey = factory(WebauthnKey::class)->create([ + factory(WebauthnKey::class)->create([ 'user_id' => $user->getAuthIdentifier(), 'credentialId' => '1', ]); From 4e316209a144c7446c24330de4477844ade4ba36 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Sun, 2 Mar 2025 20:52:33 +0100 Subject: [PATCH 5/7] update --- .github/workflows/tests.yml | 8 +------- README.md | 9 +++++---- composer.json | 4 ++-- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 417338d..5f53ce9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,15 +33,9 @@ jobs: fail-fast: false matrix: php-version: ['8.1', '8.2', '8.3', '8.4'] - laravel-version: ['9.0', '10.0', '11.0', '12.0'] + laravel-version: ['10.0', '11.0', '12.0'] psr7: ['guzzle'] include: - - php-version: '8.1' - laravel-version: '9.0' - psr7: 'nyholm' - - php-version: '8.1' - laravel-version: '9.0' - psr7: 'discovery' - php-version: '8.2' laravel-version: '10.0' psr7: 'nyholm' diff --git a/README.md b/README.md index 40b34a4..8b470b6 100644 --- a/README.md +++ b/README.md @@ -427,11 +427,12 @@ List of methods and their expected response contracts: This package has the following Laravel compatibility: -| Laravel | [asbiin/laravel-webauthn](https://github.com/asbiin/laravel-webauthn) | +| [asbiin/laravel-webauthn](https://github.com/asbiin/laravel-webauthn) | Laravel | |----------|----------| -| 5.8-8.x | <= 1.2.0 | -| 7.x-8.x | 2.0.1 | -| >= 9.x | >= 3.0.0 | +| <= 1.2.0 | 5.8-8.x | +| 2.0.1 | 7.x-8.x | +| >= 3.0.0, <= 4.6.0 | 9.x-11.x | +| >= 5.0.0 | >= 10.x | ## Browser compatibility diff --git a/composer.json b/composer.json index 438f758..3812e2d 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ ], "require": { "php": ">=8.1", - "illuminate/support": "^9.0 || ^10.0 || ^11.0 || ^12.0", + "illuminate/support": "^10.0 || ^11.0 || ^12.0", "phpdocumentor/reflection-docblock": "^5.3", "psr/http-factory-implementation": "1.0", "symfony/property-access": "^6.4 || ^7.0", @@ -42,7 +42,7 @@ "laravel/legacy-factories": "^1.0", "laravel/pint": "^1.13", "ocramius/package-versions": "^2.0", - "orchestra/testbench": "^7.0 || ^8.0 || ^9.0 || ^10.0", + "orchestra/testbench": "^8.0 || ^9.0 || ^10.0", "phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0", "phpstan/phpstan-phpunit": "^1.0 || ^2.0", "phpstan/phpstan-strict-rules": "^1.0 || ^2.0", From b5107bb9b4254bfa219989e8a568040d34475e12 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Sun, 2 Mar 2025 21:05:14 +0100 Subject: [PATCH 6/7] update --- .github/workflows/tests.yml | 15 ++------------- README.md | 2 +- composer.json | 13 +++++-------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5f53ce9..c4f3e14 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,16 +32,10 @@ jobs: strategy: fail-fast: false matrix: - php-version: ['8.1', '8.2', '8.3', '8.4'] - laravel-version: ['10.0', '11.0', '12.0'] + php-version: ['8.2', '8.3', '8.4'] + laravel-version: ['11.0', '12.0'] psr7: ['guzzle'] include: - - php-version: '8.2' - laravel-version: '10.0' - psr7: 'nyholm' - - php-version: '8.2' - laravel-version: '10.0' - psr7: 'discovery' - php-version: '8.2' laravel-version: '11.0' psr7: 'nyholm' @@ -60,11 +54,6 @@ jobs: - php-version: '8.4' laravel-version: '12.0' psr7: 'discovery' - exclude: - - php-version: '8.1' - laravel-version: '11.0' - - php-version: '8.1' - laravel-version: '12.0' steps: - name: Checkout sources diff --git a/README.md b/README.md index 8b470b6..8015994 100644 --- a/README.md +++ b/README.md @@ -432,7 +432,7 @@ This package has the following Laravel compatibility: | <= 1.2.0 | 5.8-8.x | | 2.0.1 | 7.x-8.x | | >= 3.0.0, <= 4.6.0 | 9.x-11.x | -| >= 5.0.0 | >= 10.x | +| >= 5.0.0 | >= 11.x | ## Browser compatibility diff --git a/composer.json b/composer.json index 3812e2d..0805075 100644 --- a/composer.json +++ b/composer.json @@ -20,20 +20,17 @@ } ], "require": { - "php": ">=8.1", - "illuminate/support": "^10.0 || ^11.0 || ^12.0", + "php": ">=8.2", + "illuminate/support": "^11.0 || ^12.0", "phpdocumentor/reflection-docblock": "^5.3", "psr/http-factory-implementation": "1.0", "symfony/property-access": "^6.4 || ^7.0", "symfony/property-info": "^6.4 || ^7.0", "symfony/serializer": "^6.4 || ^7.0", "web-auth/cose-lib": "^4.0", - "web-auth/webauthn-lib": "^4.8 || ^5.0", + "web-auth/webauthn-lib": "^5.0", "web-token/jwt-library": "^3.0 || ^4.0" }, - "conflict": { - "web-auth/webauthn-lib": "4.7.0" - }, "require-dev": { "ext-sqlite3": "*", "brainmaestro/composer-git-hooks": "^3.0", @@ -42,11 +39,11 @@ "laravel/legacy-factories": "^1.0", "laravel/pint": "^1.13", "ocramius/package-versions": "^2.0", - "orchestra/testbench": "^8.0 || ^9.0 || ^10.0", + "orchestra/testbench": "^9.0 || ^10.0", "phpstan/phpstan-deprecation-rules": "^1.0 || ^2.0", "phpstan/phpstan-phpunit": "^1.0 || ^2.0", "phpstan/phpstan-strict-rules": "^1.0 || ^2.0", - "phpunit/phpunit": "^9.5 || ^10.0 || ^11.0 || ^12.0", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", "psalm/plugin-laravel": "^2.8 || ^3.0" }, "suggest": { From 08f3cccd68c72ed936edf97e7e1f19c02cd3a5a7 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Sun, 2 Mar 2025 21:09:54 +0100 Subject: [PATCH 7/7] update --- composer.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0805075..c089afd 100644 --- a/composer.json +++ b/composer.json @@ -28,9 +28,12 @@ "symfony/property-info": "^6.4 || ^7.0", "symfony/serializer": "^6.4 || ^7.0", "web-auth/cose-lib": "^4.0", - "web-auth/webauthn-lib": "^5.0", + "web-auth/webauthn-lib": "^4.8 || ^5.0", "web-token/jwt-library": "^3.0 || ^4.0" }, + "conflict": { + "web-auth/webauthn-lib": "4.7.0" + }, "require-dev": { "ext-sqlite3": "*", "brainmaestro/composer-git-hooks": "^3.0",