← back to Designer Portfolio Pages
src/auth.ts
34 lines
import crypto from "node:crypto";
import bcrypt from "bcryptjs";
export async function hashPasswordIfProvided(password?: string): Promise<string | null> {
const trimmed = (password ?? "").trim();
if (!trimmed) return null;
const saltRounds = 12;
return bcrypt.hash(trimmed, saltRounds);
}
export async function verifyPassword(password: string, hash: string): Promise<boolean> {
return bcrypt.compare(password, hash);
}
function hmac(secret: string, value: string): string {
return crypto.createHmac("sha256", secret).update(value).digest("base64url");
}
export function makePortfolioAuthCookieValue(cookieSecret: string, slug: string): string {
return `${slug}.${hmac(cookieSecret, slug)}`;
}
export function isValidPortfolioAuthCookieValue(cookieSecret: string, slug: string, cookieValue?: string): boolean {
if (!cookieValue) return false;
const [cookieSlug, sig] = cookieValue.split(".");
if (!cookieSlug || !sig) return false;
if (cookieSlug !== slug) return false;
return sig === hmac(cookieSecret, slug);
}
export function createSlug(bytes: number = 9): string {
return crypto.randomBytes(bytes).toString("base64url");
}