mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-11 14:04:49 -05:00
* Initial plan * Remove web worker support from microsoft-authentication extension - Remove browser entry point from package.json - Remove browser webpack configuration - Remove browser-specific scripts (compile-web, watch-web) - Remove src/browser/ directory with browser-specific implementations - Remove ExtensionHost.WebWorker enum value - Remove supportsWebWorkerExtensionHost flags from all flows - Simplify authProvider.ts by removing web worker detection logic - Remove web worker test case from flows.test.ts - Successfully compiled with 0 errors Co-authored-by: TylerLeonhardt <2644648+TylerLeonhardt@users.noreply.github.com> * couple references --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
148 lines
4.5 KiB
TypeScript
148 lines
4.5 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { AuthenticationResult } from '@azure/msal-node';
|
|
import { Uri, LogOutputChannel, env } from 'vscode';
|
|
import { ICachedPublicClientApplication } from '../common/publicClientCache';
|
|
import { UriHandlerLoopbackClient } from '../common/loopbackClientAndOpener';
|
|
import { UriEventHandler } from '../UriEventHandler';
|
|
import { loopbackTemplate } from './loopbackTemplate';
|
|
import { Config } from '../common/config';
|
|
|
|
const DEFAULT_REDIRECT_URI = 'https://vscode.dev/redirect';
|
|
|
|
export const enum ExtensionHost {
|
|
Remote,
|
|
Local
|
|
}
|
|
|
|
interface IMsalFlowOptions {
|
|
supportsRemoteExtensionHost: boolean;
|
|
supportsUnsupportedClient: boolean;
|
|
supportsBroker: boolean;
|
|
}
|
|
|
|
interface IMsalFlowTriggerOptions {
|
|
cachedPca: ICachedPublicClientApplication;
|
|
authority: string;
|
|
scopes: string[];
|
|
callbackUri: Uri;
|
|
loginHint?: string;
|
|
windowHandle?: Buffer;
|
|
logger: LogOutputChannel;
|
|
uriHandler: UriEventHandler;
|
|
claims?: string;
|
|
}
|
|
|
|
interface IMsalFlow {
|
|
readonly label: string;
|
|
readonly options: IMsalFlowOptions;
|
|
trigger(options: IMsalFlowTriggerOptions): Promise<AuthenticationResult>;
|
|
}
|
|
|
|
class DefaultLoopbackFlow implements IMsalFlow {
|
|
label = 'default';
|
|
options: IMsalFlowOptions = {
|
|
supportsRemoteExtensionHost: false,
|
|
supportsUnsupportedClient: true,
|
|
supportsBroker: true
|
|
};
|
|
|
|
async trigger({ cachedPca, authority, scopes, claims, loginHint, windowHandle, logger }: IMsalFlowTriggerOptions): Promise<AuthenticationResult> {
|
|
logger.info('Trying default msal flow...');
|
|
let redirectUri: string | undefined;
|
|
if (cachedPca.isBrokerAvailable && process.platform === 'darwin') {
|
|
redirectUri = Config.macOSBrokerRedirectUri;
|
|
}
|
|
return await cachedPca.acquireTokenInteractive({
|
|
openBrowser: async (url: string) => { await env.openExternal(Uri.parse(url)); },
|
|
scopes,
|
|
authority,
|
|
successTemplate: loopbackTemplate,
|
|
errorTemplate: loopbackTemplate,
|
|
loginHint,
|
|
prompt: loginHint ? undefined : 'select_account',
|
|
windowHandle,
|
|
claims,
|
|
redirectUri
|
|
});
|
|
}
|
|
}
|
|
|
|
class UrlHandlerFlow implements IMsalFlow {
|
|
label = 'protocol handler';
|
|
options: IMsalFlowOptions = {
|
|
supportsRemoteExtensionHost: true,
|
|
supportsUnsupportedClient: false,
|
|
supportsBroker: false
|
|
};
|
|
|
|
async trigger({ cachedPca, authority, scopes, claims, loginHint, windowHandle, logger, uriHandler, callbackUri }: IMsalFlowTriggerOptions): Promise<AuthenticationResult> {
|
|
logger.info('Trying protocol handler flow...');
|
|
const loopbackClient = new UriHandlerLoopbackClient(uriHandler, DEFAULT_REDIRECT_URI, callbackUri, logger);
|
|
let redirectUri: string | undefined;
|
|
if (cachedPca.isBrokerAvailable && process.platform === 'darwin') {
|
|
redirectUri = Config.macOSBrokerRedirectUri;
|
|
}
|
|
return await cachedPca.acquireTokenInteractive({
|
|
openBrowser: (url: string) => loopbackClient.openBrowser(url),
|
|
scopes,
|
|
authority,
|
|
loopbackClient,
|
|
loginHint,
|
|
prompt: loginHint ? undefined : 'select_account',
|
|
windowHandle,
|
|
claims,
|
|
redirectUri
|
|
});
|
|
}
|
|
}
|
|
|
|
class DeviceCodeFlow implements IMsalFlow {
|
|
label = 'device code';
|
|
options: IMsalFlowOptions = {
|
|
supportsRemoteExtensionHost: true,
|
|
supportsUnsupportedClient: true,
|
|
supportsBroker: false
|
|
};
|
|
|
|
async trigger({ cachedPca, authority, scopes, claims, logger }: IMsalFlowTriggerOptions): Promise<AuthenticationResult> {
|
|
logger.info('Trying device code flow...');
|
|
const result = await cachedPca.acquireTokenByDeviceCode({ scopes, authority, claims });
|
|
if (!result) {
|
|
throw new Error('Device code flow did not return a result');
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
const allFlows: IMsalFlow[] = [
|
|
new DefaultLoopbackFlow(),
|
|
new UrlHandlerFlow(),
|
|
new DeviceCodeFlow()
|
|
];
|
|
|
|
export interface IMsalFlowQuery {
|
|
extensionHost: ExtensionHost;
|
|
supportedClient: boolean;
|
|
isBrokerSupported: boolean;
|
|
}
|
|
|
|
export function getMsalFlows(query: IMsalFlowQuery): IMsalFlow[] {
|
|
const flows = [];
|
|
for (const flow of allFlows) {
|
|
let useFlow: boolean = true;
|
|
if (query.extensionHost === ExtensionHost.Remote) {
|
|
useFlow &&= flow.options.supportsRemoteExtensionHost;
|
|
}
|
|
useFlow &&= flow.options.supportsBroker || !query.isBrokerSupported;
|
|
useFlow &&= flow.options.supportsUnsupportedClient || query.supportedClient;
|
|
if (useFlow) {
|
|
flows.push(flow);
|
|
}
|
|
}
|
|
return flows;
|
|
}
|