| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- <?php
- declare(strict_types=1);
- require_once __DIR__ . "/../config.php";
- require_once __DIR__ . "/../includes/version.php";
- require_once __DIR__ . "/../includes/updater.php";
- if (empty($_SESSION["admin_logged_in"])) {
- header("Location: login.php");
- exit();
- }
- if (!defined("UPDATE_MANIFEST_URL")) {
- define("UPDATE_MANIFEST_URL", "");
- }
- if (!defined("UPDATE_WORK_DIR")) {
- define("UPDATE_WORK_DIR", DATA_DIR . "updates/work/");
- }
- if (!defined("UPDATE_BACKUP_DIR")) {
- define("UPDATE_BACKUP_DIR", DATA_DIR . "updates/backups/");
- }
- if (!defined("UPDATE_PRESERVE_PATHS")) {
- define("UPDATE_PRESERVE_PATHS", ["config.php", "data/", ".git/"]);
- }
- if (!defined("UPDATE_REQUIRED_PACKAGE_PATHS")) {
- define("UPDATE_REQUIRED_PACKAGE_PATHS", ["index.php", "admin/", "includes/"]);
- }
- if (!defined("UPDATE_USER_AGENT")) {
- define("UPDATE_USER_AGENT", "Simple-PHP-Updater/" . APP_VERSION);
- }
- $messages = [];
- $errors = [];
- $manifest = null;
- $updateAvailable = false;
- function updaterEscape($value): string
- {
- return htmlspecialchars((string) $value, ENT_QUOTES, "UTF-8");
- }
- function updaterCsrfToken(): string
- {
- if (empty($_SESSION["updater_csrf_token"])) {
- $_SESSION["updater_csrf_token"] = bin2hex(random_bytes(32));
- }
- return $_SESSION["updater_csrf_token"];
- }
- function updaterValidateCsrfToken(string $token): bool
- {
- return !empty($_SESSION["updater_csrf_token"]) &&
- hash_equals($_SESSION["updater_csrf_token"], $token);
- }
- try {
- $appRoot = realpath(__DIR__ . "/..");
- $updater = new SimpleUpdater([
- "manifest_url" => UPDATE_MANIFEST_URL,
- "work_dir" => UPDATE_WORK_DIR,
- "backup_dir" => UPDATE_BACKUP_DIR,
- "current_version" => APP_VERSION,
- "app_root" => $appRoot === false ? "" : $appRoot,
- "user_agent" => UPDATE_USER_AGENT,
- "preserve_paths" => UPDATE_PRESERVE_PATHS,
- "required_package_paths" => UPDATE_REQUIRED_PACKAGE_PATHS,
- ]);
- try {
- $manifest = $updater->fetchManifest();
- $updateAvailable = $updater->updateAvailable($manifest);
- } catch (Throwable $exception) {
- $errors[] = $exception->getMessage();
- }
- if ($_SERVER["REQUEST_METHOD"] === "POST") {
- if (!updaterValidateCsrfToken((string) ($_POST["csrf_token"] ?? ""))) {
- $errors[] = "Invalid token. Please reload the page and try again.";
- } else {
- try {
- $manifest = $updater->fetchManifest();
- $force = !empty($_POST["force_redeploy"]);
- $updateAvailable = $updater->updateAvailable($manifest);
- if (!$updateAvailable && !$force) {
- throw new RuntimeException(
- "No newer update is available. Enable force redeployment to deploy this package anyway.",
- );
- }
- $result = $updater->deploy($manifest);
- $messages[] = "Deployment finished.";
- $messages[] = "Files copied: " . $result["copied"];
- $messages[] = "Files backed up: " . $result["backed_up"];
- $messages[] = "Old backup directories removed: " . $result["removed_backups"];
- $messages[] = "Skipped preserved paths: " . $result["skipped"];
- $messages[] = "Backup directory: " . $result["backup_dir"];
- } catch (Throwable $exception) {
- $errors[] = $exception->getMessage();
- }
- }
- }
- } catch (Throwable $exception) {
- $errors[] = $exception->getMessage();
- }
- ?>
- <!DOCTYPE html>
- <html lang="de">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Updater</title>
- </head>
- <body>
- <h1>Updater</h1>
- <p><a href="settings.php">Back to settings</a></p>
- <?php foreach ($messages as $message): ?>
- <p><strong><?php echo updaterEscape($message); ?></strong></p>
- <?php endforeach; ?>
- <?php foreach ($errors as $error): ?>
- <p><strong>Error:</strong> <?php echo updaterEscape($error); ?></p>
- <?php endforeach; ?>
- <table border="1" cellpadding="6" cellspacing="0">
- <tbody>
- <tr>
- <th align="left">Installed version</th>
- <td><?php echo updaterEscape(APP_VERSION); ?></td>
- </tr>
- <tr>
- <th align="left">Update target URL</th>
- <td><?php echo updaterEscape(UPDATE_MANIFEST_URL); ?></td>
- </tr>
- <tr>
- <th align="left">Available version</th>
- <td><?php echo updaterEscape($manifest["version"] ?? "Unavailable"); ?></td>
- </tr>
- <tr>
- <th align="left">Package URL</th>
- <td><?php echo updaterEscape($manifest["package_url"] ?? "Unavailable"); ?></td>
- </tr>
- <tr>
- <th align="left">SHA-256</th>
- <td><?php echo updaterEscape($manifest["sha256"] ?? "Unavailable"); ?></td>
- </tr>
- <tr>
- <th align="left">Published at</th>
- <td><?php echo updaterEscape($manifest["published_at"] ?? "Unavailable"); ?></td>
- </tr>
- <tr>
- <th align="left">Update available</th>
- <td><?php echo $updateAvailable ? "Yes" : "No"; ?></td>
- </tr>
- </tbody>
- </table>
- <h2>Manual deployment</h2>
- <form method="POST">
- <input type="hidden" name="csrf_token" value="<?php echo updaterEscape(updaterCsrfToken()); ?>">
- <p>
- <label>
- <input type="checkbox" name="force_redeploy" value="1">
- Force redeployment
- </label>
- </p>
- <button type="submit" name="deploy_update" value="1">Deploy update</button>
- </form>
- </body>
- </html>
|