forked from coder/vscode-coder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsecretsManager.ts
More file actions
67 lines (59 loc) · 1.9 KB
/
Copy pathsecretsManager.ts
File metadata and controls
67 lines (59 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import type { SecretStorage, Disposable } from "vscode";
const SESSION_TOKEN_KEY = "sessionToken";
const LOGIN_STATE_KEY = "loginState";
type AuthAction = "login" | "logout";
export class SecretsManager {
constructor(private readonly secrets: SecretStorage) {}
/**
* Set or unset the last used token.
*/
public async setSessionToken(sessionToken?: string): Promise<void> {
if (!sessionToken) {
await this.secrets.delete(SESSION_TOKEN_KEY);
} else {
await this.secrets.store(SESSION_TOKEN_KEY, sessionToken);
}
}
/**
* Get the last used token.
*/
public async getSessionToken(): Promise<string | undefined> {
try {
return await this.secrets.get(SESSION_TOKEN_KEY);
} catch {
// The VS Code session store has become corrupt before, and
// will fail to get the session token...
return undefined;
}
}
/**
* Triggers a login/logout event that propagates across all VS Code windows.
* Uses the secrets storage onDidChange event as a cross-window communication mechanism.
* Appends a timestamp to ensure the value always changes, guaranteeing the event fires.
*/
public async triggerLoginStateChange(action: AuthAction): Promise<void> {
const date = new Date().toISOString();
await this.secrets.store(LOGIN_STATE_KEY, `${action}-${date}`);
}
/**
* Listens for login/logout events from any VS Code window.
* The secrets storage onDidChange event fires across all windows, enabling cross-window sync.
*/
public onDidChangeLoginState(
listener: (state?: AuthAction) => Promise<void>,
): Disposable {
return this.secrets.onDidChange(async (e) => {
if (e.key === LOGIN_STATE_KEY) {
const state = await this.secrets.get(LOGIN_STATE_KEY);
if (state?.startsWith("login")) {
listener("login");
} else if (state?.startsWith("logout")) {
listener("logout");
} else {
// Secret was deleted or is invalid
listener(undefined);
}
}
});
}
}