query("SELECT COUNT(*) FROM admin_users")->fetchColumn(); if ($cnt > 0) { header('Location: ' . url_path('/public/admin/login.php')); exit; } $err = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $csrf = (string)($_POST['csrf'] ?? ''); $user = trim((string)($_POST['username'] ?? '')); $pass = (string)($_POST['password'] ?? ''); $pass2 = (string)($_POST['password2'] ?? ''); if (!csrf_check($csrf)) { $err = 'Invalid session. Refresh and try again.'; } elseif (!preg_match('/^[a-zA-Z0-9_]{3,32}$/', $user)) { $err = 'Username: 3-32 chars (letters, numbers, underscore).'; } elseif (strlen($pass) < 10) { $err = 'Password must be at least 10 characters.'; } elseif ($pass !== $pass2) { $err = 'Passwords do not match.'; } else { // even though cnt==0, still check just in case (race condition) $st = pdo()->prepare("SELECT id FROM admin_users WHERE username=? LIMIT 1"); $st->execute([$user]); if ($st->fetch()) { $err = 'Username already exists.'; } else { $algo = defined('PASSWORD_ARGON2ID') ? PASSWORD_ARGON2ID : PASSWORD_DEFAULT; $hash = password_hash($pass, $algo, [ 'memory_cost' => 1 << 17, // 128MB 'time_cost' => 4, 'threads' => 2, ]); $ins = pdo()->prepare("INSERT INTO admin_users (username, pass_hash) VALUES (?, ?)"); $ins->execute([$user, $hash]); $id = (int)pdo()->lastInsertId(); admin_login(['id' => $id, 'username' => $user]); header('Location: ' . url_path('/public/admin/dashboard.php')); exit; } } } ?>