forked from kindfi-org/kindfi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient-example.js
More file actions
174 lines (155 loc) · 4.95 KB
/
Copy pathclient-example.js
File metadata and controls
174 lines (155 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/**
* Example client-side code for interacting with the Passkey Authentication API
*
* This example demonstrates how to:
* 1. Register a new passkey
* 2. Authenticate with a passkey
* 3. Properly include the origin parameter in all requests
*/
// API base URL - replace with your actual API URL
const API_BASE_URL = 'https://api.example.com'
/**
* Register a new passkey for a user
* @param {string} identifier - User identifier (e.g., email)
* @returns {Promise<boolean>} - Whether registration was successful
*/
async function registerPasskey(identifier) {
try {
// Step 1: Get registration options
const optionsResponse = await fetch(
`${API_BASE_URL}/api/passkey/generate-registration-options`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
identifier,
origin: window.location.origin, // Always include the current origin
}),
},
)
if (!optionsResponse.ok) {
const error = await optionsResponse.json()
throw new Error(error.error || 'Failed to get registration options')
}
const options = await optionsResponse.json()
// Step 2: Create credentials using the browser's WebAuthn API
// The options returned by the server need to be properly formatted for navigator.credentials.create()
const credential = await navigator.credentials.create({
publicKey: options,
})
// Step 3: Verify the registration with the server
const verificationResponse = await fetch(
`${API_BASE_URL}/api/passkey/verify-registration`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
identifier,
origin: window.location.origin, // Always include the current origin
registrationResponse: credential, // This needs to be properly formatted for the server
}),
},
)
if (!verificationResponse.ok) {
const error = await verificationResponse.json()
throw new Error(error.error || 'Failed to verify registration')
}
const result = await verificationResponse.json()
return result.verified === true
} catch (error) {
console.error('Passkey registration error:', error)
return false
}
}
/**
* Authenticate a user with a passkey
* @param {string} identifier - User identifier (e.g., email)
* @returns {Promise<boolean>} - Whether authentication was successful
*/
async function authenticateWithPasskey(identifier) {
try {
// Step 1: Get authentication options
const optionsResponse = await fetch(
`${API_BASE_URL}/api/passkey/generate-authentication-options`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
identifier,
origin: window.location.origin, // Always include the current origin
}),
},
)
if (!optionsResponse.ok) {
const error = await optionsResponse.json()
throw new Error(error.error || 'Failed to get authentication options')
}
const options = await optionsResponse.json()
// Step 2: Get credentials using the browser's WebAuthn API
// The options returned by the server need to be properly formatted for navigator.credentials.get()
const credential = await navigator.credentials.get({
publicKey: options,
})
// Step 3: Verify the authentication with the server
const verificationResponse = await fetch(
`${API_BASE_URL}/api/passkey/verify-authentication`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
identifier,
origin: window.location.origin, // Always include the current origin
authenticationResponse: credential, // This needs to be properly formatted for the server
}),
},
)
if (!verificationResponse.ok) {
const error = await verificationResponse.json()
throw new Error(error.error || 'Failed to verify authentication')
}
const result = await verificationResponse.json()
return result.verified === true
} catch (error) {
console.error('Passkey authentication error:', error)
return false
}
}
// Example usage in a web application
document.addEventListener('DOMContentLoaded', () => {
// Registration form
const registrationForm = document.getElementById('registration-form')
if (registrationForm) {
registrationForm.addEventListener('submit', async (event) => {
event.preventDefault()
const email = document.getElementById('email').value
const success = await registerPasskey(email)
if (success) {
alert('Passkey registered successfully!')
} else {
alert('Failed to register passkey. Please try again.')
}
})
}
// Authentication form
const authForm = document.getElementById('auth-form')
if (authForm) {
authForm.addEventListener('submit', async (event) => {
event.preventDefault()
const email = document.getElementById('auth-email').value
const success = await authenticateWithPasskey(email)
if (success) {
alert('Authentication successful!')
} else {
alert('Authentication failed. Please try again.')
}
})
}
})