@@ -17,18 +17,18 @@ import { PasskeyChallengeManager } from './passkey.challenge.manager';
1717import { AppError } from '@fxa/accounts/errors' ;
1818
1919jest . mock ( './webauthn-adapter' , ( ) => ( {
20- generateRegistrationOptions : jest . fn ( ) ,
21- verifyRegistrationResponse : jest . fn ( ) ,
22- generateAuthenticationOptions : jest . fn ( ) ,
23- verifyAuthenticationResponse : jest . fn ( ) ,
20+ generateWebauthnRegistrationOptions : jest . fn ( ) ,
21+ verifyWebauthnRegistrationResponse : jest . fn ( ) ,
22+ generateWebauthnAuthenticationOptions : jest . fn ( ) ,
23+ verifyWebauthnAuthenticationResponse : jest . fn ( ) ,
2424} ) ) ;
2525
2626import * as webauthnAdapter from './webauthn-adapter' ;
2727
28- const mockGenerateRegistrationOptions =
29- webauthnAdapter . generateRegistrationOptions as jest . Mock ;
30- const mockVerifyRegistrationResponse =
31- webauthnAdapter . verifyRegistrationResponse as jest . Mock ;
28+ const mockGenerateWebauthnRegistrationOptions =
29+ webauthnAdapter . generateWebauthnRegistrationOptions as jest . Mock ;
30+ const mockVerifyWebauthnRegistrationResponse =
31+ webauthnAdapter . verifyWebauthnRegistrationResponse as jest . Mock ;
3232
3333describe ( 'PasskeyService' , ( ) => {
3434 let service : PasskeyService ;
@@ -147,7 +147,9 @@ describe('PasskeyService', () => {
147147 mockChallengeManager . generateRegistrationChallenge . mockResolvedValue (
148148 MOCK_CHALLENGE
149149 ) ;
150- mockGenerateRegistrationOptions . mockResolvedValue ( mockWebAuthnOptions ) ;
150+ mockGenerateWebauthnRegistrationOptions . mockResolvedValue (
151+ mockWebAuthnOptions
152+ ) ;
151153 } ) ;
152154
153155 it ( 'returns PublicKeyCredentialCreationOptionsJSON from the adapter' , async ( ) => {
@@ -177,7 +179,9 @@ describe('PasskeyService', () => {
177179 mockChallengeManager . generateRegistrationChallenge
178180 ) . toHaveBeenCalledWith ( MOCK_UID . toString ( 'hex' ) ) ;
179181
180- expect ( mockGenerateRegistrationOptions ) . toHaveBeenCalledWith (
182+ expect (
183+ webauthnAdapter . generateWebauthnRegistrationOptions
184+ ) . toHaveBeenCalledWith (
181185 mockConfig ,
182186 expect . objectContaining ( {
183187 uid : MOCK_UID ,
@@ -195,10 +199,11 @@ describe('PasskeyService', () => {
195199 credentialId : MOCK_CREDENTIAL_ID ,
196200 publicKey : MOCK_PUBLIC_KEY ,
197201 signCount : 0 ,
198- transports : [ 'internal' ] as any ,
202+ transports : [ 'internal' ] ,
199203 aaguid : MOCK_AAGUID_ZEROS ,
200204 backupEligible : false ,
201205 backupState : false ,
206+ prfEnabled : false ,
202207 } ;
203208
204209 beforeEach ( ( ) => {
@@ -209,7 +214,7 @@ describe('PasskeyService', () => {
209214 createdAt : Date . now ( ) - 1000 ,
210215 expiresAt : Date . now ( ) + 299000 ,
211216 } ) ;
212- mockVerifyRegistrationResponse . mockResolvedValue ( {
217+ mockVerifyWebauthnRegistrationResponse . mockResolvedValue ( {
213218 verified : true ,
214219 data : mockVerifiedData ,
215220 } ) ;
@@ -230,11 +235,13 @@ describe('PasskeyService', () => {
230235 message : 'Passkey challenge not found' ,
231236 code : 404 ,
232237 } ) ;
233- expect ( mockVerifyRegistrationResponse ) . not . toHaveBeenCalled ( ) ;
238+ expect ( mockVerifyWebauthnRegistrationResponse ) . not . toHaveBeenCalled ( ) ;
234239 } ) ;
235240
236241 it ( 'throws passkeyRegistrationFailed AppError when adapter returns verified: false' , async ( ) => {
237- mockVerifyRegistrationResponse . mockResolvedValue ( { verified : false } ) ;
242+ mockVerifyWebauthnRegistrationResponse . mockResolvedValue ( {
243+ verified : false ,
244+ } ) ;
238245 await expect (
239246 service . createPasskeyFromRegistrationResponse (
240247 MOCK_UID ,
@@ -249,7 +256,7 @@ describe('PasskeyService', () => {
249256 } ) ;
250257
251258 it ( 'throws passkeyRegistrationFailed AppError when adapter throws' , async ( ) => {
252- mockVerifyRegistrationResponse . mockRejectedValue (
259+ mockVerifyWebauthnRegistrationResponse . mockRejectedValue (
253260 new Error ( 'Invalid attestation format' )
254261 ) ;
255262 await expect (
@@ -294,14 +301,20 @@ describe('PasskeyService', () => {
294301 lastUsedAt : null ,
295302 backupEligible : 0 ,
296303 backupState : 0 ,
304+ prfEnabled : 0 ,
297305 } )
298306 ) ;
299307 } ) ;
300308
301- it ( 'sets backupEligible=1 and backupState =1 when flags are true' , async ( ) => {
302- mockVerifyRegistrationResponse . mockResolvedValue ( {
309+ it ( 'sets backupEligible=1, backupState=1 and prfEnabled =1 when flags are true' , async ( ) => {
310+ mockVerifyWebauthnRegistrationResponse . mockResolvedValue ( {
303311 verified : true ,
304- data : { ...mockVerifiedData , backupEligible : true , backupState : true } ,
312+ data : {
313+ ...mockVerifiedData ,
314+ backupEligible : true ,
315+ backupState : true ,
316+ prfEnabled : true ,
317+ } ,
305318 } ) ;
306319 await service . createPasskeyFromRegistrationResponse (
307320 MOCK_UID ,
@@ -310,7 +323,11 @@ describe('PasskeyService', () => {
310323 ) ;
311324
312325 expect ( mockManager . registerPasskey ) . toHaveBeenCalledWith (
313- expect . objectContaining ( { backupEligible : 1 , backupState : 1 } )
326+ expect . objectContaining ( {
327+ backupEligible : 1 ,
328+ backupState : 1 ,
329+ prfEnabled : 1 ,
330+ } )
314331 ) ;
315332 } ) ;
316333
@@ -386,7 +403,7 @@ describe('PasskeyService', () => {
386403 transports : string [ ] ,
387404 aaguid : Buffer = MOCK_AAGUID_ZEROS
388405 ) : Promise < string > {
389- mockVerifyRegistrationResponse . mockResolvedValue ( {
406+ mockVerifyWebauthnRegistrationResponse . mockResolvedValue ( {
390407 verified : true ,
391408 data : { ...mockVerifiedData , transports, aaguid } ,
392409 } ) ;
@@ -489,7 +506,7 @@ describe('PasskeyService', () => {
489506 MOCK_CHALLENGE
490507 ) ;
491508 (
492- webauthnAdapter . generateAuthenticationOptions as jest . Mock
509+ webauthnAdapter . generateWebauthnAuthenticationOptions as jest . Mock
493510 ) . mockResolvedValue ( mockOptions ) ;
494511 } ) ;
495512
@@ -508,7 +525,7 @@ describe('PasskeyService', () => {
508525 it ( 'calls generateAuthenticationOptions with empty allowCredentials when no uid' , async ( ) => {
509526 await service . generateAuthenticationChallenge ( ) ;
510527 expect (
511- webauthnAdapter . generateAuthenticationOptions
528+ webauthnAdapter . generateWebauthnAuthenticationOptions
512529 ) . toHaveBeenCalledWith ( mockConfig , {
513530 challenge : MOCK_CHALLENGE ,
514531 allowCredentials : [ ] ,
@@ -527,7 +544,7 @@ describe('PasskeyService', () => {
527544
528545 expect ( mockManager . listPasskeysForUser ) . toHaveBeenCalledWith ( MOCK_UID ) ;
529546 expect (
530- webauthnAdapter . generateAuthenticationOptions
547+ webauthnAdapter . generateWebauthnAuthenticationOptions
531548 ) . toHaveBeenCalledWith ( mockConfig , {
532549 challenge : MOCK_CHALLENGE ,
533550 allowCredentials : [ MOCK_CREDENTIAL_ID ] ,
@@ -540,23 +557,23 @@ describe('PasskeyService', () => {
540557 await service . generateAuthenticationChallenge ( MOCK_UID ) ;
541558
542559 expect (
543- webauthnAdapter . generateAuthenticationOptions
560+ webauthnAdapter . generateWebauthnAuthenticationOptions
544561 ) . toHaveBeenCalledWith ( mockConfig , {
545562 challenge : MOCK_CHALLENGE ,
546563 allowCredentials : [ ] ,
547564 } ) ;
548565 } ) ;
549566 } ) ;
550567
551- describe ( 'verifyAuthenticationResponse ' , ( ) => {
568+ describe ( 'verifyWebauthnAuthenticationResponse ' , ( ) => {
552569 beforeEach ( ( ) => {
553570 mockManager . findPasskeyByCredentialId . mockResolvedValue ( mockPasskey ) ;
554571 mockChallengeManager . consumeAuthenticationChallenge . mockResolvedValue (
555572 mockStoredChallenge
556573 ) ;
557574 mockManager . updatePasskeyAfterAuth . mockResolvedValue ( true ) ;
558575 (
559- webauthnAdapter . verifyAuthenticationResponse as jest . Mock
576+ webauthnAdapter . verifyWebauthnAuthenticationResponse as jest . Mock
560577 ) . mockResolvedValue ( {
561578 verified : true ,
562579 data : { newSignCount : 6 , backupState : false } ,
@@ -585,18 +602,17 @@ describe('PasskeyService', () => {
585602 ) . toHaveBeenCalledWith ( MOCK_CHALLENGE ) ;
586603 } ) ;
587604
588- it ( 'calls verifyAuthenticationResponse adapter with correct passkey data' , async ( ) => {
605+ it ( 'calls verifyWebauthnAuthenticationResponse adapter with correct passkey data' , async ( ) => {
589606 await service . verifyAuthenticationResponse ( mockResponse , MOCK_CHALLENGE ) ;
590- expect ( webauthnAdapter . verifyAuthenticationResponse ) . toHaveBeenCalledWith (
591- mockConfig ,
592- {
593- response : mockResponse ,
594- challenge : MOCK_CHALLENGE ,
595- credentialId : mockPasskey . credentialId ,
596- publicKey : mockPasskey . publicKey ,
597- signCount : mockPasskey . signCount ,
598- }
599- ) ;
607+ expect (
608+ webauthnAdapter . verifyWebauthnAuthenticationResponse
609+ ) . toHaveBeenCalledWith ( mockConfig , {
610+ response : mockResponse ,
611+ challenge : MOCK_CHALLENGE ,
612+ credentialId : mockPasskey . credentialId ,
613+ publicKey : mockPasskey . publicKey ,
614+ signCount : mockPasskey . signCount ,
615+ } ) ;
600616 } ) ;
601617
602618 it ( 'updates passkey with new signCount and backupState after verification' , async ( ) => {
@@ -653,7 +669,7 @@ describe('PasskeyService', () => {
653669
654670 it ( 'throws a passkeyAuthenticationFailed AppError when the assertion is not verified' , async ( ) => {
655671 (
656- webauthnAdapter . verifyAuthenticationResponse as jest . Mock
672+ webauthnAdapter . verifyWebauthnAuthenticationResponse as jest . Mock
657673 ) . mockResolvedValue ( { verified : false } ) ;
658674
659675 await expect (
@@ -663,7 +679,7 @@ describe('PasskeyService', () => {
663679
664680 it ( 'throws a passkeyAuthenticationFailed AppError when the adapter throws' , async ( ) => {
665681 (
666- webauthnAdapter . verifyAuthenticationResponse as jest . Mock
682+ webauthnAdapter . verifyWebauthnAuthenticationResponse as jest . Mock
667683 ) . mockRejectedValue ( new Error ( 'crypto error' ) ) ;
668684
669685 await expect (
@@ -690,7 +706,7 @@ describe('PasskeyService', () => {
690706
691707 it ( 'logs a signCount rollback warning when simplewebauthn throws a counter error' , async ( ) => {
692708 (
693- webauthnAdapter . verifyAuthenticationResponse as jest . Mock
709+ webauthnAdapter . verifyWebauthnAuthenticationResponse as jest . Mock
694710 ) . mockRejectedValue (
695711 // Exact message thrown by @simplewebauthn /server
696712 new Error ( 'Response counter value 2 was lower than expected 5' )
@@ -715,7 +731,7 @@ describe('PasskeyService', () => {
715731
716732 it ( 'does not log a rollback warning for non-counter adapter errors' , async ( ) => {
717733 (
718- webauthnAdapter . verifyAuthenticationResponse as jest . Mock
734+ webauthnAdapter . verifyWebauthnAuthenticationResponse as jest . Mock
719735 ) . mockRejectedValue ( new Error ( 'Invalid signature' ) ) ;
720736
721737 await expect (
0 commit comments