/** Berechtigungen, die ein API-Schlüssel tragen kann - wie API_KEY_SCOPES im Backend. */ export const API_KEY_SCOPES = ["shop-sync:read", "shop-sync:write", "erp-inventory:read"] as const; export type ApiKeyScope = (typeof API_KEY_SCOPES)[number]; export const API_KEY_SCOPE_LABELS: Record = { "shop-sync:read": "Shop-Daten lesen (Wabenhain)", "shop-sync:write": "Verkäufe und Rückbuchungen buchen (Wabenhain)", "erp-inventory:read": "Inventar-Spiegel lesen (ERPNext)", }; /** Buchende Rechte - wie API_KEY_WRITE_SCOPES im Backend; alle anderen lesen nur. */ const WRITE_SCOPES: readonly string[] = ["shop-sync:write"]; /** Label für die Anzeige; unbekannte Rechte (neueres Backend) unverändert. */ export function apiKeyScopeLabel(scope: string): string { return (API_KEY_SCOPE_LABELS as Record)[scope] ?? scope; } /** * Keys issued before reading and booking were split may still carry both; * the server no longer creates such keys, the UI nudges towards two keys. * The ERP inventory scope counts as reading. */ export function hasReadAndWriteScopes(apiKey: { scopes: readonly string[] }): boolean { const isWrite = (scope: string) => WRITE_SCOPES.includes(scope); return apiKey.scopes.some(isWrite) && apiKey.scopes.some((scope) => !isWrite(scope)); } /** Welches System einen Schlüssel mit diesem Recht benutzt. */ const CONSUMING_SYSTEM: Record = { "shop-sync:read": "Wabenhain", "shop-sync:write": "Wabenhain", "erp-inventory:read": "ERPNext", }; function consumingSystems(scopes: readonly string[]): string[] { const systems = scopes .map((scope) => (CONSUMING_SYSTEM as Record)[scope]) .filter((system): system is string => system !== undefined); return [...new Set(systems)]; } /** * Hinweis für einen älteren Schlüssel mit mehreren Rechten (der Server legt * nur noch Schlüssel mit genau einem Recht an), oder null. Nennt das System, * in dem die neuen Schlüssel einzutragen sind. */ export function separationAdvice(scopes: readonly string[]): string | null { if (new Set(scopes).size < 2) return null; const systems = consumingSystems(scopes); const where = systems.length > 0 ? `in ${systems.join(" bzw. ")}` : "im angebundenen System"; const why = hasReadAndWriteScopes({ scopes }) ? "Dieser Schlüssel darf lesen und buchen. Sicherer sind zwei getrennte Schlüssel: einer zum Lesen, einer zum Buchen." : "Dieser Schlüssel trägt mehrere Rechte. Sicherer ist je Recht ein eigener Schlüssel."; return `${why} Neue Schlüssel anlegen, ${where} eintragen, dann diesen widerrufen.`; }