2026-04-17 11:32:17 +08:00

72 lines
1.8 KiB
TypeScript

import { cookies } from "next/headers";
import { randomUUID } from "node:crypto";
import { prisma } from "@/lib/prisma";
export const CAREGIVER_SESSION_COOKIE = "dh-caregiver-session";
const CAREGIVER_SESSION_MAX_AGE = 60 * 60 * 24 * 365;
function createSessionToken() {
return randomUUID().replaceAll("-", "");
}
function getCookieOptions() {
return {
httpOnly: true,
sameSite: "lax" as const,
secure: process.env.NODE_ENV === "production",
path: "/",
maxAge: CAREGIVER_SESSION_MAX_AGE,
};
}
function normalizeRedirectPath(redirectTo?: string) {
if (!redirectTo || !redirectTo.startsWith("/") || redirectTo.startsWith("//")) {
return "/";
}
return redirectTo;
}
async function upsertCaregiverByToken(sessionToken: string) {
return prisma.caregiverAccount.upsert({
where: { sessionToken },
update: {},
create: { sessionToken },
});
}
export function buildCaregiverSessionBootstrapPath(redirectTo: string) {
const normalizedRedirect = normalizeRedirectPath(redirectTo);
return `/api/family/session?redirectTo=${encodeURIComponent(normalizedRedirect)}`;
}
export async function getCaregiverSession() {
const sessionToken = (await cookies()).get(CAREGIVER_SESSION_COOKIE)?.value;
if (!sessionToken) {
return null;
}
return upsertCaregiverByToken(sessionToken);
}
export async function getOrCreateCaregiverSession() {
const cookieStore = await cookies();
let sessionToken = cookieStore.get(CAREGIVER_SESSION_COOKIE)?.value;
if (!sessionToken) {
sessionToken = createSessionToken();
cookieStore.set(CAREGIVER_SESSION_COOKIE, sessionToken, getCookieOptions());
}
return upsertCaregiverByToken(sessionToken);
}
export function createCaregiverSessionCookieValue() {
return {
sessionToken: createSessionToken(),
options: getCookieOptions(),
};
}