// The password is prompted for and never echoed or passed on the command line. if (PHP_SAPI !== 'cli') { http_response_code(403); exit; } require __DIR__ . '/../includes/db.php'; const MIN_PASSWORD_LENGTH = 12; function promptHidden(string $prompt): string { echo $prompt; $interactive = function_exists('posix_isatty') && posix_isatty(STDIN); if ($interactive) shell_exec('stty -echo'); $value = rtrim((string)fgets(STDIN), "\r\n"); if ($interactive) { shell_exec('stty echo'); echo "\n"; } return $value; } $username = $argv[1] ?? ''; if (!preg_match('/^[A-Za-z0-9_.-]{1,64}$/', $username)) { fwrite(STDERR, "Usage: php cli/create_admin.php \n(letters, numbers, dot, dash and underscore only)\n"); exit(1); } $password = promptHidden('Password: '); if (strlen($password) < MIN_PASSWORD_LENGTH) { fwrite(STDERR, 'Password must be at least ' . MIN_PASSWORD_LENGTH . " characters.\n"); exit(1); } if (promptHidden('Confirm password: ') !== $password) { fwrite(STDERR, "Passwords do not match.\n"); exit(1); } $db = getDB(); $hash = password_hash($password, PASSWORD_DEFAULT); $stmt = $db->prepare('SELECT id FROM admins WHERE username = ?'); $stmt->execute([$username]); if ($stmt->fetch()) { $db->prepare('UPDATE admins SET password_hash = ? WHERE username = ?')->execute([$hash, $username]); echo "Password reset for {$username}.\n"; } else { $db->prepare('INSERT INTO admins (username, password_hash) VALUES (?, ?)')->execute([$username, $hash]); echo "Admin {$username} created.\n"; }