Skip to content

Commit

Permalink
[vscode] support AuthenticationForceNewSessionOptions with detail mes…
Browse files Browse the repository at this point in the history
…sage (#12752)

* Defines and supports this new type in the authentification service.
* Updates prompt when new session is forced if detail message is present.

Contributed on behalf of STMicroelectronics
  • Loading branch information
rschnekenbu authored Jul 27, 2023
1 parent c8fb5ad commit e3ecd7b
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
- [vscode] Add support for the TaskPresentationOptions close property [#12749](https://github.com/eclipse-theia/theia/pull/12749) - Contributed on behalf of STMicroelectronics

<a name="breaking_changes_1.40.0">[Breaking Changes:](#breaking_changes_1.40.0)</a>
Expand Down
29 changes: 23 additions & 6 deletions packages/plugin-ext/src/main/browser/authentication-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { interfaces } from '@theia/core/shared/inversify';
import { AuthenticationExt, AuthenticationMain, MAIN_RPC_CONTEXT } from '../../common/plugin-api-rpc';
import { RPCProtocol } from '../../common/rpc-protocol';
import { MessageService } from '@theia/core/lib/common/message-service';
import { Dialog, StorageService } from '@theia/core/lib/browser';
import { ConfirmDialog, Dialog, StorageService } from '@theia/core/lib/browser';
import {
AuthenticationProvider,
AuthenticationService,
Expand All @@ -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}`; }

Expand Down Expand Up @@ -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.');
Expand Down Expand Up @@ -197,12 +198,24 @@ export class AuthenticationMainImpl implements AuthenticationMain {
return allow;
}

protected async loginPrompt(providerName: string, extensionName: string, recreatingSession: boolean, _detail?: string): Promise<boolean> {
const message = recreatingSession
protected async loginPrompt(providerName: string, extensionName: string, recreatingSession: boolean, detail?: string): Promise<boolean> {
const msg = document.createElement('span');
msg.textContent = 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);
const choice = await this.messageService.info(message, 'Allow', 'Cancel');
return choice === 'Allow';

if (detail) {
const detailElement = document.createElement('p');
detailElement.textContent = detail;
msg.appendChild(detailElement);
}

return !!await new ConfirmDialog({
title: nls.localize('theia/plugin-ext/authentication-main/loginTitle', 'Login'),
msg,
ok: nls.localizeByDefault('Allow'),
cancel: Dialog.CANCEL
}).open();
}

protected async isAccessAllowed(providerId: string, accountName: string, extensionId: string): Promise<boolean> {
Expand All @@ -224,6 +237,10 @@ export class AuthenticationMainImpl implements AuthenticationMain {
}
}

function isAuthenticationForceNewSessionOptions(arg: unknown): arg is theia.AuthenticationForceNewSessionOptions {
return isObject<theia.AuthenticationForceNewSessionOptions>(arg) && typeof arg.detail === 'string';
}

async function addAccountUsage(storageService: StorageService, providerId: string, accountName: string, extensionId: string, extensionName: string): Promise<void> {
const accountKey = `authentication-${providerId}-${accountName}-usages`;
const usages = await readAccountUsages(storageService, providerId, accountName);
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-ext/src/plugin/authentication-ext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<theia.AuthenticationSession>;
async getSession(requestingExtension: InternalPlugin, providerId: string, scopes: readonly string[],
options: theia.AuthenticationGetSessionOptions & { forceNewSession: true }): Promise<theia.AuthenticationSession>;
async getSession(requestingExtension: InternalPlugin, providerId: string, scopes: readonly string[],
options: theia.AuthenticationGetSessionOptions & { forceNewSession: { detail: string } }): Promise<theia.AuthenticationSession>;
options: theia.AuthenticationGetSessionOptions & { forceNewSession: theia.AuthenticationForceNewSessionOptions }): Promise<theia.AuthenticationSession>;
async getSession(requestingExtension: InternalPlugin, providerId: string, scopes: readonly string[],
options: theia.AuthenticationGetSessionOptions): Promise<theia.AuthenticationSession | undefined>;
async getSession(requestingExtension: InternalPlugin, providerId: string, scopes: readonly string[],
Expand Down
13 changes: 12 additions & 1 deletion packages/plugin/src/theia.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13671,6 +13671,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}.
*/
Expand Down Expand Up @@ -13705,7 +13716,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.
Expand Down

0 comments on commit e3ecd7b

Please sign in to comment.