Olympus/frontend/athena/lib/server/hermes.ts

103 lines
2.2 KiB
TypeScript

import { cookies } from "next/headers";
import { NextResponse } from "next/server";
const ACCESS_TOKEN_COOKIE = "access_token";
const DEFAULT_COOKIE_MAX_AGE_SECONDS = 60 * 60;
export function getHermesUrl() {
return process.env.HERMES_INTERNAL_URL?.replace(/\/$/, "") ?? null;
}
export async function getAccessToken() {
const cookieStore = await cookies();
return cookieStore.get(ACCESS_TOKEN_COOKIE)?.value;
}
function isSecureCookieEnabled() {
if (process.env.AUTH_COOKIE_SECURE) {
return process.env.AUTH_COOKIE_SECURE !== "false";
}
return process.env.NODE_ENV === "production";
}
function normalizeMaxAge(maxAge?: number) {
if (typeof maxAge !== "number" || !Number.isFinite(maxAge) || maxAge <= 0) {
return DEFAULT_COOKIE_MAX_AGE_SECONDS;
}
return Math.floor(maxAge);
}
export function setAuthCookie(response: NextResponse, token: string, maxAge: number) {
response.cookies.set({
name: ACCESS_TOKEN_COOKIE,
value: token,
httpOnly: true,
secure: isSecureCookieEnabled(),
sameSite: "lax",
path: "/",
maxAge: normalizeMaxAge(maxAge),
});
}
export function clearAuthCookie(response: NextResponse) {
response.cookies.set({
name: ACCESS_TOKEN_COOKIE,
value: "",
httpOnly: true,
secure: isSecureCookieEnabled(),
sameSite: "lax",
path: "/",
maxAge: 0,
});
}
export function unauthorizedResponse() {
return NextResponse.json(
{ detail: "Nicht authentifiziert" },
{ status: 401 },
);
}
export function upstreamUnavailableResponse() {
return NextResponse.json(
{ detail: "Hermes ist nicht erreichbar" },
{ status: 502 },
);
}
export function upstreamConfigurationErrorResponse() {
return NextResponse.json(
{ detail: "Hermes ist nicht konfiguriert" },
{ status: 500 },
);
}
export async function readJson(response: Response) {
const text = await response.text();
if (!text) {
return null;
}
try {
return JSON.parse(text);
} catch {
return { detail: text };
}
}
export async function hermesJsonResponse(response: Response) {
if (response.status === 204) {
return new NextResponse(null, {
status: 204,
});
}
const body = await readJson(response);
return NextResponse.json(body, {
status: response.status,
});
}