From ebb2ebc2602a885cc10e2a8e9df1532e03070a52 Mon Sep 17 00:00:00 2001 From: Osvaldo Ortega <48293249+osortega@users.noreply.github.com> Date: Mon, 20 Apr 2026 17:13:29 -0700 Subject: [PATCH] feat: enhance authentication handling for web sessions and account initialization (#311538) --- .../welcome/browser/welcome.contribution.ts | 27 +++++++++++++++++++ .../accounts/browser/defaultAccount.ts | 5 +++- .../chat/common/chatEntitlementService.ts | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/vs/sessions/contrib/welcome/browser/welcome.contribution.ts b/src/vs/sessions/contrib/welcome/browser/welcome.contribution.ts index 8efccdb6b73..3ad2a355b19 100644 --- a/src/vs/sessions/contrib/welcome/browser/welcome.contribution.ts +++ b/src/vs/sessions/contrib/welcome/browser/welcome.contribution.ts @@ -136,6 +136,7 @@ export class SessionsWelcomeContribution extends Disposable implements IWorkbenc // Auth is handled by the walkthrough's GitHub button via // IAuthenticationService. Discovery runs separately after auth. this._checkWebAuth(); + this._watchWebAuth(); return; } const isFirstLaunch = !this.storageService.getBoolean(WELCOME_COMPLETE_KEY, StorageScope.APPLICATION, false); @@ -165,6 +166,32 @@ export class SessionsWelcomeContribution extends Disposable implements IWorkbenc this.showWalkthrough(); } + /** + * Web-only: react to GitHub session loss. When the user's last GitHub + * session is removed (token expired, secret storage wiped, or explicit + * sign-out from the account menu), clear the welcome completion marker + * and show the sign-in walkthrough again. Without this, passive sign-out + * leaves the user on a seemingly-working workbench with a stale UI. + */ + private _watchWebAuth(): void { + this._register(this.authenticationService.onDidChangeSessions(async e => { + if (e.providerId !== 'github' || !e.event.removed?.length) { + return; + } + try { + const remaining = await this.authenticationService.getSessions('github'); + if (remaining.length > 0) { + return; + } + } catch { + // Provider became unavailable — treat as signed out + } + this.logService.info('[sessions welcome] GitHub session removed on web, re-showing walkthrough'); + this.storageService.remove(WELCOME_COMPLETE_KEY, StorageScope.APPLICATION); + this.showWalkthrough(); + })); + } + private showWalkthroughIfNeeded(): void { if (this._needsChatSetup()) { this.showWalkthrough(); diff --git a/src/vs/workbench/services/accounts/browser/defaultAccount.ts b/src/vs/workbench/services/accounts/browser/defaultAccount.ts index 20eb5b46b5c..a7a98102097 100644 --- a/src/vs/workbench/services/accounts/browser/defaultAccount.ts +++ b/src/vs/workbench/services/accounts/browser/defaultAccount.ts @@ -318,7 +318,10 @@ class DefaultAccountProvider extends Disposable implements IDefaultAccountProvid } private async init(): Promise { - if (isWeb && !this.environmentService.remoteAuthority) { + // Skip initialization for classic web-no-remote (vscode.dev editor), but + // still initialize for the agents web workbench (vscode.dev/agents) where + // account state drives the title bar and the welcome walkthrough. + if (isWeb && !this.environmentService.remoteAuthority && !this.environmentService.isSessionsWindow) { this.logService.debug('[DefaultAccount] Running in web without remote, skipping initialization'); return; } diff --git a/src/vs/workbench/services/chat/common/chatEntitlementService.ts b/src/vs/workbench/services/chat/common/chatEntitlementService.ts index 54a061cec5a..f3fa03bbf62 100644 --- a/src/vs/workbench/services/chat/common/chatEntitlementService.ts +++ b/src/vs/workbench/services/chat/common/chatEntitlementService.ts @@ -343,7 +343,7 @@ export class ChatEntitlementService extends Disposable implements IChatEntitleme ); this.sentimentObs = observableFromEvent(this.onDidChangeSentiment, () => this.sentiment); - if ((isWeb && !environmentService.remoteAuthority)) { + if ((isWeb && !environmentService.remoteAuthority && !environmentService.isSessionsWindow)) { ChatEntitlementContextKeys.Setup.hidden.bindTo(this.contextKeyService).set(true); // hide copilot UI on web if unsupported return; }