Initial commit: PodcastYes — AI podcast platform
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user