diff --git a/packages/mgt-components/src/utils/FluentComponents.ts b/packages/mgt-components/src/utils/FluentComponents.ts index cfdbc4bf72..b4cc02031d 100644 --- a/packages/mgt-components/src/utils/FluentComponents.ts +++ b/packages/mgt-components/src/utils/FluentComponents.ts @@ -1,3 +1,10 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + import { provideFluentDesignSystem } from '@fluentui/web-components'; const designSystem = provideFluentDesignSystem(); diff --git a/packages/mgt-element/src/Graph.ts b/packages/mgt-element/src/Graph.ts index a380b41d6d..803755b491 100644 --- a/packages/mgt-element/src/Graph.ts +++ b/packages/mgt-element/src/Graph.ts @@ -17,7 +17,7 @@ import { TelemetryHandler } from '@microsoft/microsoft-graph-client'; -import { IGraph } from './IGraph'; +import { IGraph, MICROSOFT_GRAPH_DEFAULT_ENDPOINT } from './IGraph'; import { IProvider } from './providers/IProvider'; import { Batch } from './utils/Batch'; import { ComponentMiddlewareOptions } from './utils/ComponentMiddlewareOptions'; @@ -155,8 +155,10 @@ export function createFromProvider(provider: IProvider, version?: string, compon new HTTPMessageHandler() ]; + let baseURL = provider.baseURL ? provider.baseURL : MICROSOFT_GRAPH_DEFAULT_ENDPOINT; const client = Client.initWithMiddleware({ - middleware: chainMiddleware(...middleware) + middleware: chainMiddleware(...middleware), + baseUrl: baseURL }); const graph = new Graph(client, version); diff --git a/packages/mgt-element/src/IGraph.ts b/packages/mgt-element/src/IGraph.ts index 23517e01d1..277dd43838 100644 --- a/packages/mgt-element/src/IGraph.ts +++ b/packages/mgt-element/src/IGraph.ts @@ -66,3 +66,35 @@ export interface IGraph { */ createBatch(): IBatch; } + +/** + * GraphEndpoint is a valid URL that is used to access the Graph. + */ +export type GraphEndpoint = + | 'https://graph.microsoft.com' + | 'https://graph.microsoft.us' + | 'https://dod-graph.microsoft.us' + | 'https://graph.microsoft.de' + | 'https://microsoftgraph.chinacloudapi.cn'; + +/** + * MICROSOFT_GRAPH_ENDPOINTS is a set of all the valid Graph URL endpoints. + */ +export const MICROSOFT_GRAPH_ENDPOINTS: Set = new Set(); + +/** + * MICROSOFT_GRAPH_DEFAULT_ENDPOINT is the default Graph endpoint that is silently set on + * the providers as the baseURL. + */ +export const MICROSOFT_GRAPH_DEFAULT_ENDPOINT: GraphEndpoint = 'https://graph.microsoft.com'; + +(() => { + const endpoints: GraphEndpoint[] = [ + MICROSOFT_GRAPH_DEFAULT_ENDPOINT, + 'https://graph.microsoft.us', + 'https://dod-graph.microsoft.us', + 'https://graph.microsoft.de', + 'https://microsoftgraph.chinacloudapi.cn' + ]; + endpoints.forEach(endpoint => MICROSOFT_GRAPH_ENDPOINTS.add(endpoint)); +})(); diff --git a/packages/mgt-element/src/components/baseProvider.ts b/packages/mgt-element/src/components/baseProvider.ts index 3ec122e11b..e887aeaa7f 100644 --- a/packages/mgt-element/src/components/baseProvider.ts +++ b/packages/mgt-element/src/components/baseProvider.ts @@ -8,6 +8,7 @@ import { property } from 'lit/decorators.js'; import { MgtBaseComponent } from './baseComponent'; import { IProvider } from '../providers/IProvider'; +import { GraphEndpoint } from '../IGraph'; /** * Abstract implementation for provider component @@ -65,6 +66,17 @@ export abstract class MgtBaseProvider extends MgtBaseComponent { }) public dependsOn: MgtBaseProvider; + /** + * The base URL that should be used in the graph client config. + * + * @memberof MgtBaseProvider + */ + @property({ + attribute: 'base-url', + type: String + }) + public baseUrl: GraphEndpoint; + private _provider: IProvider; /** diff --git a/packages/mgt-element/src/providers/IProvider.ts b/packages/mgt-element/src/providers/IProvider.ts index 1c238b9769..02ea943afe 100644 --- a/packages/mgt-element/src/providers/IProvider.ts +++ b/packages/mgt-element/src/providers/IProvider.ts @@ -6,7 +6,8 @@ */ import { AuthenticationProvider, AuthenticationProviderOptions } from '@microsoft/microsoft-graph-client'; -import { IGraph } from '../IGraph'; +import { validateBaseURL } from '../utils/GraphHelpers'; +import { GraphEndpoint, IGraph, MICROSOFT_GRAPH_DEFAULT_ENDPOINT } from '../IGraph'; import { EventDispatcher, EventHandler } from '../utils/EventDispatcher'; /** @@ -48,6 +49,23 @@ export abstract class IProvider implements AuthenticationProvider { private _state: ProviderState; private _loginChangedDispatcher = new EventDispatcher(); private _activeAccountChangedDispatcher = new EventDispatcher(); + private _baseURL: GraphEndpoint = MICROSOFT_GRAPH_DEFAULT_ENDPOINT; + + /** + * The base URL to be used in the graph client config. + */ + public set baseURL(url: GraphEndpoint) { + if (validateBaseURL(url)) { + this._baseURL = url; + return; + } else { + throw new Error(`${url} is not a valid Graph URL endpoint.`); + } + } + + public get baseURL(): GraphEndpoint { + return this._baseURL; + } /** * Enable/Disable incremental consent diff --git a/packages/mgt-element/src/utils/GraphHelpers.ts b/packages/mgt-element/src/utils/GraphHelpers.ts index 736a5ea485..16b9507bbf 100644 --- a/packages/mgt-element/src/utils/GraphHelpers.ts +++ b/packages/mgt-element/src/utils/GraphHelpers.ts @@ -6,7 +6,7 @@ */ import { AuthenticationHandlerOptions, Middleware } from '@microsoft/microsoft-graph-client'; -import { Providers } from '..'; +import { GraphEndpoint, MICROSOFT_GRAPH_ENDPOINTS, Providers } from '..'; /** * creates an AuthenticationHandlerOptions from scopes array that @@ -46,3 +46,20 @@ export function chainMiddleware(...middleware: Middleware[]): Middleware { } return rootMiddleware; } + +/** + * Helper method to validate a base URL string + * @param url a URL string + * @returns GraphEndpoint + */ +export function validateBaseURL(url: string): GraphEndpoint { + try { + const urlObj = new URL(url); + const originAsEndpoint = urlObj.origin as GraphEndpoint; + if (MICROSOFT_GRAPH_ENDPOINTS.has(originAsEndpoint)) { + return originAsEndpoint; + } + } catch (error) { + return; + } +} diff --git a/packages/mgt-spfx/src/index.ts b/packages/mgt-spfx/src/index.ts index 0843f0dbc1..a53815a9fb 100644 --- a/packages/mgt-spfx/src/index.ts +++ b/packages/mgt-spfx/src/index.ts @@ -1,3 +1,10 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + export { MgtLibrary } from './libraries/mgt/MgtLibrary'; export * from '@microsoft/mgt-sharepoint-provider'; export * from '@microsoft/mgt-components'; diff --git a/packages/mgt-spfx/src/libraries/mgt/MgtLibrary.ts b/packages/mgt-spfx/src/libraries/mgt/MgtLibrary.ts index 144fcdaee6..55a8658223 100644 --- a/packages/mgt-spfx/src/libraries/mgt/MgtLibrary.ts +++ b/packages/mgt-spfx/src/libraries/mgt/MgtLibrary.ts @@ -1,3 +1,10 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + export class MgtLibrary { public name(): string { return 'MgtLibrary'; diff --git a/packages/mgt-spfx/src/libraries/mgt/loc/en-us.js b/packages/mgt-spfx/src/libraries/mgt/loc/en-us.js index 6e2c5d4679..c3b1eaf678 100644 --- a/packages/mgt-spfx/src/libraries/mgt/loc/en-us.js +++ b/packages/mgt-spfx/src/libraries/mgt/loc/en-us.js @@ -1,3 +1,10 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + define([], function() { return { } diff --git a/packages/providers/mgt-electron-provider/src/Authenticator/ElectronAuthenticator.ts b/packages/providers/mgt-electron-provider/src/Authenticator/ElectronAuthenticator.ts index 2b7d707e58..c0fb91d71c 100644 --- a/packages/providers/mgt-electron-provider/src/Authenticator/ElectronAuthenticator.ts +++ b/packages/providers/mgt-electron-provider/src/Authenticator/ElectronAuthenticator.ts @@ -17,6 +17,7 @@ import { PublicClientApplication } from '@azure/msal-node'; import { AuthenticationProviderOptions } from '@microsoft/microsoft-graph-client'; +import { GraphEndpoint } from '@microsoft/mgt-element'; import { BrowserWindow, ipcMain } from 'electron'; import { CustomFileProtocolListener } from './CustomFileProtocol'; import { REDIRECT_URI, COMMON_AUTHORITY_URL } from './Constants'; @@ -65,6 +66,10 @@ export interface MsalElectronConfig { * @memberof MsalElectronConfig */ cachePlugin?: ICachePlugin; + /** + * The base URL for the graph client + */ + baseURL?: GraphEndpoint; } /** @@ -86,6 +91,11 @@ enum AuthState { LOGGED_OUT = 'logged_out' } +/** + * AccountDetails defines the available AccountInfo or undefined. + */ +type AccountDetails = AccountInfo | undefined; + /** * ElectronAuthenticator class to be instantiated in the main process. * Responsible for MSAL authentication flow and token acqusition. @@ -133,10 +143,10 @@ export class ElectronAuthenticator { * Logged in account * * @private - * @type {AccountInfo} + * @type {AccountDetails} * @memberof ElectronAuthenticator */ - private account: AccountInfo; + private account: AccountDetails; /** * Params to generate the URL for MSAL auth @@ -182,7 +192,7 @@ export class ElectronAuthenticator { */ private constructor(config: MsalElectronConfig) { this.setConfig(config); - this.account = null; + this.account = undefined; this.mainWindow = config.mainWindow; this.setRequestObjects(config.scopes); this.setupProvider(); @@ -224,7 +234,7 @@ export class ElectronAuthenticator { clientId: config.clientId, authority: config.authority ? config.authority : COMMON_AUTHORITY_URL }, - cache: config.cachePlugin ? { cachePlugin: config.cachePlugin } : null, + cache: config.cachePlugin ? { cachePlugin: config.cachePlugin } : undefined, system: { loggerOptions: { loggerCallback(loglevel, message, containsPii) {}, @@ -255,7 +265,7 @@ export class ElectronAuthenticator { this.authCodeRequest = { scopes: requestScopes, redirectUri, - code: null + code: '' }; } @@ -311,7 +321,7 @@ export class ElectronAuthenticator { * @return {*} {Promise} * @memberof ElectronAuthenticator */ - protected async getAccessToken(options?: AuthenticationProviderOptions): Promise { + protected async getAccessToken(options?: AuthenticationProviderOptions): Promise { let authResponse; const scopes = options && options.scopes ? options.scopes : this.authCodeUrlParams.scopes; const account = this.account || (await this.getAccount()); @@ -326,6 +336,7 @@ export class ElectronAuthenticator { if (authResponse) { return authResponse.accessToken; } + return undefined; } /** @@ -337,7 +348,7 @@ export class ElectronAuthenticator { * @return {*} {Promise} * @memberof ElectronAuthenticator */ - protected async getTokenSilent(tokenRequest, scopes?): Promise { + protected async getTokenSilent(tokenRequest, scopes?): Promise { try { return await this.clientApplication.acquireTokenSilent(tokenRequest); } catch (error) { @@ -366,7 +377,7 @@ export class ElectronAuthenticator { protected async logout(): Promise { if (this.account) { await this.clientApplication.getTokenCache().removeAccount(this.account); - this.account = null; + this.account = undefined; } } @@ -379,8 +390,8 @@ export class ElectronAuthenticator { * @memberof ElectronAuthenticator */ private async setAccountFromResponse(response: AuthenticationResult) { - if (response !== null) { - this.account = response.account; + if (response) { + this.account = response?.account || undefined; } else { this.account = await this.getAccount(); } @@ -412,7 +423,7 @@ export class ElectronAuthenticator { .acquireTokenByCode({ ...this.authCodeRequest, scopes: requestScopes, - code: authCode + code: authCode || '' }) .catch((e: AuthError) => { throw e; @@ -429,7 +440,7 @@ export class ElectronAuthenticator { * @return {*} {Promise} * @memberof ElectronAuthenticator */ - private async listenForAuthCode(navigateUrl: string, prompt_type: promptType): Promise { + private async listenForAuthCode(navigateUrl: string, prompt_type: promptType): Promise { this.setAuthWindow(true); await this.authWindow.loadURL(navigateUrl); return new Promise((resolve, reject) => { @@ -474,20 +485,12 @@ export class ElectronAuthenticator { * @return {*} {Promise} * @memberof ElectronAuthenticator */ - private async getAccount(): Promise { + private async getAccount(): Promise { const cache = this.clientApplication.getTokenCache(); const currentAccounts = await cache.getAllAccounts(); - - if (currentAccounts === null) { - return null; - } - - if (currentAccounts.length > 1) { + if (currentAccounts?.length >= 1) { return currentAccounts[0]; - } else if (currentAccounts.length === 1) { - return currentAccounts[0]; - } else { - return null; } + return undefined; } } diff --git a/packages/providers/mgt-electron-provider/src/Provider/ElectronProvider.ts b/packages/providers/mgt-electron-provider/src/Provider/ElectronProvider.ts index 25440d809d..dfe46602ad 100644 --- a/packages/providers/mgt-electron-provider/src/Provider/ElectronProvider.ts +++ b/packages/providers/mgt-electron-provider/src/Provider/ElectronProvider.ts @@ -5,7 +5,14 @@ * ------------------------------------------------------------------------------------------- */ -import { IProvider, Providers, ProviderState, createFromProvider } from '@microsoft/mgt-element'; +import { + IProvider, + Providers, + ProviderState, + createFromProvider, + GraphEndpoint, + MICROSOFT_GRAPH_DEFAULT_ENDPOINT +} from '@microsoft/mgt-element'; import { AuthenticationProviderOptions } from '@microsoft/microsoft-graph-client'; import { ipcRenderer } from 'electron'; @@ -28,8 +35,9 @@ export class ElectronProvider extends IProvider { return 'MgtElectronProvider'; } - constructor() { + constructor(baseUrl: GraphEndpoint = MICROSOFT_GRAPH_DEFAULT_ENDPOINT) { super(); + this.baseURL = baseUrl; this.graph = createFromProvider(this); this.setupProvider(); } diff --git a/packages/providers/mgt-msal-provider/src/MsalProvider.ts b/packages/providers/mgt-msal-provider/src/MsalProvider.ts index f295f5bd40..9230257537 100644 --- a/packages/providers/mgt-msal-provider/src/MsalProvider.ts +++ b/packages/providers/mgt-msal-provider/src/MsalProvider.ts @@ -6,7 +6,7 @@ */ import { AuthenticationProviderOptions } from '@microsoft/microsoft-graph-client'; -import { IProvider, LoginType, ProviderState, createFromProvider } from '@microsoft/mgt-element'; +import { IProvider, LoginType, ProviderState, createFromProvider, GraphEndpoint } from '@microsoft/mgt-element'; import { AuthenticationParameters, AuthError, AuthResponse, Configuration, UserAgentApplication } from 'msal'; /** @@ -51,6 +51,10 @@ interface MsalConfigBase { * @memberof MsalConfigBase */ prompt?: string; + /** + * The base URL for the graph client + */ + baseURL?: GraphEndpoint; } /** @@ -439,6 +443,7 @@ export class MsalProvider extends IProvider { } this.clientId = clientId; + this.baseURL = typeof config.baseURL !== 'undefined' ? config.baseURL : this.baseURL; this._userAgentApplication = userAgentApplication; this._userAgentApplication.handleRedirectCallback( diff --git a/packages/providers/mgt-msal-provider/src/mgt-msal-provider.ts b/packages/providers/mgt-msal-provider/src/mgt-msal-provider.ts index c9cb060dbf..541ac326bc 100644 --- a/packages/providers/mgt-msal-provider/src/mgt-msal-provider.ts +++ b/packages/providers/mgt-msal-provider/src/mgt-msal-provider.ts @@ -5,7 +5,7 @@ * ------------------------------------------------------------------------------------------- */ import { customElement, property } from 'lit/decorators.js'; -import { Providers, LoginType, MgtBaseProvider } from '@microsoft/mgt-element'; +import { Providers, LoginType, MgtBaseProvider, validateBaseURL } from '@microsoft/mgt-element'; import { MsalConfig, MsalProvider } from './MsalProvider'; /** * Authentication Library Provider for Microsoft personal accounts @@ -135,6 +135,10 @@ export class MgtMsalProvider extends MgtBaseProvider { config.redirectUri = this.redirectUri; } + if (this.baseUrl) { + config.baseURL = this.baseUrl; + } + this.provider = new MsalProvider(config); Providers.globalProvider = this.provider; } diff --git a/packages/providers/mgt-msal2-provider/src/Msal2Provider.ts b/packages/providers/mgt-msal2-provider/src/Msal2Provider.ts index c1b34440a9..a87347b9df 100644 --- a/packages/providers/mgt-msal2-provider/src/Msal2Provider.ts +++ b/packages/providers/mgt-msal2-provider/src/Msal2Provider.ts @@ -1,4 +1,18 @@ -import { IProvider, LoginType, ProviderState, createFromProvider, IProviderAccount } from '@microsoft/mgt-element'; +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + +import { + IProvider, + LoginType, + ProviderState, + createFromProvider, + IProviderAccount, + GraphEndpoint +} from '@microsoft/mgt-element'; import { Configuration, PublicClientApplication, @@ -126,6 +140,11 @@ export interface Msal2Config extends Msal2ConfigBase { * @memberof Msal2Config */ isMultiAccountEnabled?: boolean; + + /** + * The base URL for the graph client + */ + baseURL?: GraphEndpoint; } /** @@ -369,6 +388,7 @@ export class Msal2Provider extends IProvider { const msal2config = config as Msal2Config; this.isMultipleAccountEnabled = typeof msal2config.isMultiAccountEnabled !== 'undefined' ? msal2config.isMultiAccountEnabled : true; + this.baseURL = typeof msal2config.baseURL !== 'undefined' ? msal2config.baseURL : this.baseURL; this.graph = createFromProvider(this); try { diff --git a/packages/providers/mgt-msal2-provider/src/index.ts b/packages/providers/mgt-msal2-provider/src/index.ts index 9bc3a2de1e..eeae918924 100644 --- a/packages/providers/mgt-msal2-provider/src/index.ts +++ b/packages/providers/mgt-msal2-provider/src/index.ts @@ -1,2 +1,9 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + export * from './Msal2Provider'; export * from './mgt-msal2-provider'; diff --git a/packages/providers/mgt-msal2-provider/src/mgt-msal2-provider.ts b/packages/providers/mgt-msal2-provider/src/mgt-msal2-provider.ts index 96c9fc2ac7..b9b705c83a 100644 --- a/packages/providers/mgt-msal2-provider/src/mgt-msal2-provider.ts +++ b/packages/providers/mgt-msal2-provider/src/mgt-msal2-provider.ts @@ -6,7 +6,7 @@ */ import { customElement, property } from 'lit/decorators.js'; -import { Providers, LoginType, MgtBaseProvider } from '@microsoft/mgt-element'; +import { Providers, LoginType, MgtBaseProvider, validateBaseURL } from '@microsoft/mgt-element'; import { Msal2Config, Msal2Provider, PromptType } from './Msal2Provider'; /** * Authentication Library Provider for Microsoft personal accounts @@ -188,6 +188,11 @@ export class MgtMsal2Provider extends MgtBaseProvider { if (this.isMultiAccountDisabled) { config.isMultiAccountEnabled = false; } + + if (this.baseUrl) { + config.baseURL = this.baseUrl; + } + this.provider = new Msal2Provider(config); Providers.globalProvider = this.provider; } diff --git a/packages/providers/mgt-sharepoint-provider/src/SharePointProvider.ts b/packages/providers/mgt-sharepoint-provider/src/SharePointProvider.ts index c0cd98c450..fc1081285b 100644 --- a/packages/providers/mgt-sharepoint-provider/src/SharePointProvider.ts +++ b/packages/providers/mgt-sharepoint-provider/src/SharePointProvider.ts @@ -5,7 +5,13 @@ * ------------------------------------------------------------------------------------------- */ -import { IProvider, ProviderState, createFromProvider } from '@microsoft/mgt-element'; +import { + IProvider, + ProviderState, + createFromProvider, + GraphEndpoint, + MICROSOFT_GRAPH_DEFAULT_ENDPOINT +} from '@microsoft/mgt-element'; /** * AadTokenProvider @@ -91,11 +97,12 @@ export class SharePointProvider extends IProvider { private _provider: AadTokenProvider; - constructor(context: WebPartContext) { + constructor(context: WebPartContext, baseUrl: GraphEndpoint = MICROSOFT_GRAPH_DEFAULT_ENDPOINT) { super(); context.aadTokenProviderFactory.getTokenProvider().then((tokenProvider: AadTokenProvider): void => { this._provider = tokenProvider; + this.baseURL = baseUrl; this.graph = createFromProvider(this); this.internalLogin(); }); @@ -109,8 +116,9 @@ export class SharePointProvider extends IProvider { */ public async getAccessToken(): Promise { let accessToken: string; + const baseUrl = this.baseURL ? this.baseURL : MICROSOFT_GRAPH_DEFAULT_ENDPOINT; try { - accessToken = await this.provider.getToken('https://graph.microsoft.com'); + accessToken = await this.provider.getToken(baseUrl); } catch (e) { throw e; } diff --git a/packages/providers/mgt-teams-msal2-provider/src/TeamsMsal2Provider.ts b/packages/providers/mgt-teams-msal2-provider/src/TeamsMsal2Provider.ts index 53f69830a0..f747b871ef 100644 --- a/packages/providers/mgt-teams-msal2-provider/src/TeamsMsal2Provider.ts +++ b/packages/providers/mgt-teams-msal2-provider/src/TeamsMsal2Provider.ts @@ -7,7 +7,13 @@ import { AuthenticationProviderOptions } from '@microsoft/microsoft-graph-client'; import { Configuration, InteractionRequiredAuthError, SilentRequest } from '@azure/msal-browser'; -import { LoginType, ProviderState, TeamsHelper } from '@microsoft/mgt-element'; +import { + GraphEndpoint, + LoginType, + MICROSOFT_GRAPH_DEFAULT_ENDPOINT, + ProviderState, + TeamsHelper +} from '@microsoft/mgt-element'; import { Msal2Provider, PromptType } from '@microsoft/mgt-msal2-provider'; // tslint:disable-next-line: completed-docs @@ -142,6 +148,10 @@ export interface TeamsMsal2Config { * @memberof TeamsMsal2Config */ httpMethod?: HttpMethod; + /** + * The base URL for the graph client + */ + baseURL?: GraphEndpoint; } /** @@ -196,7 +206,7 @@ export class TeamsMsal2Provider extends Msal2Provider { * @returns * @memberof TeamsMsal2Provider */ - public static async handleAuth() { + public static async handleAuth(baseURL: GraphEndpoint = MICROSOFT_GRAPH_DEFAULT_ENDPOINT) { // we are in popup world now - authenticate and handle it const teams = TeamsHelper.microsoftTeamsLib; if (!teams) { @@ -242,7 +252,8 @@ export class TeamsMsal2Provider extends Msal2Provider { options, scopes, loginHint: authParams.loginHint, - prompt: prompt + prompt: prompt, + baseURL: baseURL }); const handleProviderState = async () => { @@ -306,7 +317,8 @@ export class TeamsMsal2Provider extends Msal2Provider { clientId: config.clientId, loginType: LoginType.Redirect, options: config.msalOptions, - scopes: config.scopes + scopes: config.scopes, + baseURL: config.baseURL }); this.clientId = config.clientId; this._msalOptions = config.msalOptions; diff --git a/packages/providers/mgt-teams-msal2-provider/src/mgt-teams-msal2-provider.ts b/packages/providers/mgt-teams-msal2-provider/src/mgt-teams-msal2-provider.ts index 6068ae5b25..25b29adee4 100644 --- a/packages/providers/mgt-teams-msal2-provider/src/mgt-teams-msal2-provider.ts +++ b/packages/providers/mgt-teams-msal2-provider/src/mgt-teams-msal2-provider.ts @@ -7,7 +7,7 @@ import { customElement, property } from 'lit/decorators.js'; import { Configuration } from '@azure/msal-browser'; -import { Providers, MgtBaseProvider } from '@microsoft/mgt-element'; +import { Providers, MgtBaseProvider, validateBaseURL } from '@microsoft/mgt-element'; import { HttpMethod, TeamsMsal2Config, TeamsMsal2Provider } from './TeamsMsal2Provider'; /** @@ -89,6 +89,7 @@ export class MgtTeamsMsal2Provider extends MgtBaseProvider { type: String }) public httpMethod; + /** * Gets whether this provider can be used in this environment * @@ -142,6 +143,10 @@ export class MgtTeamsMsal2Provider extends MgtBaseProvider { config.httpMethod = httpMethodEnum; } + if (this.baseUrl) { + config.baseURL = this.baseUrl; + } + this.provider = new TeamsMsal2Provider(config); Providers.globalProvider = this.provider; } diff --git a/packages/providers/mgt-teams-provider/src/TeamsProvider.ts b/packages/providers/mgt-teams-provider/src/TeamsProvider.ts index 8221a4551b..1658bd3450 100644 --- a/packages/providers/mgt-teams-provider/src/TeamsProvider.ts +++ b/packages/providers/mgt-teams-provider/src/TeamsProvider.ts @@ -7,7 +7,7 @@ import { AuthenticationProviderOptions } from '@microsoft/microsoft-graph-client'; import { AuthenticationParameters, Configuration, UserAgentApplication } from 'msal'; -import { TeamsHelper } from '@microsoft/mgt-element'; +import { GraphEndpoint, MICROSOFT_GRAPH_DEFAULT_ENDPOINT, TeamsHelper } from '@microsoft/mgt-element'; import { LoginType, ProviderState } from '@microsoft/mgt-element'; import { MsalProvider } from '@microsoft/mgt-msal-provider'; @@ -97,6 +97,10 @@ export interface TeamsConfig { * @memberof TeamsConfig */ msalOptions?: Configuration; + /** + * The base URL for the graph client + */ + baseURL?: GraphEndpoint; } /** @@ -151,7 +155,7 @@ export class TeamsProvider extends MsalProvider { * @returns * @memberof TeamsProvider */ - public static async handleAuth() { + public static async handleAuth(baseURL: GraphEndpoint = MICROSOFT_GRAPH_DEFAULT_ENDPOINT) { // we are in popup world now - authenticate and handle it const teams = TeamsHelper.microsoftTeamsLib; if (!teams) { @@ -194,7 +198,8 @@ export class TeamsProvider extends MsalProvider { const provider = new MsalProvider({ clientId: authParams.clientId, options, - scopes + scopes, + baseURL }); if (provider.userAgentApplication.urlContainsHash(window.location.hash)) { @@ -252,7 +257,8 @@ export class TeamsProvider extends MsalProvider { clientId: config.clientId, loginType: LoginType.Redirect, options: config.msalOptions, - scopes: config.scopes + scopes: config.scopes, + baseURL: config.baseURL }); this._msalOptions = config.msalOptions; diff --git a/packages/providers/mgt-teams-provider/src/mgt-teams-provider.ts b/packages/providers/mgt-teams-provider/src/mgt-teams-provider.ts index bd3cc6731c..0ef9f70fc2 100644 --- a/packages/providers/mgt-teams-provider/src/mgt-teams-provider.ts +++ b/packages/providers/mgt-teams-provider/src/mgt-teams-provider.ts @@ -7,7 +7,7 @@ import { customElement, property } from 'lit/decorators.js'; import { Configuration } from 'msal'; -import { Providers, MgtBaseProvider } from '@microsoft/mgt-element'; +import { Providers, MgtBaseProvider, validateBaseURL } from '@microsoft/mgt-element'; import { TeamsConfig, TeamsProvider } from './TeamsProvider'; /** @@ -64,6 +64,7 @@ export class MgtTeamsProvider extends MgtBaseProvider { * @readonly * @memberof MgtTeamsProvider */ + public get isAvailable() { return TeamsProvider.isAvailable; } @@ -97,6 +98,10 @@ export class MgtTeamsProvider extends MgtBaseProvider { config.msalOptions = msalConfig; } + if (this.baseUrl) { + config.baseURL = this.baseUrl; + } + this.provider = new TeamsProvider(config); Providers.globalProvider = this.provider; } diff --git a/packages/providers/mgt-teamsfx-provider/src/TeamsFxProvider.ts b/packages/providers/mgt-teamsfx-provider/src/TeamsFxProvider.ts index eb8352df2e..f154aba5e8 100644 --- a/packages/providers/mgt-teamsfx-provider/src/TeamsFxProvider.ts +++ b/packages/providers/mgt-teamsfx-provider/src/TeamsFxProvider.ts @@ -5,7 +5,13 @@ * ------------------------------------------------------------------------------------------- */ -import { IProvider, ProviderState, createFromProvider } from '@microsoft/mgt-element'; +import { + IProvider, + ProviderState, + createFromProvider, + GraphEndpoint, + MICROSOFT_GRAPH_DEFAULT_ENDPOINT +} from '@microsoft/mgt-element'; import { TeamsFx } from '@microsoft/teamsfx'; /** @@ -62,7 +68,7 @@ export class TeamsFxProvider extends IProvider { */ private _accessToken: string = ''; - constructor(teamsfx: TeamsFx, scopes: string | string[]) { + constructor(teamsfx: TeamsFx, scopes: string | string[], baseURL: GraphEndpoint = MICROSOFT_GRAPH_DEFAULT_ENDPOINT) { super(); if (!this._teamsfx) { @@ -79,6 +85,7 @@ export class TeamsFxProvider extends IProvider { this.scopes = scopesArr; } + this.baseURL = baseURL; this.graph = createFromProvider(this); } diff --git a/packages/providers/mgt-teamsfx-provider/src/index.ts b/packages/providers/mgt-teamsfx-provider/src/index.ts index f222d2f0e8..8f48adc929 100644 --- a/packages/providers/mgt-teamsfx-provider/src/index.ts +++ b/packages/providers/mgt-teamsfx-provider/src/index.ts @@ -1 +1,8 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + export * from './TeamsFxProvider';