mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 11:09:18 +02:00
All admin action files (account, tag, page, edit, visibility, maintenance,
publish, formulaire) now call App::flash('error'|'success', ...) instead of
writing to raw per-page session keys ($_SESSION['error'], 'admin_error',
'edit_error', 'admin_success', 'edit_success', 'form_error').
All admin display pages (add, edit, account, tags, pages, index) now include
templates/partials/flash-messages.php instead of manually reading and
unsetting the legacy session keys and inlining their own alert HTML.
App::consumeFlash() already drained all legacy key variants as a safety net,
so the partial works correctly whether called from pages that were already
migrated or any remaining stragglers. No behaviour change for end users.
123 lines
4.6 KiB
PHP
123 lines
4.6 KiB
PHP
<?php
|
|
/**
|
|
* Admin account action — update or remove admin_credentials.php
|
|
*
|
|
* Actions:
|
|
* POST (default) — set/change the PHP admin password
|
|
* POST action=remove_credentials — delete admin_credentials.php
|
|
*/
|
|
|
|
require_once __DIR__ . '/../../../config/bootstrap.php';
|
|
require_once __DIR__ . '/../../../src/AdminAuth.php';
|
|
AdminAuth::requireLogin();
|
|
|
|
// ── CSRF ──────────────────────────────────────────────────────────────────────
|
|
if (empty($_SESSION['csrf_token']) || ($_POST['csrf_token'] ?? '') !== $_SESSION['csrf_token']) {
|
|
http_response_code(403);
|
|
die('Invalid CSRF token.');
|
|
}
|
|
|
|
$credentialsFile = APP_ROOT . '/config/admin_credentials.php';
|
|
$hasPassword = defined('ADMIN_PASSWORD_HASH');
|
|
$action = $_POST['action'] ?? 'change_password';
|
|
|
|
// ── Remove credentials ────────────────────────────────────────────────────────
|
|
if ($action === 'remove_credentials') {
|
|
if (!$hasPassword) {
|
|
App::flash('error', 'Aucun fichier de mot de passe à supprimer.');
|
|
header('Location: /admin/account.php');
|
|
exit;
|
|
}
|
|
|
|
if (!is_writable($credentialsFile) && !is_writable(dirname($credentialsFile))) {
|
|
App::flash('error', 'Le fichier de configuration n\'est pas accessible en écriture.');
|
|
header('Location: /admin/account.php');
|
|
exit;
|
|
}
|
|
|
|
if (@unlink($credentialsFile)) {
|
|
// Destroy session so the user is forced to re-authenticate via nginx Basic Auth.
|
|
AdminAuth::logout();
|
|
header('Location: /admin/login.php');
|
|
exit;
|
|
} else {
|
|
App::flash('error', 'Impossible de supprimer le fichier de configuration.');
|
|
header('Location: /admin/account.php');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// ── Change / set password ─────────────────────────────────────────────────────
|
|
|
|
// 1. If a password is already set, verify the current one.
|
|
if ($hasPassword) {
|
|
$currentPassword = $_POST['current_password'] ?? '';
|
|
if (!AdminAuth::login($currentPassword)) {
|
|
App::flash('error', 'Mot de passe actuel incorrect.');
|
|
header('Location: /admin/account.php');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// 2. Validate new password.
|
|
$newPassword = $_POST['new_password'] ?? '';
|
|
$confirmPassword = $_POST['confirm_password'] ?? '';
|
|
|
|
if (strlen($newPassword) < 12) {
|
|
App::flash('error', 'Le nouveau mot de passe doit contenir au moins 12 caractères.');
|
|
header('Location: /admin/account.php');
|
|
exit;
|
|
}
|
|
|
|
if ($newPassword !== $confirmPassword) {
|
|
App::flash('error', 'Les mots de passe ne correspondent pas.');
|
|
header('Location: /admin/account.php');
|
|
exit;
|
|
}
|
|
|
|
// 3. Generate bcrypt hash (cost 12).
|
|
$hash = password_hash($newPassword, PASSWORD_BCRYPT, ['cost' => 12]);
|
|
if ($hash === false) {
|
|
App::flash('error', 'Erreur lors du hachage du mot de passe.');
|
|
header('Location: /admin/account.php');
|
|
exit;
|
|
}
|
|
|
|
// 4. Write credentials file.
|
|
$configContent = '<?php' . "\n"
|
|
. '/**' . "\n"
|
|
. ' * Admin PHP-level password for the session auth guard (defence-in-depth).' . "\n"
|
|
. ' *' . "\n"
|
|
. ' * Generated by the admin panel on ' . date('Y-m-d H:i:s') . '.' . "\n"
|
|
. ' * To regenerate manually:' . "\n"
|
|
. ' * php -r "echo password_hash(\'your-password\', PASSWORD_BCRYPT, [\'cost\' => 12]);"' . "\n"
|
|
. ' */' . "\n"
|
|
. "\n"
|
|
. 'define(\'ADMIN_PASSWORD_HASH\', ' . var_export($hash, true) . ');' . "\n";
|
|
|
|
// Write atomically via a temp file.
|
|
$tmpFile = $credentialsFile . '.tmp.' . bin2hex(random_bytes(6));
|
|
if (file_put_contents($tmpFile, $configContent, LOCK_EX) === false) {
|
|
@unlink($tmpFile);
|
|
App::flash('error', 'Impossible d\'écrire le fichier de configuration. Vérifiez les permissions sur config/.');
|
|
header('Location: /admin/account.php');
|
|
exit;
|
|
}
|
|
if (!rename($tmpFile, $credentialsFile)) {
|
|
@unlink($tmpFile);
|
|
App::flash('error', 'Impossible de mettre à jour le fichier de configuration.');
|
|
header('Location: /admin/account.php');
|
|
exit;
|
|
}
|
|
|
|
// 5. Regenerate session (password changed — invalidate old sessions).
|
|
session_regenerate_id(true);
|
|
$_SESSION['admin_authenticated'] = true;
|
|
|
|
App::flash('success', $hasPassword
|
|
? 'Mot de passe mis à jour avec succès.'
|
|
: 'Mot de passe défini avec succès. L\'authentification PHP est maintenant active.');
|
|
|
|
header('Location: /admin/account.php');
|
|
exit;
|