feat(web): add iron-session wrapper (web/lib/auth.ts)
This commit is contained in:
parent
f2facb200f
commit
a8751b6731
61
web/lib/auth.ts
Normal file
61
web/lib/auth.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import "server-only";
|
||||
import { cookies } from "next/headers";
|
||||
import { sealData, unsealData } from "iron-session";
|
||||
|
||||
const COOKIE_NAME = "cm_auth";
|
||||
const COOKIE_TTL_SECONDS = 30 * 24 * 60 * 60;
|
||||
|
||||
export type Session = {
|
||||
username: string;
|
||||
authenticatedAt: number;
|
||||
pendingChallenge?: {
|
||||
kind: "register" | "authenticate";
|
||||
challenge: string;
|
||||
expiresAt: number;
|
||||
};
|
||||
};
|
||||
|
||||
function secret(): string {
|
||||
const s = process.env.CM_AUTH_SECRET;
|
||||
if (!s || s.length < 32) {
|
||||
throw new Error("CM_AUTH_SECRET missing or shorter than 32 chars");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
export async function getSession(): Promise<Session | null> {
|
||||
const jar = await cookies();
|
||||
const raw = jar.get(COOKIE_NAME)?.value;
|
||||
if (!raw) return null;
|
||||
try {
|
||||
return await unsealData<Session>(raw, { password: secret() });
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function setSession(session: Session): Promise<void> {
|
||||
const sealed = await sealData(session, {
|
||||
password: secret(),
|
||||
ttl: COOKIE_TTL_SECONDS,
|
||||
});
|
||||
const jar = await cookies();
|
||||
jar.set(COOKIE_NAME, sealed, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
sameSite: "lax",
|
||||
path: "/",
|
||||
maxAge: COOKIE_TTL_SECONDS,
|
||||
});
|
||||
}
|
||||
|
||||
export async function clearSession(): Promise<void> {
|
||||
const jar = await cookies();
|
||||
jar.delete(COOKIE_NAME);
|
||||
}
|
||||
|
||||
export async function requireSession(): Promise<Session> {
|
||||
const s = await getSession();
|
||||
if (!s) throw new Error("Unauthenticated");
|
||||
return s;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user