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']; // ------------------------------------------------------------ // OVĚŘENÍ ODKAZU (parametry z URL) // ------------------------------------------------------------ $token_ok = false; // true pokud je token platný $zaznam_id = 0; // ID záznamu v auth_password_resets $uzivatel_id = 0; // ID uživatele $id_z_url = $_GET['id'] ?? ''; $token_z_url = $_GET['token'] ?? ''; if (!empty($id_z_url) && !empty($token_z_url)) { // Vyhledáme záznam podle ID $stmt = $pdo->prepare(" SELECT `id`, `uzivatel_id`, `token_hash`, `expiruje` FROM `" . DB_TABULKA_RESET . "` WHERE `id` = :id LIMIT 1 "); $stmt->execute([':id' => (int) $id_z_url]); $zaznam = $stmt->fetch(); if ($zaznam) { // Zkontrolujeme expiraci if (time() < strtotime($zaznam['expiruje'])) { // Ověříme token (password_verify = konstantní čas, // ochrana před timing útoky) if (password_verify($token_z_url, $zaznam['token_hash'])) { $token_ok = true; $zaznam_id = $zaznam['id']; $uzivatel_id = $zaznam['uzivatel_id']; } } } } // ------------------------------------------------------------ // ZPRACOVÁNÍ FORMULÁŘE (nastavení nového hesla) // ------------------------------------------------------------ $chyba = ''; $uspech = false; if ($_SERVER['REQUEST_METHOD'] === 'POST' && $token_ok) { // -- 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)) { $heslo = $_POST['heslo'] ?? ''; $heslo2 = $_POST['heslo2'] ?? ''; // Validace hesla if (empty($heslo)) { $chyba = 'Heslo nesmí být prázdné.'; } elseif (mb_strlen($heslo) < HESLO_MIN_DELKA) { $chyba = 'Heslo musí mít alespoň ' . HESLO_MIN_DELKA . ' znaků.'; } elseif ($heslo !== $heslo2) { $chyba = 'Hesla se neshodují.'; } } if (empty($chyba)) { try { // Zahashujeme nové heslo $heslo_hash = password_hash($heslo, PASSWORD_DEFAULT); // Aktualizujeme heslo uživatele v DB $stmt = $pdo->prepare(" UPDATE `" . DB_TABULKA_UZIVATELE . "` SET `heslo` = :heslo WHERE `id` = :id "); $stmt->execute([ ':heslo' => $heslo_hash, ':id' => $uzivatel_id, ]); // Smažeme použitý reset token – je jednorázový $stmt2 = $pdo->prepare(" DELETE FROM `" . DB_TABULKA_RESET . "` WHERE `id` = :id "); $stmt2->execute([':id' => $zaznam_id]); // Smažeme všechny remember me tokeny tohoto uživatele – // po změně hesla jsou všechna zařízení odhlášena $stmt3 = $pdo->prepare(" DELETE FROM `" . DB_TABULKA_TOKENY . "` WHERE `uzivatel_id` = :uzivatel_id "); $stmt3->execute([':uzivatel_id' => $uzivatel_id]); $uspech = true; } catch (PDOException $e) { error_log('Chyba při změně hesla: ' . $e->getMessage()); $chyba = 'Při ukládání hesla došlo k chybě. Zkuste to prosím znovu.'; } } } // ------------------------------------------------------------ // HTML VÝSTUP // ------------------------------------------------------------ ?> Nové heslo – <?php echo htmlspecialchars(PROJEKT_NAZEV); ?>

Nastavení nového hesla

Heslo bylo úspěšně změněno.

Všechna zařízení byla odhlášena. Můžeš se nyní přihlásit novým heslem.

Tento odkaz pro obnovu hesla je neplatný nebo vypršel.

Požádej o nový odkaz pro obnovu hesla.

Chyba:

Zadej nové heslo pro svůj účet.



Síla hesla: zadej heslo


(čekám na dostatečně silné heslo)