@@ -23,13 +23,13 @@ describe('WebAuthn Serialization/Deserialization', () => {
2323
2424 describe ( 'deserializeCredentialCreationOptions' , ( ) => {
2525 const validServerOptions = {
26- challenge : 'dGVzdC1jaGFsbGVuZ2U ' , // "test-challenge" in base64url
26+ challenge : 'SGVsbG8gV2ViQXV0aG4h ' ,
2727 rp : {
2828 name : 'Test RP' ,
2929 id : 'example.com' ,
3030 } ,
3131 user : {
32- id : 'dXNlci1pZA ' , // "user-id" in base64url
32+ id : 'dXNlci0xMjM0NTY ' ,
33333434 displayName : 'Test User' ,
3535 } ,
@@ -41,37 +41,40 @@ describe('WebAuthn Serialization/Deserialization', () => {
4141 attestation : 'direct' as const ,
4242 excludeCredentials : [
4343 {
44- id : 'Y3JlZC1pZA ' , // "cred-id" in base64url
44+ id : 'Y3JlZGVudGlhbC1hYmMteHl6 ' ,
4545 type : 'public-key' as const ,
4646 transports : [ 'usb' , 'nfc' ] as AuthenticatorTransportFuture [ ] ,
4747 } ,
4848 ] ,
4949 }
5050
5151 it ( 'should convert base64url strings to ArrayBuffers using polyfill' , ( ) => {
52- // Force polyfill path by removing PublicKeyCredential
52+
5353 delete ( global as any ) . PublicKeyCredential
5454
5555 const result = deserializeCredentialCreationOptions ( validServerOptions )
5656
57- // Verify challenge was converted to ArrayBuffer
57+
5858 expect ( result . challenge ) . toBeInstanceOf ( ArrayBuffer )
5959 const challengeBytes = new Uint8Array ( result . challenge )
60+
6061 expect ( challengeBytes ) . toEqual (
61- new Uint8Array ( [ 116 , 101 , 115 , 116 , 45 , 99 , 104 , 97 , 108 , 108 , 101 , 110 , 103 , 101 ] )
62+ new Uint8Array ( [ 72 , 101 , 108 , 108 , 111 , 32 , 87 , 101 , 98 , 65 , 117 , 116 , 104 , 110 , 33 ] )
6263 )
6364
64- // Verify user.id was converted to ArrayBuffer
65+
6566 expect ( result . user . id ) . toBeInstanceOf ( ArrayBuffer )
6667 const userIdBytes = new Uint8Array ( result . user . id )
67- expect ( userIdBytes ) . toEqual ( new Uint8Array ( [ 117 , 115 , 101 , 114 , 45 , 105 , 100 ] ) )
68+
69+ expect ( userIdBytes ) . toEqual ( new Uint8Array ( [ 117 , 115 , 101 , 114 , 45 , 49 , 50 , 51 , 52 , 53 , 54 ] ) )
6870
69- // Verify excludeCredentials[0].id was converted to ArrayBuffer
71+
7072 expect ( result . excludeCredentials ! [ 0 ] . id ) . toBeInstanceOf ( ArrayBuffer )
7173 const credIdBytes = new Uint8Array ( result . excludeCredentials ! [ 0 ] . id as ArrayBuffer )
72- expect ( credIdBytes ) . toEqual ( new Uint8Array ( [ 99 , 114 , 101 , 100 , 45 , 105 , 100 ] ) )
74+
75+ expect ( credIdBytes ) . toEqual ( new Uint8Array ( [ 99 , 114 , 101 , 100 , 101 , 110 , 116 , 105 , 97 , 108 , 45 , 97 , 98 , 99 , 45 , 120 , 121 , 122 ] ) )
7376
74- // Verify other fields are preserved
77+
7578 expect ( result . rp ) . toEqual ( validServerOptions . rp )
7679 expect ( result . pubKeyCredParams ) . toEqual ( validServerOptions . pubKeyCredParams )
7780 expect ( result . timeout ) . toBe ( 60000 )
@@ -99,10 +102,10 @@ describe('WebAuthn Serialization/Deserialization', () => {
99102
100103 it ( 'should handle missing optional fields correctly' , ( ) => {
101104 const minimalOptions = {
102- challenge : 'dGVzdC1jaGFsbGVuZ2U' ,
105+ challenge : 'SGVsbG8gV2ViQXV0aG4h' ,
103106 rp : { name : 'Test RP' } ,
104107 user : {
105- id : 'dXNlci1pZA' ,
108+ id : 'dXNlci0xMjM0NTY' ,
106109107110 displayName : 'Test User' ,
108111 } ,
@@ -130,13 +133,13 @@ describe('WebAuthn Serialization/Deserialization', () => {
130133
131134 describe ( 'deserializeCredentialRequestOptions' , ( ) => {
132135 const validServerOptions = {
133- challenge : 'dGVzdC1jaGFsbGVuZ2U' ,
136+ challenge : 'QXV0aGVudGljYXRlTWU' ,
134137 timeout : 60000 ,
135138 rpId : 'example.com' ,
136139 userVerification : 'preferred' as const ,
137140 allowCredentials : [
138141 {
139- id : 'Y3JlZC1pZA' ,
142+ id : 'YWxsb3dlZC1jcmVkLTEyMw' ,
140143 type : 'public-key' as const ,
141144 transports : [ 'usb' , 'nfc' ] as AuthenticatorTransportFuture [ ] ,
142145 } ,
@@ -148,19 +151,21 @@ describe('WebAuthn Serialization/Deserialization', () => {
148151
149152 const result = deserializeCredentialRequestOptions ( validServerOptions )
150153
151- // Verify challenge was converted
154+
152155 expect ( result . challenge ) . toBeInstanceOf ( ArrayBuffer )
153156 const challengeBytes = new Uint8Array ( result . challenge )
157+
154158 expect ( challengeBytes ) . toEqual (
155- new Uint8Array ( [ 116 , 101 , 115 , 116 , 45 , 99 , 104 , 97 , 108 , 108 , 101 , 110 , 103 , 101 ] )
159+ new Uint8Array ( [ 65 , 117 , 116 , 104 , 101 , 110 , 116 , 105 , 99 , 97 , 116 , 101 , 77 , 101 ] )
156160 )
157161
158- // Verify allowCredentials[0].id was converted
162+
159163 expect ( result . allowCredentials ! [ 0 ] . id ) . toBeInstanceOf ( ArrayBuffer )
160164 const credIdBytes = new Uint8Array ( result . allowCredentials ! [ 0 ] . id as ArrayBuffer )
161- expect ( credIdBytes ) . toEqual ( new Uint8Array ( [ 99 , 114 , 101 , 100 , 45 , 105 , 100 ] ) )
165+
166+ expect ( credIdBytes ) . toEqual ( new Uint8Array ( [ 97 , 108 , 108 , 111 , 119 , 101 , 100 , 45 , 99 , 114 , 101 , 100 , 45 , 49 , 50 , 51 ] ) )
162167
163- // Verify other fields preserved
168+
164169 expect ( result . rpId ) . toBe ( 'example.com' )
165170 expect ( result . userVerification ) . toBe ( 'preferred' )
166171 expect ( result . timeout ) . toBe ( 60000 )
@@ -192,15 +197,15 @@ describe('WebAuthn Serialization/Deserialization', () => {
192197 }
193198
194199 const result = deserializeCredentialRequestOptions ( optionsWithEmptyArray )
195- // Empty array is not added to result per implementation
200+
196201 expect ( result . allowCredentials ) . toBeUndefined ( )
197202 } )
198203
199204 it ( 'should handle missing allowCredentials' , ( ) => {
200205 delete ( global as any ) . PublicKeyCredential
201206
202207 const optionsWithoutAllow = {
203- challenge : 'dGVzdC1jaGFsbGVuZ2U' ,
208+ challenge : 'QXV0aGVudGljYXRlTWU' ,
204209 rpId : 'example.com' ,
205210 }
206211
@@ -233,10 +238,10 @@ describe('WebAuthn Serialization/Deserialization', () => {
233238
234239 const result = serializeCredentialCreationResponse ( mockCredential )
235240
236- // Verify ArrayBuffers were converted to base64url
237- expect ( result . rawId ) . toBe ( mockCredential . id ) // Now correctly converts rawId ArrayBuffer to base64url
238- expect ( result . response . attestationObject ) . toBe ( 'AQIDBAU' )
239- expect ( result . response . clientDataJSON ) . toBe ( 'BgcICQo' )
241+
242+ expect ( result . rawId ) . toBe ( mockCredential . id )
243+ expect ( result . response . attestationObject ) . toBe ( 'AQIDBAU' )
244+ expect ( result . response . clientDataJSON ) . toBe ( 'BgcICQo' )
240245 expect ( result . authenticatorAttachment ) . toBe ( 'platform' )
241246 expect ( result . clientExtensionResults ) . toEqual ( { credProps : { rk : true } } )
242247 } )
@@ -320,12 +325,12 @@ describe('WebAuthn Serialization/Deserialization', () => {
320325
321326 const result = serializeCredentialRequestResponse ( mockCredential )
322327
323- // Verify conversions
324- expect ( result . rawId ) . toBe ( mockCredential . id ) // Now correctly converts rawId ArrayBuffer to base64url
325- expect ( result . response . authenticatorData ) . toBe ( 'AQIDBAU' )
326- expect ( result . response . clientDataJSON ) . toBe ( 'BgcICQo' )
327- expect ( result . response . signature ) . toBe ( 'CwwNDg8' )
328- expect ( result . response . userHandle ) . toBe ( 'EBESExQ' )
328+
329+ expect ( result . rawId ) . toBe ( mockCredential . id )
330+ expect ( result . response . authenticatorData ) . toBe ( 'AQIDBAU' )
331+ expect ( result . response . clientDataJSON ) . toBe ( 'BgcICQo' )
332+ expect ( result . response . signature ) . toBe ( 'CwwNDg8' )
333+ expect ( result . response . userHandle ) . toBe ( 'EBESExQ' )
329334 } )
330335
331336 it ( 'should handle null userHandle correctly' , ( ) => {
@@ -386,10 +391,10 @@ describe('WebAuthn Serialization/Deserialization', () => {
386391
387392 describe ( 'mergeCredentialCreationOptions' , ( ) => {
388393 const baseOptions : PublicKeyCredentialCreationOptionsFuture = {
389- challenge : new Uint8Array ( [ 1 , 2 , 3 , 4 ] ) . buffer ,
394+ challenge : new Uint8Array ( [ 67 , 104 , 97 , 108 , 108 , 101 , 110 , 103 , 101 , 49 , 50 , 51 ] ) . buffer ,
390395 rp : { name : 'Test RP' , id : 'example.com' } ,
391396 user : {
392- id : new Uint8Array ( [ 5 , 6 , 7 , 8 ] ) . buffer ,
397+ id : new Uint8Array ( [ 85 , 115 , 101 , 114 , 49 , 50 , 51 ] ) . buffer ,
393398394399 displayName : 'Test User' ,
395400 } ,
@@ -399,7 +404,7 @@ describe('WebAuthn Serialization/Deserialization', () => {
399404 it ( 'should apply DEFAULT_CREATION_OPTIONS correctly' , ( ) => {
400405 const result = mergeCredentialCreationOptions ( baseOptions )
401406
402- // Verify defaults are applied
407+
403408 expect ( result . authenticatorSelection ) . toEqual ( {
404409 authenticatorAttachment : 'cross-platform' ,
405410 requireResidentKey : false ,
@@ -409,7 +414,7 @@ describe('WebAuthn Serialization/Deserialization', () => {
409414 expect ( result . hints ) . toEqual ( [ 'security-key' ] )
410415 expect ( result . attestation ) . toBe ( 'direct' )
411416
412- // Verify base options are preserved
417+
413418 expect ( result . challenge ) . toBe ( baseOptions . challenge )
414419 expect ( result . rp ) . toEqual ( baseOptions . rp )
415420 expect ( result . user ) . toEqual ( baseOptions . user )
@@ -422,12 +427,12 @@ describe('WebAuthn Serialization/Deserialization', () => {
422427 } ,
423428 } )
424429
425- // Should merge, not replace
430+
426431 expect ( result . authenticatorSelection ) . toEqual ( {
427432 authenticatorAttachment : 'cross-platform' ,
428433 requireResidentKey : false ,
429434 residentKey : 'discouraged' ,
430- userVerification : 'required' , // Override applied
435+ userVerification : 'required' ,
431436 } )
432437 } )
433438
@@ -454,7 +459,7 @@ describe('WebAuthn Serialization/Deserialization', () => {
454459 } )
455460
456461 it ( 'should not modify ArrayBuffer fields during merge' , ( ) => {
457- const customChallenge = new Uint8Array ( [ 9 , 10 , 11 , 12 ] ) . buffer
462+ const customChallenge = new Uint8Array ( [ 78 , 101 , 119 , 67 , 104 , 97 , 108 , 108 ] ) . buffer
458463 const result = mergeCredentialCreationOptions ( baseOptions , {
459464 challenge : customChallenge ,
460465 } )
@@ -466,11 +471,11 @@ describe('WebAuthn Serialization/Deserialization', () => {
466471
467472 describe ( 'mergeCredentialRequestOptions' , ( ) => {
468473 const baseOptions : PublicKeyCredentialRequestOptionsFuture = {
469- challenge : new Uint8Array ( [ 1 , 2 , 3 , 4 ] ) . buffer ,
474+ challenge : new Uint8Array ( [ 82 , 101 , 113 , 117 , 101 , 115 , 116 ] ) . buffer ,
470475 rpId : 'example.com' ,
471476 allowCredentials : [
472477 {
473- id : new Uint8Array ( [ 5 , 6 , 7 , 8 ] ) . buffer ,
478+ id : new Uint8Array ( [ 67 , 114 , 101 , 100 , 49 , 50 , 51 ] ) . buffer ,
474479 type : 'public-key' ,
475480 transports : [ 'usb' ] ,
476481 } ,
@@ -483,7 +488,7 @@ describe('WebAuthn Serialization/Deserialization', () => {
483488 expect ( result . userVerification ) . toBe ( 'preferred' )
484489 expect ( result . hints ) . toEqual ( [ 'security-key' ] )
485490
486- // Base options preserved
491+
487492 expect ( result . challenge ) . toBe ( baseOptions . challenge )
488493 expect ( result . allowCredentials ) . toBe ( baseOptions . allowCredentials )
489494 } )
@@ -503,7 +508,7 @@ describe('WebAuthn Serialization/Deserialization', () => {
503508 it ( 'should preserve allowCredentials ArrayBuffers' , ( ) => {
504509 const newCreds = [
505510 {
506- id : new Uint8Array ( [ 9 , 10 , 11 , 12 ] ) . buffer ,
511+ id : new Uint8Array ( [ 78 , 101 , 119 , 67 , 114 , 101 , 100 ] ) . buffer ,
507512 type : 'public-key' as const ,
508513 transports : [ 'nfc' ] as AuthenticatorTransportFuture [ ] ,
509514 } ,
0 commit comments