UNPKG

sst

Version:
83 lines (82 loc) 3.19 kB
import { generators } from "openid-client"; import { AdapterError } from "./adapter.js"; import { getCookie } from "hono/cookie"; export class OauthError extends AdapterError { } export const OauthAdapter = /* @__PURE__ */ (config) => { return async function (routes, ctx) { function getClient(c) { const callback = new URL(c.req.url); callback.pathname = callback.pathname.replace(/authorize.*$/, "callback"); callback.search = ""; callback.host = c.req.header("x-forwarded-host") || callback.host; return [ callback, new config.issuer.Client({ client_id: config.clientID, client_secret: config.clientSecret, redirect_uris: [callback.toString()], response_types: ["code"], }), ]; } routes.get("/authorize", async (c) => { const [_, client] = getClient(c); const code_verifier = generators.codeVerifier(); const state = generators.state(); const code_challenge = generators.codeChallenge(code_verifier); const url = client.authorizationUrl({ scope: config.scope, code_challenge: code_challenge, code_challenge_method: "S256", state, prompt: config.prompt, ...config.params, }); ctx.cookie(c, "auth_code_verifier", code_verifier, 60 * 10); ctx.cookie(c, "auth_state", state, 60 * 10); return c.redirect(url); }); routes.get("/callback", async (c) => { const [callback, client] = getClient(c); const query = c.req.query(); if (query.error) { throw new OauthError(query.error); } const code_verifier = getCookie(c, "auth_code_verifier"); const state = getCookie(c, "auth_state"); const tokenset = await client[config.issuer.metadata.userinfo_endpoint ? "callback" : "oauthCallback"](callback.toString(), query, { code_verifier, state, }); return ctx.success(c, { client, tokenset, }); }); // response_mode=form_post routes.post("/callback", async (c) => { const [callback, client] = getClient(c); const form = await c.req.formData(); if (form.get("error")) { throw new OauthError(form.get("error").toString()); } const code_verifier = getCookie(c, "auth_code_verifier"); const state = getCookie(c, "auth_state"); const tokenset = await client[config.issuer.metadata.userinfo_endpoint ? "callback" : "oauthCallback"](callback.toString(), Object.fromEntries(form), { code_verifier, state, }); return ctx.success(c, { client, tokenset, }); }); }; };