feat: add backoffice authentication with login page
- Add login page with logo background, glassmorphism card - Add session management via JWT (jose) with httpOnly cookie - Add Next.js proxy middleware to protect all routes - Add logout button in nav - Restructure app into (app) route group to isolate login layout - Add ADMIN_USERNAME, ADMIN_PASSWORD, SESSION_SECRET env vars Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
33
apps/backoffice/lib/session.ts
Normal file
33
apps/backoffice/lib/session.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { SignJWT, jwtVerify } from "jose";
|
||||
import { cookies } from "next/headers";
|
||||
|
||||
export const SESSION_COOKIE = "sl_session";
|
||||
|
||||
function getSecret(): Uint8Array {
|
||||
const secret = process.env.SESSION_SECRET;
|
||||
if (!secret) throw new Error("SESSION_SECRET env var is required");
|
||||
return new TextEncoder().encode(secret);
|
||||
}
|
||||
|
||||
export async function createSessionToken(): Promise<string> {
|
||||
return new SignJWT({})
|
||||
.setProtectedHeader({ alg: "HS256" })
|
||||
.setExpirationTime("7d")
|
||||
.sign(getSecret());
|
||||
}
|
||||
|
||||
export async function verifySessionToken(token: string): Promise<boolean> {
|
||||
try {
|
||||
await jwtVerify(token, getSecret());
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSession(): Promise<boolean> {
|
||||
const cookieStore = await cookies();
|
||||
const token = cookieStore.get(SESSION_COOKIE)?.value;
|
||||
if (!token) return false;
|
||||
return verifySessionToken(token);
|
||||
}
|
||||
Reference in New Issue
Block a user