Files
PassKeeper/app/templates/auth/login.html
T

129 lines
3.9 KiB
HTML

{% extends "base.html" %} {% block title %}Sign In — PassKeeper{% endblock %} {%
block body_class %}auth-page{% endblock %} {% block body %}
<div class="auth-container">
<div class="auth-card">
<div class="auth-logo">
<span class="logo-icon">🔒</span>
<span class="logo-text">PassKeeper</span>
</div>
<p id="register-notice" class="notice-success hidden">
Account created! Please sign in.
</p>
<!-- Step 1: Email + Master Password -->
<div id="login-step-1">
<h1 class="auth-title">Sign in</h1>
<form id="login-form" novalidate>
<div class="form-group">
<label for="email">Email address</label>
<input
type="email"
id="email"
name="email"
required
autocomplete="email"
placeholder="you@example.com"
/>
</div>
<div class="form-group">
<label for="password">Master password</label>
<div class="input-with-toggle">
<input
type="password"
id="password"
name="password"
required
autocomplete="current-password"
placeholder="Enter master password"
/>
<button
type="button"
class="btn-show-pass"
id="toggle-login-pass"
aria-label="Toggle password visibility"
>
👁
</button>
</div>
</div>
<button
type="submit"
class="btn-primary btn-full"
data-loading-text="Verifying…"
>
Sign in
</button>
</form>
<p class="auth-footer">
Don't have an account? <a href="/register">Create one</a><br />
Forgot your password? <a href="/recover">Use recovery code</a>
</p>
</div>
<!-- Step 2: TOTP verification (hidden until MFA required) -->
<div id="login-step-2" class="hidden">
<h1 class="auth-title">Two-factor authentication</h1>
<p class="auth-step-hint">
Enter the 6-digit code from your authenticator app.
</p>
<form id="mfa-form" novalidate>
<p id="mfa-error" class="form-error hidden">
Invalid or expired code. Try again.
</p>
<!-- TOTP input (default) -->
<div id="mfa-totp-section" class="form-group">
<label for="mfa-code">Authenticator code</label>
<input
type="text"
id="mfa-code"
name="mfa_code"
inputmode="numeric"
pattern="[0-9]{6}"
maxlength="6"
autocomplete="one-time-code"
placeholder="000000"
/>
</div>
<!-- Backup code input (hidden until user switches) -->
<div id="mfa-backup-section" class="form-group hidden">
<label for="mfa-backup-code">Backup code</label>
<input
type="text"
id="mfa-backup-code"
name="mfa_backup_code"
autocomplete="off"
placeholder="e.g. ab3rqxyz9p"
style="letter-spacing: 0.05em"
/>
</div>
<button
type="submit"
class="btn-primary btn-full"
data-loading-text="Verifying…"
>
Verify
</button>
</form>
<div class="auth-footer">
<button class="btn-text" id="btn-use-backup-code">
Use a backup code instead
</button>
<button class="btn-text hidden" id="btn-use-totp-code">
Use authenticator code instead
</button>
<button class="btn-text" id="btn-back-to-password">
← Back to sign in
</button>
</div>
</div>
</div>
</div>
{% endblock %} {% block scripts %}
<script src="{{ url_for('static', filename='js/crypto.js') }}"></script>
<script src="{{ url_for('static', filename='js/auth.js') }}"></script>
{% endblock %}