wiki/z-archive/implementation/implementation_doc_userauth_ui_adaptations.md

14 KiB

User Authentication UI Adaptations

Overview

This document describes the necessary UI changes and adaptations required to implement the magic link-based user authentication process described in doc_userauth_process_concept.md.

Last Updated: Based on codebase analysis of current frontend implementation.

Current Frontend State

Existing Pages

  1. frontend_agents/public/login.html

    • Contains login form with username/password fields
    • Has buttons for Microsoft and Google authentication
    • Has registration link
    • Missing: Password reset button
  2. frontend_agents/public/register.html

    • Contains registration form with:
      • Username field
      • Password field (required)
      • Confirm password field (required)
      • Email field
      • Full name field
      • Language selector
    • Needs modification: Remove password fields, add email-only registration
  3. frontend_agents/public/js/security/auth.js

    • Contains setupRegisterPage() function
    • Contains validateRegistrationForm() function that requires password
    • Contains email validation logic
    • Needs modification: Remove password validation, add shared email validation function
  4. frontend_agents/public/js/shared/apiCalls.js

    • Contains register() function that sends password
    • Missing: Password reset request and reset password API calls

Required UI Changes

1. Login Page (frontend_agents/public/login.html)

Changes Required:

  • Add "Password Reset" button/link below the login form
  • Button should link to /password-reset-request.html
  • Style should match existing button styles (use btn class with appropriate variant)

Implementation:

<!-- Add after login form, before register-options div -->
<div class="password-reset-link">
    <a href="password-reset-request.html" class="btn btn-link">
        <i class="fas fa-key"></i> Passwort zurücksetzen
    </a>
</div>

Styling Considerations:

  • Use existing CSS classes from htmlparts/styles.css
  • Match styling with registration link
  • Ensure responsive design matches login page layout

2. Registration Page (frontend_agents/public/register.html)

Changes Required:

  • Remove password and confirm password fields
  • Keep username, email, fullName, language fields
  • Update form validation to not require password
  • Update success message to indicate email will be sent
  • Add spam folder reminder message

Implementation:

<!-- Remove these fields: -->
<!-- <div class="login-form-group">
    <label for="password">Passwort*</label>
    <input type="password" id="password" name="password" required minlength="8">
    <div class="field-error"></div>
</div>
<div class="login-form-group">
    <label for="confirm-password">Passwort bestätigen*</label>
    <input type="password" id="confirm-password" name="confirm-password" required>
    <div class="field-error"></div>
</div> -->

<!-- Add info message after form: -->
<div class="registration-info">
    <p>Nach der Registrierung erhalten Sie eine E-Mail mit einem Link zum Setzen Ihres Passworts.</p>
    <p class="spam-reminder">Bitte prüfen Sie auch Ihren Spam-Ordner, falls Sie keine E-Mail erhalten.</p>
</div>

JavaScript Changes (frontend_agents/public/js/security/auth.js):

  • Update validateRegistrationForm() to remove password validation
  • Update setupRegisterPage() to handle no-password registration
  • Create shared validateEmailFormat() function for reuse

3. New Page: Password Reset Request (frontend_agents/public/password-reset-request.html)

Purpose:

Allow users to request a password reset by entering their email address.

Structure:

  • Similar layout to register.html
  • Single email input field
  • Submit button
  • Link back to login page
  • Success/error message area

Implementation:

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PowerOn - Passwort zurücksetzen</title>
    <link rel="stylesheet" href="./htmlparts/styles_variables.css">
    <link rel="stylesheet" href="./htmlparts/styles_base.css">
    <link rel="stylesheet" href="./htmlparts/styles.css">
    <link rel="stylesheet" href="./htmlparts/styles_icons.css">
