'grav-recovery', 'cookie_httponly' => true, 'cookie_secure' => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off', 'cookie_samesite' => 'Lax', ]); $manager = new RecoveryManager(); $context = $manager->getContext() ?? []; $token = $context['token'] ?? null; $authenticated = $token && isset($_SESSION['grav_recovery_authenticated']) && hash_equals($_SESSION['grav_recovery_authenticated'], $token); $errorMessage = null; $notice = null; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? ''; if ($action === 'authenticate') { $provided = trim($_POST['token'] ?? ''); if ($token && hash_equals($token, $provided)) { $_SESSION['grav_recovery_authenticated'] = $token; header('Location: ' . $_SERVER['REQUEST_URI']); exit; } $errorMessage = 'Invalid recovery token.'; } elseif ($authenticated) { $service = new SafeUpgradeService(); try { if ($action === 'rollback' && !empty($_POST['manifest'])) { $service->rollback(trim($_POST['manifest'])); $manager->clear(); $_SESSION['grav_recovery_authenticated'] = null; $notice = 'Rollback complete. Please reload Grav.'; } if ($action === 'clear-flag') { $manager->clear(); $_SESSION['grav_recovery_authenticated'] = null; $notice = 'Recovery flag cleared.'; } } catch (\Throwable $e) { $errorMessage = $e->getMessage(); } } else { $errorMessage = 'Authentication required.'; } } $quarantineFile = GRAV_ROOT . '/user/data/upgrades/quarantine.json'; $quarantine = []; if (is_file($quarantineFile)) { $decoded = json_decode(file_get_contents($quarantineFile), true); if (is_array($decoded)) { $quarantine = $decoded; } } $manifestDir = GRAV_ROOT . '/user/data/upgrades'; $manifests = []; if (is_dir($manifestDir)) { $files = glob($manifestDir . '/*.json'); if ($files) { rsort($files); foreach ($files as $file) { $decoded = json_decode(file_get_contents($file), true); if (is_array($decoded)) { $decoded['file'] = basename($file); $manifests[] = $decoded; } } } } header('Content-Type: text/html; charset=utf-8'); ?> Grav Recovery Mode

Grav Recovery Mode

This site is running in recovery mode because Grav detected a fatal error.

Locate the recovery token in user/data/recovery.flag and enter it below.

Failure Details

Quarantined Plugins

Rollback

No upgrade snapshots were found.