aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/login/callback/+server.ts
blob: 32b164780f1dd99a35d1522330fdc12174802d67 (plain) (blame)
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
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');
  }
};