4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
6
import { isStandalone } from 'vs/base/browser/browser' ;
7
- import { CancellationToken } from 'vs/base/common/cancellation' ;
8
7
import { parse } from 'vs/base/common/marshalling' ;
9
8
import { Emitter } from 'vs/base/common/event' ;
10
9
import { Disposable , IDisposable } from 'vs/base/common/lifecycle' ;
11
10
import { Schemas } from 'vs/base/common/network' ;
12
11
import { isEqual } from 'vs/base/common/resources' ;
13
12
import { URI , UriComponents } from 'vs/base/common/uri' ;
14
- import { request } from 'vs/base/parts/request/browser/request' ;
15
13
import product from 'vs/platform/product/common/product' ;
16
14
import { isFolderToOpen , isWorkspaceToOpen } from 'vs/platform/window/common/window' ;
17
15
import { create } from 'vs/workbench/workbench.web.main' ;
18
16
import { posix } from 'vs/base/common/path' ;
19
17
import { ltrim } from 'vs/base/common/strings' ;
20
- import type { ICredentialsProvider } from 'vs/platform/credentials/common/credentials' ;
21
18
import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService' ;
22
19
import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api' ;
23
20
import 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' ;
24
23
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' ;
32
26
33
- private static readonly CREDENTIALS_STORAGE_KEY = 'credentials.provider' ;
27
+ private _secrets : Record < string , string > | undefined ;
34
28
35
- private readonly authService : string | undefined ;
29
+ type : 'in-memory' | 'persisted' | 'unknown' = 'persisted' ;
36
30
37
31
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 ;
39
33
const authSessionElement = document . getElementById ( 'vscode-workbench-auth-session' ) ;
40
34
const authSessionElementAttribute = authSessionElement ? authSessionElement . getAttribute ( 'data-settings' ) : undefined ;
41
35
if ( authSessionElementAttribute ) {
@@ -46,133 +40,60 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider {
46
40
47
41
if ( authSessionInfo ) {
48
42
// Settings Sync Entry
49
- this . setPassword ( `${ product . urlProtocol } .login` , 'account' , JSON . stringify ( authSessionInfo ) ) ;
43
+ this . set ( `${ product . urlProtocol } .loginAccount` , JSON . stringify ( authSessionInfo ) ) ;
50
44
51
45
// 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 => ( {
54
52
id : authSessionInfo ! . id ,
55
53
scopes,
56
54
accessToken : authSessionInfo ! . accessToken
57
55
} ) ) ) ) ;
58
56
}
59
57
}
60
58
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 ] ) ;
87
61
}
62
+ set ( key : string , value : string ) : Promise < void > {
63
+ this . secrets [ key ] = value ;
64
+ this . save ( ) ;
88
65
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 ( ) ;
99
67
}
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 ] ;
105
70
106
71
this . save ( ) ;
107
72
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 ( ) ;
118
74
}
119
75
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 ) {
124
78
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
+ }
126
83
} catch ( error ) {
127
- console . log ( error ) ;
84
+ // ignore
128
85
}
129
- }
130
-
131
- return result ;
132
- }
133
86
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 = { } ;
142
89
}
143
-
144
- return true ;
145
- } ) ;
146
-
147
- if ( found ) {
148
- this . save ( ) ;
149
90
}
150
91
151
- return found ;
152
- }
153
-
154
- async findPassword ( service : string ) : Promise < string | null > {
155
- return this . doGetPassword ( service ) ;
92
+ return this . _secrets ;
156
93
}
157
94
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 ) ) ;
176
97
}
177
98
}
178
99
@@ -469,24 +390,6 @@ class WorkspaceProvider implements IWorkspaceProvider {
469
390
}
470
391
}
471
392
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
-
490
393
( function ( ) {
491
394
492
395
// Find config by checking for DOM
@@ -504,6 +407,6 @@ function doCreateUri(path: string, queryValues: Map<string, string>): URI {
504
407
settingsSyncOptions : config . settingsSyncOptions ? { enabled : config . settingsSyncOptions . enabled , } : undefined ,
505
408
workspaceProvider : WorkspaceProvider . create ( config ) ,
506
409
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 ( )
508
411
} ) ;
509
412
} ) ( ) ;
0 commit comments