@@ -12,6 +12,7 @@ import { CoderApi } from "./api/coderApi";
12
12
import { needToken } from "./api/utils" ;
13
13
import { type CliManager } from "./core/cliManager" ;
14
14
import { type ServiceContainer } from "./core/container" ;
15
+ import { type ContextManager } from "./core/contextManager" ;
15
16
import { type MementoManager } from "./core/mementoManager" ;
16
17
import { type PathResolver } from "./core/pathResolver" ;
17
18
import { type SecretsManager } from "./core/secretsManager" ;
@@ -32,6 +33,7 @@ export class Commands {
32
33
private readonly mementoManager : MementoManager ;
33
34
private readonly secretsManager : SecretsManager ;
34
35
private readonly cliManager : CliManager ;
36
+ private readonly contextManager : ContextManager ;
35
37
// These will only be populated when actively connected to a workspace and are
36
38
// used in commands. Because commands can be executed by the user, it is not
37
39
// possible to pass in arguments, so we have to store the current workspace
@@ -53,6 +55,7 @@ export class Commands {
53
55
this . mementoManager = serviceContainer . getMementoManager ( ) ;
54
56
this . secretsManager = serviceContainer . getSecretsManager ( ) ;
55
57
this . cliManager = serviceContainer . getCliManager ( ) ;
58
+ this . contextManager = serviceContainer . getContextManager ( ) ;
56
59
}
57
60
58
61
/**
@@ -189,6 +192,11 @@ export class Commands {
189
192
label ?: string ;
190
193
autoLogin ?: boolean ;
191
194
} ) : Promise < void > {
195
+ if ( this . contextManager . get ( "coder.authenticated" ) ) {
196
+ return ;
197
+ }
198
+ this . logger . info ( "Logging in" ) ;
199
+
192
200
const url = await this . maybeAskUrl ( args ?. url ) ;
193
201
if ( ! url ) {
194
202
return ; // The user aborted.
@@ -219,13 +227,9 @@ export class Commands {
219
227
await this . secretsManager . setSessionToken ( res . token ) ;
220
228
221
229
// These contexts control various menu items and the sidebar.
222
- await vscode . commands . executeCommand (
223
- "setContext" ,
224
- "coder.authenticated" ,
225
- true ,
226
- ) ;
230
+ this . contextManager . set ( "coder.authenticated" , true ) ;
227
231
if ( res . user . roles . find ( ( role ) => role . name === "owner" ) ) {
228
- await vscode . commands . executeCommand ( "setContext" , "coder.isOwner" , true ) ;
232
+ this . contextManager . set ( "coder.isOwner" , true ) ;
229
233
}
230
234
231
235
vscode . window
@@ -245,6 +249,7 @@ export class Commands {
245
249
246
250
// Fetch workspaces for the new deployment.
247
251
vscode . commands . executeCommand ( "coder.refreshWorkspaces" ) ;
252
+ this . secretsManager . triggerLoginStateChange ( "login" ) ;
248
253
}
249
254
250
255
/**
@@ -376,6 +381,10 @@ export class Commands {
376
381
}
377
382
378
383
public async forceLogout ( ) : Promise < void > {
384
+ if ( ! this . contextManager . get ( "coder.authenticated" ) ) {
385
+ return ;
386
+ }
387
+ this . logger . info ( "Logging out" ) ;
379
388
// Clear from the REST client. An empty url will indicate to other parts of
380
389
// the code that we are logged out.
381
390
this . restClient . setHost ( "" ) ;
@@ -385,11 +394,7 @@ export class Commands {
385
394
await this . mementoManager . setUrl ( undefined ) ;
386
395
await this . secretsManager . setSessionToken ( undefined ) ;
387
396
388
- await vscode . commands . executeCommand (
389
- "setContext" ,
390
- "coder.authenticated" ,
391
- false ,
392
- ) ;
397
+ this . contextManager . set ( "coder.authenticated" , false ) ;
393
398
vscode . window
394
399
. showInformationMessage ( "You've been logged out of Coder!" , "Login" )
395
400
. then ( ( action ) => {
@@ -400,6 +405,7 @@ export class Commands {
400
405
401
406
// This will result in clearing the workspace list.
402
407
vscode . commands . executeCommand ( "coder.refreshWorkspaces" ) ;
408
+ this . secretsManager . triggerLoginStateChange ( "logout" ) ;
403
409
}
404
410
405
411
/**
0 commit comments