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

81 lines
3.7 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/includes/app.php';
app_boot();
if (current_user()) {
redirect('index.php');
}
$error = null;
if (is_post()) {
verify_csrf();
$email = strtolower(trim((string) ($_POST['email'] ?? '')));
$password = (string) ($_POST['password'] ?? '');
$stmt = db()->prepare('SELECT * FROM users WHERE email = :email LIMIT 1');
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();
if (!$user) {
$error = 'Identifiants invalides.';
} else {
$lockedUntil = $user['locked_until'] ?? null;
if ($lockedUntil && strtotime((string) $lockedUntil) > time()) {
$seconds = max(1, strtotime((string) $lockedUntil) - time());
$error = 'Compte temporairement bloqué. Réessayez dans ' . $seconds . ' secondes.';
} elseif (password_verify($password, (string) $user['password_hash'])) {
$reset = db()->prepare('UPDATE users SET failed_attempts = 0, locked_until = NULL WHERE id = :id');
$reset->execute(['id' => (int) $user['id']]);
login_user($user);
set_flash('success', 'Connexion réussie.');
redirect('index.php');
} else {
$attempts = (int) $user['failed_attempts'] + 1;
$locked = $attempts >= 5 ? date('Y-m-d H:i:s', time() + 30) : null;
$update = db()->prepare('UPDATE users SET failed_attempts = :failed_attempts, locked_until = :locked_until WHERE id = :id');
$update->bindValue(':failed_attempts', $attempts, PDO::PARAM_INT);
$update->bindValue(':locked_until', $locked);
$update->bindValue(':id', (int) $user['id'], PDO::PARAM_INT);
$update->execute();
$error = $attempts >= 5
? '5 tentatives atteintes. Compte bloqué pendant 30 secondes.'
: 'Identifiants invalides. Tentative ' . $attempts . '/5.';
}
}
}
render_header('Connexion', ['description' => 'Se connecter à RJLRESAKA pour accéder au registre des sportifs.']);
?>
<main class="container py-5 auth-wrap">
<div class="row justify-content-center">
<div class="col-lg-5 col-xl-4">
<div class="panel-card p-4 p-lg-5">
<p class="section-kicker mb-1">Authentification</p>
<h1 class="h3 mb-3">Connexion sécurisée</h1>
<p class="text-secondary mb-4">5 tentatives maximum, puis pause automatique de 30 secondes.</p>
<?php if ($error): ?>
<div class="alert alert-danger" role="alert"><?= e($error) ?></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="password">Mot de passe</label>
<input class="form-control" id="password" type="password" name="password" required>
</div>
<button class="btn btn-dark w-100" type="submit">Se connecter</button>
</form>
<div class="d-flex justify-content-between flex-wrap gap-2 mt-3 small">
<a href="forgot_password.php" class="link-dark">Mot de passe oublié ?</a>
<a href="register.php" class="link-dark">Créer un compte</a>
</div>
</div>
</div>
</div>
</main>
<?php render_footer(); ?>