</head>
<body>
    <div class="login-container">
        <h1>Passwort zurücksetzen</h1>
        <div id="reset-request-error" class="login-error-message"></div>
        <form id="password-reset-request-form">
            <div class="login-form-group">
                <label for="email">E-Mail-Adresse*</label>
                <input type="email" id="email" name="email" required autocomplete="email">
                <div class="field-error"></div>
            </div>
            <button type="submit" class="btn btn-success login-btn">Reset-Link anfordern</button>
        </form>
        <div class="register-link">
            <p>Zurück zum <a href="login.html">Login</a></p>
        </div>
    </div>

    <!-- Benötigte globale Utilities -->
    <script type="module" src="js/shared/utils.js"></script>
    
    <!-- Module -->
    <script type="module" src="js/security/passwordResetRequest.js"></script>
</body>
</html>

JavaScript Module (frontend_agents/public/js/security/passwordResetRequest.js):

  • Handle form submission
  • Validate email format using shared function from auth.js
  • Call password reset request API
  • Show generic success message
  • Redirect to login page after showing message

4. New Page: Password Reset (frontend_agents/public/reset.html)

Purpose:

Allow users to set a new password using the token from the magic link.

Structure:

  • Similar layout to register.html
  • Password field (with strength indicator)
  • Confirm password field
  • Submit button
  • Extract token from URL parameter (?token=<UUID>)
  • Success/error message area

Implementation:

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PowerOn - Neues Passwort setzen</title>
    <link rel="stylesheet" href="./htmlparts/styles_variables.css">
    <link rel="stylesheet" href="./htmlparts/styles_base.css">
    <link rel="stylesheet" href="./htmlparts/styles.css">
    <link rel="stylesheet" href="./htmlparts/styles_icons.css">
</head>
<body>
    <div class="login-container">
        <h1>Neues Passwort setzen</h1>
        <div id="reset-error" class="login-error-message"></div>
        <form id="reset-password-form">
            <div class="login-form-group">
                <label for="password">Neues Passwort*</label>
                <input type="password" id="password" name="password" required minlength="8">
                <div class="field-error"></div>
                <small class="password-hint">Mindestens 8 Zeichen</small>
            </div>
            <div class="login-form-group">
                <label for="confirm-password">Passwort bestätigen*</label>
                <input type="password" id="confirm-password" name="confirm-password" required>
                <div class="field-error"></div>
            </div>
            <button type="submit" class="btn btn-success login-btn">Passwort setzen</button>
        </form>
        <div class="register-link">
            <p>Zurück zum <a href="login.html">Login</a></p>
        </div>
    </div>

    <!-- Benötigte globale Utilities -->
    <script type="module" src="js/shared/utils.js"></script>
    
    <!-- Module -->
    <script type="module" src="js/security/reset.js"></script>
</body>
</html>

JavaScript Module (frontend_agents/public/js/security/reset.js):

  • Extract token from URL parameter
  • Validate token format (UUID)
  • Handle form submission
  • Validate password strength (min 8 chars, match requirements from config)
  • Validate password confirmation matches
  • Call password reset API
  • Show success message with spam folder reminder
  • Redirect to login page after 3 seconds

5. API Calls (frontend_agents/public/js/shared/apiCalls.js)

New Functions Required:

  1. requestPasswordReset(email)

    requestPasswordReset: async function(email) {
        try {
            return await privateApi.post('/api/local/password-reset-request', { email });
        } catch (error) {
            ui.log.error('Password reset request error:', error);
            throw error;
        }
    }
    
  2. resetPassword(token, password)

    resetPassword: async function(token, password) {
        try {
            return await privateApi.post('/api/local/password-reset', { token, password });
        } catch (error) {
            ui.log.error('Password reset error:', error);
            throw error;
        }
    }
    
  3. Update register() function

    • Remove password from request body
    • Update to handle new registration flow (no password required)

6. Shared Email Validation (frontend_agents/public/js/security/auth.js)

New Function:

/**
 * Validates email format
 * @param {string} email - Email address to validate
 * @returns {boolean} - True if valid, false otherwise
 */
