Files
stepan a116b30df7 [ui] Extrahována kontrola síly hesla do samostatného JS souboru, přidána kontrola minimální délky
[ui] registrace.php – použit společný JS pro kontrolu hesla
[ui] nove_heslo.php – použit společný JS pro kontrolu hesla, opraven odkaz na reset
[ui] admin.php – použit společný JS pro kontrolu hesla
[FÁZE-1][install] Vícekrokový průběh instalace, použit společný JS pro kontrolu hesla
2026-03-17 10:06:44 +01:00

215 lines
6.2 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// ============================================================
// OBNOVA HESLA KROK 2
// ============================================================
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/db.php';
session_name(SESSION_NAZEV);
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'httponly' => true,
'samesite' => 'Strict',
// 'secure' => true,
]);
session_start();
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;
$zaznam_id = 0;
$uzivatel_id = 0;
$id_z_url = $_GET['id'] ?? '';
$token_z_url = $_GET['token'] ?? '';
if (!empty($id_z_url) && !empty($token_z_url)) {
$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) {
if (time() < strtotime($zaznam['expiruje'])) {
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
// ------------------------------------------------------------
$chyba = '';
$uspech = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $token_ok) {
$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'] ?? '';
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 {
$heslo_hash = password_hash($heslo, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("
UPDATE `" . DB_TABULKA_UZIVATELE . "`
SET `heslo` = :heslo
WHERE `id` = :id
");
$stmt->execute([
':heslo' => $heslo_hash,
':id' => $uzivatel_id,
]);
$stmt2 = $pdo->prepare("
DELETE FROM `" . DB_TABULKA_RESET . "`
WHERE `id` = :id
");
$stmt2->execute([':id' => $zaznam_id]);
$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
// ------------------------------------------------------------
?>
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<title>Nové heslo <?php echo htmlspecialchars(PROJEKT_NAZEV); ?></title>
<?php if (AUTH_CSS !== ''): ?>
<link rel="stylesheet" href="<?php echo htmlspecialchars(AUTH_CSS); ?>">
<?php endif; ?>
</head>
<body>
<h1>Nastavení nového hesla</h1>
<h2><?php echo htmlspecialchars(PROJEKT_NAZEV); ?></h2>
<?php if ($uspech): ?>
<p><strong>Heslo bylo úspěšně změněno.</strong></p>
<p>Všechna zařízení byla odhlášena. Můžeš se nyní
<a href="<?php echo htmlspecialchars(AUTH_LOGIN_URL); ?>">přihlásit</a>
novým heslem.</p>
<?php elseif (!$token_ok): ?>
<p><strong>Tento odkaz pro obnovu hesla je neplatný nebo vypršel.</strong></p>
<p>Požádej o <a href="<?php echo htmlspecialchars(AUTH_RESET_URL); ?>">nový odkaz pro obnovu hesla</a>.</p>
<?php else: ?>
<?php if (!empty($chyba)): ?>
<p><strong>Chyba: <?php echo htmlspecialchars($chyba); ?></strong></p>
<?php endif; ?>
<p>Zadej nové heslo pro svůj účet.</p>
<form method="POST" action="">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token); ?>">
<p>
<label for="heslo">Nové heslo:</label><br>
<input
type="password"
id="heslo"
name="heslo"
required
autocomplete="new-password"
>
<br>
<span id="heslo-sila">Síla hesla: zadej heslo</span>
</p>
<p>
<label for="heslo2">Nové heslo znovu (pro ověření):</label><br>
<input
type="password"
id="heslo2"
name="heslo2"
required
autocomplete="new-password"
>
</p>
<p>
<button type="submit" id="tlacitko-odeslat" disabled>
Nastavit nové heslo
</button>
<span id="tlacitko-duvod"> (čekám na dostatečně silné heslo)</span>
</p>
</form>
<?php endif; ?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
<script>
var AUTH_HESLO_MIN_SILA = <?php echo (int) HESLO_MIN_SILA; ?>;
var AUTH_HESLO_MIN_DELKA = <?php echo (int) HESLO_MIN_DELKA; ?>;
</script>
<script src="<?php echo htmlspecialchars(PROJEKT_URL); ?>/auth/js/heslo-sila.js"></script>
</body>
</html>