Skip to content

Commit f29a97a

Browse files
committed
Handle secretsManager comments part 1
1 parent 9b2e4fc commit f29a97a

File tree

6 files changed

+42
-44
lines changed

6 files changed

+42
-44
lines changed

src/core/cliManager.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -732,13 +732,10 @@ export class CliManager {
732732
*
733733
* If the label is empty, read the old deployment-unaware config instead.
734734
*/
735-
private async updateTokenForCli(
736-
label: string,
737-
token: string | undefined | null,
738-
) {
735+
private async updateTokenForCli(label: string, token: string | null) {
739736
if (token !== null) {
740737
const tokenPath = this.pathResolver.getSessionTokenPath(label);
741-
await this.atomicWriteFile(tokenPath, token ?? "");
738+
await this.atomicWriteFile(tokenPath, token);
742739
}
743740
}
744741

src/core/secretsManager.ts

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import { type Logger } from "../logging/logger";
12
import { toSafeHost } from "../util";
23

34
import type { Memento, SecretStorage, Disposable } from "vscode";
45

56
import type { Deployment } from "../deployment";
67

8+
// Each deployment has its own key to ensure atomic operations (multiple windows
9+
// writing to a shared key could drop data) and to receive proper VS Code events.
710
const SESSION_KEY_PREFIX = "coder.session.";
811

912
const CURRENT_DEPLOYMENT_KEY = "coder.currentDeployment";
@@ -31,6 +34,7 @@ export class SecretsManager {
3134
constructor(
3235
private readonly secrets: SecretStorage,
3336
private readonly memento: Memento,
37+
private readonly logger: Logger,
3438
) {}
3539

3640
/**
@@ -50,16 +54,16 @@ export class SecretsManager {
5054
/**
5155
* Gets the current deployment from storage.
5256
*/
53-
public async getCurrentDeployment(): Promise<Deployment | undefined> {
57+
public async getCurrentDeployment(): Promise<Deployment | null> {
5458
try {
5559
const data = await this.secrets.get(CURRENT_DEPLOYMENT_KEY);
5660
if (!data) {
57-
return undefined;
61+
return null;
5862
}
59-
const parsed = JSON.parse(data) as { deployment: Deployment | null };
60-
return parsed.deployment ?? undefined;
63+
const parsed = JSON.parse(data) as CurrentDeploymentState;
64+
return parsed.deployment;
6165
} catch {
62-
return undefined;
66+
return null;
6367
}
6468
}
6569

@@ -75,16 +79,14 @@ export class SecretsManager {
7579
return;
7680
}
7781

82+
const deployment = await this.getCurrentDeployment();
7883
try {
79-
const data = await this.secrets.get(CURRENT_DEPLOYMENT_KEY);
80-
if (data) {
81-
const parsed = JSON.parse(data) as {
82-
deployment: Deployment | null;
83-
};
84-
await listener({ deployment: parsed.deployment });
85-
}
86-
} catch {
87-
// Ignore parse errors
84+
await listener({ deployment });
85+
} catch (err) {
86+
this.logger.error(
87+
"Error in onDidChangeCurrentDeployment listener",
88+
err,
89+
);
8890
}
8991
});
9092
}
@@ -102,7 +104,11 @@ export class SecretsManager {
102104
return;
103105
}
104106
const auth = await this.getSessionAuth(label);
105-
await listener(auth);
107+
try {
108+
await listener(auth);
109+
} catch (err) {
110+
this.logger.error("Error in onDidChangeSessionAuth listener", err);
111+
}
106112
});
107113
}
108114

@@ -122,16 +128,6 @@ export class SecretsManager {
122128
}
123129
}
124130

