Skip to content

Commit 796c9eb

Browse files
committed
Simplify the OAuth flow
1 parent 29d1a13 commit 796c9eb

File tree

4 files changed

+191
-267
lines changed

4 files changed

+191
-267
lines changed

src/commands.ts

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,14 @@ export class Commands {
305305
}
306306

307307
if (choice === "oauth") {
308-
return this.loginWithOAuth(url, client);
308+
return this.loginWithOAuth(client);
309309
} else if (choice === "legacy") {
310-
return this.loginWithToken(url, token, client);
310+
const initialToken =
311+
token || (await this.secretsManager.getSessionToken());
312+
return this.loginWithToken(client, initialToken);
311313
}
312314

313-
// User aborted.
314-
return null;
315+
return null; // User aborted.
315316
}
316317

317318
private async checkOAuthSupport(client: CoderApi): Promise<boolean> {
@@ -350,10 +351,13 @@ export class Commands {
350351
}
351352

352353
private async loginWithToken(
353-
url: string,
354-
token: string | undefined,
355354
client: CoderApi,
355+
initialToken: string | undefined,
356356
): Promise<{ user: User; token: string } | null> {
357+
const url = client.getAxiosInstance().defaults.baseURL;
358+
if (!url) {
359+
throw new Error("No base URL set on REST client");
360+
}
357361
// This prompt is for convenience; do not error if they close it since
358362
// they may already have a token or already have the page opened.
359363
await vscode.env.openExternal(vscode.Uri.parse(`${url}/cli-auth`));
@@ -366,7 +370,7 @@ export class Commands {
366370
title: "Coder API Key",
367371
password: true,
368372
placeHolder: "Paste your API key.",
369-
value: token || (await this.secretsManager.getSessionToken()),
373+
value: initialToken,
370374
ignoreFocusOut: true,
371375
validateInput: async (value) => {
372376
if (!value) {
@@ -410,29 +414,17 @@ export class Commands {
410414
* Returns the access token and authenticated user, or null if failed/cancelled.
411415
*/
412416
private async loginWithOAuth(
413-
url: string,
414417
client: CoderApi,
415418
): Promise<{ user: User; token: string } | null> {
416419
try {
417420
this.logger.info("Starting OAuth authentication");
418421

419-
// Start OAuth authorization flow
420-
// TODO just pass the client here and do all the neccessary steps (If we are already logged in we'd have the right token and the OAuth client registration saved).
421-
const { code, verifier } =
422-
await this.oauthSessionManager.startAuthorization(url);
423-
424-
// Exchange authorization code for tokens
425-
const tokenResponse = await this.oauthSessionManager.exchangeToken(
426-
code,
427-
verifier,
428-
);
422+
const tokenResponse = await this.oauthSessionManager.login(client);
429423

430424
// Validate token by fetching user
431425
client.setSessionToken(tokenResponse.access_token);
432426
const user = await client.getAuthenticatedUser();
433427

434-
this.logger.info("OAuth authentication successful");
435-
436428
return {
437429
token: tokenResponse.access_token,
438430
user,
@@ -481,9 +473,19 @@ export class Commands {
481473
throw new Error("You are not logged in");
482474
}
483475

476+
await this.forceLogout();
477+
}
478+
479+
public async forceLogout(): Promise<void> {
480+
if (!this.contextManager.get("coder.authenticated")) {
481+
return;
482+
}
483+
this.logger.info("Logging out");
484+
484485
// Check if using OAuth
485-
const hasOAuthTokens = await this.secretsManager.getOAuthTokens();
486-
if (hasOAuthTokens) {
486+
const isOAuthLoggedIn =
487+
await this.oauthSessionManager.isLoggedInWithOAuth();
488+
if (isOAuthLoggedIn) {
487489
this.logger.info("Logging out via OAuth");
488490
try {
489491
await this.oauthSessionManager.logout();
@@ -495,15 +497,6 @@ export class Commands {
495497
}
496498
}
497499

498-
// Continue with standard logout (clears sessionToken, contexts, etc)
499-
await this.forceLogout();
500-
}
501-
502-
public async forceLogout(): Promise<void> {
503-
if (!this.contextManager.get("coder.authenticated")) {
504-
return;
505-
}
506-
this.logger.info("Logging out");
507500
// Clear from the REST client. An empty url will indicate to other parts of
508501
// the code that we are logged out.
509502
this.restClient.setHost("");

src/extension.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,18 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
134134
// Listen for session token changes and sync state across all components
135135
ctx.subscriptions.push(
136136
secretsManager.onDidChangeSessionToken(async (token) => {
137+
client.setSessionToken(token ?? "");
137138
if (!token) {
138139
output.debug("Session token cleared");
139-
client.setSessionToken("");
140140
return;
141141
}
142142

143143
output.debug("Session token changed, syncing state");
144144

145-
client.setSessionToken(token);
146145
const url = mementoManager.getUrl();
147146
if (url) {
148147
const cliManager = serviceContainer.getCliManager();
149-
// TODO label might not match?
148+
// TODO label might not match the one in remote?
150149
await cliManager.configure(toSafeHost(url), url, token);
151150
output.debug("Updated CLI config with new token");
152151
}

src/oauth/clientRegistry.ts

Lines changed: 0 additions & 111 deletions
This file was deleted.

0 commit comments

Comments
 (0)