@@ -17,6 +17,7 @@ import product from 'vs/platform/product/common/product';
17
17
import { ISecretStorageProvider } from 'vs/platform/secrets/common/secrets' ;
18
18
import { isFolderToOpen , isWorkspaceToOpen } from 'vs/platform/window/common/window' ;
19
19
import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api' ;
20
+ import { AuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService' ;
20
21
import type { IWorkspace , IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService' ;
21
22
import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService' ;
22
23
import { create } from 'vs/workbench/workbench.web.main' ;
@@ -176,19 +177,56 @@ export class LocalStorageSecretStorageProvider implements ISecretStorageProvider
176
177
) { }
177
178
178
179
private async load ( ) : Promise < Record < string , string > > {
180
+ const record = this . loadAuthSessionFromElement ( ) ;
179
181
// Get the secrets from localStorage
180
182
const encrypted = window . localStorage . getItem ( this . _storageKey ) ;
181
183
if ( encrypted ) {
182
184
try {
183
- return JSON . parse ( await this . crypto . unseal ( encrypted ) ) ;
185
+ const decrypted = JSON . parse ( await this . crypto . unseal ( encrypted ) ) ;
186
+ return { ...record , ...decrypted } ;
184
187
} catch ( err ) {
185
188
// TODO: send telemetry
186
189
console . error ( 'Failed to decrypt secrets from localStorage' , err ) ;
187
190
window . localStorage . removeItem ( this . _storageKey ) ;
188
191
}
189
192
}
190
193
191
- return { } ;
194
+ return record ;
195
+ }
196
+
197
+ private loadAuthSessionFromElement ( ) : Record < string , string > {
198
+ let authSessionInfo : ( AuthenticationSessionInfo & { scopes : string [ ] [ ] } ) | undefined ;
199
+ const authSessionElement = document . getElementById ( 'vscode-workbench-auth-session' ) ;
200
+ const authSessionElementAttribute = authSessionElement ? authSessionElement . getAttribute ( 'data-settings' ) : undefined ;
201
+ if ( authSessionElementAttribute ) {
202
+ try {
203
+ authSessionInfo = JSON . parse ( authSessionElementAttribute ) ;
204
+ } catch ( error ) { /* Invalid session is passed. Ignore. */ }
205
+ }
206
+
207
+ if ( ! authSessionInfo ) {
208
+ return { } ;
209
+ }
210
+
211
+ const record : Record < string , string > = { } ;
212
+
213
+ // Settings Sync Entry
214
+ record [ `${ product . urlProtocol } .loginAccount` ] = JSON . stringify ( authSessionInfo ) ;
215
+
216
+ // Auth extension Entry
217
+ if ( authSessionInfo . providerId !== 'github' ) {
218
+ console . error ( `Unexpected auth provider: ${ authSessionInfo . providerId } . Expected 'github'.` ) ;
219
+ return record ;
220
+ }
221
+
222
+ const authAccount = JSON . stringify ( { extensionId : 'vscode.github-authentication' , key : 'github.auth' } ) ;
223
+ record [ authAccount ] = JSON . stringify ( authSessionInfo . scopes . map ( scopes => ( {
224
+ id : authSessionInfo ! . id ,
225
+ scopes,
226
+ accessToken : authSessionInfo ! . accessToken
227
+ } ) ) ) ;
228
+
229
+ return record ;
192
230
}
193
231
194
232
async get ( key : string ) : Promise < string | undefined > {
0 commit comments