125-
public async getSessionToken(label: string): Promise<string | undefined> {
126-
const auth = await this.getSessionAuth(label);
127-
return auth?.token;
128-
}
129-
130-
public async getUrl(label: string): Promise<string | undefined> {
131-
const auth = await this.getSessionAuth(label);
132-
return auth?.url;
133-
}
134-
135131
public async setSessionAuth(label: string, auth: SessionAuth): Promise<void> {
136132
await this.secrets.store(
137133
`${SESSION_KEY_PREFIX}${label}`,
@@ -210,6 +206,7 @@ export class SecretsManager {
210206

211207
await this.setSessionAuth(label, { url: legacyUrl, token: oldToken });
212208
await this.secrets.delete(LEGACY_SESSION_TOKEN_KEY);
209+
await this.memento.update("url", undefined);
213210

214211
// Also set as current deployment if none exists
215212
const currentDeployment = await this.getCurrentDeployment();

src/deployment/deploymentManager.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,13 @@ export class DeploymentManager implements vscode.Disposable {
142142

143143
this.logger.info("Deployment changed from another window");
144144
if (deployment) {
145-
const token = await this.secretsManager.getSessionToken(
145+
const auth = await this.secretsManager.getSessionAuth(
146146
deployment.label,
147147
);
148-
await this.setDeploymentWithoutAuth({ ...deployment, token });
148+
await this.setDeploymentWithoutAuth({
149+
...deployment,
150+
token: auth?.token,
151+
});
149152
}
150153
},
151154
);

src/extension.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
7474
// in commands that operate on the current login.
7575
const client = CoderApi.create(
7676
deployment?.url || "",
77-
await secretsManager.getSessionToken(deployment?.label ?? ""),
77+
(await secretsManager.getSessionAuth(deployment?.label ?? ""))?.token,
7878
output,
7979
);
8080
ctx.subscriptions.push(client);
@@ -362,9 +362,9 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
362362
contextManager.set("coder.loaded", true);
363363
} else if (deployment) {
364364
output.info(`Initializing deployment: ${deployment.url}`);
365-
const storedToken = await secretsManager.getSessionToken(deployment.label);
365+
const auth = await secretsManager.getSessionAuth(deployment.label);
366366
deploymentManager
367-
.setDeploymentWithoutAuth({ ...deployment, token: storedToken })
367+
.setDeploymentWithoutAuth({ ...deployment, token: auth?.token })
368368
.then(() => {
369369
if (deploymentManager.isAuthenticated()) {
370370
output.info("Credentials are valid");
@@ -468,7 +468,7 @@ async function setupDeploymentFromUri(
468468
let token: string | undefined = params.get("token") ?? undefined;
469469
if (token === undefined) {
470470
if (needToken(vscode.workspace.getConfiguration())) {
471-
token = await secretsManager.getSessionToken(label);
471+
token = (await secretsManager.getSessionAuth(label))?.token;
472472
} else {
473473
token = "";
474474
}

src/login/loginCoordinator.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ export class LoginCoordinator {
8181
.then(async (action) => {
8282
if (action === "Login") {
8383
// Proceed with the login flow, handling logging in from another window
84-
const storedUrl = await this.secretsManager.getUrl(label);
84+
const storedAuth = await this.secretsManager.getSessionAuth(label);
8585
const newUrl = await maybeAskUrl(
8686
this.mementoManager,
8787
url,
88-
storedUrl,
88+
storedAuth?.url,
8989
);
9090
if (!newUrl) {
9191
throw new Error("URL must be provided");
@@ -178,7 +178,8 @@ export class LoginCoordinator {
178178

179179
let storedToken: string | undefined;
180180
if (needsToken) {
181-
storedToken = await this.secretsManager.getSessionToken(deployment.label);
181+
const auth = await this.secretsManager.getSessionAuth(deployment.label);
182+
storedToken = auth?.token;
182183
if (storedToken) {
183184
client.setSessionToken(storedToken);
184185
}

src/remote/remote.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,10 @@ export class Remote {
9797
await this.migrateSessionToken(parts.label);
9898

9999
// Get the URL and token belonging to this host.
100-
const baseUrlRaw = (await this.secretsManager.getUrl(parts.label)) ?? "";
101-
const token =
102-
(await this.secretsManager.getSessionToken(parts.label)) ?? "";
103-
if (baseUrlRaw && token) {
100+
const auth = await this.secretsManager.getSessionAuth(parts.label);
101+
const baseUrlRaw = auth?.url ?? "";
102+
const token = auth?.token;
103+
if (baseUrlRaw && token !== undefined) {
104104
await this.cliManager.configure(parts.label, baseUrlRaw, token);
105105
}
106106

@@ -543,7 +543,7 @@ export class Remote {
543543
return {
544544
label: parts.label,
545545
url: baseUrlRaw,
546-
token,
546+
token: token ?? "",
547547
dispose: () => {
548548
disposables.forEach((d) => d.dispose());
549549
},

0 commit comments

Comments
 (0)