feat: render one login button per configured auth provider

This commit is contained in:
2026-08-03 10:56:03 +01:00
parent dde47de145
commit 3a626922a5
3 changed files with 228 additions and 48 deletions
+93
View File
@@ -364,6 +364,61 @@ export interface OrgOIDCInput {
enabled: boolean;
}
export interface PublicProvider {
id: string;
name: string;
preset: string;
}
export interface ProvidersResponse {
local_enabled: boolean;
providers: PublicProvider[];
}
export interface AuthProvider {
provider_id: string;
instance_id: string;
name: string;
kind: "oidc" | "oauth2";
preset: string;
issuer: string;
client_id: string;
scopes: string[];
enabled: boolean;
callback_notice: boolean;
order: number;
created_at: string;
updated_at: string;
client_secret_set: boolean;
callback_url: string;
}
export interface AuthPreset {
id: string;
label: string;
kind: "oidc" | "oauth2";
input_label: string;
input_hint: string;
}
export interface AuthProviderInput {
name: string;
preset: string;
issuer_input?: string;
client_id: string;
client_secret: string;
enabled: boolean;
}
export interface AuthProviderUpdate {
name?: string;
issuer_input?: string;
client_id?: string;
client_secret?: string;
enabled?: boolean;
order?: number;
}
class ApiError extends Error {
constructor(
public status: number,
@@ -457,6 +512,16 @@ export const auth = {
if (typeof window === "undefined") return "/auth/oidc/callback";
return `${window.location.origin}/auth/oidc/callback`;
},
/** Unauthenticated: what the login page draws itself from. */
providers(): Promise<ProvidersResponse> {
return authRequest<ProvidersResponse>("/auth/providers");
},
/** Where a provider button sends the browser. */
ssoStartUrl(providerId: string): string {
return `/auth/oidc/${providerId}/start`;
},
};
export const api = {
@@ -487,6 +552,34 @@ export const api = {
return request<{ saved: boolean }>("/instance/oidc", { method: "PUT", body: JSON.stringify(input) });
},
listAuthPresets(): Promise<AuthPreset[]> {
return request<AuthPreset[]>("/auth/presets");
},
listAuthProviders(): Promise<AuthProvider[]> {
return request<AuthProvider[]>("/auth/providers");
},
createAuthProvider(input: AuthProviderInput): Promise<AuthProvider> {
return request<AuthProvider>("/auth/providers", { method: "POST", body: JSON.stringify(input) });
},
updateAuthProvider(id: string, input: AuthProviderUpdate): Promise<{ saved: boolean }> {
return request<{ saved: boolean }>(`/auth/providers/${id}`, { method: "PUT", body: JSON.stringify(input) });
},
deleteAuthProvider(id: string): Promise<{ deleted: boolean }> {
return request<{ deleted: boolean }>(`/auth/providers/${id}`, { method: "DELETE" });
},
testAuthProvider(id: string): Promise<{ ok: boolean; message: string }> {
return request<{ ok: boolean; message: string }>(`/auth/providers/${id}/test`, { method: "POST" });
},
ackAuthProviderNotice(id: string): Promise<{ acknowledged: boolean }> {
return request<{ acknowledged: boolean }>(`/auth/providers/${id}/ack-notice`, { method: "POST" });
},
listServers(): Promise<Server[]> {
return request<Server[]>("/servers");
},