Download src/lib/services/apiKey.ts from automindy/fiemwl: direct link, hf CLI and curl.
- Browser
- Download file 1.54 kB
-
https://huggingface.co/spaces/automindy/fiemwl/resolve/main/src/lib/services/apiKey.ts
- Command line
-
hf download hf://spaces/automindy/fiemwl/src/lib/services/apiKey.ts
-
curl -L -o apiKey.ts https://huggingface.co/spaces/automindy/fiemwl/resolve/main/src/lib/services/apiKey.ts
1.54 kB
| import { randomBytes } from "node:crypto"; | |
| import { encrypt, decrypt } from "@/lib/db/encryption"; | |
| import { getServiceRow, updateServiceField } from "@/lib/db/versionManager"; | |
| export function generateServiceApiKey(prefix = "nr"): string { | |
| return `${prefix}_${randomBytes(32).toString("base64url")}`; | |
| } | |
| export class ServiceApiKeyDecryptError extends Error { | |
| constructor(tool: string) { | |
| super( | |
| `Stored API key for service '${tool}' could not be decrypted. ` + | |
| `STORAGE_ENCRYPTION_KEY may have changed, the row may be corrupted, ` + | |
| `or it was written on a different machine. Reinstall the service ` + | |
| `or rotate the key via POST /api/services/${tool}/rotate-key.` | |
| ); | |
| this.name = "ServiceApiKeyDecryptError"; | |
| } | |
| } | |
| export async function getOrCreateApiKey(tool: string): Promise<string> { | |
| const row = await getServiceRow(tool); | |
| if (row?.apiKey) { | |
| const decrypted = decrypt(row.apiKey); | |
| if (decrypted) return decrypted; | |
| // Fail loud: silently regenerating would mint a new key the embedded | |
| // service has never been told, causing every request to 401 with no | |
| // operator-facing signal. | |
| throw new ServiceApiKeyDecryptError(tool); | |
| } | |
| const key = generateServiceApiKey(tool === "9router" ? "nr" : "cp"); | |
| await updateServiceField(tool, "apiKey", encrypt(key) ?? key); | |
| return key; | |
| } | |
| export function maskApiKey(plainKey: string): string { | |
| const last4 = plainKey.slice(-4); | |
| return `nr_••••••••${last4}`; | |
| } | |