Files

242 lines
10 KiB
PHP

<?php
require_once __DIR__ . '/public/includes/init_auth.php';
$erreur = '';
$email = '';
$mot_de_passe = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = trim($_POST['email'] ?? '');
$mot_de_passe = $_POST['mot_de_passe'] ?? '';
// 🔒 --- Protection brute force ---
$_SESSION['login_tries'] = (int) ($_SESSION['login_tries'] ?? 0);
$blockedUntil = (int) ($_SESSION['login_blocked_until'] ?? 0);
if ($blockedUntil > time()) {
$remaining = $blockedUntil - time();
$erreur = sprintf(
$translations['trop_de_tentatives_connexion'] ?? 'Trop de tentatives. Réessayez dans %d secondes.',
$remaining
);
} else {
if ($email === '' || $mot_de_passe === '') {
$erreur = $translations['erreur_champs_vides'];
} else {
$stmt = $pdo->prepare("SELECT * FROM compte WHERE email = :email LIMIT 1");
$stmt->execute(['email' => $email]);
$compte = $stmt->fetch();
if ($compte && password_verify($mot_de_passe, $compte['mot_de_passe'])) {
// ✅ reset brute force
$_SESSION['login_tries'] = 0;
unset($_SESSION['login_blocked_until']);
if (empty($compte['email_valide'])) {
$_SESSION['pending_validation_resend'] = [
'compte_id' => (int) $compte['id'],
'email' => (string) $compte['email'],
'authorized' => true,
'expires_at' => time() + 900,
];
$erreur = $translations['tvalidat_erreur_email_non_valide'] ?? $translations['erreur_email_non_valide'] ?? 'Veuillez valider votre adresse email.';
} else {
session_regenerate_id(true);
$_SESSION['compte_id'] = $compte['id'];
$_SESSION['role'] = strtolower(trim($compte['role'] ?? ''));
$_SESSION['reference_id'] = $compte['reference_id'];
$_SESSION['email'] = $compte['email'];
$_SESSION['last_activity'] = time();
// 🔁 redirection next
$next = $_POST['next'] ?? $_GET['next'] ?? ($_SESSION['redirect_to'] ?? null);
$next = next_safe($next);
if ($next) {
unset($_SESSION['redirect_to']);
header('Location: ' . $next);
exit;
}
// 🎯 fallback rôle
if ($_SESSION['role'] === 'client') {
header('Location: /public/client/mes_rendez_vous.php');exit;
} elseif ($_SESSION['role'] === 'admin') {
header('Location: /admin/index.php');exit;
} elseif ($_SESSION['role'] === 'secretaire') {
header('Location: /public/cabinet/dashboard.php');exit;
} else {
header('Location: /public/praticien/agenda.php');exit;
}
}
} else {
// ❌ Mauvais login
$_SESSION['login_tries']++;
// ⏱️ Blocage après 5 tentatives
if ($_SESSION['login_tries'] >= 3) {
$_SESSION['login_blocked_until'] = time() + 600; // 10 min
}
// 🐢 ralentissement progressif
sleep(min($_SESSION['login_tries'], 3));
$erreur = $translations['erreur_identifiants'];
}
}
}
}
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title><?php echo htmlspecialchars($translations['seo_connexion_title'], ENT_QUOTES, 'UTF-8') ?></title>
<meta name="description" content="<?php echo htmlspecialchars($translations['seo_connexion_desc'], ENT_QUOTES, 'UTF-8') ?>">
<meta name="keywords" content="<?php echo htmlspecialchars($translations['seo_connexion_keywords'], ENT_QUOTES, 'UTF-8') ?>">
<meta name="author" content="Uslugi.fr">
<meta name="robots" content="noindex, nofollow, noarchive, nosnippet">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="<?php echo asset('/includes/site_style.css') ?>">
<link rel="stylesheet" href="<?php echo asset('/includes/custom_style.css') ?>">
<link rel="stylesheet" href="<?php echo asset('/includes/mobil_style.css') ?>">
</head>
<body>
<header class="site-header">
<div class="container">
<div class="header-left">
<div class="brand">
<a href="/index.php"><img src="/public/uploads/img/logo_u.png" alt="uslugi.fr" class="logo-mobile"></a>
<a href="/index.php"><img src="/public/uploads/img/logo.png" alt="uslugi.fr" class="logo-desktop"></a>
</div>
<div class="lang-switch">
<?php require __DIR__ . '/includes/menu_langue.php'; ?>
</div>
</div>
<nav class="header-actions">
<div class="dropdown">
<button class="btn btn-logo rounded-circle d-inline-flex align-items-center justify-content-center question-btn"
type="button" data-bs-toggle="dropdown" data-bs-auto-close="true"
aria-expanded="false" aria-label="Помощь">?</button>
<ul class="dropdown-menu dropdown-menu-end shadow help-menu menu-panel">
<li><a href="/how-it-work.php"><?php echo $translations['kak_rabotaet'] ?></a></li>
<li><a href="/about.php"><?php echo $translations['pro_nas'] ?></a></li>
<li><a href="/faq.php"><?php echo $translations['faq'] ?></a></li>
<li><a href="/contact.php"><?php echo $translations['nam_pisat'] ?></a></li>
</ul>
</div>
</nav>
</div>
</header>
<div class="main">
<div class="card shadow-sm p-4" style="min-width:380px; max-width:520px; margin:40px auto;">
<h3 class="mb-4 text-center text-dark"><?php echo $translations['connexion_titre'] ?></h3>
<?php if ($erreur): ?>
<?php
$canResend = ! empty($_SESSION['pending_validation_resend']['authorized'])
&& ! empty($_SESSION['pending_validation_resend']['expires_at'])
&& (int) $_SESSION['pending_validation_resend']['expires_at'] >= time()
&& ! empty($email)
&& ! empty($_SESSION['pending_validation_resend']['email'])
&& hash_equals(
(string) $_SESSION['pending_validation_resend']['email'],
(string) $email
);
?>
<div class="alert alert-danger py-2 text-center" role="alert">
<?php echo htmlspecialchars($erreur, ENT_QUOTES, 'UTF-8'); ?>
<?php if ($canResend): ?>
<div class="mt-3">
<form method="POST" action="/renvoyer_validat_mail.php" class="m-0">
<input type="hidden" name="email"
value="<?php echo htmlspecialchars($email, ENT_QUOTES, 'UTF-8'); ?>">
<button type="submit" class="btn btn-light btn-sm">
<?php echo htmlspecialchars($translations['tvalidat_btn_renvoyer'] ?? 'Renvoyer le mail de validation', ENT_QUOTES, 'UTF-8'); ?>
</button>
</form>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<form method="POST">
<div class="mb-3">
<input type="email" name="email" class="form-control"
placeholder="<?php echo $translations['email_placeholder'] ?>"
value="<?php echo htmlspecialchars($email) ?>" required>
</div>
<div class="mb-3 position-relative">
<input id="mot_de_passe" type="password" name="mot_de_passe" class="form-control"
placeholder="<?php echo $translations['motdepasse_placeholder'] ?>"
required autocomplete="current-password">
<span class="toggle-password"
id="eyePwd"
onmouseenter="revealPwd('mot_de_passe')"
onmouseleave="hidePwd('mot_de_passe')"
onmousedown="revealPwd('mot_de_passe')"
onmouseup="hidePwd('mot_de_passe')"
ontouchstart="revealPwd('mot_de_passe')"
ontouchend="hidePwd('mot_de_passe')"
title="Наведите, чтобы показать">
👁️
</span>
</div>
<input type="hidden" name="next"
value="<?php echo htmlspecialchars($_GET['next'] ?? ($_SESSION['redirect_to'] ?? ''), ENT_QUOTES); ?>">
<button type="submit" class="btn btn-primary w-100"><?php echo $translations['btn_se_connecter'] ?></button>
<div class="text-center mt-3">
<a href="mdp_oublie.php" class="me-2"><?php echo $translations['lien_mdp_oublie'] ?></a> |
<a href="choix_inscr.php" class="ms-2"><?php echo $translations['lien_inscription'] ?></a>
</div>
</form>
</div>
</div>
<footer class="site-footer">
<div class="container">
<p><?php echo $translations['copyr'] ?></p>
</div>
</footer>
<script>
function revealPwd(id){ var el = document.getElementById(id); if(el) el.type = 'text'; }
function hidePwd(id){ var el = document.getElementById(id); if(el) el.type = 'password'; }
(function(){
var eye = document.getElementById('eyePwd');
var input = document.getElementById('mot_de_passe');
if(!eye || !input) return;
eye.addEventListener('touchstart', function(e){ e.preventDefault(); revealPwd('mot_de_passe'); }, {passive:false});
eye.addEventListener('touchend', function(e){ e.preventDefault(); hidePwd('mot_de_passe'); }, {passive:false});
eye.addEventListener('touchcancel',function(){ hidePwd('mot_de_passe'); });
eye.addEventListener('mousedown', function(e){ e.preventDefault(); revealPwd('mot_de_passe'); });
eye.addEventListener('mouseup', function(e){ e.preventDefault(); hidePwd('mot_de_passe'); });
eye.addEventListener('mouseleave',function(){ hidePwd('mot_de_passe'); });
})();
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>