Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
2.0 kB ยท 64 lines
TypeScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465// oxlint-disable-next-line unicorn/prefer-node-protocolimport crypto from "crypto";
import bcrypt from "bcryptjs";
/** * Generates a new API key with token, prefix, and hash * @returns Object containing the full token, prefix for lookup, and SHA-256 hash */export async function generateApiKey(): Promise<{ token: string; prefix: string; hash: string;}> { const randomBytes = crypto.randomBytes(16).toString("hex"); // 32 hex chars const token = `os_${randomBytes}`; const prefix = token.slice(0, 11); // "os_" (3 chars) + 8 hex chars = 11 total const hash = await bcrypt.hash(token, 10); return { token, prefix, hash };}
/** * Hashes an API key token using bcrypt * @param token - The API key token to hash * @returns The bcrypt hash of the token */export async function hashApiKey(token: string): Promise<string> { return bcrypt.hash(token, 10);}
/** * Verifies an API key token against a stored hash * Supports both bcrypt hashes (new) and SHA-256 hashes (legacy) for migration * @param token - The API key token to verify * @param storedHash - The stored hash to verify against * @returns True if the token matches the hash */export async function verifyApiKeyHash( token: string, storedHash: string,): Promise<boolean> { // Check if it's a bcrypt hash (starts with $2a$, $2b$, or $2y$) if (storedHash.startsWith("$2")) { return bcrypt.compare(token, storedHash); }
// Unknown hash format return false;}
/** * Determines if lastUsedAt should be updated based on debounce period * @param lastUsedAt - The last time the key was used (or null) * @param debounceMinutes - Minutes to wait before updating again (default: 5) * @returns True if lastUsedAt should be updated */export function shouldUpdateLastUsed( lastUsedAt: Date | null, debounceMinutes = 5,): boolean { if (!lastUsedAt) return true; const diffMs = Date.now() - lastUsedAt.getTime(); return diffMs > debounceMinutes * 60 * 1000;}