| 
2 | 2 | 
 
  | 
3 | 3 | {% block content %}  | 
4 | 4 | <div class="login-container">  | 
5 |  | -    <h2>Login</h2>  | 
6 |  | -    <form method="POST">  | 
7 |  | -        <div class="form-group">  | 
8 |  | -            <label for="username">Username</label>  | 
9 |  | -            <input type="text" id="username" name="username" required>  | 
10 |  | -        </div>  | 
11 |  | -        <div class="form-group">  | 
12 |  | -            <label for="password">Password</label>  | 
13 |  | -            <input type="password" id="password" name="password" required>  | 
14 |  | -        </div>  | 
15 |  | -        <div class="form-group">  | 
16 |  | -            <label for="totp_token">2FA Token (if enabled)</label>  | 
17 |  | -            <input type="text" id="totp_token" name="totp_token" placeholder="000000">  | 
18 |  | -        </div>  | 
19 |  | -        <button type="submit">Login</button>  | 
 | 5 | +    <h1>Login</h1>  | 
 | 6 | + | 
 | 7 | +    {% with messages = get_flashed_messages(with_categories=true) %}  | 
 | 8 | +        {% if messages %}  | 
 | 9 | +            {% for category, message in messages %}  | 
 | 10 | +                <div class="alert alert-{{ category }}">{{ message }}</div>  | 
 | 11 | +            {% endfor %}  | 
 | 12 | +        {% endif %}  | 
 | 13 | +    {% endwith %}  | 
 | 14 | + | 
 | 15 | +    <form method="POST" action="{{ url_for('auth.login') }}">  | 
 | 16 | +        {% if not require_totp %}  | 
 | 17 | +            <!-- Normal login form -->  | 
 | 18 | +            <div class="form-group">  | 
 | 19 | +                <label for="username">Username</label>  | 
 | 20 | +                <input type="text" id="username" name="username" required autofocus   | 
 | 21 | +                       value="{{ username if username else '' }}">  | 
 | 22 | +            </div>  | 
 | 23 | + | 
 | 24 | +            <div class="form-group">  | 
 | 25 | +                <label for="password">Password</label>  | 
 | 26 | +                <input type="password" id="password" name="password" required>  | 
 | 27 | +            </div>  | 
 | 28 | +        {% else %}  | 
 | 29 | +            <!-- 2FA form - username and password are hidden -->  | 
 | 30 | +            <input type="hidden" name="username" value="{{ username }}">  | 
 | 31 | +            <input type="hidden" name="password" value="{{ request.form.password }}">  | 
 | 32 | + | 
 | 33 | +            <div class="form-group">  | 
 | 34 | +                <label for="totp_code">2FA Code</label>  | 
 | 35 | +                <input type="text" id="totp_code" name="totp_code"   | 
 | 36 | +                       pattern="[0-9]{6}" maxlength="6"   | 
 | 37 | +                       placeholder="000000" required autofocus  | 
 | 38 | +                       autocomplete="off">  | 
 | 39 | +                <small class="help-text">Enter the 6-digit code from your authenticator app</small>  | 
 | 40 | +            </div>  | 
 | 41 | +        {% endif %}  | 
 | 42 | + | 
 | 43 | +        <button type="submit" class="btn-primary">  | 
 | 44 | +            {% if require_totp %}Verify{% else %}Login{% endif %}  | 
 | 45 | +        </button>  | 
20 | 46 |     </form>  | 
21 | 47 | </div>  | 
 | 48 | + | 
 | 49 | +<style>  | 
 | 50 | +.login-container {  | 
 | 51 | +    max-width: 400px;  | 
 | 52 | +    margin: 5rem auto;  | 
 | 53 | +    padding: 2rem;  | 
 | 54 | +    background: white;  | 
 | 55 | +    border-radius: 8px;  | 
 | 56 | +    box-shadow: 0 2px 10px rgba(0,0,0,0.1);  | 
 | 57 | +}  | 
 | 58 | + | 
 | 59 | +.alert {  | 
 | 60 | +    padding: 0.75rem 1rem;  | 
 | 61 | +    margin-bottom: 1rem;  | 
 | 62 | +    border-radius: 4px;  | 
 | 63 | +}  | 
 | 64 | + | 
 | 65 | +.alert-error {  | 
 | 66 | +    background-color: #f8d7da;  | 
 | 67 | +    color: #721c24;  | 
 | 68 | +    border: 1px solid #f5c6cb;  | 
 | 69 | +}  | 
 | 70 | + | 
 | 71 | +.help-text {  | 
 | 72 | +    display: block;  | 
 | 73 | +    margin-top: 0.25rem;  | 
 | 74 | +    color: #6c757d;  | 
 | 75 | +    font-size: 0.875rem;  | 
 | 76 | +}  | 
 | 77 | + | 
 | 78 | +input[type="text"]#totp_code {  | 
 | 79 | +    font-size: 1.5rem;  | 
 | 80 | +    letter-spacing: 0.5em;  | 
 | 81 | +    text-align: center;  | 
 | 82 | +}  | 
 | 83 | +</style>  | 
22 | 84 | {% endblock %}  | 
0 commit comments