39773-vm/reset_password.php
2026-04-22 14:26:14 +00:00

96 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/includes/app.php';
app_boot();
$errors = [];
if (is_post()) {
verify_csrf();
$email = strtolower(trim((string) ($_POST['email'] ?? '')));
$token = strtoupper(trim((string) ($_POST['token'] ?? '')));
$password = (string) ($_POST['password'] ?? '');
$confirm = (string) ($_POST['password_confirm'] ?? '');
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Adresse email invalide.';
}
if ($token === '') {
$errors[] = 'Le token est obligatoire.';
}
if (!password_rules_ok($password)) {
$errors[] = 'Le nouveau mot de passe doit contenir au moins 8 caractères.';
}
if ($password !== $confirm) {
$errors[] = 'La confirmation du mot de passe est incorrecte.';
}
if (!$errors) {
$stmt = db()->prepare('SELECT id, reset_token_hash, reset_expires_at FROM users WHERE email = :email LIMIT 1');
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();
$hash = hash('sha256', $token);
$valid = $user
&& !empty($user['reset_token_hash'])
&& hash_equals((string) $user['reset_token_hash'], $hash)
&& !empty($user['reset_expires_at'])
&& strtotime((string) $user['reset_expires_at']) >= time();
if (!$valid) {
$errors[] = 'Token invalide ou expiré.';
} else {
$update = db()->prepare('UPDATE users SET password_hash = :password_hash, reset_token_hash = NULL, reset_expires_at = NULL, failed_attempts = 0, locked_until = NULL WHERE id = :id');
$update->execute([
'password_hash' => password_hash($password, PASSWORD_BCRYPT),
'id' => (int) $user['id'],
]);
set_flash('success', 'Mot de passe réinitialisé. Vous pouvez maintenant vous connecter.');
redirect('login.php');
}
}
}
render_header('Reset mot de passe', ['description' => 'Valider un token et définir un nouveau mot de passe sur RJLRESAKA.']);
?>
<main class="container py-5 auth-wrap">
<div class="row justify-content-center">
<div class="col-lg-6 col-xl-5">
<div class="panel-card p-4 p-lg-5">
<p class="section-kicker mb-1">Validation du token</p>
<h1 class="h3 mb-3">Définir un nouveau mot de passe</h1>
<p class="text-secondary mb-4">Copiez le token reçu puis confirmez un nouveau mot de passe sécurisé.</p>
<?php if ($errors): ?>
<div class="alert alert-danger" role="alert">
<ul class="mb-0 ps-3">
<?php foreach ($errors as $error): ?>
<li><?= e($error) ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form method="post" class="vstack gap-3">
<input type="hidden" name="csrf_token" value="<?= e(csrf_token()) ?>">
<div>
<label class="form-label" for="email">Email</label>
<input class="form-control" id="email" type="email" name="email" value="<?= old('email') ?>" required>
</div>
<div>
<label class="form-label" for="token">Token</label>
<input class="form-control text-uppercase" id="token" name="token" value="<?= old('token', (string) ($_GET['token'] ?? '')) ?>" required>
</div>
<div>
<label class="form-label" for="password">Nouveau mot de passe</label>
<input class="form-control" id="password" type="password" name="password" minlength="8" required>
</div>
<div>
<label class="form-label" for="password_confirm">Confirmer</label>
<input class="form-control" id="password_confirm" type="password" name="password_confirm" minlength="8" required>
</div>
<button class="btn btn-dark" type="submit">Mettre à jour le mot de passe</button>
</form>
</div>
</div>
</div>
</main>
<?php render_footer(); ?>