Media Browser

options.allowCredentials = options.allowCredentials.map(cred => ({ ...cred, id: base64ToArrayBuffer(cred.id) })); } // Get credential const credential = await navigator.credentials.get({ publicKey: options }); // Send to server const finishResponse = await fetch('/api/passkey-auth-finish.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: credential.id, rawId: arrayBufferToBase64(credential.rawId), response: { clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON), authenticatorData: arrayBufferToBase64(credential.response.authenticatorData), signature: arrayBufferToBase64(credential.response.signature), userHandle: credential.response.userHandle ? arrayBufferToBase64(credential.response.userHandle) : null }, type: credential.type }) }); const result = await finishResponse.json(); if (result.success) { window.location.href = result.redirect; } else { throw new Error(result.error || 'Authentication failed'); } } catch (error) { console.error('Passkey authentication error:', error); showError('Passkey authentication failed: ' + error.message); } } function showError(message) { const errorDiv = document.getElementById('error-message'); errorDiv.textContent = message; errorDiv.style.display = 'block'; } // Helper functions function base64ToArrayBuffer(base64) { const binaryString = atob(base64.replace(/-/g, '+').replace(/_/g, '/')); const bytes = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes.buffer; } function arrayBufferToBase64(buffer) { const bytes = new Uint8Array(buffer); let binary = ''; for (let i = 0; i < bytes.byteLength; i++) { binary += String.fromCharCode(bytes[i]); } return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); }