Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
58 lines
2.6 KiB
TypeScript
58 lines
2.6 KiB
TypeScript
/** 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<ApiKeyScope, string> = {
|
|
"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<string, string>)[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<ApiKeyScope, string> = {
|
|
"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<string, string>)[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.`;
|
|
}
|