diff options
feat: oidc attempt 1
Diffstat (limited to 'src/routes/login/callback/+server.ts')
| -rw-r--r-- | src/routes/login/callback/+server.ts | 80 |
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'); + } +}; |