diff --git a/src/pages/OidcSettingsPage.tsx b/src/pages/OidcSettingsPage.tsx index feac13f..a33b3a0 100644 --- a/src/pages/OidcSettingsPage.tsx +++ b/src/pages/OidcSettingsPage.tsx @@ -10,6 +10,7 @@ interface Settings { redirect_uri: string | null scopes: string | null post_login_redirect: string | null + admin_role: string oidc_only: boolean effective_enabled: boolean source: string @@ -31,6 +32,7 @@ export default function OidcSettingsPage() { redirect_uri: '', scopes: 'openid email profile', post_login_redirect: '', + admin_role: 'admin', }) useEffect(() => { @@ -46,6 +48,7 @@ export default function OidcSettingsPage() { redirect_uri: data.redirect_uri || '', scopes: data.scopes || 'openid email profile', post_login_redirect: data.post_login_redirect || '', + admin_role: data.admin_role || 'admin', }) }) .catch((e) => setMessage(e.response?.data?.detail || 'Failed to load OIDC settings')) @@ -63,6 +66,7 @@ export default function OidcSettingsPage() { redirect_uri: form.redirect_uri.trim(), scopes: form.scopes.trim(), post_login_redirect: form.post_login_redirect.trim(), + admin_role: form.admin_role.trim() || 'admin', } if (form.client_secret) payload.client_secret = form.client_secret const { data } = await api.put('/auth/oidc/settings', payload) @@ -150,6 +154,14 @@ export default function OidcSettingsPage() { Post-login redirect (frontend) setForm({ ...form, post_login_redirect: e.target.value })} /> + +

+ OIDC-only bootstrap: before any admin is linked, an IdP user whose token carries this role + auto-connects to the HarborForge admin account on first sign-in. Disables itself once an admin is bound. +

diff --git a/src/pages/SetupWizardPage.tsx b/src/pages/SetupWizardPage.tsx index 5ffd8b5..9b6f2f9 100644 --- a/src/pages/SetupWizardPage.tsx +++ b/src/pages/SetupWizardPage.tsx @@ -22,7 +22,7 @@ interface SetupForm { oidc_redirect_uri: string oidc_scopes: string oidc_post_login_redirect: string - oidc_admin_subject: string + oidc_admin_role: string } const oidcOnly = getRuntimeOidcOnly() === true @@ -52,7 +52,7 @@ export default function SetupWizardPage({ initialWizardPort, onComplete }: Props oidc_redirect_uri: '', oidc_scopes: 'openid email profile', oidc_post_login_redirect: '', - oidc_admin_subject: '', + oidc_admin_role: 'admin', }) const set = (key: keyof SetupForm, value: string | number | boolean) => @@ -85,8 +85,8 @@ export default function SetupWizardPage({ initialWizardPort, onComplete }: Props if (!form.oidc_client_id.trim()) return 'OIDC client ID is required' if (!form.oidc_client_secret.trim()) return 'OIDC client secret is required' if (!form.oidc_redirect_uri.trim()) return 'OIDC redirect/callback URL is required' - if (oidcOnly && !form.oidc_admin_subject.trim()) { - return "In OIDC-only mode the admin's OIDC subject is required so the admin can sign in" + if (oidcOnly && !form.oidc_admin_role.trim()) { + return 'In OIDC-only mode the admin role is required so the admin can bootstrap' } return '' } @@ -115,7 +115,7 @@ export default function SetupWizardPage({ initialWizardPort, onComplete }: Props redirect_uri: form.oidc_redirect_uri.trim(), scopes: form.oidc_scopes.trim() || 'openid email profile', post_login_redirect: form.oidc_post_login_redirect.trim() || undefined, - admin_subject: form.oidc_admin_subject.trim() || undefined, + admin_role: form.oidc_admin_role.trim() || 'admin', } } @@ -230,12 +230,16 @@ export default function SetupWizardPage({ initialWizardPort, onComplete }: Props - {oidcOnly && ( - - )} +

Register the Redirect / Callback URL above at your identity provider.

+ {oidcOnly && ( +

+ OIDC-only: before any admin is linked, the first IdP user whose token carries the + role above auto-connects to the HarborForge admin account. It then disables itself. +

+ )} )}