import crypto from "node:crypto"; import { prisma } from "@/lib/db"; const PREFIX = "pky_live_"; export function generateRawKey(): string { return PREFIX + crypto.randomBytes(24).toString("base64url"); } export function hashKey(raw: string): string { return crypto.createHash("sha256").update(raw).digest("hex"); } /** Display-only prefix, e.g. "pky_live_abc123…". */ export function keyPreview(raw: string): string { return raw.slice(0, PREFIX.length + 6) + "…"; } /** Verify a raw API key and return its owner, updating lastUsedAt. */ export async function verifyApiKey(raw: string | null): Promise<{ userId: string } | null> { if (!raw || !raw.startsWith(PREFIX)) return null; const key = await prisma.apiKey.findUnique({ where: { hashedKey: hashKey(raw) }, select: { id: true, userId: true, revokedAt: true }, }); if (!key || key.revokedAt) return null; void prisma.apiKey.update({ where: { id: key.id }, data: { lastUsedAt: new Date() } }).catch(() => {}); return { userId: key.userId }; } /** Extract a bearer key from an Authorization header. */ export function bearerKey(authorization: string | null): string | null { if (!authorization) return null; const match = authorization.match(/^Bearer\s+(.+)$/i); return match?.[1] ?? null; }