feat: OIDC SSO provider support (Keycloak, Azure AD, custom)
All checks were successful
CI Pipeline / Rust Format Check (push) Successful in 4s
CI Pipeline / Clippy Lints (push) Successful in 52s
CI Pipeline / Rust Unit Tests (push) Successful in 1m11s
CI Pipeline / Security Audit (push) Successful in 5s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 15s
CI Pipeline / Build .deb & Release (push) Has been skipped
All checks were successful
CI Pipeline / Rust Format Check (push) Successful in 4s
CI Pipeline / Clippy Lints (push) Successful in 52s
CI Pipeline / Rust Unit Tests (push) Successful in 1m11s
CI Pipeline / Security Audit (push) Successful in 5s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 15s
CI Pipeline / Build .deb & Release (push) Has been skipped
- Refactored azure_sso.rs to sso.rs with generic OIDC provider support - Added OIDC discovery URL lookup with 1hr TTL caching - Added PKCE for all providers, client_secret optional for public clients - Added /api/v1/auth/sso/login and /api/v1/auth/sso/callback routes - Added /api/v1/auth/azure/* backward-compatible routes - Added POST /settings/sso/discover and POST /settings/sso/test endpoints - Frontend: Provider dropdown (Keycloak/Azure AD/Custom OIDC) - Frontend: Auto-fill discovery URL for Keycloak - Frontend: Discover Endpoints and Test Connection buttons - Frontend: Dynamic SSO button based on provider display name - Made migration 014 idempotent with DO blocks and IF NOT EXISTS - Fixed debian/install to use /usr/local/bin/ for binaries - Fixed frontend file path in .deb package - Reset admin password on dev server - Fixed database permissions for oidc_config table
This commit is contained in:
@ -212,6 +212,8 @@ export const reportsApi = {
|
||||
}),
|
||||
}
|
||||
// ── Settings API (M10) ────────────────────────────────────────────────────
|
||||
|
||||
/** @deprecated Use OidcConfigResponse instead */
|
||||
export interface AzureSsoConfig {
|
||||
enabled: boolean
|
||||
tenant_id: string
|
||||
@ -220,6 +222,27 @@ export interface AzureSsoConfig {
|
||||
scopes: string
|
||||
}
|
||||
|
||||
export interface OidcConfigResponse {
|
||||
enabled: boolean
|
||||
provider_type: 'keycloak' | 'azure' | 'custom'
|
||||
display_name: string
|
||||
discovery_url: string
|
||||
client_id: string
|
||||
client_secret: string
|
||||
redirect_uri: string
|
||||
scopes: string
|
||||
}
|
||||
|
||||
export interface OidcDiscoveryResult {
|
||||
success: boolean
|
||||
issuer: string
|
||||
authorization_endpoint: string
|
||||
token_endpoint: string
|
||||
jwks_uri: string
|
||||
userinfo_endpoint?: string | null
|
||||
message?: string
|
||||
}
|
||||
|
||||
export interface SmtpConfig {
|
||||
enabled: boolean
|
||||
host: string
|
||||
@ -241,12 +264,13 @@ export interface NotificationConfig {
|
||||
}
|
||||
|
||||
export interface SettingsResponse {
|
||||
azure_sso: AzureSsoConfig
|
||||
oidc: OidcConfigResponse
|
||||
smtp: SmtpConfig
|
||||
polling: PollingConfig
|
||||
ip_whitelist: string[]
|
||||
web_tls_strategy: string
|
||||
notification: NotificationConfig
|
||||
sso_callback_url?: string
|
||||
}
|
||||
|
||||
export interface TestResult {
|
||||
@ -267,11 +291,14 @@ export interface AuditIntegrityResult {
|
||||
export const settingsApi = {
|
||||
get: () => apiClient.get<SettingsResponse>('/settings'),
|
||||
update: (data: Partial<SettingsResponse> & {
|
||||
azure_sso?: AzureSsoConfig & { client_secret?: string }
|
||||
oidc?: OidcConfigResponse & { client_secret?: string }
|
||||
smtp?: SmtpConfig & { password?: string }
|
||||
notification?: NotificationConfig
|
||||
}) => apiClient.put<SettingsResponse>('/settings', data),
|
||||
testAzureSso: () => apiClient.post<TestResult>('/settings/azure-sso/test'),
|
||||
discoverOidc: (discoveryUrl: string) => apiClient.post<OidcDiscoveryResult>('/settings/sso/discover', { discovery_url: discoveryUrl }),
|
||||
testOidc: () => apiClient.post<TestResult>('/settings/sso/test'),
|
||||
/** @deprecated Use testOidc instead */
|
||||
testAzureSso: () => apiClient.post<TestResult>('/settings/sso/test'),
|
||||
testSmtp: () => apiClient.post<TestResult>('/settings/smtp/test'),
|
||||
getIpWhitelist: () => apiClient.get<{ entries: string[] }>('/settings/ip-whitelist'),
|
||||
updateIpWhitelist: (entries: string[]) => apiClient.put<{ entries: string[] }>('/settings/ip-whitelist', { entries }),
|
||||
|
||||
Reference in New Issue
Block a user