@@ -84,19 +84,6 @@ const PasskeyRegistrationModal = ({isOpen, onClose}) => {
8484 }
8585 }
8686
87- /**
88- * Convert base64url string to ArrayBuffer
89- */
90- const base64UrlToArrayBuffer = ( base64Url ) => {
91- const base64 = base64Url . replace ( / - / g, '+' ) . replace ( / _ / g, '/' )
92- const binaryString = atob ( base64 )
93- const bytes = new Uint8Array ( binaryString . length )
94- for ( let i = 0 ; i < binaryString . length ; i ++ ) {
95- bytes [ i ] = binaryString . charCodeAt ( i )
96- }
97- return bytes . buffer
98- }
99-
10087 /**
10188 * Convert ArrayBuffer to base64url string
10289 */
@@ -123,21 +110,7 @@ const PasskeyRegistrationModal = ({isOpen, onClose}) => {
123110 } )
124111
125112 // Step 2: Convert response to WebAuthn PublicKeyCredentialCreationOptions format
126- const publicKey = {
127- challenge : base64UrlToArrayBuffer ( response . challenge ) ,
128- rp : {
129- name : response . rp . name ,
130- id : response . rp . id
131- } ,
132- user : {
133- ...response . user ,
134- id : base64UrlToArrayBuffer ( response . user . id )
135- } ,
136- pubKeyCredParams : response . pubKeyCredParams || [ ] ,
137- authenticatorSelection : response . authenticatorSelection ,
138- timeout : response . timeout ,
139- attestation : response . attestation || 'none'
140- }
113+ const publicKey = window . PublicKeyCredential . parseCreationOptionsFromJSON ( response )
141114
142115 // Step 3: Call navigator.credentials.create()
143116 if ( ! navigator . credentials || ! navigator . credentials . create ) {
@@ -163,19 +136,27 @@ const PasskeyRegistrationModal = ({isOpen, onClose}) => {
163136 throw new Error ( 'Failed to create credential: user cancelled or operation failed' )
164137 }
165138
166- // Step 4: Convert credential to JSON format
167- const clientExtensionResults = credential . getClientExtensionResults ?. ( ) || { }
168- const credentialJson = {
169- type : credential . type ,
170- id : credential . id ,
171- rawId : arrayBufferToBase64Url ( credential . rawId ) ,
172- response : {
173- attestationObject : arrayBufferToBase64Url (
174- credential . response . attestationObject
175- ) ,
176- clientDataJSON : arrayBufferToBase64Url ( credential . response . clientDataJSON )
177- } ,
178- ...( Object . keys ( clientExtensionResults ) . length > 0 && { clientExtensionResults} )
139+ // Step 4: Convert credential to JSON format before sending to SLAS
140+ // https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/toJSON
141+ let credentialJson
142+ try {
143+ credentialJson = credential . toJSON ( )
144+ } catch ( error ) {
145+ // Fallback to manual encoding if toJSON() fails
146+ // Some passkey providers (e.g., 1Password) may not support the toJSON() method and return an error
147+ const clientExtensionResults = credential . getClientExtensionResults ?. ( ) || { }
148+ credentialJson = {
149+ type : credential . type ,
150+ id : credential . id ,
151+ rawId : arrayBufferToBase64Url ( credential . rawId ) ,
152+ response : {
153+ attestationObject : arrayBufferToBase64Url (
154+ credential . response . attestationObject
155+ ) ,
156+ clientDataJSON : arrayBufferToBase64Url ( credential . response . clientDataJSON )
157+ } ,
158+ ...( Object . keys ( clientExtensionResults ) . length > 0 && { clientExtensionResults} )
159+ }
179160 }
180161
181162 // Step 5: Finish WebAuthn registration
0 commit comments