diff --git a/CHANGELOG.md b/CHANGELOG.md index f1a14b317e024..7e3ca9e1e61c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - [workspace] Implement CanonicalUriProvider API #12743 (https://github.com/eclipse-theia/theia/pull/12743 - Contributed on behalf of STMicroelectronics - Show command shortcuts in toolbar item tooltips. #12660 (https://github.com/eclipse-theia/theia/pull/12660) - Contributed on behalf of STMicroelectronics - [cli] added `check:theia-extensions` which checks the uniqueness of Theia extension versions [#12596](https://github.com/eclipse-theia/theia/pull/12596) - Contributed on behalf of STMicroelectronics +- [vscode] Support AuthenticationForceNewSessionOptions and detail message [#12752](https://github.com/eclipse-theia/theia/pull/12752) - Contributed on behalf of STMicroelectronics [Breaking Changes:](#breaking_changes_1.40.0) diff --git a/packages/plugin-ext/src/main/browser/authentication-main.ts b/packages/plugin-ext/src/main/browser/authentication-main.ts index d058ba2577b2e..087b1c0893177 100644 --- a/packages/plugin-ext/src/main/browser/authentication-main.ts +++ b/packages/plugin-ext/src/main/browser/authentication-main.ts @@ -34,6 +34,7 @@ import { QuickPickService } from '@theia/core/lib/common/quick-pick-service'; import * as theia from '@theia/plugin'; import { QuickPickValue } from '@theia/core/lib/browser/quick-input/quick-input-service'; import { nls } from '@theia/core/lib/common/nls'; +import { isObject } from '@theia/core'; export function getAuthenticationProviderActivationEvent(id: string): string { return `onAuthenticationRequest:${id}`; } @@ -117,7 +118,7 @@ export class AuthenticationMainImpl implements AuthenticationMain { // We may need to prompt because we don't have a valid session modal flows if (options.createIfNone || options.forceNewSession) { const providerName = this.authenticationService.getLabel(providerId); - const detail = (typeof options.forceNewSession === 'object') ? options.forceNewSession!.detail : undefined; + const detail = isAuthenticationForceNewSessionOptions(options.forceNewSession) ? 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.'); @@ -197,10 +198,12 @@ export class AuthenticationMainImpl implements AuthenticationMain { return allow; } - protected async loginPrompt(providerName: string, extensionName: string, recreatingSession: boolean, _detail?: string): Promise { - const message = recreatingSession + protected async loginPrompt(providerName: string, extensionName: string, recreatingSession: boolean, detail?: string): Promise { + let message = recreatingSession ? nls.localizeByDefault("The extension '{0}' wants you to sign in again using {1}.", extensionName, providerName) : nls.localizeByDefault("The extension '{0}' wants to sign in using {1}.", extensionName, providerName); + + message = detail ? message + ' ' + detail : message; const choice = await this.messageService.info(message, 'Allow', 'Cancel'); return choice === 'Allow'; } @@ -224,6 +227,10 @@ export class AuthenticationMainImpl implements AuthenticationMain { } } +function isAuthenticationForceNewSessionOptions(arg: unknown): arg is theia.AuthenticationForceNewSessionOptions { + return isObject(arg) && typeof arg.detail === 'string'; +} + async function addAccountUsage(storageService: StorageService, providerId: string, accountName: string, extensionId: string, extensionName: string): Promise { const accountKey = `authentication-${providerId}-${accountName}-usages`; const usages = await readAccountUsages(storageService, providerId, accountName); diff --git a/packages/plugin-ext/src/plugin/authentication-ext.ts b/packages/plugin-ext/src/plugin/authentication-ext.ts index b8977bf33509c..25dba1325d0ab 100644 --- a/packages/plugin-ext/src/plugin/authentication-ext.ts +++ b/packages/plugin-ext/src/plugin/authentication-ext.ts @@ -42,12 +42,12 @@ export class AuthenticationExtImpl implements AuthenticationExt { } async getSession(requestingExtension: InternalPlugin, providerId: string, scopes: readonly string[], - options: theia.AuthenticationGetSessionOptions & ({ createIfNone: true } | { forceNewSession: true } | { forceNewSession: { detail: string } })): + options: theia.AuthenticationGetSessionOptions & ({ createIfNone: true } | { forceNewSession: true } | { forceNewSession: theia.AuthenticationForceNewSessionOptions })): Promise; async getSession(requestingExtension: InternalPlugin, providerId: string, scopes: readonly string[], options: theia.AuthenticationGetSessionOptions & { forceNewSession: true }): Promise; async getSession(requestingExtension: InternalPlugin, providerId: string, scopes: readonly string[], - options: theia.AuthenticationGetSessionOptions & { forceNewSession: { detail: string } }): Promise; + options: theia.AuthenticationGetSessionOptions & { forceNewSession: theia.AuthenticationForceNewSessionOptions }): Promise; async getSession(requestingExtension: InternalPlugin, providerId: string, scopes: readonly string[], options: theia.AuthenticationGetSessionOptions): Promise; async getSession(requestingExtension: InternalPlugin, providerId: string, scopes: readonly string[], diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts index a8e0bc8b3b075..ef2a5fe88d07c 100644 --- a/packages/plugin/src/theia.d.ts +++ b/packages/plugin/src/theia.d.ts @@ -13666,6 +13666,17 @@ export module '@theia/plugin' { readonly label: string; } + /** + * Optional options to be used when calling {@link authentication.getSession} with the flag `forceNewSession`. + */ + export interface AuthenticationForceNewSessionOptions { + /** + * An optional message that will be displayed to the user when we ask to re-authenticate. Providing additional context + * as to why you are asking a user to re-authenticate can help increase the odds that they will accept. + */ + detail?: string; + } + /** * Options to be used when getting an {@link AuthenticationSession AuthenticationSession} from an {@link AuthenticationProvider AuthenticationProvider}. */ @@ -13700,7 +13711,7 @@ export module '@theia/plugin' { * * Defaults to false. */ - forceNewSession?: boolean | { detail: string }; + forceNewSession?: boolean | AuthenticationForceNewSessionOptions; /** * Whether we should show the indication to sign in in the Accounts menu.