From a4b4ad54750f9dbda436951ad6c29605d9ccec35 Mon Sep 17 00:00:00 2001 From: stepan Date: Tue, 17 Mar 2026 00:11:15 +0100 Subject: [PATCH] =?UTF-8?q?[F=C3=81ZE-3][admin]=20P=C5=99id=C3=A1no=20admi?= =?UTF-8?q?nistra=C4=8Dn=C3=AD=20rozhran=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auth/admin.php | 602 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 602 insertions(+) create mode 100644 auth/admin.php diff --git a/auth/admin.php b/auth/admin.php new file mode 100644 index 0000000..96e4b39 --- /dev/null +++ b/auth/admin.php @@ -0,0 +1,602 @@ +Stránka nenalezena

Stránka nebyla nalezena.

'); +} + +// ------------------------------------------------------------ +// CSRF TOKEN +// ------------------------------------------------------------ + +if (empty($_SESSION['csrf_token'])) { + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); +} +$csrf_token = $_SESSION['csrf_token']; + +// ------------------------------------------------------------ +// ZPRACOVÁNÍ AKCÍ (POST požadavky) +// ------------------------------------------------------------ + +$zprava = ''; // zpráva o úspěchu +$chyba = ''; // chybová hláška + +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.'; + } + + if (empty($chyba)) { + + $akce = $_POST['akce'] ?? ''; + + // ==================================================== + // AKCE: Založení nového uživatele + // ==================================================== + if ($akce === 'novy_uzivatel') { + + $email = trim($_POST['email'] ?? ''); + $heslo = $_POST['heslo'] ?? ''; + $heslo2 = $_POST['heslo2'] ?? ''; + $admin = isset($_POST['admin']) ? 1 : 0; + + // Validace emailu + if (empty($email)) { + $chyba = 'Email nesmí být prázdný.'; + } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + $chyba = 'Email není platná emailová adresa.'; + } + + // Validace hesla + if (empty($chyba) && empty($heslo)) { + $chyba = 'Heslo nesmí být prázdné.'; + } elseif (empty($chyba) && mb_strlen($heslo) < HESLO_MIN_DELKA) { + $chyba = 'Heslo musí mít alespoň ' . HESLO_MIN_DELKA . ' znaků.'; + } elseif (empty($chyba) && $heslo !== $heslo2) { + $chyba = 'Hesla se neshodují.'; + } + + if (empty($chyba)) { + + // Kontrola, zda email již neexistuje + $stmt = $pdo->prepare(" + SELECT COUNT(*) AS pocet + FROM `" . DB_TABULKA_UZIVATELE . "` + WHERE `email` = :email + "); + $stmt->execute([':email' => $email]); + if ($stmt->fetch()['pocet'] > 0) { + $chyba = 'Uživatel s tímto emailem již existuje.'; + } + } + + if (empty($chyba)) { + + try { + $heslo_hash = password_hash($heslo, PASSWORD_DEFAULT); + + $stmt = $pdo->prepare(" + INSERT INTO `" . DB_TABULKA_UZIVATELE . "` + (`email`, `heslo`, `admin`) + VALUES + (:email, :heslo, :admin) + "); + $stmt->execute([ + ':email' => $email, + ':heslo' => $heslo_hash, + ':admin' => $admin, + ]); + + $novy_id = $pdo->lastInsertId(); + + // Vytvoříme prázdný řádek v tabulce služby + if (DB_TABULKA_SLUZBA !== '') { + $stmt2 = $pdo->prepare(" + INSERT INTO `" . DB_TABULKA_SLUZBA . "` + (`uzivatel_id`) + VALUES + (:uzivatel_id) + "); + $stmt2->execute([':uzivatel_id' => $novy_id]); + } + + $zprava = 'Uživatel ' . htmlspecialchars($email) . ' byl úspěšně vytvořen.'; + + } catch (PDOException $e) { + error_log('Admin – chyba při vytváření uživatele: ' . $e->getMessage()); + $chyba = 'Při vytváření uživatele došlo k chybě databáze.'; + } + } + } + + // ==================================================== + // AKCE: Změna hesla uživatele + // ==================================================== + elseif ($akce === 'zmena_hesla') { + + $uzivatel_id = (int) ($_POST['uzivatel_id'] ?? 0); + $heslo = $_POST['heslo'] ?? ''; + $heslo2 = $_POST['heslo2'] ?? ''; + + if ($uzivatel_id <= 0) { + $chyba = 'Neplatné ID uživatele.'; + } elseif (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, + ]); + + // Po změně hesla smažeme všechny remember me tokeny + // tohoto uživatele – odhlásíme ho ze všech zařízení + $stmt2 = $pdo->prepare(" + DELETE FROM `" . DB_TABULKA_TOKENY . "` + WHERE `uzivatel_id` = :uzivatel_id + "); + $stmt2->execute([':uzivatel_id' => $uzivatel_id]); + + $zprava = 'Heslo uživatele bylo úspěšně změněno. Uživatel byl odhlášen ze všech zařízení.'; + + } catch (PDOException $e) { + error_log('Admin – chyba při změně hesla: ' . $e->getMessage()); + $chyba = 'Při změně hesla došlo k chybě databáze.'; + } + } + } + + // ==================================================== + // AKCE: Smazání uživatele + // ==================================================== + elseif ($akce === 'smazat_uzivatele') { + + $uzivatel_id = (int) ($_POST['uzivatel_id'] ?? 0); + + if ($uzivatel_id <= 0) { + $chyba = 'Neplatné ID uživatele.'; + } + + // Admin nesmí smazat sám sebe + if (empty($chyba) && $uzivatel_id === (int) $auth_uzivatel['id']) { + $chyba = 'Nemůžeš smazat svůj vlastní účet.'; + } + + if (empty($chyba)) { + + try { + // Díky FOREIGN KEY s ON DELETE CASCADE se automaticky + // smažou i záznamy v auth_remember_tokens a auth_password_resets + // a v tabulce služby (users) + $stmt = $pdo->prepare(" + DELETE FROM `" . DB_TABULKA_UZIVATELE . "` + WHERE `id` = :id + "); + $stmt->execute([':id' => $uzivatel_id]); + + $zprava = 'Uživatel byl úspěšně smazán.'; + + } catch (PDOException $e) { + error_log('Admin – chyba při mazání uživatele: ' . $e->getMessage()); + $chyba = 'Při mazání uživatele došlo k chybě databáze.'; + } + } + } + + // ==================================================== + // AKCE: Testovací email + // ==================================================== + elseif ($akce === 'test_email') { + + $vysledek = odesli_mail( + MAIL_TEST_ADRESA, + 'Testovací email – ' . PROJEKT_NAZEV, + "Toto je testovací email ze systému přihlašování.\n\n" + . "Projekt: " . PROJEKT_NAZEV . "\n" + . "URL: " . PROJEKT_URL . "\n" + . "Čas odeslání: " . date('Y-m-d H:i:s') . "\n\n" + . "Pokud tento email vidíš, odesílání emailů funguje správně." + ); + + if ($vysledek) { + $zprava = 'Testovací email byl odeslán na ' . htmlspecialchars(MAIL_TEST_ADRESA) . '.'; + } else { + $chyba = 'Odeslání testovacího emailu selhalo. Zkontroluj PHP error log a nastavení v config.php.'; + } + } + } +} + +// ------------------------------------------------------------ +// NAČTENÍ SEZNAMU UŽIVATELŮ +// ------------------------------------------------------------ + +$uzivatele = []; +try { + $stmt = $pdo->query(" + SELECT `id`, `email`, `admin`, `vytvoreno` + FROM `" . DB_TABULKA_UZIVATELE . "` + ORDER BY `vytvoreno` ASC + "); + $uzivatele = $stmt->fetchAll(); +} catch (PDOException $e) { + error_log('Admin – chyba při načítání uživatelů: ' . $e->getMessage()); + $chyba = 'Nepodařilo se načíst seznam uživatelů.'; +} + +// ------------------------------------------------------------ +// HTML VÝSTUP +// ------------------------------------------------------------ +?> + + + + + Administrace – <?php echo htmlspecialchars(PROJEKT_NAZEV); ?> + + + + + + +

Administrace

+

+ +

Přihlášen jako:

+ + + +

OK:

+ + + +

Chyba:

+ + +
+ + + +

Seznam uživatelů

+ + +

Žádní uživatelé.

+ + + + + + + + + + + + + + + + + + +
IDEmailAdminRegistrovánAkce
+ + +
+ + + + + + +
+ +   + + + +
+ + + + +
+ + +
+ + +
+ + + +

Přidat nového uživatele

+ +
+ + + + +

+
+ +

+ +

+
+ +
+ Síla hesla: zadej heslo +

+ +

+
+ +

+ +

+ +

+ +

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

+ +
+ +
+ + + +

Konfigurace systému

+ +

Hodnoty jsou načteny z auth/config.php. Citlivé údaje jsou skryté – zobrazíš je kliknutím.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KonstantaHodnota
DB_HOST
DB_NAME
DB_USER
DB_PASS + + [skryto] + + + +
DB_TABULKA_UZIVATELE
DB_TABULKA_TOKENY
DB_TABULKA_BRUTE
DB_TABULKA_RESET
DB_TABULKA_SLUZBA
PROJEKT_NAZEV
PROJEKT_URL
AUTH_LOGIN_URL
AUTH_LOGOUT_URL
AUTH_REDIRECT_PO_PRIHLASENI
REGISTRACE_OTEVRENA
VYZADOVAT_PRIHLASENI
SESSION_NAZEV
SESSION_EXPIRACE sekund + ( hodin)
REMEMBER_EXPIRACE sekund + ( dní)
BRUTE_MAX_POKUSU
BRUTE_OKNO sekund + ( minut)
HESLO_MIN_SILA / 4
HESLO_MIN_DELKA znaků
MAIL_ODESILATEL
MAIL_ODESILATEL_JMENO
MAIL_TEST_ADRESA
AUTH_CSS
+ +
+ + + +

Test odesílání emailů

+ +

Odešle testovací email na adresu +(nastaveno v config.php jako MAIL_TEST_ADRESA).

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