44 *--------------------------------------------------------------------------------------------*/
55
66import { isStandalone } from 'vs/base/browser/browser' ;
7- import { CancellationToken } from 'vs/base/common/cancellation' ;
87import { parse } from 'vs/base/common/marshalling' ;
98import { Emitter } from 'vs/base/common/event' ;
109import { Disposable , IDisposable } from 'vs/base/common/lifecycle' ;
1110import { Schemas } from 'vs/base/common/network' ;
1211import { isEqual } from 'vs/base/common/resources' ;
1312import { URI , UriComponents } from 'vs/base/common/uri' ;
14- import { request } from 'vs/base/parts/request/browser/request' ;
1513import product from 'vs/platform/product/common/product' ;
1614import { isFolderToOpen , isWorkspaceToOpen } from 'vs/platform/window/common/window' ;
1715import { create } from 'vs/workbench/workbench.web.main' ;
1816import { posix } from 'vs/base/common/path' ;
1917import { ltrim } from 'vs/base/common/strings' ;
20- import type { ICredentialsProvider } from 'vs/platform/credentials/common/credentials' ;
2118import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService' ;
2219import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api' ;
2320import type { IWorkspace , IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService' ;
21+ import { ISecretStorageProvider } from 'vs/platform/secrets/common/secrets' ;
22+ import { AuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService' ;
2423
25- interface ICredential {
26- service : string ;
27- account : string ;
28- password : string ;
29- }
30-
31- class LocalStorageCredentialsProvider implements ICredentialsProvider {
24+ class LocalStorageSecretStorageProvider implements ISecretStorageProvider {
25+ private static readonly STORAGE_KEY = 'secrets.provider' ;
3226
33- private static readonly CREDENTIALS_STORAGE_KEY = 'credentials.provider' ;
27+ private _secrets : Record < string , string > | undefined ;
3428
35- private readonly authService : string | undefined ;
29+ type : 'in-memory' | 'persisted' | 'unknown' = 'persisted' ;
3630
3731 constructor ( ) {
38- let authSessionInfo : { readonly id : string ; readonly accessToken : string ; readonly providerId : string ; readonly canSignOut ?: boolean ; readonly scopes : string [ ] [ ] } | undefined ;
32+ let authSessionInfo : ( AuthenticationSessionInfo & { scopes : string [ ] [ ] } ) | undefined ;
3933 const authSessionElement = document . getElementById ( 'vscode-workbench-auth-session' ) ;
4034 const authSessionElementAttribute = authSessionElement ? authSessionElement . getAttribute ( 'data-settings' ) : undefined ;
4135 if ( authSessionElementAttribute ) {
@@ -46,133 +40,60 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider {
4640
4741 if ( authSessionInfo ) {
4842 // Settings Sync Entry
49- this . setPassword ( `${ product . urlProtocol } .login` , 'account' , JSON . stringify ( authSessionInfo ) ) ;
43+ this . set ( `${ product . urlProtocol } .loginAccount` , JSON . stringify ( authSessionInfo ) ) ;
5044
5145 // Auth extension Entry
52- this . authService = `${ product . urlProtocol } -${ authSessionInfo . providerId } .login` ;
53- this . setPassword ( this . authService , 'account' , JSON . stringify ( authSessionInfo . scopes . map ( scopes => ( {
46+ if ( authSessionInfo . providerId !== 'github' ) {
47+ console . error ( `Unexpected auth provider: ${ authSessionInfo . providerId } . Expected 'github'.` ) ;
48+ return ;
49+ }
50+ const authAccount = JSON . stringify ( { extensionId : 'vscode.github-authentication' , key : 'github.auth' } ) ;
51+ this . set ( authAccount , JSON . stringify ( authSessionInfo . scopes . map ( scopes => ( {
5452 id : authSessionInfo ! . id ,
5553 scopes,
5654 accessToken : authSessionInfo ! . accessToken
5755 } ) ) ) ) ;
5856 }
5957 }
6058
61- private _credentials : ICredential [ ] | undefined ;
62- private get credentials ( ) : ICredential [ ] {
63- if ( ! this . _credentials ) {
64- try {
65- const serializedCredentials = window . localStorage . getItem ( LocalStorageCredentialsProvider . CREDENTIALS_STORAGE_KEY ) ;
66- if ( serializedCredentials ) {
67- this . _credentials = JSON . parse ( serializedCredentials ) ;
68- }
69- } catch ( error ) {
70- // ignore
71- }
72-
73- if ( ! Array . isArray ( this . _credentials ) ) {
74- this . _credentials = [ ] ;
75- }
76- }
77-
78- return this . _credentials ;
79- }
80-
81- private save ( ) : void {
82- window . localStorage . setItem ( LocalStorageCredentialsProvider . CREDENTIALS_STORAGE_KEY , JSON . stringify ( this . credentials ) ) ;
83- }
84-
85- async getPassword ( service : string , account : string ) : Promise < string | null > {
86- return this . doGetPassword ( service , account ) ;
59+ get ( key : string ) : Promise < string | undefined > {
60+ return Promise . resolve ( this . secrets [ key ] ) ;
8761 }
62+ set ( key : string , value : string ) : Promise < void > {
63+ this . secrets [ key ] = value ;
64+ this . save ( ) ;
8865
89- private async doGetPassword ( service : string , account ?: string ) : Promise < string | null > {
90- for ( const credential of this . credentials ) {
91- if ( credential . service === service ) {
92- if ( typeof account !== 'string' || account === credential . account ) {
93- return credential . password ;
94- }
95- }
96- }
97-
98- return null ;
66+ return Promise . resolve ( ) ;
9967 }
100-
101- async setPassword ( service : string , account : string , password : string ) : Promise < void > {
102- this . doDeletePassword ( service , account ) ;
103-
104- this . credentials . push ( { service, account, password } ) ;
68+ async delete ( key : string ) : Promise < void > {
69+ delete this . secrets [ key ] ;
10570
10671 this . save ( ) ;
10772
108- try {
109- if ( password && service === this . authService ) {
110- const value = JSON . parse ( password ) ;
111- if ( Array . isArray ( value ) && value . length === 0 ) {
112- await this . logout ( service ) ;
113- }
114- }
115- } catch ( error ) {
116- console . log ( error ) ;
117- }
73+ return Promise . resolve ( ) ;
11874 }
11975
120- async deletePassword ( service : string , account : string ) : Promise < boolean > {
121- const result = await this . doDeletePassword ( service , account ) ;
122-
123- if ( result && service === this . authService ) {
76+ private get secrets ( ) : Record < string , string > {
77+ if ( ! this . _secrets ) {
12478 try {
125- await this . logout ( service ) ;
79+ const serializedCredentials = window . localStorage . getItem ( LocalStorageSecretStorageProvider . STORAGE_KEY ) ;
80+ if ( serializedCredentials ) {
81+ this . _secrets = JSON . parse ( serializedCredentials ) ;
82+ }
12683 } catch ( error ) {
127- console . log ( error ) ;
84+ // ignore
12885 }
129- }
130-
131- return result ;
132- }
13386
134- private async doDeletePassword ( service : string , account : string ) : Promise < boolean > {
135- let found = false ;
136-
137- this . _credentials = this . credentials . filter ( credential => {
138- if ( credential . service === service && credential . account === account ) {
139- found = true ;
140-
141- return false ;
87+ if ( ! ( this . _secrets instanceof Object ) ) {
88+ this . _secrets = { } ;
14289 }
143-
144- return true ;
145- } ) ;
146-
147- if ( found ) {
148- this . save ( ) ;
14990 }
15091
151- return found ;
152- }
153-
154- async findPassword ( service : string ) : Promise < string | null > {
155- return this . doGetPassword ( service ) ;
92+ return this . _secrets ;
15693 }
15794
158- async findCredentials ( service : string ) : Promise < Array < { account : string ; password : string } > > {
159- return this . credentials
160- . filter ( credential => credential . service === service )
161- . map ( ( { account, password } ) => ( { account, password } ) ) ;
162- }
163-
164- private async logout ( service : string ) : Promise < void > {
165- const queryValues : Map < string , string > = new Map ( ) ;
166- queryValues . set ( 'logout' , String ( true ) ) ;
167- queryValues . set ( 'service' , service ) ;
168-
169- await request ( {
170- url : doCreateUri ( '/auth/logout' , queryValues ) . toString ( true )
171- } , CancellationToken . None ) ;
172- }
173-
174- async clear ( ) : Promise < void > {
175- window . localStorage . removeItem ( LocalStorageCredentialsProvider . CREDENTIALS_STORAGE_KEY ) ;
95+ private save ( ) : void {
96+ window . localStorage . setItem ( LocalStorageSecretStorageProvider . STORAGE_KEY , JSON . stringify ( this . secrets ) ) ;
17697 }
17798}
17899
@@ -469,24 +390,6 @@ class WorkspaceProvider implements IWorkspaceProvider {
469390 }
470391}
471392
472- function doCreateUri ( path : string , queryValues : Map < string , string > ) : URI {
473- let query : string | undefined = undefined ;
474-
475- if ( queryValues ) {
476- let index = 0 ;
477- queryValues . forEach ( ( value , key ) => {
478- if ( ! query ) {
479- query = '' ;
480- }
481-
482- const prefix = ( index ++ === 0 ) ? '' : '&' ;
483- query += `${ prefix } ${ key } =${ encodeURIComponent ( value ) } ` ;
484- } ) ;
485- }
486-
487- return URI . parse ( window . location . href ) . with ( { path, query } ) ;
488- }
489-
490393( function ( ) {
491394
492395 // Find config by checking for DOM
@@ -504,6 +407,6 @@ function doCreateUri(path: string, queryValues: Map<string, string>): URI {
504407 settingsSyncOptions : config . settingsSyncOptions ? { enabled : config . settingsSyncOptions . enabled , } : undefined ,
505408 workspaceProvider : WorkspaceProvider . create ( config ) ,
506409 urlCallbackProvider : new LocalStorageURLCallbackProvider ( config . callbackRoute ) ,
507- credentialsProvider : config . remoteAuthority ? undefined /* with a remote, we don't use a local credentials provider */ : new LocalStorageCredentialsProvider ( )
410+ secretStorageProvider : config . remoteAuthority ? undefined /* with a remote, we don't use a local secret storage provider */ : new LocalStorageSecretStorageProvider ( )
508411 } ) ;
509412} ) ( ) ;
0 commit comments