Skip to content

Commit d726de6

Browse files
authored
public extension points (#12)
1 parent 470f9e9 commit d726de6

6 files changed

Lines changed: 34 additions & 9 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ use Webauthn\AuthenticatorSelectionCriteria;
179179

180180
class CustomRegistrationOptions extends GenerateRegistrationOptions
181181
{
182-
protected function authenticatorSelection(): AuthenticatorSelectionCriteria
182+
public function authenticatorSelection(): AuthenticatorSelectionCriteria
183183
{
184184
// Only allow platform authenticators (Touch ID, Face ID, Windows Hello)
185185
return AuthenticatorSelectionCriteria::create(

src/Actions/GenerateRegistrationOptions.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ protected function userEntity(PasskeyUser $user): PublicKeyCredentialUserEntity
7171
*
7272
* @see https://www.w3.org/TR/webauthn-3/#dictdef-authenticatorselectioncriteria
7373
*/
74-
protected function authenticatorSelection(): AuthenticatorSelectionCriteria
74+
public function authenticatorSelection(): AuthenticatorSelectionCriteria
7575
{
7676
// Allow any authenticator: built-in (Touch ID, Windows Hello) or external (YubiKey).
7777
$crossPlatform = AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE;
@@ -95,7 +95,7 @@ protected function authenticatorSelection(): AuthenticatorSelectionCriteria
9595
*
9696
* @return array<PublicKeyCredentialDescriptor>
9797
*/
98-
protected function excludedCredentials(PasskeyUser $user): array
98+
public function excludedCredentials(PasskeyUser $user): array
9999
{
100100
$type = PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY;
101101

@@ -112,7 +112,7 @@ protected function excludedCredentials(PasskeyUser $user): array
112112
*
113113
* @return array<PublicKeyCredentialParameters>
114114
*/
115-
protected function supportedAlgorithms(): array
115+
public function supportedAlgorithms(): array
116116
{
117117
$type = PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY;
118118

src/Actions/GenerateVerificationOptions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function __invoke(?PasskeyUser $user = null): PublicKeyCredentialRequestO
3636
*
3737
* @return array<PublicKeyCredentialDescriptor>
3838
*/
39-
protected function allowCredentials(?PasskeyUser $user): array
39+
public function allowCredentials(?PasskeyUser $user): array
4040
{
4141
if (! $user instanceof PasskeyUser) {
4242
return [];

src/Actions/StorePasskey.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ protected function ensureCredentialIsUnique(PublicKeyCredentialSource $source):
9595
/**
9696
* Create the passkey record for the user.
9797
*/
98-
protected function createPasskey(
98+
public function createPasskey(
9999
PasskeyUser $user,
100100
string $name,
101101
PublicKeyCredentialSource $source

src/Actions/VerifyPasskey.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ protected function getResponse(PublicKeyCredential $credential): AuthenticatorAs
6161
*
6262
* @throws InvalidPasskeyException
6363
*/
64-
protected function getPasskey(PublicKeyCredential $credential): Passkey
64+
public function getPasskey(PublicKeyCredential $credential): Passkey
6565
{
6666
$credentialId = Base64UrlSafe::encodeUnpadded($credential->rawId);
6767

@@ -74,7 +74,7 @@ protected function getPasskey(PublicKeyCredential $credential): Passkey
7474
*
7575
* @throws InvalidPasskeyException
7676
*/
77-
protected function ensurePasskeyBelongsToUser(Passkey $passkey, ?PasskeyUser $user): void
77+
public function ensurePasskeyBelongsToUser(Passkey $passkey, ?PasskeyUser $user): void
7878
{
7979
if (! $user instanceof PasskeyUser) {
8080
return;
@@ -115,7 +115,7 @@ protected function validate(
115115
* The credential must be persisted after each use to store the updated
116116
* signature counter, which is used to detect cloned authenticators.
117117
*/
118-
protected function updatePasskey(Passkey $passkey, PublicKeyCredentialSource $source): void
118+
public function updatePasskey(Passkey $passkey, PublicKeyCredentialSource $source): void
119119
{
120120
$passkey->forceFill([
121121
'credential' => json_decode(WebAuthn::toJson($source), true, flags: JSON_THROW_ON_ERROR),

tests/Feature/Actions/GenerateRegistrationOptionsTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use Laravel\Passkeys\Actions\GenerateRegistrationOptions;
44
use Laravel\Passkeys\Tests\User;
5+
use Webauthn\AuthenticatorSelectionCriteria;
56
use Webauthn\PublicKeyCredentialCreationOptions;
67

78
it('generates registration options with user data', function (): void {
@@ -33,3 +34,27 @@
3334

3435
expect($options->excludeCredentials)->toHaveCount(1);
3536
});
37+
38+
it('allows overriding authenticator selection with a custom action binding', function (): void {
39+
$user = User::create([
40+
'name' => 'John Doe',
41+
'email' => 'john@example.com',
42+
]);
43+
44+
app()->bind(GenerateRegistrationOptions::class, fn () => new class extends GenerateRegistrationOptions
45+
{
46+
public function authenticatorSelection(): AuthenticatorSelectionCriteria
47+
{
48+
return AuthenticatorSelectionCriteria::create(
49+
authenticatorAttachment: AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_PLATFORM,
50+
userVerification: AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED,
51+
residentKey: AuthenticatorSelectionCriteria::RESIDENT_KEY_REQUIREMENT_REQUIRED,
52+
);
53+
}
54+
});
55+
56+
$options = app(GenerateRegistrationOptions::class)($user);
57+
58+
expect($options->authenticatorSelection->authenticatorAttachment)
59+
->toBe(AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_PLATFORM);
60+
});

0 commit comments

Comments
 (0)