-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy path+server.ts
51 lines (43 loc) · 1.69 KB
/
+server.ts
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
import { getAuthSessionIdFromCookie, resolveUserId } from '$lib/server/auth/utilities';
import { generateAuthenticationOptions, type GenerateAuthenticationOptionsOpts } from '@simplewebauthn/server';
import { error, json, type RequestHandler } from '@sveltejs/kit';
import { Buffer } from 'node:buffer';
import { createChallenge } from '$lib/server/data/authentication/challenge';
import { listAuthenticatorsForUser } from '$lib/server/data/authentication/authenticator';
import { findUserByIdentifier } from '$lib/server/data/authentication/user';
export const GET: RequestHandler = async function handler({
url,
cookies,
locals: { database }
}) {
const userId = resolveUserId(cookies);
const sessionId = getAuthSessionIdFromCookie(cookies);
if (!sessionId) {
throw error(403, {
title: 'Not authorized',
message: 'Session ID cookie is missing or invalid'
});
}
const options: GenerateAuthenticationOptionsOpts = {
userVerification: 'required',
rpID: url.hostname,
timeout: 60_000
};
if (userId) {
const user = await findUserByIdentifier(database, userId);
const authenticators = await listAuthenticatorsForUser(database, user);
options.allowCredentials = authenticators.map(({ identifier, transports }) => ({
type: 'public-key',
id: Buffer.from(identifier, 'base64url'),
transports
}));
}
const responseData = await generateAuthenticationOptions(options);
const timeout = responseData.timeout || options.timeout || 60_000;
await createChallenge(database, {
challenge: responseData.challenge,
expires_at: new Date(+new Date() + timeout).toISOString(),
session_identifier: sessionId
});
return json(responseData);
};