Fix: Add OIDC/SSO login button and hide password form when OIDC-only

- Added SSO login button on login page that appears when OIDC is configured
- Button shows provider name (e.g. 'Sign in with Authentik')
- When 'Disable password login' is enabled, hides password form and
  shows only the SSO button
- Added auth divider between password and SSO sections
- Added i18n keys (or, sso_login, sso_login_provider) for all 8 locales
- Fixed missing comma in it.json locale file

Fixes #88, Fixes #89
This commit is contained in:
Dionisio
2026-02-13 19:59:13 +01:00
parent c2c9bb700d
commit 53625776cb
11 changed files with 139 additions and 9 deletions
+44
View File
@@ -126,6 +126,50 @@
cursor: not-allowed;
}
/* SSO / OIDC button */
.auth-button-oidc {
background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%);
box-shadow: 0 4px 12px rgba(45, 55, 72, 0.3);
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.auth-button-oidc:hover {
box-shadow: 0 6px 20px rgba(45, 55, 72, 0.4);
}
.auth-button-oidc i {
font-size: 14px;
}
/* Divider between password and SSO login */
.auth-divider {
display: flex;
align-items: center;
margin: 20px 0;
color: #a0aec0;
font-size: 13px;
}
.auth-divider::before,
.auth-divider::after {
content: '';
flex: 1;
height: 1px;
background: #e2e8f0;
}
.auth-divider span {
padding: 0 12px;
}
/* OIDC-only mode: hide password form */
.auth-form.hidden {
display: none;
}
.auth-toggle {
margin-top: 20px;
font-size: 14px;
+51
View File
@@ -282,6 +282,8 @@ function initLanguageSelector() {
}
} else {
document.getElementById('login-panel').style.display = 'block';
// Configure OIDC login UI if SSO is enabled
await configureOidcLoginUI();
}
// Translate the page with new locale
@@ -358,6 +360,55 @@ async function showInitialPanel() {
if (showAdminSetupLink && systemStatus.admin_count > 0) {
showAdminSetupLink.parentElement.style.display = 'none';
}
// Check for OIDC/SSO configuration and update login panel accordingly
await configureOidcLoginUI();
}
// Fetch OIDC provider info and configure the login UI
async function configureOidcLoginUI() {
try {
const response = await fetch('/api/auth/oidc/providers');
if (!response.ok) return;
const oidcInfo = await response.json();
if (!oidcInfo.enabled) return;
const oidcSection = document.getElementById('oidc-login-section');
const oidcBtn = document.getElementById('oidc-login-btn');
const loginForm = document.getElementById('login-form');
const authDivider = document.getElementById('auth-divider');
const showRegisterToggle = document.getElementById('show-register');
if (!oidcSection || !oidcBtn) return;
// Update button text with provider name
const btnTextEl = oidcBtn.querySelector('span');
if (btnTextEl && oidcInfo.provider_name) {
const template = (window.i18n && window.i18n.t)
? window.i18n.t('auth.sso_login_provider')
: 'Sign in with {{provider}}';
btnTextEl.textContent = template.replace('{{provider}}', oidcInfo.provider_name);
}
// Redirect to OIDC authorize endpoint on click
oidcBtn.addEventListener('click', () => {
window.location.href = oidcInfo.authorize_endpoint;
});
if (!oidcInfo.password_login_enabled) {
// OIDC-only mode: hide password form and divider, show only SSO button
if (loginForm) loginForm.style.display = 'none';
if (authDivider) authDivider.style.display = 'none';
if (showRegisterToggle) showRegisterToggle.parentElement.style.display = 'none';
oidcSection.style.display = 'block';
} else {
// Both password and OIDC enabled: show divider + SSO button
oidcSection.style.display = 'block';
}
} catch (err) {
console.error('Failed to fetch OIDC provider info:', err);
}
}
// DOM elements
+4 -1
View File
@@ -283,7 +283,10 @@
"admin_success": "Administratorkonto erfolgreich erstellt! Sie können sich jetzt anmelden.",
"account_success": "Konto erfolgreich erstellt! Sie können sich jetzt anmelden.",
"passwords_mismatch": "Die Passwörter stimmen nicht überein",
"admin_create_error": "Fehler beim Erstellen des Administratorkontos"
"admin_create_error": "Fehler beim Erstellen des Administratorkontos",
"or": "oder",
"sso_login": "Mit SSO anmelden",
"sso_login_provider": "Mit {{provider}} anmelden"
},
"storage": {
"title": "Speicher",
+4 -1
View File
@@ -283,7 +283,10 @@
"admin_success": "Administrator account created successfully! You can now sign in.",
"account_success": "Account created successfully! You can now sign in.",
"passwords_mismatch": "Passwords do not match",
"admin_create_error": "Error creating administrator account"
"admin_create_error": "Error creating administrator account",
"or": "or",
"sso_login": "Sign in with SSO",
"sso_login_provider": "Sign in with {{provider}}"
},
"storage": {
"title": "Storage",
+4 -1
View File
@@ -283,7 +283,10 @@
"admin_success": "¡Cuenta de administrador creada con éxito! Ahora puedes iniciar sesión.",
"account_success": "¡Cuenta creada con éxito! Ahora puedes iniciar sesión.",
"passwords_mismatch": "Las contraseñas no coinciden",
"admin_create_error": "Error al crear cuenta de administrador"
"admin_create_error": "Error al crear cuenta de administrador",
"or": "o",
"sso_login": "Iniciar sesión con SSO",
"sso_login_provider": "Iniciar sesión con {{provider}}"
},
"storage": {
"title": "Almacenamiento",
+4 -1
View File
@@ -269,7 +269,10 @@
"admin_success": "حساب کاربری مدیر با موفقیت ایجاد شد! اکنون می‌توانید وارد شوید.",
"account_success": "حساب کاربری با موفقیت ایجاد شد! اکنون می‌توانید وارد شوید.",
"passwords_mismatch": "گذرواژه‌ها مطابقت ندارند",
"admin_create_error": "خطا در ایجاد حساب کاربری مدیر"
"admin_create_error": "خطا در ایجاد حساب کاربری مدیر",
"or": "یا",
"sso_login": "ورود با SSO",
"sso_login_provider": "ورود با {{provider}}"
},
"storage": {
"title": "فضای ذخیره‌سازی",
+4 -1
View File
@@ -283,7 +283,10 @@
"admin_success": "Compte administrateur créé avec succès ! Vous pouvez maintenant vous connecter.",
"account_success": "Compte créé avec succès ! Vous pouvez maintenant vous connecter.",
"passwords_mismatch": "Les mots de passe ne correspondent pas",
"admin_create_error": "Erreur lors de la création du compte administrateur"
"admin_create_error": "Erreur lors de la création du compte administrateur",
"or": "ou",
"sso_login": "Se connecter avec SSO",
"sso_login_provider": "Se connecter avec {{provider}}"
},
"storage": {
"title": "Stockage",
+5 -2
View File
@@ -283,7 +283,10 @@
"admin_success": "Account amministratore creato con successo! Ora puoi accedere.",
"account_success": "Account creato con successo! Ora puoi accedere.",
"passwords_mismatch": "Le password non corrispondono",
"admin_create_error": "Errore durante la creazione dell'account amministratore"
"admin_create_error": "Errore durante la creazione dell'account amministratore",
"or": "o",
"sso_login": "Accedi con SSO",
"sso_login_provider": "Accedi con {{provider}}"
},
"storage": {
"title": "Archiviazione",
@@ -308,7 +311,7 @@
"fa": "Persiano",
"fr": "Francese",
"de": "Tedesco",
"pt": "Portoghese"
"pt": "Portoghese",
"it": "Italiano"
}
},
+4 -1
View File
@@ -283,7 +283,10 @@
"admin_success": "Conta de administrador criada com sucesso! Agora você pode entrar.",
"account_success": "Conta criada com sucesso! Agora você pode entrar.",
"passwords_mismatch": "As senhas não coincidem",
"admin_create_error": "Erro ao criar conta de administrador"
"admin_create_error": "Erro ao criar conta de administrador",
"or": "ou",
"sso_login": "Entrar com SSO",
"sso_login_provider": "Entrar com {{provider}}"
},
"storage": {
"title": "Armazenamento",
+4 -1
View File
@@ -231,7 +231,10 @@
"admin_success": "管理员账号创建成功!您现在可以登录。",
"account_success": "账号创建成功!您现在可以登录。",
"passwords_mismatch": "密码不匹配",
"admin_create_error": "创建管理员账号时出错"
"admin_create_error": "创建管理员账号时出错",
"or": "或",
"sso_login": "使用 SSO 登录",
"sso_login_provider": "使用 {{provider}} 登录"
},
"storage": {
"title": "存储空间",
+11
View File
@@ -94,6 +94,17 @@
<button type="submit" class="auth-button" data-i18n="auth.login_button">Log in</button>
</form>
<!-- SSO / OIDC login section (hidden by default, shown dynamically) -->
<div id="oidc-login-section" style="display: none;">
<div class="auth-divider" id="auth-divider">
<span data-i18n="auth.or">or</span>
</div>
<button type="button" class="auth-button auth-button-oidc" id="oidc-login-btn">
<i class="fas fa-key"></i>
<span data-i18n="auth.sso_login">Sign in with SSO</span>
</button>
</div>
<div class="auth-toggle">
<span data-i18n="auth.no_account">Don't have an account?</span>
<span class="auth-toggle-link" id="show-register" data-i18n="auth.register">Sign up</span>