diff --git a/src/auth/passkeys/CredentialRepository.php b/src/auth/passkeys/CredentialRepository.php index efdbe4887d6..18292a997ed 100644 --- a/src/auth/passkeys/CredentialRepository.php +++ b/src/auth/passkeys/CredentialRepository.php @@ -25,6 +25,17 @@ */ class CredentialRepository implements PublicKeyCredentialSourceRepository { + /** + * @var WebauthnServer + */ + private WebauthnServer $_webauthnServer; + + + public function __construct() + { + $this->_webauthnServer = new WebauthnServer(); + } + /** * @inheritdoc */ @@ -33,7 +44,13 @@ public function findOneByCredentialId(string $publicKeyCredentialId): ?PublicKey $record = $this->_findByCredentialId($publicKeyCredentialId); if ($record) { - return PublicKeyCredentialSource::createFromArray(Json::decodeIfJson($record->credential)); + $serializer = $this->_webauthnServer->getSerializer(); + + return $serializer->deserialize( + $record->credential, + PublicKeyCredentialSource::class, + 'json', + ); } return null; @@ -50,8 +67,13 @@ public function findAllForUserEntity(PublicKeyCredentialUserEntity $publicKeyCre $keySources = []; if ($user && $user->id) { $records = WebAuthn::findAll(['userId' => $user->id]); + $serializer = $this->_webauthnServer->getSerializer(); foreach ($records as $record) { - $keySources[] = PublicKeyCredentialSource::createFromArray(Json::decodeIfJson($record->credential)); + $keySources[] = $serializer->deserialize( + $record->credential, + PublicKeyCredentialSource::class, + 'json', + ); } } @@ -66,7 +88,7 @@ public function findAllForUserEntity(PublicKeyCredentialUserEntity $publicKeyCre */ public function savedNamedCredentialSource(PublicKeyCredentialSource $publicKeyCredentialSource, ?string $credentialName = null): void { - $publicKeyCredentialId = $publicKeyCredentialSource->getPublicKeyCredentialId(); + $publicKeyCredentialId = $publicKeyCredentialSource->publicKeyCredentialId; $record = $this->_findByCredentialId($publicKeyCredentialId); if (!$record) { diff --git a/src/auth/passkeys/WebauthnServer.php b/src/auth/passkeys/WebauthnServer.php index e56eee5ff3e..63f73448cac 100644 --- a/src/auth/passkeys/WebauthnServer.php +++ b/src/auth/passkeys/WebauthnServer.php @@ -25,7 +25,6 @@ use Webauthn\AuthenticatorAttestationResponseValidator; use Webauthn\AuthenticatorSelectionCriteria; use Webauthn\Denormalizer\WebauthnSerializerFactory; -use Webauthn\PublicKeyCredentialLoader; use Webauthn\PublicKeyCredentialParameters; use Webauthn\TokenBinding\IgnoreTokenBindingHandler; @@ -45,6 +44,7 @@ class WebauthnServer * * @return IgnoreTokenBindingHandler * @see https://webauthn-doc.spomky-labs.com/v/v4.5/pure-php/the-hard-way#token-binding-handler + * todo: remove when updating to web-auth 5.0 */ public function getTokenBindingHandler(): IgnoreTokenBindingHandler { @@ -81,19 +81,6 @@ public function getAttestationObjectLoader(): AttestationObjectLoader ); } - /** - * Returns the object that will load the Public Key. - * - * @return PublicKeyCredentialLoader - * @see https://webauthn-doc.spomky-labs.com/pure-php/the-hard-way#public-key-credential-loader - */ - public function getPublicKeyCredentialLoader(): PublicKeyCredentialLoader - { - return PublicKeyCredentialLoader::create( - $this->getAttestationObjectLoader() - ); - } - /** * Return the Symphony Serializer that will deal with serialization/deserialization of data. * @@ -158,8 +145,8 @@ public function getAuthenticatorAttestationResponseValidator(): AuthenticatorAtt { return AuthenticatorAttestationResponseValidator::create( $this->getAttestationStatementManager(), - new CredentialRepository(), - $this->getTokenBindingHandler(), + new CredentialRepository(), // todo: set to null when updating to web-auth 5.0 + $this->getTokenBindingHandler(), // todo: set to null when updating to web-auth 5.0 $this->getExtensionOutputCheckerHandler(), ); } @@ -174,8 +161,8 @@ public function getAuthenticatorAssertionResponseValidator(): AuthenticatorAsser { return AuthenticatorAssertionResponseValidator::create( new CredentialRepository(), - $this->getTokenBindingHandler(), - $this->getExtensionOutputCheckerHandler(), + $this->getTokenBindingHandler(), // todo: set to null when updating to web-auth 5.0 + $this->getExtensionOutputCheckerHandler(), // todo: set to null when updating to web-auth 5.0 $this->getAlgorithmManager(), ); } diff --git a/src/services/Auth.php b/src/services/Auth.php index 466fe2a8739..864655f862c 100644 --- a/src/services/Auth.php +++ b/src/services/Auth.php @@ -450,7 +450,12 @@ public function verifyPasskeyCreationResponse(string $credentials, ?string $cred $serializer = $this->webauthnServer()->getSerializer(); - $publicKeyCredentialCreationOptions = PublicKeyCredentialCreationOptions::createFromArray(Json::decode($optionsJson)); + $publicKeyCredentialCreationOptions = $serializer->deserialize( + $optionsJson, + PublicKeyCredentialCreationOptions::class, + 'json', + ); + $publicKeyCredential = $serializer->deserialize( $credentials, PublicKeyCredential::class, @@ -506,14 +511,20 @@ public function verifyPasskey( PublicKeyCredentialRequestOptions|array|string $requestOptions, string $response, ): bool { - if (is_array($requestOptions)) { - $requestOptions = PublicKeyCredentialRequestOptions::createFromArray($requestOptions); - } elseif (is_string($requestOptions)) { - $requestOptions = PublicKeyCredentialRequestOptions::createFromString($requestOptions); - } + $serializer = $this->webauthnServer()->getSerializer(); + + $requestOptions = $serializer->deserialize( + $requestOptions, + PublicKeyCredentialRequestOptions::class, + 'json', + ); $userEntity = $this->passkeyUserEntity($user); - $publicKeyCredential = $this->webauthnServer()->getPublicKeyCredentialLoader()->load($response); + $publicKeyCredential = $serializer->deserialize( + $response, + PublicKeyCredential::class, + 'json', + ); $authenticatorAssertionResponse = $publicKeyCredential->response; if (!$authenticatorAssertionResponse instanceof AuthenticatorAssertionResponse) { @@ -571,13 +582,11 @@ private function webauthnServer(): WebauthnServer */ private function passkeyUserEntity(User $user): PublicKeyCredentialUserEntity { - $data = [ - 'name' => $user->email, - 'id' => Base64UrlSafe::encodeUnpadded($user->uid), - 'displayName' => $user->getName(), - ]; - - return PublicKeyCredentialUserEntity::createFromArray($data); + return PublicKeyCredentialUserEntity::create( + $user->email, + Base64UrlSafe::encodeUnpadded($user->uid), + $user->getName(), + ); } /** @@ -587,9 +596,9 @@ private function passkeyUserEntity(User $user): PublicKeyCredentialUserEntity */ private function passkeyRpEntity(): PublicKeyCredentialRpEntity { - return PublicKeyCredentialRpEntity::createFromArray([ - 'name' => Craft::$app->getSystemName(), - 'id' => Craft::$app->getRequest()->getHostName(), - ]); + return PublicKeyCredentialRpEntity::create( + Craft::$app->getSystemName(), + Craft::$app->getRequest()->getHostName(), + ); } }