41 lines
1.2 KiB
TypeScript

import { createHmac, randomBytes } from "node:crypto";
export const ACCESS_KEY_PREFIX = "ydr_live_";
export function generateAccessKey() {
const visibleId = randomBytes(6).toString("hex");
const secret = randomBytes(32).toString("base64url");
const token = `${ACCESS_KEY_PREFIX}${visibleId}_${secret}`;
return {
token,
tokenPrefix: `${ACCESS_KEY_PREFIX}${visibleId}`,
};
}
export function hashAccessKey(token: string, pepper: string) {
const normalizedToken = String(token || "").trim();
const normalizedPepper = String(pepper || "").trim();
if (!normalizedToken || !normalizedPepper) {
throw new Error("Access Key token and pepper are required");
}
return createHmac("sha256", normalizedPepper)
.update(normalizedToken)
.digest("hex");
}
export function getAccessKeyPrefix(token: string) {
const normalized = String(token || "").trim();
const match = /^(ydr_live_[a-f0-9]{12})_[A-Za-z0-9_-]{20,}$/.exec(
normalized
);
return match?.[1] || null;
}
export function parseBearerAccessKey(header: string | null | undefined) {
const match = /^Bearer\s+(.+)$/i.exec(String(header || "").trim());
const token = match?.[1]?.trim() || "";
return getAccessKeyPrefix(token) ? token : null;
}