diff --git a/auth/install.php b/auth/install.php
index 5c2bde1..e40a0ae 100644
--- a/auth/install.php
+++ b/auth/install.php
@@ -6,11 +6,14 @@
// Vytvoří všechny potřebné tabulky v databázi a prvního
// administrátora.
//
+// Průběh:
+// Krok 1 – pokus o automatické vytvoření tabulek
+// Krok 2 – pokud selže, zobrazí SQL pro ruční zadání do phpMyAdmin
+// Krok 3 – ověření, že tabulky existují a mají správnou strukturu
+// Krok 4 – formulář pro vytvoření prvního admina + zámek
+//
// Po úspěšné instalaci se vytvoří soubor install.lock
// a tento skript již nepůjde spustit znovu.
-//
-// BEZPEČNOST: Po instalaci můžeš install.php smazat,
-// nebo ho nechat – install.lock ho zablokuje.
// ============================================================
require_once __DIR__ . '/config.php';
@@ -23,131 +26,187 @@ require_once __DIR__ . '/db.php';
$lock_soubor = __DIR__ . '/install.lock';
if (file_exists($lock_soubor)) {
- die('
Instalace již proběhla. Pokud chceš instalaci opakovat, smaž soubor auth/install.lock. Pozor – tím přijdeš o všechna data!
');
+ die('
+ Instalace
+ Instalace již proběhla.
+ Pokud chceš instalaci opakovat, smaž soubor
+ auth/install.lock. Pozor – tím přijdeš o všechna data!
+ ');
}
// ------------------------------------------------------------
-// ZPRACOVÁNÍ FORMULÁŘE (pokud byl odeslán)
+// SQL PŘÍKAZY PRO VYTVOŘENÍ TABULEK
+// ------------------------------------------------------------
+// Definujeme je jako pole – použijeme je jak pro automatické
+// spuštění, tak pro zobrazení uživateli k ručnímu zadání.
+
+$sql_tabulky = [
+
+ 'auth_users' => "CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_UZIVATELE . "` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `email` VARCHAR(255) NOT NULL,
+ `heslo` VARCHAR(255) NOT NULL,
+ `admin` TINYINT(1) NOT NULL DEFAULT 0,
+ `vytvoreno` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `email` (`email`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
+
+ 'auth_remember_tokens' => "CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_TOKENY . "` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `uzivatel_id` INT UNSIGNED NOT NULL,
+ `selector` VARCHAR(32) NOT NULL,
+ `token_hash` VARCHAR(255) NOT NULL,
+ `expiruje` DATETIME NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `selector` (`selector`),
+ FOREIGN KEY (`uzivatel_id`)
+ REFERENCES `" . DB_TABULKA_UZIVATELE . "` (`id`)
+ ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
+
+ 'auth_brute_force' => "CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_BRUTE . "` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `ip_adresa` VARCHAR(45) NOT NULL,
+ `email` VARCHAR(255) NOT NULL,
+ `cas` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`),
+ KEY `ip_adresa` (`ip_adresa`),
+ KEY `email` (`email`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
+
+ 'auth_password_resets' => "CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_RESET . "` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `uzivatel_id` INT UNSIGNED NOT NULL,
+ `token_hash` VARCHAR(255) NOT NULL,
+ `expiruje` DATETIME NOT NULL,
+ PRIMARY KEY (`id`),
+ FOREIGN KEY (`uzivatel_id`)
+ REFERENCES `" . DB_TABULKA_UZIVATELE . "` (`id`)
+ ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
+
+];
+
+// Tabulka služby je volitelná
+if (DB_TABULKA_SLUZBA !== '') {
+ $sql_tabulky['sluzba'] = "CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_SLUZBA . "` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `uzivatel_id` INT UNSIGNED NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uzivatel_id` (`uzivatel_id`),
+ FOREIGN KEY (`uzivatel_id`)
+ REFERENCES `" . DB_TABULKA_UZIVATELE . "` (`id`)
+ ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
+}
+
+// ------------------------------------------------------------
+// POMOCNÁ FUNKCE: Ověření existence tabulek
+// ------------------------------------------------------------
+// Zkontroluje, zda všechny potřebné tabulky existují v DB.
+// Vrací pole chybějících tabulek (prázdné = vše OK).
+
+function zkontroluj_tabulky(PDO $pdo): array
+{
+ // Zjistíme, které tabulky existují v aktuální databázi
+ $stmt = $pdo->query("SHOW TABLES");
+ $existuje = $stmt->fetchAll(PDO::FETCH_COLUMN);
+
+ $potrebne = [
+ DB_TABULKA_UZIVATELE,
+ DB_TABULKA_TOKENY,
+ DB_TABULKA_BRUTE,
+ DB_TABULKA_RESET,
+ ];
+
+ if (DB_TABULKA_SLUZBA !== '') {
+ $potrebne[] = DB_TABULKA_SLUZBA;
+ }
+
+ // Vrátíme seznam tabulek, které chybí
+ return array_diff($potrebne, $existuje);
+}
+
+// ------------------------------------------------------------
+// URČENÍ AKTUÁLNÍHO KROKU
// ------------------------------------------------------------
-$chyba = '';
-$uspech = false;
+$krok = 1; // výchozí krok
+$chyba = '';
+$zprava = '';
-if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+// Krok se přenáší přes skryté pole ve formuláři
+$krok_z_post = (int) ($_POST['krok'] ?? 0);
+
+// ------------------------------------------------------------
+// ZPRACOVÁNÍ AKCÍ
+// ------------------------------------------------------------
+
+// == KROK 1: Pokus o automatické vytvoření tabulek ============
+if ($krok_z_post === 0 || $krok_z_post === 1) {
+
+ $auto_ok = true;
+
+ foreach ($sql_tabulky as $nazev => $sql) {
+ try {
+ $pdo->exec($sql);
+ } catch (PDOException $e) {
+ // Automatické vytvoření selhalo – uživatel nemá práva
+ $auto_ok = false;
+ break;
+ }
+ }
+
+ if ($auto_ok) {
+ // Tabulky byly vytvořeny automaticky – přeskočíme na krok 4
+ $krok = 4;
+ } else {
+ // Nemáme práva – přejdeme na krok 2 (ruční SQL)
+ $krok = 2;
+ }
+}
+
+// == KROK 3: Ověření tabulek po ručním zadání SQL =============
+elseif ($krok_z_post === 3) {
+
+ $chybejici = zkontroluj_tabulky($pdo);
+
+ if (empty($chybejici)) {
+ // Všechny tabulky existují – přejdeme na krok 4
+ $krok = 4;
+ } else {
+ // Stále chybí tabulky – zůstaneme na kroku 2/3
+ $krok = 3;
+ $chyba = 'Následující tabulky stále chybí: '
+ . implode(', ', $chybejici)
+ . '. Zkontroluj, zda jsi SQL správně zadal do phpMyAdmin.';
+ }
+}
+
+// == KROK 4: Vytvoření prvního admina =========================
+elseif ($krok_z_post === 4) {
- // Načtení hodnot z formuláře
$email = trim($_POST['email'] ?? '');
$heslo = $_POST['heslo'] ?? '';
$heslo2 = $_POST['heslo2'] ?? '';
- // Validace emailu
+ // Validace
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)) {
+ } elseif (empty($heslo)) {
$chyba = 'Heslo nesmí být prázdné.';
- } elseif (empty($chyba) && mb_strlen($heslo) < HESLO_MIN_DELKA) {
+ } elseif (mb_strlen($heslo) < HESLO_MIN_DELKA) {
$chyba = 'Heslo musí mít alespoň ' . HESLO_MIN_DELKA . ' znaků.';
- } elseif (empty($chyba) && $heslo !== $heslo2) {
+ } elseif ($heslo !== $heslo2) {
$chyba = 'Hesla se neshodují.';
}
- // Pokud není chyba, spustíme instalaci
if (empty($chyba)) {
try {
-
- // ------------------------------------------------
- // VYTVOŘENÍ TABULEK
- // ------------------------------------------------
-
- // Tabulka uživatelů přihlašovacího systému
- // utf8mb4 = plná podpora Unicode (diakritika, emoji, ...)
- $pdo->exec("
- CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_UZIVATELE . "` (
- `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
- `email` VARCHAR(255) NOT NULL,
- `heslo` VARCHAR(255) NOT NULL,
- `admin` TINYINT(1) NOT NULL DEFAULT 0,
- `vytvoreno` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- UNIQUE KEY `email` (`email`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
- ");
-
- // Tabulka remember me tokenů
- // selector = veřejný identifikátor pro vyhledání záznamu v DB
- // token_hash = bcrypt hash tajného tokenu (samotný token je jen v cookie)
- $pdo->exec("
- CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_TOKENY . "` (
- `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
- `uzivatel_id` INT UNSIGNED NOT NULL,
- `selector` VARCHAR(32) NOT NULL,
- `token_hash` VARCHAR(255) NOT NULL,
- `expiruje` DATETIME NOT NULL,
- PRIMARY KEY (`id`),
- UNIQUE KEY `selector` (`selector`),
- FOREIGN KEY (`uzivatel_id`)
- REFERENCES `" . DB_TABULKA_UZIVATELE . "` (`id`)
- ON DELETE CASCADE
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
- ");
-
- // Tabulka brute force záznamů
- // Ukládají se neúspěšné pokusy o přihlášení (IP adresa, email, čas)
- $pdo->exec("
- CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_BRUTE . "` (
- `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
- `ip_adresa` VARCHAR(45) NOT NULL,
- `email` VARCHAR(255) NOT NULL,
- `cas` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- KEY `ip_adresa` (`ip_adresa`),
- KEY `email` (`email`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
- ");
-
- // Tabulka tokenů pro obnovu hesla
- // Token je jednorázový a platí omezenou dobu (viz config.php)
- $pdo->exec("
- CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_RESET . "` (
- `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
- `uzivatel_id` INT UNSIGNED NOT NULL,
- `token_hash` VARCHAR(255) NOT NULL,
- `expiruje` DATETIME NOT NULL,
- PRIMARY KEY (`id`),
- FOREIGN KEY (`uzivatel_id`)
- REFERENCES `" . DB_TABULKA_UZIVATELE . "` (`id`)
- ON DELETE CASCADE
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
- ");
-
- // Tabulka uživatelů konkrétní služby (pokud je nastavena v config.php)
- // Tato tabulka slouží pro data specifická pro tvůj projekt.
- // Zatím obsahuje jen vazbu na auth_users – sloupce si přidáš sám.
- if (DB_TABULKA_SLUZBA !== '') {
- $pdo->exec("
- CREATE TABLE IF NOT EXISTS `" . DB_TABULKA_SLUZBA . "` (
- `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
- `uzivatel_id` INT UNSIGNED NOT NULL,
- PRIMARY KEY (`id`),
- UNIQUE KEY `uzivatel_id` (`uzivatel_id`),
- FOREIGN KEY (`uzivatel_id`)
- REFERENCES `" . DB_TABULKA_UZIVATELE . "` (`id`)
- ON DELETE CASCADE
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
- ");
- }
-
- // ------------------------------------------------
- // VYTVOŘENÍ PRVNÍHO ADMIN UŽIVATELE
- // ------------------------------------------------
-
- // Heslo zahashujeme pomocí bcrypt – nikdy neukládáme plaintext!
$heslo_hash = password_hash($heslo, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("
@@ -161,9 +220,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
':heslo' => $heslo_hash,
]);
- $novy_uzivatel_id = $pdo->lastInsertId();
+ $novy_id = $pdo->lastInsertId();
- // Pokud existuje tabulka služby, vytvoříme k novému uživateli prázdný řádek
if (DB_TABULKA_SLUZBA !== '') {
$stmt2 = $pdo->prepare("
INSERT INTO `" . DB_TABULKA_SLUZBA . "`
@@ -171,33 +229,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
VALUES
(:uzivatel_id)
");
- $stmt2->execute([':uzivatel_id' => $novy_uzivatel_id]);
+ $stmt2->execute([':uzivatel_id' => $novy_id]);
}
- // ------------------------------------------------
- // VYTVOŘENÍ ZÁMKU – zabránění opakované instalaci
- // ------------------------------------------------
-
+ // Vytvoříme zámek – instalace je hotová
file_put_contents($lock_soubor, 'Instalace proběhla: ' . date('Y-m-d H:i:s'));
- $uspech = true;
+ $krok = 5; // krok 5 = úspěšné dokončení
} catch (PDOException $e) {
- // Chybu zalogujeme, uživateli zobrazíme obecnou hlášku
- error_log('Chyba při instalaci: ' . $e->getMessage());
- $chyba = 'Při instalaci došlo k chybě databáze. Zkontroluj nastavení v config.php a PHP error log.';
- } catch (Exception $e) {
- error_log('Chyba při instalaci: ' . $e->getMessage());
- $chyba = 'Při instalaci došlo k neočekávané chybě.';
+ error_log('Chyba při instalaci (admin): ' . $e->getMessage());
+ $chyba = 'Při vytváření admina došlo k chybě databáze. Zkontroluj PHP error log.';
+ $krok = 4;
}
+
+ } else {
+ // Validace selhala – zůstaneme na kroku 4
+ $krok = 4;
}
}
// ------------------------------------------------------------
-// HTML VÝSTUP
+// SESTAVENÍ SQL TEXTU PRO ZOBRAZENÍ UŽIVATELI (krok 2)
// ------------------------------------------------------------
-// Poznámka: žádné stylování – vše je záměrně prosté,
-// aby žádný prvek nebyl skrytý nebo překrytý.
+
+$sql_pro_zobrazeni = implode(";\n\n", $sql_tabulky) . ';';
+
+// ------------------------------------------------------------
+// HTML VÝSTUP
// ------------------------------------------------------------
?>
@@ -211,23 +270,70 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
Instalace systému přihlašování
-
+
+ Chyba:
+
- Instalace proběhla úspěšně!
- Tabulky byly vytvořeny a první administrátor byl založen.
- Byl vytvořen soubor auth/install.lock – instalaci již nelze spustit znovu.
- Přejít na přihlášení
+
-
+ Nepodařilo se automaticky vytvořit tabulky v databázi –
+ pravděpodobně nemá databázový uživatel dostatečná oprávnění
+ (CREATE TABLE).
- Tento skript vytvoří potřebné tabulky v databázi a založí prvního administrátora.
- Spusť ho pouze jednou. Po instalaci bude zablokován souborem install.lock.
+ Postup:
+
+ - Zkopíruj SQL níže.
+ - Otevři phpMyAdmin a vyber svou databázi
+ (
).
+ - Klikni na záložku SQL, vlož SQL a spusť ho.
+ - Vrať se sem a klikni na tlačítko níže.
+
-
- Chyba:
-
+
+
+
+
+
+
+
+
+ Tabulky ještě nejsou v pořádku. Zkontroluj phpMyAdmin a zkus to znovu.
+
+
+
+
+
+
+
+
+
+ Tabulky jsou připraveny.
+ Nyní vytvoř prvního administrátora.
+
+
+ Instalace proběhla úspěšně!
+ Tabulky byly vytvořeny a první administrátor byl založen.
+ Byl vytvořen soubor auth/install.lock –
+ instalaci již nelze spustit znovu.
+ Přejít na přihlášení
+
-