feat: implement passkey support with Supabase auth
Add WebAuthn utility functions and passkey manager component; update login and dashboard pages Co-authored-by: ASOwnerYT <[email protected]>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
'use client'
|
||||
|
||||
import { createClient } from '@/lib/supabase/client'
|
||||
|
||||
export async function registerPasskey(userId: string, displayName: string) {
|
||||
const supabase = createClient()
|
||||
|
||||
if (!window.PublicKeyCredential) {
|
||||
throw new Error('Passkeys are not supported in your browser')
|
||||
}
|
||||
|
||||
try {
|
||||
// Get registration options from Supabase
|
||||
const { data, error } = await supabase.auth.signInWithEnrollFactors({
|
||||
factorType: 'totp',
|
||||
})
|
||||
|
||||
if (error) throw error
|
||||
|
||||
// For now, we'll use a simplified approach with browser's WebAuthn API
|
||||
// Create a passkey credential
|
||||
const credential = await navigator.credentials.create({
|
||||
publicKey: {
|
||||
challenge: new Uint8Array(32),
|
||||
rp: {
|
||||
name: 'Cloudrite',
|
||||
id: window.location.hostname,
|
||||
},
|
||||
user: {
|
||||
id: new TextEncoder().encode(userId),
|
||||
name: userId,
|
||||
displayName: displayName,
|
||||
},
|
||||
pubKeyCredParams: [{ type: 'public-key', alg: -7 }],
|
||||
timeout: 60000,
|
||||
attestation: 'direct',
|
||||
},
|
||||
}) as PublicKeyCredential | null
|
||||
|
||||
if (!credential) {
|
||||
throw new Error('Failed to create passkey')
|
||||
}
|
||||
|
||||
return credential
|
||||
} catch (error) {
|
||||
console.error('[v0] Passkey registration failed:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export async function authenticateWithPasskey() {
|
||||
if (!window.PublicKeyCredential) {
|
||||
throw new Error('Passkeys are not supported in your browser')
|
||||
}
|
||||
|
||||
try {
|
||||
const assertion = await navigator.credentials.get({
|
||||
publicKey: {
|
||||
challenge: new Uint8Array(32),
|
||||
timeout: 60000,
|
||||
userVerification: 'preferred',
|
||||
},
|
||||
}) as PublicKeyCredential | null
|
||||
|
||||
if (!assertion) {
|
||||
throw new Error('Passkey authentication cancelled or failed')
|
||||
}
|
||||
|
||||
return assertion
|
||||
} catch (error) {
|
||||
console.error('[v0] Passkey authentication failed:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export function isPasskeySupported(): boolean {
|
||||
return !!(
|
||||
window.PublicKeyCredential &&
|
||||
navigator.credentials &&
|
||||
navigator.credentials.create &&
|
||||
navigator.credentials.get
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user