/** * Organization API keys — STUB MODULE, no backend endpoint exists yet. * * This is a distinct concept from the two API-key-shaped things that already * exist server-side: * - `node_keys` (Firestore collection) — per-node upload credentials, issued * via /nodes/{id}/reissue-key. Not this. * - The Discord bot token pool (app/tokens) — Discord bot tokens, not this. * * This module models organization-level API keys for third-party * integrations (a standard SaaS feature) that DRB does not yet expose. * Everything below is in-memory demo state so the settings UI has something * real to render; nothing here is persisted or capable of authenticating * against the real API. * * TODO(api-keys): to make this real, add to drb-c2-core: * - `org_api_keys` Firestore collection: {key_id, org_id, name, key_hash, * key_prefix, created_at, last_used_at, created_by_uid, revoked} * - POST /org/api-keys → generate, return the raw key ONCE * - GET /org/api-keys → list (prefix + metadata only, never the raw key) * - DELETE /org/api-keys/{id} → revoke * - A new auth path in internal/auth.py that checks `Authorization: Bearer drb_live_…` * against `key_hash` (constant-time compare), scoped like a viewer/operator token. * Then replace the functions below with c2api calls hitting those routes. */ export interface ApiKeyRecord { key_id: string; name: string; /** Only the prefix is ever shown after creation — mirrors how real key systems (Stripe, GitHub) do it. */ key_prefix: string; created_at: string; last_used_at: string | null; revoked: boolean; } // Sample/demo fixture — obviously not real keys, never sent anywhere. let DEMO_KEYS: ApiKeyRecord[] = [ { key_id: "demo_key_1", name: "Ops dashboard integration", key_prefix: "drb_live_sample_4f2a", created_at: "2026-07-02T14:00:00.000Z", last_used_at: "2026-08-15T09:12:00.000Z", revoked: false, }, ]; export async function listApiKeys(): Promise { return DEMO_KEYS; } /** * Returns the full (fake) key exactly once, same UX contract a real key * issuance flow would have — the raw secret is shown once and never again. */ export async function createApiKey(name: string): Promise<{ record: ApiKeyRecord; rawKey: string }> { const suffix = Math.random().toString(36).slice(2, 10); const record: ApiKeyRecord = { key_id: `demo_key_${DEMO_KEYS.length + 1}`, name, key_prefix: `drb_live_sample_${suffix.slice(0, 4)}`, created_at: new Date().toISOString(), last_used_at: null, revoked: false, }; DEMO_KEYS = [...DEMO_KEYS, record]; return { record, rawKey: `drb_live_sample_${suffix}_DEMO_NOT_A_REAL_KEY` }; } export async function revokeApiKey(keyId: string): Promise { DEMO_KEYS = DEMO_KEYS.map((k) => (k.key_id === keyId ? { ...k, revoked: true } : k)); }