04/18 Enhance app functionalities: master password reset, account deletion/recovery

This commit is contained in:
2026-04-18 14:39:01 -04:00
parent 4d3f9844f0
commit f7fdb9db8a
10 changed files with 1186 additions and 2 deletions
+2 -1
View File
@@ -37,7 +37,8 @@
</button>
</form>
<p class="auth-footer">
Don't have an account? <a href="/register">Create one</a>
Don't have an account? <a href="/register">Create one</a><br>
Forgot your password? <a href="/recover">Use recovery code</a>
</p>
</div>
+72
View File
@@ -0,0 +1,72 @@
{% extends "base.html" %}
{% block title %}Recover Account — 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>
<!-- Step 1: Email + Recovery Code -->
<div id="recover-step-1">
<h1 class="auth-title">Recover your account</h1>
<p class="auth-step-hint">Enter your email and the recovery code you saved when you set up account recovery.</p>
<form id="recover-form-step1" novalidate>
<p id="recover-error-1" class="form-error hidden"></p>
<div class="form-group">
<label for="recover-email">Email address</label>
<input type="email" id="recover-email" name="email" required
autocomplete="email" placeholder="you@example.com">
</div>
<div class="form-group">
<label for="recover-code">Recovery code</label>
<input type="text" id="recover-code" name="recovery_code" required
autocomplete="off" placeholder="xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx"
style="font-family: monospace; letter-spacing: 0.05em;">
</div>
<button type="submit" class="btn-primary btn-full" data-loading-text="Verifying…">
Verify recovery code
</button>
</form>
<p class="auth-footer">
Remember your password? <a href="/login">Sign in</a>
</p>
</div>
<!-- Step 2: Set new master password (hidden until step 1 verified) -->
<div id="recover-step-2" class="hidden">
<h1 class="auth-title">Set a new master password</h1>
<p class="auth-step-hint">Your recovery code is valid. Choose a new master password — your vault will be re-encrypted automatically.</p>
<form id="recover-form-step2" novalidate>
<p id="recover-error-2" class="form-error hidden"></p>
<div class="form-group">
<label for="recover-new-pass">New master password</label>
<div class="input-with-toggle">
<input type="password" id="recover-new-pass" name="new_password" required
autocomplete="new-password" placeholder="Minimum 12 characters">
<button type="button" class="btn-show-pass" id="toggle-recover-pass"
aria-label="Toggle password visibility">👁</button>
</div>
</div>
<div class="form-group">
<label for="recover-confirm-pass">Confirm new password</label>
<input type="password" id="recover-confirm-pass" name="confirm_password" required
autocomplete="new-password" placeholder="Repeat new password">
</div>
<button type="submit" class="btn-primary btn-full" data-loading-text="Recovering account…">
Recover account
</button>
</form>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/crypto.js') }}"></script>
<script src="{{ url_for('static', filename='js/recover.js') }}"></script>
{% endblock %}
+58
View File
@@ -335,6 +335,64 @@
<div id="sharing-keys-actions"></div>
</div>
<!-- Change Password Section -->
<div class="settings-section">
<h4 class="settings-section-title">🔑 Change Master Password</h4>
<p class="settings-desc">Your vault will be automatically re-encrypted with the new password.</p>
<div id="change-password-area">
<div class="form-group">
<label for="cp-current">Current master password</label>
<input type="password" id="cp-current" autocomplete="current-password" placeholder="Current password">
</div>
<div class="form-group">
<label for="cp-new">New master password</label>
<input type="password" id="cp-new" autocomplete="new-password" placeholder="Minimum 12 characters">
</div>
<div class="form-group">
<label for="cp-confirm">Confirm new password</label>
<input type="password" id="cp-confirm" autocomplete="new-password" placeholder="Repeat new password">
</div>
<p id="cp-error" class="form-error hidden"></p>
<button class="btn-primary" id="btn-change-password">Change Password</button>
</div>
</div>
<!-- Recovery Code Section -->
<div class="settings-section">
<h4 class="settings-section-title">🆘 Account Recovery</h4>
<p class="settings-desc">A recovery code lets you regain access if you forget your master password. Store it somewhere safe — it is shown only once and never stored on our servers.</p>
<p id="recovery-status-text" class="settings-desc"></p>
<div id="recovery-code-display" class="hidden">
<div class="recovery-code-box">
<code id="recovery-code-value"></code>
<button class="btn-icon" id="btn-copy-recovery-code" title="Copy to clipboard">📋</button>
</div>
<p class="settings-desc warning-text">⚠️ Copy this code now. It will not be shown again.</p>
<button class="btn-secondary" id="btn-recovery-done">I've saved my recovery code</button>
</div>
<div id="recovery-actions"></div>
</div>
<!-- Danger Zone -->
<div class="settings-section settings-section-danger">
<h4 class="settings-section-title">⚠️ Danger Zone</h4>
<p class="settings-desc">Permanently delete your account and all vault data. This cannot be undone.</p>
<div id="delete-account-area">
<div id="delete-confirm-area" class="hidden">
<div class="form-group">
<label for="delete-password">Enter your master password to confirm</label>
<input type="password" id="delete-password" autocomplete="current-password" placeholder="Master password">
</div>
<p id="delete-error" class="form-error hidden"></p>
<div class="modal-actions">
<button class="btn-secondary" id="btn-delete-cancel">Cancel</button>
<button class="btn-danger" id="btn-delete-confirm">Permanently Delete Account</button>
</div>
</div>
<button class="btn-danger" id="btn-delete-account">Delete My Account</button>
</div>
</div>
</div>
</div>