Add registration flow and improve admin post management
This commit is contained in:
33
lib/auth.ts
33
lib/auth.ts
@@ -3,6 +3,8 @@ import { NextRequest } from "next/server";
|
||||
|
||||
const COOKIE_NAME = "admin_session";
|
||||
const encoder = new TextEncoder();
|
||||
let cachedKey: CryptoKey | null = null;
|
||||
let cachedSecret: string | null = null;
|
||||
|
||||
function getSecret() {
|
||||
const secret = process.env.SESSION_SECRET;
|
||||
@@ -15,16 +17,32 @@ function getSecret() {
|
||||
export type SessionPayload = {
|
||||
role: "admin";
|
||||
iat: number;
|
||||
exp?: number;
|
||||
uid?: string;
|
||||
name?: string;
|
||||
};
|
||||
|
||||
async function hmacSha256(data: string, secret: string): Promise<string> {
|
||||
const key = await crypto.subtle.importKey(
|
||||
export function getAdminName() {
|
||||
return process.env.ADMIN_NAME?.trim() || "Admin";
|
||||
}
|
||||
|
||||
async function getHmacKey(secret: string) {
|
||||
if (cachedKey && cachedSecret === secret) {
|
||||
return cachedKey;
|
||||
}
|
||||
cachedSecret = secret;
|
||||
cachedKey = await crypto.subtle.importKey(
|
||||
"raw",
|
||||
encoder.encode(secret),
|
||||
{ name: "HMAC", hash: "SHA-256" },
|
||||
false,
|
||||
["sign"]
|
||||
);
|
||||
return cachedKey;
|
||||
}
|
||||
|
||||
async function hmacSha256(data: string, secret: string): Promise<string> {
|
||||
const key = await getHmacKey(secret);
|
||||
const sig = await crypto.subtle.sign("HMAC", key, encoder.encode(data));
|
||||
return Buffer.from(sig).toString("base64url");
|
||||
}
|
||||
@@ -45,6 +63,12 @@ export async function verifySession(token?: string): Promise<SessionPayload | nu
|
||||
if (check !== sig) return null;
|
||||
try {
|
||||
const payload = JSON.parse(Buffer.from(base, "base64url").toString());
|
||||
if (typeof payload?.exp !== "number") {
|
||||
return null;
|
||||
}
|
||||
if (Date.now() > payload.exp) {
|
||||
return null;
|
||||
}
|
||||
return payload;
|
||||
} catch {
|
||||
return null;
|
||||
@@ -57,11 +81,12 @@ export async function requireAdminFromRequest(req: NextRequest): Promise<boolean
|
||||
}
|
||||
|
||||
export function setAdminCookie(token: string) {
|
||||
const isProd = process.env.NODE_ENV === "production";
|
||||
cookies().set(COOKIE_NAME, token, {
|
||||
httpOnly: true,
|
||||
sameSite: "lax",
|
||||
secure: true,
|
||||
maxAge: 60 * 60 * 24 * 30
|
||||
secure: isProd,
|
||||
maxAge: 60 * 60 * 24
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user