login improvements

This commit is contained in:
2026-03-06 21:59:41 +01:00
parent dc6c135473
commit 5fb89485f4
14 changed files with 616 additions and 76 deletions

View File

@@ -36,8 +36,5 @@ $errorNoticeId = !empty($errors) ? 'auth-forgot-error-notice' : '';
<button type="submit"><?php e(t('Send code')); ?></button>
<?php Session::getCsrfInput(); ?>
</form>
<hr>
<p class="text-align-center">
<a href="<?php e(lurl('login')); ?>"><?php e(t('Back to Login')); ?></a>
</p>
<?php require templatePath('partials/auth-help-links.phtml'); ?>
</article>

View File

@@ -24,6 +24,15 @@ $selectedTenantId = (int) ($selectedTenantId ?? 0);
$selectedTenant = is_array($selectedTenant ?? null) ? $selectedTenant : null;
$selectedTenantMethods = is_array($selectedTenantMethods ?? null) ? $selectedTenantMethods : ['local' => false, 'microsoft' => false];
$selectedTenantSlug = (string) ($selectedTenant['slug'] ?? '');
$selectedTenantLabel = trim((string) ($selectedTenant['description'] ?? ''));
if ($selectedTenantLabel === '') {
$selectedTenantLabel = t('Select tenant');
}
$selectedTenantAvatarUrl = (string) ($selectedTenant['avatar_url'] ?? '');
$selectedTenantInitial = strtoupper(substr($selectedTenantLabel, 0, 1));
if ($selectedTenantInitial === '') {
$selectedTenantInitial = '?';
}
$errors = is_array($errors ?? null) ? $errors : [];
$errorNoticeId = $errors ? 'auth-login-error-notice' : '';
$loginHeading = t('Login');
@@ -38,15 +47,17 @@ if ($stage === 'resolve_email') {
$loginHeading = t('Login options');
$loginSubheading = t('Choose how you want to sign in');
}
?>
<article>
<article class="login-card">
<header>
<hgroup>
<h1><?php e($loginHeading); ?></h1>
<p><?php e($loginSubheading); ?></p>
</hgroup>
</header>
<?php if ($errors): ?>
<div id="<?php e($errorNoticeId); ?>" class="notice" data-variant="error" role="alert" aria-live="assertive" tabindex="-1">
<ul>
@@ -58,7 +69,7 @@ if ($stage === 'resolve_email') {
<?php endif; ?>
<?php if ($stage === 'resolve_email'): ?>
<form method="post">
<form method="post" data-login-submit-lock="1">
<input type="hidden" name="stage" value="resolve_email">
<input type="hidden" name="tenant_hint" value="<?php e($tenantHint); ?>">
<label for="email">
@@ -71,12 +82,12 @@ if ($stage === 'resolve_email') {
<?php Session::getCsrfInput(); ?>
</form>
<?php elseif ($stage === 'choose_tenant'): ?>
<form method="post" class="login-tenant-select-form">
<form method="post" class="login-tenant-select-form" data-login-submit-lock="1">
<input type="hidden" name="stage" value="choose_tenant">
<input type="hidden" name="email" value="<?php e($email); ?>">
<input type="hidden" name="tenant_hint" value="<?php e($tenantHint); ?>">
<fieldset class="login-tenant-fieldset">
<legend class="login-tenant-select-label"><?php e(t('Which tenant do you want to sign in to?')); ?></legend>
<!-- <legend class="login-tenant-select-label"><?php e(t('Which tenant do you want to sign in to?')); ?></legend> -->
<div class="login-tenant-choice-grid">
<?php foreach ($tenantCandidates as $tenantCandidate): ?>
<?php
@@ -116,49 +127,68 @@ if ($stage === 'resolve_email') {
<form method="post">
<input type="hidden" name="stage" value="reset">
<p>
<button type="submit" class="secondary outline"><?php e(t('Back')); ?></button>
<button type="submit" class="secondary outline"><?php e(t('Use different email')); ?></button>
</p>
<?php Session::getCsrfInput(); ?>
</form>
<?php else: ?>
<?php if (!empty($selectedTenantMethods['local'])): ?>
<form method="post">
<input type="hidden" name="stage" value="login_password">
<section class="login-tenant-context" role="status" aria-live="polite">
<div class="login-tenant-context-main">
<?php if ($selectedTenantAvatarUrl !== ''): ?>
<img class="login-tenant-context-avatar" src="<?php e($selectedTenantAvatarUrl); ?>" alt="" loading="lazy">
<?php else: ?>
<span class="login-tenant-context-avatar-placeholder"><?php e($selectedTenantInitial); ?></span>
<?php endif; ?>
<div class="login-tenant-context-text">
<p class="login-tenant-context-name"><?php e($selectedTenantLabel); ?></p>
</div>
</div>
<form method="post" class="login-tenant-context-form">
<input type="hidden" name="stage" value="resolve_email">
<input type="hidden" name="email" value="<?php e($email); ?>">
<input type="hidden" name="tenant_hint" value="<?php e($tenantHint); ?>">
<input type="hidden" name="tenant_id" value="<?php e((string) $selectedTenantId); ?>">
<label for="password">
<span><?php e(t('Password')); ?></span>
<input required type="password" name="password" id="password" autocomplete="current-password" <?php if ($errors): ?>aria-invalid="true" aria-describedby="<?php e($errorNoticeId); ?>"<?php endif; ?> />
</label>
<p>
<label class="app-field inline">
<input type="checkbox" name="remember" value="1">
<span><?php e(t('Remember me')); ?></span>
</label>
</p>
<p>
<button type="submit"><?php e(t('Login')); ?></button>
</p>
<p>
<a href="<?php e(lurl('password/forgot')); ?>"><?php e(t('Forgot password')); ?>?</a>
</p>
<button type="submit" class="secondary outline"><?php e(t('Switch tenant')); ?></button>
<?php Session::getCsrfInput(); ?>
</form>
<?php endif; ?>
</section>
<?php if (!empty($selectedTenantMethods['local']) && !empty($selectedTenantMethods['microsoft'])): ?>
<div class="login-alt-separator" aria-hidden="true">
<span><?php e(t('Or')); ?></span>
</div>
<?php endif; ?>
<div class="login-methods-stack">
<?php if (!empty($selectedTenantMethods['microsoft']) && $selectedTenantSlug !== ''): ?>
<a class="primary login-microsoft-link"
href="<?php e(lurl('auth/microsoft/start?tenant=' . rawurlencode($selectedTenantSlug))); ?>">
<i class="bi bi-microsoft" aria-hidden="true"></i> <?php e(t('Sign in with Microsoft')); ?>
</a>
<?php endif; ?>
<?php if (!empty($selectedTenantMethods['microsoft']) && $selectedTenantSlug !== ''): ?>
<a class="primary login-microsoft-link"
href="<?php e(lurl('auth/microsoft/start?tenant=' . rawurlencode($selectedTenantSlug))); ?>">
<i class="bi bi-microsoft" aria-hidden="true"></i> <?php e(t('Sign in with Microsoft')); ?>
</a>
<?php endif; ?>
<?php if (!empty($selectedTenantMethods['local']) && !empty($selectedTenantMethods['microsoft'])): ?>
<div class="login-alt-separator" aria-hidden="true">
<span><?php e(t('Or')); ?></span>
</div>
<?php endif; ?>
<?php if (!empty($selectedTenantMethods['local'])): ?>
<form method="post" class="login-password-form" data-login-submit-lock="1">
<input type="hidden" name="stage" value="login_password">
<input type="hidden" name="email" value="<?php e($email); ?>">
<input type="hidden" name="tenant_hint" value="<?php e($tenantHint); ?>">
<input type="hidden" name="tenant_id" value="<?php e((string) $selectedTenantId); ?>">
<label for="password">
<span><?php e(t('Password')); ?></span>
<input required type="password" name="password" id="password" autocomplete="current-password" <?php if ($errors): ?>aria-invalid="true" aria-describedby="<?php e($errorNoticeId); ?>"<?php endif; ?> />
</label>
<p>
<label class="app-field inline">
<input type="checkbox" name="remember" value="1">
<span><?php e(t('Remember me')); ?></span>
</label>
</p>
<p>
<button type="submit"><?php e(t('Login')); ?></button>
</p>
<?php Session::getCsrfInput(); ?>
</form>
<?php endif; ?>
</div>
<?php if (empty($selectedTenantMethods['local']) && empty($selectedTenantMethods['microsoft'])): ?>
<div class="notice" data-variant="warning" role="status" aria-live="polite">
@@ -171,14 +201,17 @@ if ($stage === 'resolve_email') {
<input type="hidden" name="email" value="<?php e($email); ?>">
<input type="hidden" name="tenant_hint" value="<?php e($tenantHint); ?>">
<p>
<button type="submit" class="secondary outline"><?php e(t('Back')); ?></button>
<button type="submit" class="secondary outline"><?php e(t('Use different email')); ?></button>
</p>
<?php Session::getCsrfInput(); ?>
</form>
<?php endif; ?>
<?php if (allowRegistration()): ?>
<hr>
<p class="text-align-center"><?php e(t('No account yet')); ?>? <a href="<?php e(lurl('register')); ?>"><?php e(t('Register')); ?></a></p>
<?php endif; ?>
<?php require templatePath('partials/auth-help-links.phtml'); ?>
<hr>
<p class="login-security-note">
<i class="bi bi-lock-fill" aria-hidden="true"></i>
<span><?php e(t('Encrypted connection')); ?></span>
</p>
<small class="login-security-note-detail muted"><?php e(t('HTTPS/TLS 1.2+ in transit')); ?></small>
</article>

View File

@@ -18,8 +18,6 @@ $passwordHints = is_array($passwordHints ?? null) ? $passwordHints : [];
$errorNoticeId = !empty($error) ? 'auth-register-error-notice' : '';
$passwordHintId = 'auth-register-password-hints';
?>
<a class="back_to_login small secondary outline" href="<?php e(lurl('login')); ?>"><i
class="bi bi-arrow-left" aria-hidden="true"></i> <?php e(t('Back to Login')); ?></a>
<article>
<header>
<hgroup>
@@ -75,4 +73,5 @@ $passwordHintId = 'auth-register-password-hints';
<?php endif; ?>
<?php Session::getCsrfInput(); ?>
</form>
<?php require templatePath('partials/auth-help-links.phtml'); ?>
</article>

View File

@@ -65,8 +65,5 @@ $passwordHintId = 'auth-reset-password-hints';
<button type="submit"><?php e(t('Reset password')); ?></button>
<?php Session::getCsrfInput(); ?>
</form>
<hr>
<p class="text-align-center">
<a href="<?php e(lurl('login')); ?>"><?php e(t('Back to Login')); ?></a>
</p>
<?php require templatePath('partials/auth-help-links.phtml'); ?>
</article>

View File

@@ -42,10 +42,5 @@ $errorNoticeId = !empty($errors) ? 'auth-verify-error-notice' : '';
<button type="submit"><?php e(t('Verify')); ?></button>
<?php Session::getCsrfInput(); ?>
</form>
<hr>
<p class="text-align-center">
<a href="<?php e(lurl('password/forgot')); ?>"><?php e(t('Send code again')); ?></a>
&nbsp;·&nbsp;
<a href="<?php e(lurl('login')); ?>"><?php e(t('Back to Login')); ?></a>
</p>
<?php require templatePath('partials/auth-help-links.phtml'); ?>
</article>

View File

@@ -49,7 +49,5 @@ $errorNoticeId = !empty($errors) ? 'auth-verify-email-error-notice' : '';
<?php Session::getCsrfInput(); ?>
<button type="submit" class="secondary outline"><?php e(t('Send code again')); ?></button>
</form>
<p class="text-align-center login-secondary-action">
<a href="<?php e(lurl('login')); ?>"><?php e(t('Back to Login')); ?></a>
</p>
<?php require templatePath('partials/auth-help-links.phtml'); ?>
</article>