91 lines
3 KiB
TypeScript
91 lines
3 KiB
TypeScript
import { cookies } from "next/headers"
|
|
|
|
const SESSION_COOKIE_NAME = "session"
|
|
const SESSION_DURATION_MS = 7 * 24 * 60 * 60 * 1000 // 7 days
|
|
|
|
// In-memory session store. Replace this with your own session/token system.
|
|
const sessions = new Map<string, { email: string; expiresAt: Date }>()
|
|
|
|
function generateSessionId(): string {
|
|
const bytes = new Uint8Array(32)
|
|
crypto.getRandomValues(bytes)
|
|
return Array.from(bytes)
|
|
.map((b) => b.toString(16).padStart(2, "0"))
|
|
.join("")
|
|
}
|
|
|
|
// ─── AUTH INTERFACE ────────────────────────────────────────────────
|
|
// To integrate your own auth (JWT, OAuth, etc.), replace these functions.
|
|
// The rest of the application only calls checkAuth(), login(), and logout().
|
|
// ───────────────────────────────────────────────────────────────────
|
|
|
|
/**
|
|
* Check if the current request is authenticated.
|
|
* Replace this function to integrate JWT, OAuth, or any other auth system.
|
|
*/
|
|
export async function checkAuth(): Promise<{ authenticated: boolean; email?: string }> {
|
|
const cookieStore = await cookies()
|
|
const sessionId = cookieStore.get(SESSION_COOKIE_NAME)?.value
|
|
|
|
if (!sessionId) return { authenticated: false }
|
|
|
|
const session = sessions.get(sessionId)
|
|
if (!session) return { authenticated: false }
|
|
|
|
if (session.expiresAt < new Date()) {
|
|
sessions.delete(sessionId)
|
|
return { authenticated: false }
|
|
}
|
|
|
|
return { authenticated: true, email: session.email }
|
|
}
|
|
|
|
/**
|
|
* Authenticate with email and password.
|
|
* Default: compares against ADMIN_EMAIL/ADMIN_PASSWORD env vars.
|
|
* Replace this function to integrate your own auth system.
|
|
*/
|
|
export async function login(
|
|
email: string,
|
|
password: string
|
|
): Promise<{ success: true } | { success: false; error: string }> {
|
|
const adminEmail = process.env.ADMIN_EMAIL
|
|
const adminPassword = process.env.ADMIN_PASSWORD
|
|
|
|
if (!adminEmail || !adminPassword) {
|
|
return { success: false, error: "Admin-konfiguration mangler (ADMIN_EMAIL/ADMIN_PASSWORD)" }
|
|
}
|
|
|
|
if (email !== adminEmail || password !== adminPassword) {
|
|
return { success: false, error: "Forkert email eller adgangskode" }
|
|
}
|
|
|
|
const sessionId = generateSessionId()
|
|
const expiresAt = new Date(Date.now() + SESSION_DURATION_MS)
|
|
|
|
sessions.set(sessionId, { email, expiresAt })
|
|
|
|
const cookieStore = await cookies()
|
|
cookieStore.set(SESSION_COOKIE_NAME, sessionId, {
|
|
httpOnly: true,
|
|
secure: process.env.NODE_ENV === "production",
|
|
sameSite: "strict",
|
|
expires: expiresAt,
|
|
path: "/",
|
|
})
|
|
|
|
return { success: true }
|
|
}
|
|
|
|
/**
|
|
* Log out the current session.
|
|
*/
|
|
export async function logout(): Promise<void> {
|
|
const cookieStore = await cookies()
|
|
const sessionId = cookieStore.get(SESSION_COOKIE_NAME)?.value
|
|
|
|
if (sessionId) {
|
|
sessions.delete(sessionId)
|
|
cookieStore.delete(SESSION_COOKIE_NAME)
|
|
}
|
|
}
|