aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/login/callback
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes/login/callback')
-rw-r--r--src/routes/login/callback/+server.ts80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/routes/login/callback/+server.ts b/src/routes/login/callback/+server.ts
new file mode 100644
index 0000000..32b1647
--- /dev/null
+++ b/src/routes/login/callback/+server.ts
@@ -0,0 +1,80 @@
+import * as auth from '$lib/auth.server.js';
+import { error, json, redirect } from '@sveltejs/kit';
+import * as client from 'openid-client';
+
+// Pre-checker for nonce, not the primary implementation
+const handleNonce = (nonce: string | null, nonceCookie: string | undefined) => {
+ if (nonce) {
+ try {
+ const n = JSON.parse(nonceCookie ?? '[]');
+ if (Array.isArray(n) && n.length && typeof n[0] === 'string') {
+ if (!n.includes(nonce)) throw error(400, 'Nonce not in array');
+ else return n.filter((v) => v !== nonce);
+ } else throw error(400, 'Nonce provided, but nonce cookie not found');
+ } catch (e) {
+ throw error(400, `Failed parsing nonce: ${e}`);
+ }
+ } else if (nonceCookie) throw error(400, 'Missing Nonce');
+};
+export const GET = async (event) => {
+ const sp = event.url.searchParams;
+ const params = {
+ sessionState: sp.get('session_state'),
+ iss: sp.get('iss'),
+ code: sp.get('code'),
+ nonce: sp.get('nonce'),
+ };
+ if (!params.sessionState || !params.iss || !params.code)
+ throw error(400, 'Missing one of session_state, iss, code');
+
+ const remainingNonces = handleNonce(
+ params.nonce,
+ event.cookies.get('pending-auth-nonces')
+ );
+
+ try {
+ const tk = await auth.authorizeNewSession(
+ new URL(event.url.href),
+ params.nonce ?? undefined
+ );
+
+ for (const [k, v] of Object.entries({
+ oid__access_token: tk.access_token,
+ oid__token_type: tk.token_type,
+ oid__expires_at: '' + (Date.now() + (tk.expiresIn() ?? 0) * 1000),
+ oid__refresh_token: tk.refresh_token,
+ oid__sub: tk.claims()!.sub,
+ 'pending-auth-nonces': JSON.stringify(remainingNonces),
+ }))
+ if (v)
+ event.cookies.set(k, v, {
+ path: '/',
+ secure: true,
+ httpOnly: true,
+ sameSite: true,
+ });
+ if (tk.scope)
+ event.cookies.set('oid__scopes', tk.scope, {
+ path: '/',
+ secure: true,
+ httpOnly: true,
+ sameSite: true,
+ });
+
+ console.warn(
+ 'New Session:',
+ await client.fetchUserInfo(
+ await auth.getConfig(),
+ tk.access_token,
+ tk.claims()!.sub
+ )
+ );
+
+ return json({
+ sub: tk.claims()!.sub,
+ at: tk.access_token,
+ });
+ } catch (e) {
+ throw redirect(307, '/login');
+ }
+};