export function validateEmailFormat(email) {
    if (!email) return false;
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email.trim());
}

Usage:

  • Used by registration form
  • Used by password reset request form
  • Ensures consistent email validation across the application

UI/UX Considerations

Error Handling

  1. Registration Errors:

    • Username already exists → Show error on username field
    • Email already exists → Show generic success (security: don't reveal email exists)
    • Email sending fails → Show generic success (don't reveal email issues)
  2. Password Reset Request Errors:

    • Invalid email format → Show error on email field
    • Email not found → Show generic success (security: don't reveal email doesn't exist)
    • Rate limiting → Show error message
  3. Password Reset Errors:

    • Invalid/expired token → Show error message, link back to password reset request
    • Password too weak → Show specific requirements
    • Password mismatch → Show error on confirm password field

Success Messages

  1. Registration Success:

    "Registrierung erfolgreich! Bitte prüfen Sie Ihre E-Mail, um Ihr Passwort zu setzen.
    Falls Sie keine E-Mail erhalten, prüfen Sie bitte auch Ihren Spam-Ordner."
    
  2. Password Reset Request Success:

    "Falls ein Konto mit dieser E-Mail-Adresse existiert, wurde ein Reset-Link gesendet.
    Bitte prüfen Sie Ihre E-Mail und auch Ihren Spam-Ordner."
    
  3. Password Reset Success:

    "Passwort erfolgreich gesetzt! Sie werden zum Login weitergeleitet..."
    

Accessibility

  • All form fields should have proper labels
  • Error messages should be associated with form fields using ARIA attributes
  • Success messages should be announced to screen readers
  • Form validation should provide clear, actionable feedback

Responsive Design

  • All pages should work on mobile devices
  • Form layouts should adapt to smaller screens
  • Buttons should be appropriately sized for touch interfaces
  • Error messages should be readable on all screen sizes

Testing Checklist

Registration Flow

  • User can register without password
  • Email validation works correctly
  • Success message displays correctly
  • Redirect to login works
  • Error handling for duplicate username
  • Error handling for duplicate email (should show generic success)

Password Reset Request Flow

  • User can access password reset request page from login
  • Email validation works correctly
  • Success message displays correctly
  • Redirect to login works
  • Error handling for invalid email format
  • Error handling for rate limiting

Password Reset Flow

  • User can access reset page with valid token
  • Token extraction from URL works
  • Password validation works correctly
  • Password confirmation validation works
  • Success message displays correctly
  • Redirect to login works after 3 seconds
  • Error handling for invalid token
  • Error handling for expired token
  • Error handling for weak password

Integration Testing

  • End-to-end registration flow works
  • End-to-end password reset flow works
  • Email links work correctly
  • Token expiration handling works
  • Multiple reset requests invalidate old tokens

Implementation Order

  1. Backend Changes First (prerequisites):

    • Add resetToken fields to UserInDB model
    • Implement password reset endpoints
    • Implement email sending functionality
  2. Frontend API Layer:

    • Add password reset API calls to apiCalls.js
    • Update registration API call
  3. Frontend Pages:

    • Create password-reset-request.html
    • Create reset.html
    • Update login.html (add reset button)
    • Update register.html (remove password fields)
  4. Frontend JavaScript:

    • Create passwordResetRequest.js
    • Create reset.js
    • Update auth.js (remove password validation, add email validation function)
    • Update register.js if needed
  5. Testing:

    • Test each flow independently
    • Test integration between frontend and backend
    • Test error scenarios
    • Test edge cases

Notes

  • All text should be in German to match existing UI (login.html uses German)
  • CSS classes should match existing patterns from htmlparts/styles.css
  • Form validation should use existing patterns from auth.js
  • Error handling should use existing patterns from auth.js (showFieldError, clearFieldError)
  • Success messages should use existing patterns (showSuccessMessage)
  • API calls should use existing patterns from apiCalls.js (privateApi.post, handleResponse)