KeyHelp: Panel-Passwort neu vergeben und verschlüsselt hinterlegen (verblurrt wie Lizenzschlüssel)

This commit is contained in:
Kundencenter 2026-09-27 21:35:15 +02:00
parent 3a2864ee76
commit 6fec6277f5
9 changed files with 136 additions and 20 deletions

View file

@ -8,15 +8,15 @@ export const CONTRACT_VERSION = 1 as const;
export type Capability =
| 'customers.list' | 'catalog.write' | 'children.read' | 'children.write' | 'secret.reveal' | 'license.customer_info' | 'catalog.list' | 'license.key_prefix' | 'license.expiry' | 'resources.list' | 'resources.get' | 'status.read' | 'usage.read'
| 'lifecycle.create' | 'lifecycle.suspend' | 'lifecycle.unsuspend' | 'lifecycle.terminate' | 'lifecycle.extend'
| 'settings.update' | 'plan.change' | 'sso.login' | 'webhooks';
| 'settings.update' | 'plan.change' | 'sso.login' | 'webhooks' | 'panel.password_reset';
/** Aktionen, die über `execute` laufen (immer als persistenter Auftrag). */
export type ActionName = 'suspend' | 'unsuspend' | 'extend' | 'terminate' | 'change_plan';
export type ActionName = 'suspend' | 'unsuspend' | 'extend' | 'terminate' | 'change_plan' | 'reset_password';
export const ACTION_CAPABILITY: Record<ActionName, Capability> = {
suspend: 'lifecycle.suspend', unsuspend: 'lifecycle.unsuspend', extend: 'lifecycle.extend', terminate: 'lifecycle.terminate', change_plan: 'plan.change',
suspend: 'lifecycle.suspend', unsuspend: 'lifecycle.unsuspend', extend: 'lifecycle.extend', terminate: 'lifecycle.terminate', change_plan: 'plan.change', reset_password: 'panel.password_reset',
};
/** Aktionen, die nie automatisch wiederholt werden dürfen (destruktiv). */
export const DESTRUCTIVE_ACTIONS: ReadonlySet<ActionName> = new Set(['terminate']);
/** Aktionen, die nie automatisch wiederholt werden dürfen (destruktiv, oder ein Fehlausgang wäre irreführend statt nur unvollständig). */
export const DESTRUCTIVE_ACTIONS: ReadonlySet<ActionName> = new Set(['terminate', 'reset_password']);
export type ResourceType = 'license' | 'hosting_account' | 'domain' | 'server';
export type ResourceState = 'active' | 'suspended' | 'expired' | 'error' | 'unknown';
@ -130,7 +130,7 @@ export interface Connector {
*/
provision?(ctx: ConnectorContext, req: { params: Record<string, unknown>; label: string; idempotencyKey: string; context?: ProvisionContext }): Promise<{ resource: NormalizedResource }>;
/** Idempotent: derselbe idempotencyKey darf beim Provider nie zu einer Doppelausführung führen. */
execute?(ctx: ConnectorContext, req: { action: ActionName; externalRef: string; params?: Record<string, unknown>; idempotencyKey: string }): Promise<{ resource?: NormalizedResource }>;
execute?(ctx: ConnectorContext, req: { action: ActionName; externalRef: string; params?: Record<string, unknown>; secrets?: Record<string, string>; idempotencyKey: string }): Promise<{ resource?: NormalizedResource }>;
}
// ---- Normalisierte Fehler --------------------------------------------------