diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 40979949..43f86d17 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2321,3 +2321,12 @@ parameters: identifier: return.type count: 1 path: src/webauthn/src/SimpleFakeCredentialGenerator.php + + - + rawMessage: ''' + Fetching deprecated class constant AUTHENTICATOR_TRANSPORT_CABLE of class Webauthn\PublicKeyCredentialDescriptor: + Please use AUTHENTICATOR_TRANSPORT_BLE instead. Will be removed in 6.0.0 + ''' + identifier: classConstant.deprecated + count: 1 + path: src/webauthn/src/PublicKeyCredentialDescriptor.php diff --git a/src/webauthn/src/AuthenticatorSelectionCriteria.php b/src/webauthn/src/AuthenticatorSelectionCriteria.php index 8ef98cde..160cbdd3 100644 --- a/src/webauthn/src/AuthenticatorSelectionCriteria.php +++ b/src/webauthn/src/AuthenticatorSelectionCriteria.php @@ -48,6 +48,15 @@ class AuthenticatorSelectionCriteria self::RESIDENT_KEY_REQUIREMENT_DISCOURAGED, ]; + /** + * Legacy property for backward compatibility. + * + * requireResidentKey is based on residentKey for backward compatibility + * Per WebAuthn Level 3 spec: "Relying Parties SHOULD set it to true if, and only if, residentKey is set to required." + * Only set when residentKey is "required"; leave uninitialized otherwise + */ + public readonly ?bool $requireResidentKey; + public function __construct( public null|string $authenticatorAttachment = null, public string $userVerification = self::USER_VERIFICATION_REQUIREMENT_PREFERRED, @@ -62,6 +71,12 @@ public function __construct( in_array($residentKey, self::RESIDENT_KEY_REQUIREMENTS, true) || throw new InvalidArgumentException( 'Invalid resident key' ); + + if ($residentKey === self::RESIDENT_KEY_REQUIREMENT_REQUIRED) { + $this->requireResidentKey = true; + } else { + $this->requireResidentKey = null; + } } public static function create( diff --git a/src/webauthn/src/PublicKeyCredentialDescriptor.php b/src/webauthn/src/PublicKeyCredentialDescriptor.php index 09fd620d..2f7cfc27 100644 --- a/src/webauthn/src/PublicKeyCredentialDescriptor.php +++ b/src/webauthn/src/PublicKeyCredentialDescriptor.php @@ -14,8 +14,15 @@ class PublicKeyCredentialDescriptor final public const AUTHENTICATOR_TRANSPORT_BLE = 'ble'; + /** + * @deprecated Please use AUTHENTICATOR_TRANSPORT_BLE instead. Will be removed in 6.0.0 + */ final public const AUTHENTICATOR_TRANSPORT_CABLE = 'cable'; + final public const AUTHENTICATOR_TRANSPORT_SMART_CARD = 'smart-card'; + + final public const AUTHENTICATOR_TRANSPORT_HYBRID = 'hybrid'; + final public const AUTHENTICATOR_TRANSPORT_INTERNAL = 'internal'; final public const AUTHENTICATOR_TRANSPORTS = [ @@ -23,6 +30,8 @@ class PublicKeyCredentialDescriptor self::AUTHENTICATOR_TRANSPORT_NFC, self::AUTHENTICATOR_TRANSPORT_BLE, self::AUTHENTICATOR_TRANSPORT_CABLE, + self::AUTHENTICATOR_TRANSPORT_SMART_CARD, + self::AUTHENTICATOR_TRANSPORT_HYBRID, self::AUTHENTICATOR_TRANSPORT_INTERNAL, ]; diff --git a/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php b/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php index 7292bb26..3462b81c 100644 --- a/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php +++ b/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php @@ -57,7 +57,7 @@ public function anAuthenticatorSelectionCriteriaCanBeCreatedAndValueAccessed(): public function anAuthenticatorSelectionCriteriaWithResidentKeyCanBeCreatedAndValueAccessed(): void { // Given - $expectedJson = '{"userVerification":"required","residentKey":"required","authenticatorAttachment":"platform"}'; + $expectedJson = '{"requireResidentKey":true,"userVerification":"required","residentKey":"required","authenticatorAttachment":"platform"}'; $authenticatorSelectionCriteria = AuthenticatorSelectionCriteria::create( AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_PLATFORM, AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED, @@ -80,6 +80,7 @@ public function anAuthenticatorSelectionCriteriaWithResidentKeyCanBeCreatedAndVa $data->authenticatorAttachment ); static::assertSame(AuthenticatorSelectionCriteria::RESIDENT_KEY_REQUIREMENT_REQUIRED, $data->residentKey); + static::assertTrue($data->requireResidentKey); static::assertJsonStringEqualsJsonString($expectedJson, $this->getSerializer()->serialize($data, 'json', [ AbstractObjectNormalizer::SKIP_NULL_VALUES => true, ])); diff --git a/tests/symfony/config/config.yml b/tests/symfony/config/config.yml index 48b8f252..d6115f5a 100644 --- a/tests/symfony/config/config.yml +++ b/tests/symfony/config/config.yml @@ -37,6 +37,7 @@ services: Symfony\Component\Serializer\Normalizer\ObjectNormalizer: tags: [ serializer.normalizer ] + autowire: true Webauthn\Tests\Bundle\Functional\MockClientCallback: ~ diff --git a/tests/symfony/functional/Firewall/RegistrationAreaTest.php b/tests/symfony/functional/Firewall/RegistrationAreaTest.php index 0196d26a..cd839eea 100644 --- a/tests/symfony/functional/Firewall/RegistrationAreaTest.php +++ b/tests/symfony/functional/Firewall/RegistrationAreaTest.php @@ -101,6 +101,7 @@ public function aValidRequestProcessed(): void static::assertArrayHasKey('authenticatorSelection', $data); static::assertSame([ + 'requireResidentKey' => true, 'authenticatorAttachment' => 'cross-platform', 'userVerification' => 'required', 'residentKey' => 'required', @@ -137,6 +138,7 @@ public function aValidRequestProcessedOnOtherHost(): void static::assertArrayHasKey('authenticatorSelection', $data); static::assertSame([ + 'requireResidentKey' => true, 'userVerification' => 'preferred', 'residentKey' => 'required', ], $data['authenticatorSelection']); @@ -181,6 +183,7 @@ public function aValidRequestProcessedWithExtensions(): void static::assertArrayHasKey('authenticatorSelection', $data); static::assertSame([ + 'requireResidentKey' => true, 'authenticatorAttachment' => 'platform', 'userVerification' => 'required', 'residentKey' => 'required',