Files
astro-oidc-rp/src/runtime.ts

87 lines
2.4 KiB
TypeScript

import type { OidcInjectedOptions } from "./index.js";
import { getSecret } from "astro:env/server";
// This constant is provided via Vite define by the integration during astro:config:setup
// eslint-disable-next-line @typescript-eslint/no-unused-vars
declare const __RESUELY_OIDC_OPTIONS: OidcInjectedOptions;
export type OidcRuntimeOptions = {
issuer: string;
clientId: string;
scopes: string;
routes: { login: string; callback: string; logout: string; logoutCallback: string };
redirectUri: { mode: "infer-from-request" } | { absolute: string };
cookie: {
name: string;
sameSite: "Lax" | "Strict" | "None";
secure: boolean;
domain?: string;
path: string;
signingSecret: string;
maxAgeSec?: number;
};
protected: string[];
};
function getInjected(): OidcInjectedOptions {
if (typeof __RESUELY_OIDC_OPTIONS === "undefined") {
throw new Error(
"@resuely/astro-oidc-rp: missing injected options; is the integration configured?",
);
}
return __RESUELY_OIDC_OPTIONS;
}
function readEnv(name: string): string | undefined {
const v = getSecret(name);
if (typeof v !== "string") return undefined;
if (v.trim().length === 0) return undefined;
return v;
}
function requireEnv(name: string): string {
const v = readEnv(name);
if (typeof v === "string") return v;
throw new Error(`@resuely/astro-oidc-rp: missing env var ${name}`);
}
let cached: OidcRuntimeOptions | null = null;
export function getOptions(): OidcRuntimeOptions {
if (cached) return cached;
const injected = getInjected();
const issuer = readEnv(injected.issuerEnv) ?? injected.issuerFallback;
if (!issuer)
throw new Error(
`@resuely/astro-oidc-rp: missing env var ${injected.issuerEnv}`,
);
const clientId = readEnv(injected.clientIdEnv) ?? injected.clientIdFallback;
if (!clientId)
throw new Error(
`@resuely/astro-oidc-rp: missing env var ${injected.clientIdEnv}`,
);
cached = {
issuer,
clientId,
scopes: injected.scopes,
routes: injected.routes,
redirectUri: injected.redirectUri,
cookie: {
name: injected.cookie.name,
sameSite: injected.cookie.sameSite,
secure: injected.cookie.secure,
domain: injected.cookie.domain,
path: injected.cookie.path,
signingSecret: requireEnv(injected.cookie.signingSecretEnv),
maxAgeSec: injected.cookie.maxAgeSec,
},
protected: injected.protected,
};
return cached;
}