- Real email/password login backed by SQLite (better-sqlite3) - HttpOnly cookie sessions with 8h sliding TTL - Admin role: invite users via Mailgun magic-link, manage roles/status - Per-user One2Edit username mapping for job filtering - Self-service forgot-password / reset-password via email - Admin console (admin.html) with user table, invite modal, row actions - New pages: change-password, forgot-password, reset-password, accept-invite - Gated /api proxy: requires valid session, anti-hijack sessionId check - Bootstrap initial admins from INITIAL_ADMINS env var on first boot - Remove Oliver login button, SSO buttons, and legacy api.js/login.js - deploy.sh: add build-essential (for native module), npm install, data dir Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
44 lines
2 KiB
HTML
44 lines
2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>3M - Reset Password</title>
|
|
<link rel="icon" type="image/png" href="Images/Favicon_logo.png">
|
|
<link rel="stylesheet" href="styles.css">
|
|
</head>
|
|
<body class="login-page">
|
|
<div class="login-container">
|
|
<div class="login-card">
|
|
<div class="logo-container">
|
|
<img src="Images/login_logo.png" alt="3M Logo" class="logo">
|
|
</div>
|
|
<h2 class="welcome-text">Set New Password</h2>
|
|
|
|
<div id="invalidState" style="display:none;" class="auth-subtitle error-state">
|
|
This reset link is invalid or has expired.
|
|
<div class="footer-links" style="margin-top:16px">
|
|
<a href="forgot-password.html" class="footer-link">Request a new link</a>
|
|
</div>
|
|
</div>
|
|
|
|
<form id="resetForm" class="login-form" style="display:none;">
|
|
<div class="form-group">
|
|
<input type="password" id="newPassword" placeholder="New password (min 10 characters)" required autocomplete="new-password" class="form-input">
|
|
</div>
|
|
<div class="form-group">
|
|
<input type="password" id="confirmPassword" placeholder="Confirm new password" required autocomplete="new-password" class="form-input">
|
|
</div>
|
|
<div class="button-container">
|
|
<button type="button" class="login-button tmm-button" id="submitBtn">
|
|
<span id="submitText">Set Password</span>
|
|
<span id="submitSpinner" class="spinner" style="display: none;"></span>
|
|
</button>
|
|
</div>
|
|
<div id="errorMessage" class="error-message" style="display: none;"></div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<script src="reset-password.js"></script>
|
|
</body>
|
|
</html>
|