From 2cb3a79ed1d613bc9de7c5ff432c9135ffb668f2 Mon Sep 17 00:00:00 2001 From: OyinloluB Date: Tue, 29 Jul 2025 16:41:47 -0400 Subject: [PATCH 1/3] fix: sync authentication state across VS Code windows Fixes #498 by implementing event-driven authentication synchronization. When a user logs out from one VS Code window, all other windows now immediately show a clear 'You've been logged out of Coder!' notification instead of confusing errors like 'Invalid argument uriOrString'. Uses ctx.secrets.onDidChange to detect session token changes and syncAuth() to update all windows consistently. - Add syncAuth() function to handle auth state changes - Listen for sessionToken changes via ctx.secrets.onDidChange - Update REST client, VS Code contexts, and workspace providers - Show consistent logout notifications across windows Tested: A/B validation confirms fix eliminates confusing user experience. --- src/extension.ts | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/extension.ts b/src/extension.ts index f38fa0cd..e0c6b092 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -412,4 +412,58 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { } } } + + /** + * Synchronize authentication state across all VS Code windows. + * Fixes Issue #498 by ensuring consistent logout behavior when the session token changes. + */ + async function syncAuth() { + const url = storage.getUrl(); + const token = await storage.getSessionToken(); + + // Update the REST client with current credentials + restClient.setHost(url || ""); + restClient.setSessionToken(token || ""); + + // Determine authentication state + const isAuthenticated = !!(url && token); + + // Update VS Code contexts to reflect current auth state + await vscode.commands.executeCommand( + "setContext", + "coder.authenticated", + isAuthenticated, + ); + + if (!isAuthenticated) { + // Clear owner context since user is not authenticated + await vscode.commands.executeCommand( + "setContext", + "coder.isOwner", + false, + ); + + // Show consistent logout notification across all windows + vscode.window + .showInformationMessage("You've been logged out of Coder!", "Login") + .then((action) => { + if (action === "Login") { + vscode.commands.executeCommand("coder.login"); + } + }); + + vscode.commands.executeCommand("coder.refreshWorkspaces"); + } else { + vscode.commands.executeCommand("coder.refreshWorkspaces"); + } + } + + // Listen for session token changes to sync auth state across windows + ctx.subscriptions.push( + ctx.secrets.onDidChange((e) => { + if (e.key === "sessionToken") { + syncAuth(); + } + }), + ); } From 856fcf546162f71de15fba8feae0ae337aac8676 Mon Sep 17 00:00:00 2001 From: OyinloluB Date: Tue, 29 Jul 2025 16:46:50 -0400 Subject: [PATCH 2/3] debug: add logging to auth sync for testing verification Add debug output to syncAuth function and event listener to help --- src/extension.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/extension.ts b/src/extension.ts index e0c6b092..40518176 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -421,6 +421,11 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { const url = storage.getUrl(); const token = await storage.getSessionToken(); + storage.output.info("Auth sync called!"); + output.info( + `Auth sync triggered: url=${url ? "present" : "none"}, token=${token ? "present" : "none"}`, + ); + // Update the REST client with current credentials restClient.setHost(url || ""); restClient.setSessionToken(token || ""); @@ -462,6 +467,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { ctx.subscriptions.push( ctx.secrets.onDidChange((e) => { if (e.key === "sessionToken") { + output.info("Session token changed, syncing auth state"); syncAuth(); } }), From f512b455d740e53aed64b3d856b51434175392a5 Mon Sep 17 00:00:00 2001 From: OyinloluB Date: Tue, 29 Jul 2025 16:50:58 -0400 Subject: [PATCH 3/3] refactor: improve auth sync function placement and removed logs Move syncAuth function and event listener to better location in code Cleaned up logs --- src/extension.ts | 114 ++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 60 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 40518176..4f641b6f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -66,6 +66,60 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { storage, ); + /** + * Synchronize authentication state across all VS Code windows. + * Fixes Issue #498 by ensuring consistent logout behavior when the session token changes. + */ + async function syncAuth() { + const url = storage.getUrl(); + const token = await storage.getSessionToken(); + + // Update the REST client with current credentials + restClient.setHost(url || ""); + restClient.setSessionToken(token || ""); + + // Determine authentication state + const isAuthenticated = !!(url && token); + + // Update VS Code contexts to reflect current auth state + await vscode.commands.executeCommand( + "setContext", + "coder.authenticated", + isAuthenticated, + ); + + if (!isAuthenticated) { + // Clear owner context since user is not authenticated + await vscode.commands.executeCommand( + "setContext", + "coder.isOwner", + false, + ); + + // Show consistent logout notification across all windows + vscode.window + .showInformationMessage("You've been logged out of Coder!", "Login") + .then((action) => { + if (action === "Login") { + vscode.commands.executeCommand("coder.login"); + } + }); + + vscode.commands.executeCommand("coder.refreshWorkspaces"); + } else { + vscode.commands.executeCommand("coder.refreshWorkspaces"); + } + } + + // Listen for session token changes to sync auth state across windows + ctx.subscriptions.push( + ctx.secrets.onDidChange((e) => { + if (e.key === "sessionToken") { + syncAuth(); + } + }), + ); + const myWorkspacesProvider = new WorkspaceProvider( WorkspaceQuery.Mine, restClient, @@ -412,64 +466,4 @@ export async function activate(ctx: vscode.ExtensionContext): Promise { } } } - - /** - * Synchronize authentication state across all VS Code windows. - * Fixes Issue #498 by ensuring consistent logout behavior when the session token changes. - */ - async function syncAuth() { - const url = storage.getUrl(); - const token = await storage.getSessionToken(); - - storage.output.info("Auth sync called!"); - output.info( - `Auth sync triggered: url=${url ? "present" : "none"}, token=${token ? "present" : "none"}`, - ); - - // Update the REST client with current credentials - restClient.setHost(url || ""); - restClient.setSessionToken(token || ""); - - // Determine authentication state - const isAuthenticated = !!(url && token); - - // Update VS Code contexts to reflect current auth state - await vscode.commands.executeCommand( - "setContext", - "coder.authenticated", - isAuthenticated, - ); - - if (!isAuthenticated) { - // Clear owner context since user is not authenticated - await vscode.commands.executeCommand( - "setContext", - "coder.isOwner", - false, - ); - - // Show consistent logout notification across all windows - vscode.window - .showInformationMessage("You've been logged out of Coder!", "Login") - .then((action) => { - if (action === "Login") { - vscode.commands.executeCommand("coder.login"); - } - }); - - vscode.commands.executeCommand("coder.refreshWorkspaces"); - } else { - vscode.commands.executeCommand("coder.refreshWorkspaces"); - } - } - - // Listen for session token changes to sync auth state across windows - ctx.subscriptions.push( - ctx.secrets.onDidChange((e) => { - if (e.key === "sessionToken") { - output.info("Session token changed, syncing auth state"); - syncAuth(); - } - }), - ); }