diff --git a/server/auth.ts b/server/auth.ts new file mode 100644 index 0000000..e1defdb --- /dev/null +++ b/server/auth.ts @@ -0,0 +1,37 @@ +import type { Client } from 'openid-client'; +import { generators } from 'openid-client'; +import { Request, Response } from 'express'; + +export function setupAuthRoutes(app: any, client: Client, redirectUri: string, scope: string, cookieOptionsBase: any) { + app.get('/auth/login', (req: Request, res: Response) => { + const code_verifier = generators.codeVerifier(); + const code_challenge = generators.codeChallenge(code_verifier); + res.cookie('pkce_verifier', code_verifier, { ...cookieOptionsBase, maxAge: 600000 }); + const authUrl = client.authorizationUrl({ scope, code_challenge, code_challenge_method: 'S256', redirect_uri: redirectUri }); + res.redirect(authUrl); + }); + + app.get('/auth/callback', async (req: Request, res: Response) => { + const params = client.callbackParams(req); + const verifier = req.signedCookies['pkce_verifier']; + const tokenSet = await client.callback(redirectUri, params, { code_verifier: verifier }); + res.clearCookie('pkce_verifier'); + res.cookie('access_token', tokenSet.access_token, { ...cookieOptionsBase }); + res.cookie('id_token', tokenSet.id_token, { ...cookieOptionsBase }); + res.redirect('/'); + }); + + app.get('/api/userinfo', async (req: Request, res: Response) => { + const access = req.signedCookies['access_token']; + if (!access) return res.status(401).json({ error: 'unauthorized' }); + const userinfo = await client.userinfo(access); + res.json(userinfo); + }); + + app.post('/auth/logout', (_req: Request, res: Response) => { + res.clearCookie('access_token'); + res.clearCookie('id_token'); + res.clearCookie('refresh_token'); + res.json({ ok: true }); + }); +}