diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index ef67d21e06d..b09b8ad46a4 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -162,7 +162,7 @@ declare module 'vscode' { * * Defaults to false. */ - forceRecreate?: boolean; + forceNewSession?: boolean | { detail: string }; } export namespace authentication { @@ -179,7 +179,8 @@ declare module 'vscode' { * @param options The {@link AuthenticationGetSessionOptions} to use * @returns A thenable that resolves to an authentication session */ - export function getSession(providerId: string, scopes: readonly string[], options: AuthenticationGetSessionOptions & { forceRecreate: true }): Thenable; + export function getSession(providerId: string, scopes: readonly string[], options: AuthenticationGetSessionOptions & { forceNewSession: true }): Thenable; + export function getSession(providerId: string, scopes: readonly string[], options: AuthenticationGetSessionOptions & { forceNewSession: { detail: string } }): Thenable; } export namespace workspace { diff --git a/src/vs/workbench/api/browser/mainThreadAuthentication.ts b/src/vs/workbench/api/browser/mainThreadAuthentication.ts index 70e795c9ea2..cd8c0da35ec 100644 --- a/src/vs/workbench/api/browser/mainThreadAuthentication.ts +++ b/src/vs/workbench/api/browser/mainThreadAuthentication.ts @@ -179,7 +179,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu $removeSession(providerId: string, sessionId: string): Promise { return this.authenticationService.removeSession(providerId, sessionId); } - private async loginPrompt(providerName: string, extensionName: string, recreatingSession: boolean): Promise { + private async loginPrompt(providerName: string, extensionName: string, recreatingSession: boolean, detail?: string): Promise { const message = recreatingSession ? nls.localize('confirmRelogin', "The extension '{0}' wants you to sign in again using {1}.", extensionName, providerName) : nls.localize('confirmLogin', "The extension '{0}' wants to sign in using {1}.", extensionName, providerName); @@ -188,7 +188,8 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu message, [nls.localize('allow', "Allow"), nls.localize('cancel', "Cancel")], { - cancelId: 1 + cancelId: 1, + detail } ); @@ -239,17 +240,17 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu return this.authenticationService.selectSession(providerId, extensionId, extensionName, scopes, potentialSessions); } - async $getSession(providerId: string, scopes: string[], extensionId: string, extensionName: string, options: { createIfNone: boolean, forceRecreate: boolean, clearSessionPreference: boolean }): Promise { + async $getSession(providerId: string, scopes: string[], extensionId: string, extensionName: string, options: { createIfNone: boolean, forceNewSession: boolean | { detail: string }, clearSessionPreference: boolean }): Promise { const sessions = await this.authenticationService.getSessions(providerId, scopes, true); let silent = !options.createIfNone; - if (options.forceRecreate && !sessions.length) { + if (options.forceNewSession && !sessions.length) { throw new Error('No existing sessions found.'); } let session: modes.AuthenticationSession | undefined; // Ignore existing sessions if we are forceRecreating - if (!options.forceRecreate && sessions.length) { + if (!options.forceNewSession && sessions.length) { if (!this.authenticationService.supportsMultipleAccounts(providerId)) { session = sessions[0]; const allowed = this.authenticationService.isAccessAllowed(providerId, session.account.label, extensionId); @@ -271,9 +272,10 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu } } else { // If we are forceRecreating, we need to show the prompt. - if (options.forceRecreate || !silent) { + if (options.forceNewSession || !silent) { const providerName = this.authenticationService.getLabel(providerId); - const isAllowed = await this.loginPrompt(providerName, extensionName, options.forceRecreate); + const detail = (typeof options.forceNewSession === 'object') ? options.forceNewSession!.detail : undefined; + const isAllowed = await this.loginPrompt(providerName, extensionName, !!options.forceNewSession, detail); if (!isAllowed) { throw new Error('User did not consent to login.'); } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 753f3db414c..bad876b57ff 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -226,7 +226,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const authentication: typeof vscode.authentication = { getSession(providerId: string, scopes: readonly string[], options?: vscode.AuthenticationGetSessionOptions) { - if (options?.forceRecreate) { + if (options?.forceNewSession) { checkProposedApiEnabled(extension); } return extHostAuthentication.getSession(extension, providerId, scopes, options as any); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 96d005734f5..b10b05fc1db 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -173,7 +173,7 @@ export interface MainThreadAuthenticationShape extends IDisposable { $unregisterAuthenticationProvider(id: string): void; $ensureProvider(id: string): Promise; $sendDidChangeSessions(providerId: string, event: modes.AuthenticationSessionsChangeEvent): void; - $getSession(providerId: string, scopes: readonly string[], extensionId: string, extensionName: string, options: { createIfNone?: boolean, forceRecreate?: boolean, clearSessionPreference?: boolean }): Promise; + $getSession(providerId: string, scopes: readonly string[], extensionId: string, extensionName: string, options: { createIfNone?: boolean, forceNewSession?: boolean | { detail: string }, clearSessionPreference?: boolean }): Promise; $removeSession(providerId: string, sessionId: string): Promise; } diff --git a/src/vs/workbench/api/common/extHostAuthentication.ts b/src/vs/workbench/api/common/extHostAuthentication.ts index b0c081cfd76..efc1cb33487 100644 --- a/src/vs/workbench/api/common/extHostAuthentication.ts +++ b/src/vs/workbench/api/common/extHostAuthentication.ts @@ -41,8 +41,9 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape { return Promise.resolve(); } - async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: readonly string[], options: vscode.AuthenticationGetSessionOptions & { createIfNone: true }): Promise; - async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: readonly string[], options: vscode.AuthenticationGetSessionOptions & { forceRecreate: true }): Promise; + async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: readonly string[], options: vscode.AuthenticationGetSessionOptions & ({ createIfNone: true } | { forceNewSession: true } | { forceNewSession: { detail: string } })): Promise; + async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: readonly string[], options: vscode.AuthenticationGetSessionOptions & { forceNewSession: true }): Promise; + async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: readonly string[], options: vscode.AuthenticationGetSessionOptions & { forceNewSession: { detail: string } }): Promise; async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: readonly string[], options: vscode.AuthenticationGetSessionOptions = {}): Promise { const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier); const inFlightRequests = this._inFlightRequests.get(extensionId) || []; diff --git a/src/vs/workbench/test/browser/api/mainThreadAuthentication.test.ts b/src/vs/workbench/test/browser/api/mainThreadAuthentication.test.ts index 850adbbf0b4..6a62a89e28c 100644 --- a/src/vs/workbench/test/browser/api/mainThreadAuthentication.test.ts +++ b/src/vs/workbench/test/browser/api/mainThreadAuthentication.test.ts @@ -125,7 +125,7 @@ suite('MainThreadAuthentication', () => { const session = await mainThreadAuthentication.$getSession('test', ['foo'], 'testextension', 'test extension', { createIfNone: true, clearSessionPreference: false, - forceRecreate: false + forceNewSession: false }); assert.strictEqual(session?.id, 'test'); assert.strictEqual(session?.scopes[0], 'foo'); @@ -135,7 +135,7 @@ suite('MainThreadAuthentication', () => { const session = await mainThreadAuthentication.$getSession('test', ['foo'], 'testextension', 'test extension', { createIfNone: true, clearSessionPreference: false, - forceRecreate: false + forceNewSession: false }); assert.strictEqual(session?.id, 'test'); @@ -144,7 +144,7 @@ suite('MainThreadAuthentication', () => { const session2 = await mainThreadAuthentication.$getSession('test', ['foo'], 'testextension', 'test extension', { createIfNone: false, clearSessionPreference: false, - forceRecreate: true + forceNewSession: true }); assert.strictEqual(session.id, session2?.id); @@ -157,7 +157,7 @@ suite('MainThreadAuthentication', () => { await mainThreadAuthentication.$getSession('empty', ['foo'], 'testextension', 'test extension', { createIfNone: false, clearSessionPreference: false, - forceRecreate: true + forceNewSession: true }); assert.fail('should have thrown an Error.'); } catch (e) {