@@ -15,9 +15,10 @@ const SESSION_KEY_PREFIX = "coder.session.";
1515const OAUTH_TOKENS_PREFIX = "coder.oauth.tokens." ;
1616const OAUTH_CLIENT_PREFIX = "coder.oauth.client." ;
1717
18- const CURRENT_DEPLOYMENT_KEY = "coder.currentDeployment" ;
1918const OAUTH_CALLBACK_KEY = "coder.oauthCallback" ;
2019
20+ const CURRENT_DEPLOYMENT_KEY = "coder.currentDeployment" ;
21+
2122const DEPLOYMENT_USAGE_KEY = "coder.deploymentUsage" ;
2223const DEFAULT_MAX_DEPLOYMENTS = 10 ;
2324
@@ -115,38 +116,6 @@ export class SecretsManager {
115116 } ) ;
116117 }
117118
118- /**
119- * Write an OAuth callback result to secrets storage.
120- * Used for cross-window communication when OAuth callback arrives in a different window.
121- */
122- public async setOAuthCallback ( data : OAuthCallbackData ) : Promise < void > {
123- await this . secrets . store ( OAUTH_CALLBACK_KEY , JSON . stringify ( data ) ) ;
124- }
125-
126- /**
127- * Listen for OAuth callback results from any VS Code window.
128- * The listener receives the state parameter, code (if success), and error (if failed).
129- */
130- public onDidChangeOAuthCallback (
131- listener : ( data : OAuthCallbackData ) => void ,
132- ) : Disposable {
133- return this . secrets . onDidChange ( async ( e ) => {
134- if ( e . key !== OAUTH_CALLBACK_KEY ) {
135- return ;
136- }
137-
138- try {
139- const data = await this . secrets . get ( OAUTH_CALLBACK_KEY ) ;
140- if ( data ) {
141- const parsed = JSON . parse ( data ) as OAuthCallbackData ;
142- listener ( parsed ) ;
143- }
144- } catch {
145- // Ignore parse errors
146- }
147- } ) ;
148- }
149-
150119 /**
151120 * Listen for changes to a specific deployment's session auth.
152121 */
@@ -203,77 +172,6 @@ export class SecretsManager {
203172 return `${ SESSION_KEY_PREFIX } ${ safeHostname || "<legacy>" } ` ;
204173 }
205174
206- public async getOAuthTokens (
207- safeHostname : string ,
208- ) : Promise < StoredOAuthTokens | undefined > {
209- try {
210- const data = await this . secrets . get (
211- `${ OAUTH_TOKENS_PREFIX } ${ safeHostname } ` ,
212- ) ;
213- if ( ! data ) {
214- return undefined ;
215- }
216- return JSON . parse ( data ) as StoredOAuthTokens ;
217- } catch {
218- return undefined ;
219- }
220- }
221-
222- public async setOAuthTokens (
223- safeHostname : string ,
224- tokens : StoredOAuthTokens ,
225- ) : Promise < void > {
226- await this . secrets . store (
227- `${ OAUTH_TOKENS_PREFIX } ${ safeHostname } ` ,
228- JSON . stringify ( tokens ) ,
229- ) ;
230- await this . recordDeploymentAccess ( safeHostname ) ;
231- }
232-
233- public async clearOAuthTokens ( safeHostname : string ) : Promise < void > {
234- await this . secrets . delete ( `${ OAUTH_TOKENS_PREFIX } ${ safeHostname } ` ) ;
235- }
236-
237- public async getOAuthClientRegistration (
238- safeHostname : string ,
239- ) : Promise < ClientRegistrationResponse | undefined > {
240- try {
241- const data = await this . secrets . get (
242- `${ OAUTH_CLIENT_PREFIX } ${ safeHostname } ` ,
243- ) ;
244- if ( ! data ) {
245- return undefined ;
246- }
247- return JSON . parse ( data ) as ClientRegistrationResponse ;
248- } catch {
249- return undefined ;
250- }
251- }
252-
253- public async setOAuthClientRegistration (
254- safeHostname : string ,
255- registration : ClientRegistrationResponse ,
256- ) : Promise < void > {
257- await this . secrets . store (
258- `${ OAUTH_CLIENT_PREFIX } ${ safeHostname } ` ,
259- JSON . stringify ( registration ) ,
260- ) ;
261- await this . recordDeploymentAccess ( safeHostname ) ;
262- }
263-
264- public async clearOAuthClientRegistration (
265- safeHostname : string ,
266- ) : Promise < void > {
267- await this . secrets . delete ( `${ OAUTH_CLIENT_PREFIX } ${ safeHostname } ` ) ;
268- }
269-
270- public async clearOAuthData ( safeHostname : string ) : Promise < void > {
271- await Promise . all ( [
272- this . clearOAuthTokens ( safeHostname ) ,
273- this . clearOAuthClientRegistration ( safeHostname ) ,
274- ] ) ;
275- }
276-
277175 /**
278176 * Record that a deployment was accessed, moving it to the front of the LRU list.
279177 * Prunes deployments beyond maxCount, clearing their auth data.
@@ -359,4 +257,107 @@ export class SecretsManager {
359257
360258 return safeHostname ;
361259 }
260+
261+ /**
262+ * Write an OAuth callback result to secrets storage.
263+ * Used for cross-window communication when OAuth callback arrives in a different window.
264+ */
265+ public async setOAuthCallback ( data : OAuthCallbackData ) : Promise < void > {
266+ await this . secrets . store ( OAUTH_CALLBACK_KEY , JSON . stringify ( data ) ) ;
267+ }
268+
269+ /**
270+ * Listen for OAuth callback results from any VS Code window.
271+ * The listener receives the state parameter, code (if success), and error (if failed).
272+ */
273+ public onDidChangeOAuthCallback (
274+ listener : ( data : OAuthCallbackData ) => void ,
275+ ) : Disposable {
276+ return this . secrets . onDidChange ( async ( e ) => {
277+ if ( e . key !== OAUTH_CALLBACK_KEY ) {
278+ return ;
279+ }
280+
281+ try {
282+ const data = await this . secrets . get ( OAUTH_CALLBACK_KEY ) ;
283+ if ( data ) {
284+ const parsed = JSON . parse ( data ) as OAuthCallbackData ;
285+ listener ( parsed ) ;
286+ }
287+ } catch {
288+ // Ignore parse errors
289+ }
290+ } ) ;
291+ }
292+
293+ public async getOAuthTokens (
294+ safeHostname : string ,
295+ ) : Promise < StoredOAuthTokens | undefined > {
296+ try {
297+ const data = await this . secrets . get (
298+ `${ OAUTH_TOKENS_PREFIX } ${ safeHostname } ` ,
299+ ) ;
300+ if ( ! data ) {
301+ return undefined ;
302+ }
303+ return JSON . parse ( data ) as StoredOAuthTokens ;
304+ } catch {
305+ return undefined ;
306+ }
307+ }
308+
309+ public async setOAuthTokens (
310+ safeHostname : string ,
311+ tokens : StoredOAuthTokens ,
312+ ) : Promise < void > {
313+ await this . secrets . store (
314+ `${ OAUTH_TOKENS_PREFIX } ${ safeHostname } ` ,
315+ JSON . stringify ( tokens ) ,
316+ ) ;
317+ await this . recordDeploymentAccess ( safeHostname ) ;
318+ }
319+
320+ public async clearOAuthTokens ( safeHostname : string ) : Promise < void > {
321+ await this . secrets . delete ( `${ OAUTH_TOKENS_PREFIX } ${ safeHostname } ` ) ;
322+ }
323+
324+ public async getOAuthClientRegistration (
325+ safeHostname : string ,
326+ ) : Promise < ClientRegistrationResponse | undefined > {
327+ try {
328+ const data = await this . secrets . get (
329+ `${ OAUTH_CLIENT_PREFIX } ${ safeHostname } ` ,
330+ ) ;
331+ if ( ! data ) {
332+ return undefined ;
333+ }
334+ return JSON . parse ( data ) as ClientRegistrationResponse ;
335+ } catch {
336+ return undefined ;
337+ }
338+ }
339+
340+ public async setOAuthClientRegistration (
341+ safeHostname : string ,
342+ registration : ClientRegistrationResponse ,
343+ ) : Promise < void > {
344+ await this . secrets . store (
345+ `${ OAUTH_CLIENT_PREFIX } ${ safeHostname } ` ,
346+ JSON . stringify ( registration ) ,
347+ ) ;
348+ await this . recordDeploymentAccess ( safeHostname ) ;
349+ }
350+
351+ public async clearOAuthClientRegistration (
352+ safeHostname : string ,
353+ ) : Promise < void > {
354+ await this . secrets . delete ( `${ OAUTH_CLIENT_PREFIX } ${ safeHostname } ` ) ;
355+ }
356+
357+ public async clearOAuthData ( safeHostname : string ) : Promise < void > {
358+ await Promise . all ( [
359+ this . clearOAuthTokens ( safeHostname ) ,
360+ this . clearOAuthClientRegistration ( safeHostname ) ,
361+ ] ) ;
362+ }
362363}
0 commit comments