feat: Manage API tokens from settings
A card in the Access group beside Members and single sign-on rather than a new nav entry — /settings/instance was folded back in for exactly this reason. The plaintext is shown once in a well block and never again. Tokens outside a newly tightened lifetime policy are flagged rather than broken, because the policy governs issuance, not existing credentials.
This commit is contained in:
+39
-1
@@ -197,8 +197,22 @@ export interface Settings {
|
||||
secrets: SecretsSettings;
|
||||
workflow_log_retention_days?: number | null;
|
||||
local_login_enabled?: boolean;
|
||||
api_token_max_days?: number | null;
|
||||
}
|
||||
|
||||
export type ApiToken = {
|
||||
token_id: string;
|
||||
name: string;
|
||||
hint: string;
|
||||
role: Role;
|
||||
scopes: string[];
|
||||
expires_at?: string | null;
|
||||
created_at: string;
|
||||
last_used_at?: string | null;
|
||||
user_id: string;
|
||||
user_email?: string;
|
||||
};
|
||||
|
||||
export interface SecretGroupSummary {
|
||||
group: string;
|
||||
key_count: number;
|
||||
@@ -683,7 +697,12 @@ export const api = {
|
||||
return request<Settings>("/settings");
|
||||
},
|
||||
|
||||
saveSettings(settings: { alerts: AlertSettings; workflow_log_retention_days?: number | null; local_login_enabled?: boolean }): Promise<{ saved: boolean }> {
|
||||
saveSettings(settings: {
|
||||
alerts: AlertSettings;
|
||||
workflow_log_retention_days?: number | null;
|
||||
local_login_enabled?: boolean;
|
||||
api_token_max_days?: number | null;
|
||||
}): Promise<{ saved: boolean }> {
|
||||
return request<{ saved: boolean }>("/settings", {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(settings),
|
||||
@@ -694,6 +713,25 @@ export const api = {
|
||||
return request<{ token: string }>("/settings/secrets-token", { method: "POST" });
|
||||
},
|
||||
|
||||
listApiTokens(all = false): Promise<{ tokens: ApiToken[]; all: boolean }> {
|
||||
return request<{ tokens: ApiToken[]; all: boolean }>(`/tokens${all ? "?all=true" : ""}`);
|
||||
},
|
||||
|
||||
listTokenScopes(): Promise<{ scopes: string[] }> {
|
||||
return request<{ scopes: string[] }>("/tokens/scopes");
|
||||
},
|
||||
|
||||
createApiToken(body: { name: string; role: Role; scopes: string[]; expires_in_days?: number | null }): Promise<{ token: string; record: ApiToken }> {
|
||||
return request<{ token: string; record: ApiToken }>("/tokens", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
},
|
||||
|
||||
revokeApiToken(tokenId: string): Promise<{ revoked: boolean }> {
|
||||
return request<{ revoked: boolean }>(`/tokens/${tokenId}`, { method: "DELETE" });
|
||||
},
|
||||
|
||||
listSecretGroups(): Promise<SecretGroupSummary[]> {
|
||||
return request<SecretGroupSummary[]>("/secrets");
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user