Add admin account page for PHP password management

Implements the admin user management UI as a self-contained PHP password
change/set flow — no SSH or sudo required.

- public/admin/account.php: shows auth status (PHP hash present, credentials
  file path), password change form (requires current password when one exists,
  min 12 chars, confirm field), and a danger-zone form to delete the
  credentials file entirely
- public/admin/actions/account.php: CSRF-guarded POST handler; verifies
  current password via AdminAuth::login() before accepting a new one;
  generates bcrypt (cost 12) hash; writes config/admin_credentials.php
  atomically via a temp file + rename; regenerates session on success;
  redirects to /admin/login.php when credentials are deleted
- templates/admin/head.php: 'Compte' nav link added (active on account.php)
- public/assets/admin.css: .admin-account-status, .admin-section-title,
  .admin-field-hint, .admin-danger-zone component styles added

Note: the nginx htpasswd flow (manage-admin-users.sh) requires root on the
server and is intentionally kept as a CLI-only operation.
This commit is contained in:
Pontoporeia
2026-03-24 15:52:00 +01:00
parent 020bfa5a33
commit 20a633c0e2
5 changed files with 319 additions and 1 deletions

View File

@@ -734,3 +734,77 @@ html, body {
color: #cc6060;
border: 1px solid #7a2020;
}
/* ---- Account page ---- */
.admin-account-status {
background: var(--admin-bg-alt);
border: 1px solid var(--admin-border);
border-radius: 4px;
padding: 1.25rem 1.5rem;
margin-bottom: 2.5rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.admin-account-status__row {
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 0.9rem;
}
.admin-account-status__label {
color: var(--admin-text-muted);
min-width: 220px;
}
.admin-account-status__code {
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
font-size: 0.82rem;
background: var(--admin-bg);
border: 1px solid var(--admin-border);
border-radius: 3px;
padding: 0.1rem 0.4rem;
color: var(--admin-text-muted);
}
.admin-account-status__note {
font-size: 0.88rem;
color: #ffc107;
margin: 0.25rem 0 0;
}
.admin-section-title {
font-size: 1rem;
font-weight: 600;
letter-spacing: 0.07em;
text-transform: uppercase;
color: var(--admin-text-muted);
margin: 0 0 1.25rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--admin-border);
}
.admin-field-hint {
font-size: 0.8rem;
color: var(--admin-text-muted);
margin: 0.3rem 0 0;
}
.admin-danger-zone {
background: rgba(180, 0, 0, 0.07);
border: 1px solid rgba(200, 60, 60, 0.3);
border-radius: 4px;
padding: 1.25rem 1.5rem;
display: flex;
align-items: center;
justify-content: space-between;
gap: 1.5rem;
flex-wrap: wrap;
}
.admin-danger-zone__description {
font-size: 0.9rem;
line-height: 1.5;
}