From 301f42d2a08f259d4d6b063cc7795fc66975c2a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 14:51:45 +0000 Subject: [PATCH] aio-interface: preserve old PHPSESSID session during cookie migration to survive 502s on mastercontainer update Agent-Logs-Url: https://github.com/nextcloud/all-in-one/sessions/aadfe06c-fde4-4a01-953a-42abd110b416 fix: rename $oldSessionTime to $oldSessionTimestamp for clarity Agent-Logs-Url: https://github.com/nextcloud/all-in-one/sessions/aadfe06c-fde4-4a01-953a-42abd110b416 Co-Authored-By: szaimen <42591237+szaimen@users.noreply.github.com> --- php/public/index.php | 18 +++++++++++++++--- php/src/Auth/AuthManager.php | 12 ++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/php/public/index.php b/php/public/index.php index 2c87ba73..5d706c2d 100644 --- a/php/public/index.php +++ b/php/public/index.php @@ -45,12 +45,16 @@ $container->set(Guard::class, function () use ($responseFactory) { // This is needed because the session cookie was renamed in a previous release. Without this, // users that were logged in before the update would be logged out after the container restarts. $wasAuthenticated = false; +$oldSessionTimestamp = null; if (!isset($_COOKIE['__Host-Http-PHPSESSID']) && isset($_COOKIE['PHPSESSID'])) { session_name('PHPSESSID'); if (session_start(['save_path' => $dataConst->GetSessionDirectory(), 'use_strict_mode' => true])) { $wasAuthenticated = isset($_SESSION[\AIO\Auth\AuthManager::SESSION_KEY]) && $_SESSION[\AIO\Auth\AuthManager::SESSION_KEY] === true; - session_unset(); - session_destroy(); + $oldSessionTimestamp = isset($_SESSION['date_time']) ? (int)$_SESSION['date_time'] : null; + // Do not destroy the old session: if the response carrying the new __Host-Http-PHPSESSID + // cookie is lost (e.g., due to a 502 during a mastercontainer update), the client can + // retry with the old PHPSESSID cookie and still be authenticated. + session_write_close(); } } @@ -68,7 +72,15 @@ session_start([ ]); if ($wasAuthenticated) { - $container->get(\AIO\Auth\AuthManager::class)->SetAuthState(true); + if ($oldSessionTimestamp !== null) { + // Use MigrateAuthState to preserve the original login timestamp. This prevents the + // session deduplicator from running and keeps the old PHPSESSID session file alive, + // so the client can retry with the old cookie if the 502 response causes the new + // __Host-Http-PHPSESSID cookie to not be received. + $container->get(\AIO\Auth\AuthManager::class)->MigrateAuthState($oldSessionTimestamp); + } else { + $container->get(\AIO\Auth\AuthManager::class)->SetAuthState(true); + } } $app->add(Guard::class); diff --git a/php/src/Auth/AuthManager.php b/php/src/Auth/AuthManager.php index 851b5ff6..9d2718e0 100644 --- a/php/src/Auth/AuthManager.php +++ b/php/src/Auth/AuthManager.php @@ -42,6 +42,18 @@ readonly class AuthManager { $_SESSION[self::SESSION_KEY] = $isLoggedIn; } + /** + * Migrates the authenticated state from an old session (different cookie name) to the new session. + * Unlike SetAuthState, this method preserves the original login timestamp and does not update + * the session_date_file, so the session deduplicator is not triggered. This keeps the old session + * file alive in case the response carrying the new cookie is lost (e.g., due to a 502 error during + * a mastercontainer update), allowing the client to retry with the old cookie. + */ + public function MigrateAuthState(int $oldTimestamp) : void { + $_SESSION[self::SESSION_KEY] = true; + $_SESSION['date_time'] = $oldTimestamp; + } + public function IsAuthenticated() : bool { return isset($_SESSION[self::SESSION_KEY]) && $_SESSION[self::SESSION_KEY] === true; }