feat(auth): let admins keep the login page on OIDC-only instances (#2925)

A new app setting oidc_auto_redirect (default on) is part of the admin form
and the public app config. Off, an instance without password login no longer
sends visitors straight to the IdP: the login page shows its SSO button,
also while the cached config is read. Admin toggle on desktop and phone.
This commit is contained in:
Maurice
2026-11-13 09:35:18 +01:00
parent d5d9428cf2
commit 924b4e0787
45 changed files with 227 additions and 8 deletions
@@ -33,7 +33,7 @@ export default function MAdminSettingsSection({ admin, t }: MAdminSettingsSectio
placesGoogleOnly, handleTogglePlacesGoogleOnly,
placeShadowEnabled,
passwordLogin, setPasswordLogin, passwordRegistration, setPasswordRegistration,
oidcLogin, setOidcLogin, oidcRegistration, setOidcRegistration,
oidcLogin, setOidcLogin, oidcRegistration, setOidcRegistration, oidcAutoRedirect, setOidcAutoRedirect,
envOverrideOidcOnly, oidcConfigured, requireMfa,
passkeyLogin, setPasskeyLogin, passkeyConfigured,
webauthnRpId, setWebauthnRpId, webauthnOrigins, setWebauthnOrigins, savingWebauthn, handleSaveWebauthn,
@@ -112,6 +112,19 @@ export default function MAdminSettingsSection({ admin, t }: MAdminSettingsSectio
}
/>
)}
{oidcConfigured && (
<MAdminRow
title={t('admin.oidcAutoRedirect')}
hint={t('admin.oidcAutoRedirectHint')}
trailing={
<MToggle
checked={oidcAutoRedirect}
ariaLabel={t('admin.oidcAutoRedirect')}
onChange={(v) => handleToggleAuthSetting('oidc_auto_redirect', v, setOidcAutoRedirect)}
/>
}
/>
)}
</MAdminCard>
{/* Passkey login */}
@@ -1,4 +1,4 @@
// FE-ADMSET-001 to FE-ADMSET-043
// FE-ADMSET-001 to FE-ADMSET-044
import { http, HttpResponse } from 'msw';
import React from 'react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
@@ -143,6 +143,7 @@ describe('AdminSettingsTab', () => {
expect(screen.queryByText('SSO Login')).not.toBeInTheDocument();
expect(screen.queryByText('SSO Auto-Provisioning')).not.toBeInTheDocument();
expect(screen.queryByText('Go straight to SSO')).not.toBeInTheDocument();
});
it('FE-ADMSET-008: SSO login toggle sends the inverted value', () => {
@@ -167,6 +168,14 @@ describe('AdminSettingsTab', () => {
expect(admin.handleToggleAuthSetting).toHaveBeenCalledWith('oidc_registration', true, admin.setOidcRegistration);
});
it('FE-ADMSET-044: the SSO auto redirect toggle sends the inverted value (#2925)', () => {
const admin = renderTab({ oidcConfigured: true, oidcAutoRedirect: true });
fireEvent.click(toggleFor('Go straight to SSO'));
expect(admin.handleToggleAuthSetting).toHaveBeenCalledWith('oidc_auto_redirect', false, admin.setOidcAutoRedirect);
});
it('FE-ADMSET-011: passkey toggle sends the inverted value', () => {
const admin = renderTab({ passkeyLogin: false });
+15 -1
View File
@@ -121,7 +121,7 @@ export default function AdminSettingsTab({ admin, t }: AdminSettingsTabProps): R
placeShadowEnabled,
oidcConfig, setOidcConfig, savingOidc,
passwordLogin, setPasswordLogin, passwordRegistration, setPasswordRegistration,
oidcLogin, setOidcLogin, oidcRegistration, setOidcRegistration,
oidcLogin, setOidcLogin, oidcRegistration, setOidcRegistration, oidcAutoRedirect, setOidcAutoRedirect,
envOverrideOidcOnly, oidcConfigured, requireMfa,
passkeyLogin, setPasskeyLogin, passkeyConfigured,
webauthnRpId, setWebauthnRpId, webauthnOrigins, setWebauthnOrigins, savingWebauthn, handleSaveWebauthn,
@@ -235,6 +235,20 @@ export default function AdminSettingsTab({ admin, t }: AdminSettingsTabProps): R
}
/>
)}
{/* Whether an instance without password login skips its own login page (#2925) */}
{oidcConfigured && (
<SettingRow
label={t('admin.oidcAutoRedirect')}
hint={t('admin.oidcAutoRedirectHint')}
control={
<ToggleSwitch
on={oidcAutoRedirect}
label={t('admin.oidcAutoRedirect')}
onToggle={() => handleToggleAuthSetting('oidc_auto_redirect', !oidcAutoRedirect, setOidcAutoRedirect)}
/>
}
/>
)}
</SettingRows>
</SettingsCard>
+2
View File
@@ -100,6 +100,7 @@ describe('useAdmin', () => {
password_registration: false,
oidc_login: false,
oidc_registration: false,
oidc_auto_redirect: false,
env_override_oidc_only: true,
oidc_configured: true,
require_mfa: 1,
@@ -116,6 +117,7 @@ describe('useAdmin', () => {
expect(result.current.passwordRegistration).toBe(false);
expect(result.current.oidcLogin).toBe(false);
expect(result.current.oidcRegistration).toBe(false);
expect(result.current.oidcAutoRedirect).toBe(false);
expect(result.current.envOverrideOidcOnly).toBe(true);
expect(result.current.oidcConfigured).toBe(true);
expect(result.current.requireMfa).toBe(true);
+3 -1
View File
@@ -145,6 +145,7 @@ export function useAdmin() {
const [passwordRegistration, setPasswordRegistration] = useState<boolean>(true)
const [oidcLogin, setOidcLogin] = useState<boolean>(true)
const [oidcRegistration, setOidcRegistration] = useState<boolean>(true)
const [oidcAutoRedirect, setOidcAutoRedirect] = useState<boolean>(true)
const [envOverrideOidcOnly, setEnvOverrideOidcOnly] = useState<boolean>(false)
const [oidcConfigured, setOidcConfigured] = useState<boolean>(false)
const [requireMfa, setRequireMfa] = useState<boolean>(false)
@@ -286,6 +287,7 @@ export function useAdmin() {
setPasswordRegistration(config.password_registration ?? config.allow_registration ?? true)
setOidcLogin(config.oidc_login ?? true)
setOidcRegistration(config.oidc_registration ?? config.allow_registration ?? true)
setOidcAutoRedirect(config.oidc_auto_redirect ?? true)
setEnvOverrideOidcOnly(config.env_override_oidc_only ?? false)
setOidcConfigured(config.oidc_configured ?? false)
if (config.require_mfa !== undefined) setRequireMfa(!!config.require_mfa)
@@ -600,7 +602,7 @@ export function useAdmin() {
collabFeatures, setCollabFeatures,
oidcConfig, setOidcConfig, savingOidc, setSavingOidc,
passwordLogin, setPasswordLogin, passwordRegistration, setPasswordRegistration,
oidcLogin, setOidcLogin, oidcRegistration, setOidcRegistration,
oidcLogin, setOidcLogin, oidcRegistration, setOidcRegistration, oidcAutoRedirect, setOidcAutoRedirect,
envOverrideOidcOnly, setEnvOverrideOidcOnly, oidcConfigured, setOidcConfigured,
requireMfa, setRequireMfa,
passkeyLogin, setPasskeyLogin, passkeyConfigured,
+37
View File
@@ -1212,6 +1212,43 @@ describe('useLogin — the wait before the sign-in is known (#1167)', () => {
expect(window.location.href).toBe('http://localhost/login');
});
it('FE-LOGIN-HOOK-215: with the auto redirect turned off the page stays, with its SSO button (#2925)', async () => {
server.use(
http.get('/api/auth/app-config', () => HttpResponse.json({ ...oidcOnlyConfig(), oidc_auto_redirect: false })),
);
const { result } = renderLogin();
await ready(result);
expect(result.current.oidcOnly).toBe(true);
expect(result.current.redirectScreen).toBe(false);
expect(result.current.configWait).toBe(false);
expect(window.location.href).toBe('http://localhost/login');
});
it('FE-LOGIN-HOOK-216: a cached config with the auto redirect off announces no redirect while the probe is out', async () => {
const config = { ...oidcOnlyConfig(), oidc_auto_redirect: false };
localStorage.setItem(CONFIG_CACHE_KEY, JSON.stringify(config));
const release = heldConfig(config);
const { result } = renderLogin();
expect(result.current.redirectScreen).toBe(false);
expect(result.current.configWait).toBe(true);
release();
await ready(result);
expect(result.current.redirectScreen).toBe(false);
expect(window.location.href).toBe('http://localhost/login');
});
it('FE-LOGIN-HOOK-217: a server from before the switch, with no field, keeps the redirect', async () => {
const config: Record<string, unknown> = { ...oidcOnlyConfig() };
delete config.oidc_auto_redirect;
server.use(http.get('/api/auth/app-config', () => HttpResponse.json(config)));
renderLogin();
await waitFor(() => expect(window.location.href).toBe('/api/auth/oidc/login?remember=1'));
});
it('FE-LOGIN-HOOK-210: right after a sign-out the cached redirect is not announced', async () => {
localStorage.setItem(CONFIG_CACHE_KEY, JSON.stringify(oidcOnlyConfig()));
const release = heldConfig(oidcOnlyConfig());
+12 -2
View File
@@ -33,6 +33,8 @@ interface AppConfig {
password_registration: boolean
oidc_login: boolean
oidc_registration: boolean
/** False when the admin wants the login page shown before the IdP; absent on servers from before #2925. */
oidc_auto_redirect?: boolean
passkey_login?: boolean
passkey_configured?: boolean
env_override_oidc_only: boolean
@@ -56,6 +58,14 @@ function readCachedConfig(): AppConfig | null {
const isOidcOnly = (config: AppConfig | null): boolean =>
!!config && !config.password_login && config.oidc_login && config.oidc_configured
/**
* Whether the login page leaves for the IdP by itself: an OIDC-only instance
* does, unless its admin turned that off to show the page and its SSO button
* first (#2925). A config without the field keeps the redirect.
*/
const redirectsToIdp = (config: AppConfig | null): boolean =>
isOidcOnly(config) && config?.oidc_auto_redirect !== false
/**
* Login data hook — owns the whole auth surface: login/register/demo, the MFA
* step-up, the must-change-password step, the OIDC code exchange + error
@@ -88,7 +98,7 @@ export function useLogin() {
const [cachedConfig] = useState(readCachedConfig)
const [expectRedirect] = useState(() => {
const params = new URLSearchParams(window.location.search)
return !isNativeApp() && isOidcOnly(cachedConfig) && !!cachedConfig?.has_users
return !isNativeApp() && redirectsToIdp(cachedConfig) && !!cachedConfig?.has_users
&& !params.get('invite') && !params.get('oidc_code') && !params.get('oidc_error')
})
const [idpRedirect, setIdpRedirect] = useState(false)
@@ -198,7 +208,7 @@ export function useLogin() {
// and auto-redirecting to the IdP could loop if the proxy changed.
// Not in the app: its WebView cannot host the IdP, and opening the
// system browser uninvited on every launch would be worse than a button.
if (allowRedirect && !fromCache && !nativeApp && isOidcOnly(config) && config.has_users && !invite && !noRedirect) {
if (allowRedirect && !fromCache && !nativeApp && redirectsToIdp(config) && config.has_users && !invite && !noRedirect) {
setIdpRedirect(true)
window.location.href = IDP_LOGIN_URL
}
+2
View File
@@ -449,6 +449,8 @@ export interface AppConfig {
password_registration?: boolean
oidc_login?: boolean
oidc_registration?: boolean
/** Whether an instance without password login sends visitors straight to the IdP */
oidc_auto_redirect?: boolean
env_override_oidc_only?: boolean
}
+2
View File
@@ -107,6 +107,8 @@ export function buildAdminHook(overrides: Record<string, unknown> = {}): AdminHo
setOidcLogin: vi.fn(),
oidcRegistration: false,
setOidcRegistration: vi.fn(),
oidcAutoRedirect: true,
setOidcAutoRedirect: vi.fn(),
envOverrideOidcOnly: false,
setEnvOverrideOidcOnly: vi.fn(),
oidcConfigured: false,
@@ -82,6 +82,7 @@ describe('MAdminSettingsSection', () => {
expect(screen.queryByRole('switch', { name: 'SSO Login' })).not.toBeInTheDocument();
expect(screen.queryByRole('switch', { name: 'SSO Auto-Provisioning' })).not.toBeInTheDocument();
expect(screen.queryByRole('switch', { name: 'Go straight to SSO' })).not.toBeInTheDocument();
});
it('FE-MOB-ASET-003: an env override disables the password toggles and shows the hint', () => {
@@ -126,6 +127,11 @@ describe('MAdminSettingsSection', () => {
'oidc_registration', true, admin.setOidcRegistration,
);
await user.click(toggle('Go straight to SSO'));
expect(admin.handleToggleAuthSetting).toHaveBeenCalledWith(
'oidc_auto_redirect', false, admin.setOidcAutoRedirect,
);
await user.click(toggle('Enable passkey login'));
expect(admin.handleToggleAuthSetting).toHaveBeenCalledWith('passkey_login', true, admin.setPasskeyLogin);
});
+3
View File
@@ -359,6 +359,9 @@ export class AuthService {
password_registration: isDemo ? false : toggles.password_registration,
oidc_login: toggles.oidc_login,
oidc_registration: isDemo ? false : toggles.oidc_registration,
// Read by the login page only where password login is off: anything but
// 'false' keeps the redirect every such instance had before (#2925).
oidc_auto_redirect: settings.get('oidc_auto_redirect') !== 'false',
// Passkey login: the instance toggle + whether a usable RP ID resolves for
// this deployment. The login page shows the passkey button only when both
// are true. `passkey_configured` stays a pure boolean — it never leaks the
@@ -84,6 +84,9 @@ export const APP_SETTINGS = {
password_registration: { schema: flag, default: 'true', adminForm: true },
oidc_login: { schema: flag, default: 'true', adminForm: true, managedLocked: true },
oidc_registration: { schema: flag, default: 'true', adminForm: true, managedLocked: true },
// Whether an instance without password login sends a visitor straight to the
// identity provider. Off shows the login page with its SSO button first (#2925).
oidc_auto_redirect: { schema: flag, default: 'true', adminForm: true, publicConfig: true },
passkey_login: { schema: flag, default: 'false', adminForm: true },
webauthn_rp_id: { schema: text, default: null, adminForm: true, managedLocked: true },
webauthn_origins: { schema: text, default: null, adminForm: true, managedLocked: true },
+22
View File
@@ -120,6 +120,28 @@ describe('Auth e2e (real auth guard + real service + real cookie service + temp
expect(res.body.permissions).toBeUndefined();
});
it('PUT /app-settings oidc_auto_redirect reaches the public app-config the login page reads (#2925)', async () => {
const admin = createUser(db as never, {
username: 'redirect-admin',
email: 'redirect-admin@example.test',
role: 'admin',
});
const autoRedirect = async () => (await request(server).get('/api/auth/app-config')).body.oidc_auto_redirect;
try {
expect(await autoRedirect()).toBe(true);
const res = await request(server)
.put('/api/auth/app-settings')
.set('Cookie', sessionCookie(admin.user.id))
.send({ oidc_auto_redirect: false });
expect(res.status).toBe(200);
expect(await readAppSetting(orm, 'oidc_auto_redirect')).toBe('false');
expect(await autoRedirect()).toBe(false);
} finally {
await deleteRows(orm, AppSettings, { key: 'oidc_auto_redirect' });
}
});
it('GET /me requires a session (401 without a cookie)', async () => {
expect((await request(server).get('/api/auth/me')).status).toBe(401);
});
@@ -45,6 +45,7 @@ describe('the derived key lists', () => {
'password_registration',
'oidc_login',
'oidc_registration',
'oidc_auto_redirect',
'passkey_login',
'webauthn_rp_id',
'webauthn_origins',
@@ -82,6 +83,7 @@ describe('the derived key lists', () => {
'places_details_enabled',
'places_enrich_enabled',
'place_shadow_enabled',
'oidc_auto_redirect',
].sort(),
);
});
@@ -815,6 +815,15 @@ describe('getAppConfig', () => {
vi.unstubAllEnvs();
});
it('AUTH-DB-052d: oidc_auto_redirect stays on until an admin stores false (#2925)', async () => {
createUser(testDb);
expect((await svc.getAppConfig(null)).oidc_auto_redirect).toBe(true);
await appSetting('oidc_auto_redirect', 'false');
expect((await svc.getAppConfig(null)).oidc_auto_redirect).toBe(false);
await appSetting('oidc_auto_redirect', 'true');
expect((await svc.getAppConfig(null)).oidc_auto_redirect).toBe(true);
});
it('AUTH-DB-052b: managed is false unless the install says otherwise', async () => {
createUser(testDb);
expect((await svc.getAppConfig(null)).managed).toBe(false);
+3
View File
@@ -900,6 +900,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'السماح للمستخدمين بتسجيل الدخول عبر SSO',
'admin.oidcRegistration': 'إنشاء الحسابات تلقائيًا عبر SSO',
'admin.oidcRegistrationHint': 'إنشاء حسابات تلقائيًا للمستخدمين الجدد عبر SSO',
'admin.oidcAutoRedirect': 'الانتقال مباشرة إلى SSO',
'admin.oidcAutoRedirectHint':
'عند إيقاف تسجيل الدخول بكلمة المرور يُحوَّل الزوار فورًا إلى مزوّد الهوية. أوقف هذا الخيار لعرض صفحة تسجيل الدخول مع زر SSO أولًا.',
'admin.envOverrideHint':
'يتم التحكم في إعدادات تسجيل الدخول بكلمة المرور عبر متغير البيئة OIDC_ONLY ولا يمكن تغييرها من هنا.',
'admin.lockoutWarning': 'يجب أن تبقى طريقة تسجيل دخول واحدة على الأقل مفعّلة',
+3
View File
@@ -141,6 +141,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'İstifadəçilərə SSO ilə daxil olmağa icazə verin',
'admin.oidcRegistration': 'SSO ilə avtomatik hesab yaratma',
'admin.oidcRegistrationHint': 'Yeni SSO istifadəçiləri üçün avtomatik hesab yaradın',
'admin.oidcAutoRedirect': 'Birbaşa SSO-ya keç',
'admin.oidcAutoRedirectHint':
'Parol ilə giriş söndürüləndə ziyarətçilər dərhal kimlik provayderinə yönləndirilir. Əvvəlcə SSO düyməsi olan giriş səhifəsini göstərmək üçün bunu söndürün.',
'admin.envOverrideHint':
'Parolla giriş tənzimləmələri OIDC_ONLY mühit dəyişəni ilə idarə olunur və burada dəyişdirilə bilməz.',
'admin.lockoutWarning': 'Ən azı bir giriş üsulu aktiv qalmalıdır',
+3
View File
@@ -85,6 +85,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Permitir que os usuários entrem com SSO',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Criar contas automaticamente para novos usuários SSO',
'admin.oidcAutoRedirect': 'Ir direto para o SSO',
'admin.oidcAutoRedirectHint':
'Com o login por senha desativado, os visitantes são enviados na hora ao provedor de identidade. Desative isto para mostrar primeiro a página de login com o botão SSO.',
'admin.envOverrideHint':
'As configurações de login com senha são controladas pela variável de ambiente OIDC_ONLY e não podem ser alteradas aqui.',
'admin.lockoutWarning': 'Pelo menos um método de login deve permanecer ativado',
+3
View File
@@ -91,6 +91,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Permet que els usuaris iniciïn sessió amb SSO',
'admin.oidcRegistration': 'Aprovisionament automàtic SSO',
'admin.oidcRegistrationHint': 'Crea comptes automàticament per als nous usuaris SSO',
'admin.oidcAutoRedirect': 'Anar directament a l’SSO',
'admin.oidcAutoRedirectHint':
'Amb l’inici de sessió amb contrasenya desactivat, els visitants van directament al proveïdor d’identitat. Desactiva-ho per mostrar primer la pàgina d’inici de sessió amb el botó SSO.',
'admin.envOverrideHint':
"La configuració d'inici de sessió amb contrasenya està controlada per la variable d'entorn OIDC_ONLY i no es pot canviar aquí.",
'admin.lockoutWarning': "Almenys un mètode d'inici de sessió ha de romandre activat",
+3
View File
@@ -89,6 +89,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Povolit uživatelům přihlášení přes SSO',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Automaticky vytvářet účty pro nové uživatele SSO',
'admin.oidcAutoRedirect': 'Rovnou na SSO',
'admin.oidcAutoRedirectHint':
'Když je přihlášení heslem vypnuté, návštěvníci jsou hned přesměrováni k poskytovateli identity. Vypněte to, aby se nejdřív zobrazila přihlašovací stránka s tlačítkem SSO.',
'admin.envOverrideHint': 'Nastavení přihlášení heslem řídí proměnná prostředí OIDC_ONLY a nelze je zde změnit.',
'admin.lockoutWarning': 'Alespoň jedna metoda přihlášení musí zůstat povolená',
'admin.requireMfa': 'Vyžadovat dvoufázové ověření (2FA)',
+3
View File
@@ -86,6 +86,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Erlaube Nutzern die Anmeldung per SSO',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Konten für neue SSO-Nutzer automatisch anlegen',
'admin.oidcAutoRedirect': 'Direkt zum SSO',
'admin.oidcAutoRedirectHint':
'Ist die Passwort-Anmeldung aus, werden Besucher sofort zum Identitätsanbieter weitergeleitet. Ausschalten, um zuerst die Anmeldeseite mit dem SSO-Button zu zeigen.',
'admin.envOverrideHint':
'Die Einstellungen zur Passwort-Anmeldung werden über die Umgebungsvariable OIDC_ONLY gesteuert und lassen sich hier nicht ändern.',
'admin.lockoutWarning': 'Mindestens eine Anmeldemethode muss aktiviert bleiben',
+3
View File
@@ -137,6 +137,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Allow users to sign in with SSO',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Automatically create accounts for new SSO users',
'admin.oidcAutoRedirect': 'Go straight to SSO',
'admin.oidcAutoRedirectHint':
'With password login off, visitors are sent to the identity provider at once. Turn this off to show the login page with the SSO button first.',
'admin.envOverrideHint':
'Password login settings are controlled by the OIDC_ONLY environment variable and cannot be changed here.',
'admin.lockoutWarning': 'At least one login method must remain enabled',
+3
View File
@@ -86,6 +86,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Permite a los usuarios iniciar sesión con SSO',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Crea cuentas automáticamente para los nuevos usuarios de SSO',
'admin.oidcAutoRedirect': 'Ir directamente al SSO',
'admin.oidcAutoRedirectHint':
'Con el inicio de sesión con contraseña desactivado, los visitantes van directamente al proveedor de identidad. Desactívalo para mostrar primero la página de inicio de sesión con el botón SSO.',
'admin.envOverrideHint':
'Los ajustes del inicio de sesión con contraseña se controlan con la variable de entorno OIDC_ONLY y no se pueden cambiar aquí.',
'admin.lockoutWarning': 'Debe quedar activado al menos un método de inicio de sesión',
+3
View File
@@ -139,6 +139,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Luba kasutajatel SSO-ga sisse logida',
'admin.oidcRegistration': 'SSO kontode automaatne loomine',
'admin.oidcRegistrationHint': 'Loo uutele SSO kasutajatele kontod automaatselt',
'admin.oidcAutoRedirect': 'Otse SSO-sse',
'admin.oidcAutoRedirectHint':
'Kui parooliga sisselogimine on välja lülitatud, suunatakse külastajad kohe identiteedipakkuja juurde. Lülita see välja, et näidata esmalt SSO-nupuga sisselogimislehte.',
'admin.envOverrideHint':
'Parooliga sisselogimise seadeid juhib keskkonnamuutuja OIDC_ONLY ja neid ei saa siin muuta.',
'admin.lockoutWarning': 'Vähemalt üks sisselogimisviis peab jääma lubatuks',
+3
View File
@@ -86,6 +86,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Autoriser les utilisateurs à se connecter via SSO',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Créer automatiquement des comptes pour les nouveaux utilisateurs SSO',
'admin.oidcAutoRedirect': 'Aller directement au SSO',
'admin.oidcAutoRedirectHint':
'Quand la connexion par mot de passe est désactivée, les visiteurs sont envoyés directement au fournisseur d’identité. Désactivez cette option pour afficher d’abord la page de connexion avec le bouton SSO.',
'admin.envOverrideHint':
"Les réglages de connexion par mot de passe sont contrôlés par la variable d'environnement OIDC_ONLY et ne peuvent pas être modifiés ici.",
'admin.lockoutWarning': 'Au moins une méthode de connexion doit rester activée',
+3
View File
@@ -141,6 +141,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Επιτρέψτε στους χρήστες να συνδέονται με SSO',
'admin.oidcRegistration': 'Αυτόματη Δημιουργία SSO',
'admin.oidcRegistrationHint': 'Αυτόματη δημιουργία λογαριασμών για νέους χρήστες SSO',
'admin.oidcAutoRedirect': 'Απευθείας στο SSO',
'admin.oidcAutoRedirectHint':
'Όταν η σύνδεση με κωδικό είναι απενεργοποιημένη, οι επισκέπτες μεταφέρονται αμέσως στον πάροχο ταυτότητας. Απενεργοποιήστε το για να εμφανίζεται πρώτα η σελίδα σύνδεσης με το κουμπί SSO.',
'admin.envOverrideHint':
'Οι ρυθμίσεις σύνδεσης με κωδικό ελέγχονται από τη μεταβλητή περιβάλλοντος OIDC_ONLY και δεν μπορούν να αλλάξουν εδώ.',
'admin.lockoutWarning': 'Πρέπει να παραμείνει ενεργοποιημένη τουλάχιστον μία μέθοδος σύνδεσης',
+3
View File
@@ -139,6 +139,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'אפשרו למשתמשים להתחבר עם SSO',
'admin.oidcRegistration': 'יצירת חשבונות אוטומטית ב-SSO',
'admin.oidcRegistrationHint': 'יצירה אוטומטית של חשבונות למשתמשי SSO חדשים',
'admin.oidcAutoRedirect': 'מעבר ישיר ל-SSO',
'admin.oidcAutoRedirectHint':
'כשהתחברות עם סיסמה כבויה, המבקרים מועברים מיד לספק הזהות. כבו את האפשרות כדי להציג קודם את דף ההתחברות עם כפתור ה-SSO.',
'admin.envOverrideHint': 'הגדרות ההתחברות בסיסמה נשלטות על ידי משתנה הסביבה OIDC_ONLY ולא ניתן לשנות אותן כאן.',
'admin.lockoutWarning': 'לפחות שיטת התחברות אחת חייבת להישאר מופעלת',
'admin.requireMfa': 'חיוב אימות דו-שלבי (2FA)',
+3
View File
@@ -85,6 +85,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'A felhasználók SSO-val jelentkezhetnek be',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Fiók automatikus létrehozása az új SSO-felhasználóknak',
'admin.oidcAutoRedirect': 'Közvetlenül az SSO-ra',
'admin.oidcAutoRedirectHint':
'Ha a jelszavas bejelentkezés ki van kapcsolva, a látogatók azonnal az identitásszolgáltatóhoz kerülnek. Kapcsold ki, hogy előbb a bejelentkezési oldal jelenjen meg az SSO gombbal.',
'admin.envOverrideHint':
'A jelszavas bejelentkezés beállításait az OIDC_ONLY környezeti változó vezérli, itt nem módosíthatók.',
'admin.lockoutWarning': 'Legalább egy bejelentkezési módnak engedélyezve kell maradnia',
+3
View File
@@ -133,6 +133,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Izinkan pengguna masuk dengan SSO',
'admin.oidcRegistration': 'Penyediaan Otomatis SSO',
'admin.oidcRegistrationHint': 'Buat akun otomatis untuk pengguna SSO baru',
'admin.oidcAutoRedirect': 'Langsung ke SSO',
'admin.oidcAutoRedirectHint':
'Saat login dengan kata sandi nonaktif, pengunjung langsung diarahkan ke penyedia identitas. Matikan ini untuk menampilkan halaman login dengan tombol SSO terlebih dahulu.',
'admin.envOverrideHint':
'Pengaturan login kata sandi dikendalikan oleh variabel lingkungan OIDC_ONLY dan tidak dapat diubah di sini.',
'admin.lockoutWarning': 'Minimal satu metode login harus tetap aktif',
+3
View File
@@ -85,6 +85,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Consenti agli utenti di accedere con SSO',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Crea automaticamente gli account per i nuovi utenti SSO',
'admin.oidcAutoRedirect': 'Vai direttamente all’SSO',
'admin.oidcAutoRedirectHint':
'Con l’accesso tramite password disattivato, i visitatori vengono inviati subito al provider di identità. Disattiva questa opzione per mostrare prima la pagina di accesso con il pulsante SSO.',
'admin.envOverrideHint':
"Le impostazioni di accesso con password sono controllate dalla variabile d'ambiente OIDC_ONLY e non possono essere modificate qui.",
'admin.lockoutWarning': 'Deve restare attivo almeno un metodo di accesso',
+3
View File
@@ -127,6 +127,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'SSOでのログインを許可',
'admin.oidcRegistration': 'SSO自動登録',
'admin.oidcRegistrationHint': '新しいSSOユーザーを自動作成',
'admin.oidcAutoRedirect': 'SSO に直接移動',
'admin.oidcAutoRedirectHint':
'パスワードログインがオフのとき、訪問者はすぐに ID プロバイダーへ移動します。オフにすると、先に SSO ボタン付きのログインページを表示します。',
'admin.envOverrideHint': 'パスワードログイン設定は OIDC_ONLY 環境変数で制御されています。',
'admin.lockoutWarning': '少なくとも1つのログイン方法を有効にしてください',
'admin.requireMfa': '二要素認証(2FA)を必須にする',
+3
View File
@@ -132,6 +132,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': '사용자가 SSO로 로그인할 수 있습니다',
'admin.oidcRegistration': 'SSO 자동 프로비저닝',
'admin.oidcRegistrationHint': '새 SSO 사용자의 계정을 자동으로 생성합니다',
'admin.oidcAutoRedirect': 'SSO로 바로 이동',
'admin.oidcAutoRedirectHint':
'비밀번호 로그인이 꺼져 있으면 방문자는 바로 ID 공급자로 이동합니다. 끄면 SSO 버튼이 있는 로그인 페이지를 먼저 보여 줍니다.',
'admin.envOverrideHint': '비밀번호 로그인 설정은 OIDC_ONLY 환경 변수로 제어되며 여기서 변경할 수 없습니다.',
'admin.lockoutWarning': '최소 하나의 로그인 방법이 활성화되어 있어야 합니다',
'admin.requireMfa': '2단계 인증 (2FA) 요구',
+3
View File
@@ -86,6 +86,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Gebruikers toestaan om in te loggen via SSO',
'admin.oidcRegistration': 'Automatische SSO-provisioning',
'admin.oidcRegistrationHint': 'Automatisch accounts aanmaken voor nieuwe SSO-gebruikers',
'admin.oidcAutoRedirect': 'Direct naar SSO',
'admin.oidcAutoRedirectHint':
'Als inloggen met een wachtwoord uit staat, gaan bezoekers meteen naar de identiteitsprovider. Zet dit uit om eerst de inlogpagina met de SSO-knop te tonen.',
'admin.envOverrideHint':
'De instellingen voor inloggen met wachtwoord worden beheerd via de omgevingsvariabele OIDC_ONLY en kunnen hier niet worden gewijzigd.',
'admin.lockoutWarning': 'Er moet minstens één inlogmethode ingeschakeld blijven',
+3
View File
@@ -84,6 +84,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Zezwalaj użytkownikom na logowanie przez SSO',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Automatycznie twórz konta dla nowych użytkowników SSO',
'admin.oidcAutoRedirect': 'Od razu do SSO',
'admin.oidcAutoRedirectHint':
'Gdy logowanie hasłem jest wyłączone, odwiedzający od razu trafiają do dostawcy tożsamości. Wyłącz to, aby najpierw pokazać stronę logowania z przyciskiem SSO.',
'admin.envOverrideHint':
'Ustawienia logowania hasłem są kontrolowane przez zmienną środowiskową OIDC_ONLY i nie można ich tu zmienić.',
'admin.lockoutWarning': 'Co najmniej jedna metoda logowania musi pozostać włączona',
+3
View File
@@ -94,6 +94,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Разрешить пользователям входить через SSO',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': 'Автоматически создавать учётные записи для новых пользователей SSO',
'admin.oidcAutoRedirect': 'Сразу к SSO',
'admin.oidcAutoRedirectHint':
'Когда вход по паролю выключен, посетители сразу попадают к провайдеру удостоверений. Выключите это, чтобы сначала показывать страницу входа с кнопкой SSO.',
'admin.envOverrideHint':
'Настройки входа по паролю управляются переменной окружения OIDC_ONLY и не могут быть изменены здесь.',
'admin.lockoutWarning': 'Должен оставаться включённым хотя бы один способ входа',
+3
View File
@@ -141,6 +141,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Umožniť používateľom prihlásiť sa cez SSO',
'admin.oidcRegistration': 'Automatické vytváranie účtov SSO',
'admin.oidcRegistrationHint': 'Automaticky vytvárať účty pre nových používateľov SSO',
'admin.oidcAutoRedirect': 'Rovno na SSO',
'admin.oidcAutoRedirectHint':
'Keď je prihlásenie heslom vypnuté, návštevníci sú hneď presmerovaní k poskytovateľovi identity. Vypnite to, aby sa najprv zobrazila prihlasovacia stránka s tlačidlom SSO.',
'admin.envOverrideHint': 'Nastavenia prihlásenia heslom riadi premenná prostredia OIDC_ONLY a nedajú sa tu zmeniť.',
'admin.lockoutWarning': 'Aspoň jedna metóda prihlásenia musí zostať zapnutá',
'admin.requireMfa': 'Vyžadovať dvojfaktorové overenie (2FA)',
+3
View File
@@ -138,6 +138,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Låt användarna logga in med SSO',
'admin.oidcRegistration': 'SSO Automatisk konfigurering',
'admin.oidcRegistrationHint': 'Skapa konton automatiskt för nya SSO-användare',
'admin.oidcAutoRedirect': 'Direkt till SSO',
'admin.oidcAutoRedirectHint':
'När inloggning med lösenord är av skickas besökare direkt till identitetsleverantören. Stäng av detta för att först visa inloggningssidan med SSO-knappen.',
'admin.envOverrideHint':
'Inställningarna för inloggning med lösenord styrs av miljövariabeln OIDC_ONLY och kan inte ändras här.',
'admin.lockoutWarning': 'Minst en inloggningsmetod måste vara aktiverad',
+3
View File
@@ -133,6 +133,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'อนุญาตให้ผู้ใช้ลงชื่อเข้าใช้ด้วย SSO',
'admin.oidcRegistration': 'การจัดสรร SSO อัตโนมัติ',
'admin.oidcRegistrationHint': 'สร้างบัญชีสำหรับผู้ใช้ SSO ใหม่โดยอัตโนมัติ',
'admin.oidcAutoRedirect': 'ไปที่ SSO โดยตรง',
'admin.oidcAutoRedirectHint':
'เมื่อปิดการเข้าสู่ระบบด้วยรหัสผ่าน ผู้เยี่ยมชมจะถูกส่งไปยังผู้ให้บริการข้อมูลประจำตัวทันที ปิดตัวเลือกนี้เพื่อแสดงหน้าเข้าสู่ระบบพร้อมปุ่ม SSO ก่อน',
'admin.envOverrideHint':
'การตั้งค่าการเข้าสู่ระบบด้วยรหัสผ่านได้รับการควบคุมโดยตัวแปรสภาพแวดล้อม OIDC_ONLY และไม่สามารถเปลี่ยนแปลงได้ที่นี่',
'admin.lockoutWarning': 'ต้องเปิดใช้งานวิธีการเข้าสู่ระบบอย่างน้อยหนึ่งวิธี',
+3
View File
@@ -138,6 +138,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Kullanıcıların SSO ile oturum açmasına izin Ver',
'admin.oidcRegistration': 'SSO Otomatik Temel Hazırlığı',
'admin.oidcRegistrationHint': 'Yeni SSO kullanıcıları için otomatik olarak hesap oluşturun',
'admin.oidcAutoRedirect': 'Doğrudan SSO’ya git',
'admin.oidcAutoRedirectHint':
'Parolayla giriş kapalıyken ziyaretçiler hemen kimlik sağlayıcısına yönlendirilir. Önce SSO düğmeli giriş sayfasını göstermek için bunu kapat.',
'admin.envOverrideHint':
'Şifre oturum açma ayarları OIDC_ONLY ortam değişkeni tarafından kontrol edilir ve burada değiştirilemez.',
'admin.lockoutWarning': 'En az bir oturum açma yöntemi etkin kalmalıdır',
+3
View File
@@ -94,6 +94,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Дозволити користувачам входити через SSO',
'admin.oidcRegistration': 'Автоматичне створення SSO-акаунтів',
'admin.oidcRegistrationHint': 'Автоматично створювати акаунти для нових SSO-користувачів',
'admin.oidcAutoRedirect': 'Одразу до SSO',
'admin.oidcAutoRedirectHint':
'Коли вхід за паролем вимкнено, відвідувачі одразу потрапляють до постачальника ідентичності. Вимкніть це, щоб спершу показувати сторінку входу з кнопкою SSO.',
'admin.envOverrideHint':
'Налаштування входу за паролем контролюються змінною середовища OIDC_ONLY і не можуть бути змінені тут.',
'admin.lockoutWarning': 'Потрібно залишити увімкненим принаймні один метод входу',
+3
View File
@@ -134,6 +134,9 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': 'Cho phép người dùng đăng nhập bằng SSO',
'admin.oidcRegistration': 'SSO Tự động cấp phép',
'admin.oidcRegistrationHint': 'Tự động tạo tài khoản cho người dùng SSO mới',
'admin.oidcAutoRedirect': 'Chuyển thẳng đến SSO',
'admin.oidcAutoRedirectHint':
'Khi tắt đăng nhập bằng mật khẩu, khách truy cập được chuyển ngay đến nhà cung cấp danh tính. Tắt tùy chọn này để hiển thị trang đăng nhập có nút SSO trước.',
'admin.envOverrideHint':
'Cài đặt đăng nhập mật khẩu được kiểm soát bởi biến môi trường OIDC_ONLY và không thể thay đổi tại đây.',
'admin.lockoutWarning': 'Ít nhất một phương thức đăng nhập phải được bật',
+2
View File
@@ -130,6 +130,8 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': '允許使用者透過 SSO 登入',
'admin.oidcRegistration': 'SSO Auto-Provisioning',
'admin.oidcRegistrationHint': '自動為新的 SSO 使用者建立帳號',
'admin.oidcAutoRedirect': '直接前往 SSO',
'admin.oidcAutoRedirectHint': '關閉密碼登入後,訪客會被直接帶到身分提供者。關閉此項可先顯示含有 SSO 按鈕的登入頁面。',
'admin.envOverrideHint': '密碼登入設定由環境變數 OIDC_ONLY 控制,無法在此變更。',
'admin.lockoutWarning': '至少須保留一種登入方式',
'admin.requireMfa': '要求雙因素身份驗證(2FA)',
+2
View File
@@ -82,6 +82,8 @@ const admin: TranslationStrings = {
'admin.oidcLoginHint': '允许用户通过 SSO 登录',
'admin.oidcRegistration': 'SSO 自动创建账户',
'admin.oidcRegistrationHint': '为首次通过 SSO 登录的用户自动创建账户',
'admin.oidcAutoRedirect': '直接跳转到 SSO',
'admin.oidcAutoRedirectHint': '关闭密码登录后,访客会被直接带到身份提供商。关闭此项可先显示带有 SSO 按钮的登录页。',
'admin.envOverrideHint': '密码登录设置由 OIDC_ONLY 环境变量控制,无法在此处修改。',
'admin.lockoutWarning': '至少需要保留一种登录方式',
'admin.requireMfa': '要求双因素身份验证(2FA)',
+2 -1
View File
@@ -16,8 +16,9 @@ Decides which ways in are offered on the login page.
| **Password Registration** | Allow new users to register with email and password. | On |
| **SSO Login** | Allow users to sign in with SSO. | On |
| **SSO Auto-Provisioning** | Automatically create accounts for new SSO users. | On |
| **Go straight to SSO** | With password login off, send visitors to the identity provider at once. Off shows the login page with its SSO button first. | On |
The two SSO rows only appear once OIDC is configured, that is, once an issuer and a client ID are known (from the **Single Sign-On (OIDC)** card or from the environment).
The three SSO rows only appear once OIDC is configured, that is, once an issuer and a client ID are known (from the **Single Sign-On (OIDC)** card or from the environment).
At least one login method must stay enabled. The switch that would remove the last way in is greyed out, and hovering it shows **At least one login method must remain enabled**. The server enforces the same rule: password login can only be switched off while SSO login is on and OIDC is configured.
+1 -1
View File
@@ -113,7 +113,7 @@ If the admin has configured OpenID Connect, a **"Sign in with SSO"** button (lab
If the identity provider's answer cannot be used, the login page shows why: registration is disabled for this instance, the provider sent no email address, the provider has not confirmed the email address so it cannot be linked to an existing account, or the sign-in could not be linked to the existing account with that email and your administrator has to confirm the address.
When OIDC-only mode is active (password login disabled), visiting `/login` automatically redirects the browser to the identity provider. The page only says where it is going ("Taking you to Keycloak…", with the configured display name) and offers nothing to fill in; should the redirect not have happened after eight seconds, a link to continue appears. The email/password form is never shown, not even while the page is still asking the server which sign-in it offers: until the answer arrives it shows a short wait, and on a repeat visit it announces the redirect straight away. The automatic redirect is suppressed when you have explicitly logged out, after a failed sign-in at the identity provider, and when the server could not be reached; the SSO button is shown instead so you can choose to sign back in.
When OIDC-only mode is active (password login disabled), visiting `/login` automatically redirects the browser to the identity provider. The page only says where it is going ("Taking you to Keycloak…", with the configured display name) and offers nothing to fill in; should the redirect not have happened after eight seconds, a link to continue appears. The email/password form is never shown, not even while the page is still asking the server which sign-in it offers: until the answer arrives it shows a short wait, and on a repeat visit it announces the redirect straight away. The automatic redirect is suppressed when you have explicitly logged out, after a failed sign-in at the identity provider, and when the server could not be reached; the SSO button is shown instead so you can choose to sign back in. An admin who wants visitors to see the login page first, with that SSO button, switches off **Go straight to SSO** under [Admin-Settings](Admin-Settings); the page then never leaves for the identity provider by itself.
---