From b866eaafd0c47b5996ebce1314ae05e7d9225c6a Mon Sep 17 00:00:00 2001 From: stepan Date: Tue, 17 Mar 2026 00:07:10 +0100 Subject: [PATCH] =?UTF-8?q?[F=C3=81ZE-2][auth]=20P=C5=99id=C3=A1na=20str?= =?UTF-8?q?=C3=A1nka=20pro=20=C5=BE=C3=A1dost=20o=20obnovu=20hesla?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auth/reset_hesla.php | 196 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 auth/reset_hesla.php diff --git a/auth/reset_hesla.php b/auth/reset_hesla.php new file mode 100644 index 0000000..6f80f25 --- /dev/null +++ b/auth/reset_hesla.php @@ -0,0 +1,196 @@ + 0, + 'path' => '/', + 'httponly' => true, + 'samesite' => 'Strict', + // 'secure' => true, +]); +session_start(); + +// Pokud je uživatel přihlášen, přesměrujeme ho +if (isset($_SESSION['uzivatel_id'])) { + header('Location: ' . AUTH_REDIRECT_PO_PRIHLASENI); + exit; +} + +// ------------------------------------------------------------ +// CSRF TOKEN +// ------------------------------------------------------------ + +if (empty($_SESSION['csrf_token'])) { + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); +} +$csrf_token = $_SESSION['csrf_token']; + +// ------------------------------------------------------------ +// ZPRACOVÁNÍ FORMULÁŘE +// ------------------------------------------------------------ + +// Tuto hlášku zobrazíme vždy po odeslání formuláře – +// bez ohledu na to, zda email existuje +$zprava_po_odeslani = 'Pokud je zadaný email registrován, ' + . 'přijde ti na něj odkaz pro obnovu hesla. ' + . 'Odkaz bude platný 1 hodinu.'; + +$odeslano = false; +$chyba = ''; + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + + // -- Ověření CSRF tokenu ---------------------------------- + $csrf_z_formulare = $_POST['csrf_token'] ?? ''; + if (!hash_equals($csrf_token, $csrf_z_formulare)) { + $chyba = 'Neplatný požadavek. Zkuste stránku obnovit a zkusit znovu.'; + } + + if (empty($chyba)) { + + $email = trim($_POST['email'] ?? ''); + + if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) { + $chyba = 'Zadejte platnou emailovou adresu.'; + } + } + + if (empty($chyba)) { + + // Vyhledáme uživatele v DB + $stmt = $pdo->prepare(" + SELECT `id` + FROM `" . DB_TABULKA_UZIVATELE . "` + WHERE `email` = :email + LIMIT 1 + "); + $stmt->execute([':email' => $email]); + $uzivatel = $stmt->fetch(); + + if ($uzivatel) { + + // -- Uživatel existuje – vytvoříme reset token ---- + + // Smažeme případné staré (nepoužité) tokeny tohoto uživatele + $stmt2 = $pdo->prepare(" + DELETE FROM `" . DB_TABULKA_RESET . "` + WHERE `uzivatel_id` = :uzivatel_id + "); + $stmt2->execute([':uzivatel_id' => $uzivatel['id']]); + + // Vygenerujeme nový token + // Do emailu jde plaintext, do DB jde jen hash + $token = bin2hex(random_bytes(32)); // 64 znaků hex + $token_hash = password_hash($token, PASSWORD_DEFAULT); + $expiruje = date('Y-m-d H:i:s', time() + 3600); // 1 hodina + + $stmt3 = $pdo->prepare(" + INSERT INTO `" . DB_TABULKA_RESET . "` + (`uzivatel_id`, `token_hash`, `expiruje`) + VALUES + (:uzivatel_id, :token_hash, :expiruje) + "); + $stmt3->execute([ + ':uzivatel_id' => $uzivatel['id'], + ':token_hash' => $token_hash, + ':expiruje' => $expiruje, + ]); + + $reset_id = $pdo->lastInsertId(); + + // Sestavíme odkaz pro obnovu hesla + // Odkaz obsahuje ID záznamu a plaintext token + $odkaz = PROJEKT_URL . '/auth/nove_heslo.php' + . '?id=' . urlencode($reset_id) + . '&token=' . urlencode($token); + + // Odešleme email + $predmet = 'Obnova hesla – ' . PROJEKT_NAZEV; + $text = "Ahoj,\n\n" + . "požádal(a) jsi o obnovu hesla na " . PROJEKT_NAZEV . ".\n\n" + . "Pro nastavení nového hesla klikni na tento odkaz:\n" + . $odkaz . "\n\n" + . "Odkaz je platný 1 hodinu.\n\n" + . "Pokud jsi o obnovu hesla nežádal(a), tento email ignoruj.\n\n" + . PROJEKT_NAZEV; + + odesli_mail($email, $predmet, $text); + } + + // Zobrazíme stejnou hlášku bez ohledu na existenci emailu + $odeslano = true; + } +} + +// ------------------------------------------------------------ +// HTML VÝSTUP +// ------------------------------------------------------------ +?> + + + + + Obnova hesla – <?php echo htmlspecialchars(PROJEKT_NAZEV); ?> + + + + + + +

Obnova hesla

+

+ + + +

+

Zpět na přihlášení

+ + + + +

Chyba:

+ + +

Zadej svůj email a pošleme ti odkaz pro obnovu hesla.

+ +
+ + + +

+
+ +

+ +

+ +

+ +
+ +

Zpět na přihlášení

+ + + + + \ No newline at end of file