From 1a59ec3f1fded93245d0bb9201273e74bd8cbd28 Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Thu, 20 Jul 2023 11:12:01 -0700 Subject: [PATCH 1/7] WIP: avoid cross-geo calls --- Composer/packages/electron-server/src/main.ts | 5 +++++ extensions/pvaPublish/src/node/publish.ts | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Composer/packages/electron-server/src/main.ts b/Composer/packages/electron-server/src/main.ts index ef42ea9685..d8fcd38ee5 100644 --- a/Composer/packages/electron-server/src/main.ts +++ b/Composer/packages/electron-server/src/main.ts @@ -343,6 +343,11 @@ async function run() { }; }); + ipcMain.handle('deeplink', async (evt, url: string) => { + const deeplink = parseDeepLinkUrl(url); + await getMainWindow()?.webContents.loadURL(getBaseUrl() + deeplink); + }); + await main(); setTimeout(() => startApp(signalThatMainWindowIsShowing), 500); await initApp(); diff --git a/extensions/pvaPublish/src/node/publish.ts b/extensions/pvaPublish/src/node/publish.ts index a842cd6e5d..246b6dc994 100644 --- a/extensions/pvaPublish/src/node/publish.ts +++ b/extensions/pvaPublish/src/node/publish.ts @@ -41,7 +41,10 @@ export const publish = async ( try { logger.log('Starting publish to Power Virtual Agents.'); // authenticate with PVA - const base = baseUrl || getBaseUrl(); + const base = baseUrl; + if (!base) { + throw new Error('Base URL is not supplied in published target'); + } const creds = getAuthCredentials(base, tenantId); const accessToken = await getAccessToken(creds); @@ -161,7 +164,10 @@ export const getStatus = async ( try { // authenticate with PVA - const base = baseUrl || getBaseUrl(); + const base = baseUrl; + if (!base) { + throw new Error('Base URL is not supplied in published target'); + } const creds = getAuthCredentials(base, tenantId); const accessToken = await getAccessToken(creds); From 7e3e406c6d7d14c93ea8593549d508062745a74a Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Thu, 27 Jul 2023 10:02:50 -0700 Subject: [PATCH 2/7] Use cluster category for credentials insead of hardcoded URLs --- .../powerVirtualAgentsProvider.ts | 73 +++++++------------ 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts b/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts index 8c0d18fef8..19d068f1d4 100644 --- a/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts +++ b/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts @@ -22,6 +22,19 @@ export const PVA_GOV_APP_ID = '9315aedd-209b-43b3-b149-2abff6a95d59'; export const PVA_GCC_HIGH_APP_ID = '69c6e40c-465f-4154-987d-da5cba10734e'; export type PowerVirtualAgentsMetadata = IContentProviderMetadata & { + clusterCategory: + | 'Dev' + | 'Prv' + | 'Test' + | 'Preprod' + | 'FirstRelease' + | 'Prod' + | 'Gov' + | 'High' + | 'DoD' + | 'Mooncake' + | 'Ex' + | 'Rx'; baseUrl: string; botId: string; dialogId?: string; @@ -32,22 +45,29 @@ export type PowerVirtualAgentsMetadata = IContentProviderMetadata & { }; const getAuthCredentials = (baseUrl: string, metadata: PowerVirtualAgentsMetadata) => { + const clusterCategory = + (process.env.COMPOSER_PVA_CLUSTER as typeof metadata.clusterCategory) ?? metadata.clusterCategory; const url = new URL(baseUrl); - if (url.hostname.includes('.int.') || url.hostname.includes('.ppe.')) { + if ( + ['Test', 'Preprod', 'Dev'].includes(clusterCategory) || + url.hostname.includes('.int.') || + url.hostname.includes('.ppe.') || + url.hostname.includes('.test.') + ) { log('Using INT / PPE auth credentials.'); return { clientId: COMPOSER_1P_APP_ID, scopes: [`${PVA_TEST_APP_ID}/.default`], targetResource: PVA_TEST_APP_ID, }; - } else if (url.hostname.includes('gcc.api.powerva.microsoft.us')) { + } else if (['Gov'].includes(clusterCategory) && url.hostname.includes('gcc.api.powerva.microsoft.us')) { log('Using GCC auth credentials.'); return { clientId: COMPOSER_1P_APP_ID, scopes: [`${PVA_GOV_APP_ID}/.default`], targetResource: PVA_GOV_APP_ID, }; - } else if (url.hostname.includes('high.api.powerva.microsoft.us')) { + } else if (['High'].includes(clusterCategory) || url.hostname.includes('high.api.powerva.microsoft.us')) { log('Using GCC High auth credentials.'); return { authority: `https://login.microsoftonline.us/${metadata.tenantId}`, @@ -56,7 +76,7 @@ const getAuthCredentials = (baseUrl: string, metadata: PowerVirtualAgentsMetadat targetResource: PVA_GCC_HIGH_APP_ID, }; } - log('Using PROD auth credentials.'); + log(`Using PROD auth credentials.\nCategory: ${clusterCategory}\nURL: ${baseUrl}`); return { clientId: COMPOSER_1P_APP_ID, scopes: [`${PVA_PROD_APP_ID}/.default`], @@ -64,47 +84,6 @@ const getAuthCredentials = (baseUrl: string, metadata: PowerVirtualAgentsMetadat }; }; -const getBaseUrl = () => { - const pvaEnv = (process.env.COMPOSER_PVA_ENV || '').toLowerCase(); - switch (pvaEnv) { - case 'prod': { - const url = 'https://powerva.microsoft.com/api/botmanagement/v1'; - log('PROD env detected, grabbing PVA content from %s', url); - return url; - } - - case 'ppe': { - const url = 'https://bots.ppe.customercareintelligence.net/api/botmanagement/v1'; - log('PPE env detected, grabbing PVA content from %s', url); - return url; - } - - case 'int': { - const url = 'https://bots.int.customercareintelligence.net/api/botmanagement/v1'; - log('INT env detected, grabbing PVA content from %s', url); - return url; - } - - case 'gcc': { - const url = 'https://gcc.api.powerva.microsoft.us/api/botmanagement/v1'; - log('GCC env detected, grabbing PVA content from %s', url); - return url; - } - - case 'gcc-high': { - const url = 'https://high.api.powerva.microsoft.us/api/botmanagement/v1'; - log('GCC High env detected, grabbing PVA content from %s', url); - return url; - } - - default: { - const url = 'https://bots.int.customercareintelligence.net/api/botmanagement/v1'; - log('No env flag detected, grabbing PVA content from %s', url); - return url; - } - } -}; - function prettyPrintError(err: string | Error): string { if (typeof err === 'string') { return err; @@ -177,7 +156,7 @@ export class PowerVirtualAgentsProvider extends ExternalContentProvider Date: Tue, 1 Aug 2023 14:59:45 -0700 Subject: [PATCH 3/7] WIP publish adjustments --- .../powerVirtualAgentsProvider.ts | 7 +- extensions/pvaPublish/src/node/constants.ts | 13 --- extensions/pvaPublish/src/node/publish.ts | 6 +- extensions/pvaPublish/src/node/types.ts | 15 ++++ extensions/pvaPublish/src/node/utils.ts | 82 +++++-------------- 5 files changed, 45 insertions(+), 78 deletions(-) diff --git a/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts b/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts index 19d068f1d4..d0768a7eeb 100644 --- a/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts +++ b/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts @@ -60,7 +60,7 @@ const getAuthCredentials = (baseUrl: string, metadata: PowerVirtualAgentsMetadat scopes: [`${PVA_TEST_APP_ID}/.default`], targetResource: PVA_TEST_APP_ID, }; - } else if (['Gov'].includes(clusterCategory) && url.hostname.includes('gcc.api.powerva.microsoft.us')) { + } else if (['Gov'].includes(clusterCategory) || url.hostname.includes('gcc.api.powerva.microsoft.us')) { log('Using GCC auth credentials.'); return { clientId: COMPOSER_1P_APP_ID, @@ -185,7 +185,7 @@ export class PowerVirtualAgentsProvider extends ExternalContentProvider { - logger.log('Base URL not supplied in publishing target. Falling back to hardcoded URL...'); - const pvaEnv = (process.env.COMPOSER_PVA_PUBLISH_ENV || '').toLowerCase(); - switch (pvaEnv) { - case 'prod': { - const url = BASE_URLS.PROD; - logger.log('prod pva publish detected, operation using PVA url: ', url); - return url; - } - - case 'ppe': { - const url = BASE_URLS.PPE; - logger.log('ppe pva publish detected, operation using PVA url: ', url); - return url; - } - - case 'int': { - const url = BASE_URLS.INT; - logger.log('int pva publish env detected, operation using PVA url: ', url); - return url; - } - - case 'gcc': { - const url = BASE_URLS.GCC; - logger.log('gcc pva publish env detected, operation using PVA url: ', url); - return url; - } - - case 'gcc-high': { - const url = BASE_URLS.GCC_HIGH; - logger.log('gcc high pva publish env detected, operation using PVA url: ', url); - return url; - } - - default: { - const url = BASE_URLS.PROD; - logger.log('No pva publish env detected, operation using PVA url: ', url); - return url; - } - } -}; +import { AUTH_CREDENTIALS } from './constants'; +import { ClusterCategory } from './types'; /** - * Looks at the base URL for a request and returns the necessary authentication parameters + * Looks at the cluster category for a request and returns the necessary authentication parameters * to get an access token for the resource. */ -export const getAuthCredentials = (baseUrl = '', tenantId?: string) => { - if (baseUrl) { - const host = new URL(baseUrl).host; - - if (host === 'bots.int.customercareintelligence.net') { - return AUTH_CREDENTIALS.INT; - } else if (host === 'bots.ppe.customercareintelligence.net') { - return AUTH_CREDENTIALS.PPE; - } else if (host === 'gcc.api.powerva.microsoft.us') { - return AUTH_CREDENTIALS.GCC; - } else if (host === 'high.api.powerva.microsoft.us') { - return { - ...AUTH_CREDENTIALS.GCC_HIGH, - authority: `https://login.microsoftonline.us/${tenantId}`, - }; - } +export const getAuthCredentials = (baseUrl = '', tenantId?: string, clusterCategory?: ClusterCategory) => { + const host = new URL(baseUrl).host; + clusterCategory = (process.env.COMPOSER_PVA_CLUSTER as ClusterCategory) ?? clusterCategory; + if (['Test', 'Preprod', 'Dev'].includes(clusterCategory) || host === 'bots.int.customercareintelligence.net') { + logger.log('Using INT / PPE auth credentials.'); + return AUTH_CREDENTIALS.INT; + } else if (host === 'bots.ppe.customercareintelligence.net') { + logger.log('Using INT / PPE auth credentials.'); + return AUTH_CREDENTIALS.INT; + } else if (['Gov'].includes(clusterCategory) || host === 'gcc.api.powerva.microsoft.us') { + logger.log('Using GCC auth credentials.'); + return AUTH_CREDENTIALS.GCC; + } else if (['High'].includes(clusterCategory) || host === 'high.api.powerva.microsoft.us') { + logger.log('Using GCC High auth credentials.'); + return { + ...AUTH_CREDENTIALS.GCC_HIGH, + authority: `https://login.microsoftonline.us/${tenantId}`, + }; } + logger.log(`Using PROD auth credentials.\nCategory: ${clusterCategory}\nURL: ${baseUrl}`); // fall back to prod return AUTH_CREDENTIALS.PROD; }; From 01f6831a3f58444b1ef919ad754f95d7dbe20e62 Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Thu, 3 Aug 2023 11:16:15 -0700 Subject: [PATCH 4/7] remove tests --- extensions/pvaPublish/src/node/utils.spec.ts | 48 +------------------- 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/extensions/pvaPublish/src/node/utils.spec.ts b/extensions/pvaPublish/src/node/utils.spec.ts index cf09c2365d..339100e822 100644 --- a/extensions/pvaPublish/src/node/utils.spec.ts +++ b/extensions/pvaPublish/src/node/utils.spec.ts @@ -1,52 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { AUTH_CREDENTIALS, BASE_URLS } from './constants'; -import { getAuthCredentials, getBaseUrl } from './utils'; - -describe('should return the proper PVA base URL for the environment', () => { - let envBackup; - beforeAll(() => { - envBackup = { ...process.env }; - }); - - beforeEach(() => { - Object.assign(process.env, { COMPOSER_PVA_PUBLISH_ENV: '' }); - }); - - afterAll(() => { - Object.assign(process.env, envBackup); // restore the platform - }); - - it('fallback to prod', () => { - expect(getBaseUrl()).toBe(BASE_URLS.PROD); - }); - - it('int', () => { - Object.assign(process.env, { COMPOSER_PVA_PUBLISH_ENV: 'INT' }); - expect(getBaseUrl()).toBe(BASE_URLS.INT); - }); - - it('ppe', () => { - Object.assign(process.env, { COMPOSER_PVA_PUBLISH_ENV: 'PPE' }); - expect(getBaseUrl()).toBe(BASE_URLS.PPE); - }); - - it('prod', () => { - Object.assign(process.env, { COMPOSER_PVA_PUBLISH_ENV: 'PROD' }); - expect(getBaseUrl()).toBe(BASE_URLS.PROD); - }); - - it('gcc', () => { - Object.assign(process.env, { COMPOSER_PVA_PUBLISH_ENV: 'GCC' }); - expect(getBaseUrl()).toBe(BASE_URLS.GCC); - }); - - it('gcc high', () => { - Object.assign(process.env, { COMPOSER_PVA_PUBLISH_ENV: 'GCC-HIGH' }); - expect(getBaseUrl()).toBe(BASE_URLS.GCC_HIGH); - }); -}); +import { AUTH_CREDENTIALS } from './constants'; +import { getAuthCredentials } from './utils'; describe('it should return the proper PVA auth parameters for the base URL', () => { it('fallback to prod', () => { From 2819d1c6dcf6222870b63fde4de59ca76ec7d233 Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Thu, 3 Aug 2023 12:12:14 -0700 Subject: [PATCH 5/7] fix more tests --- extensions/pvaPublish/src/node/utils.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/pvaPublish/src/node/utils.spec.ts b/extensions/pvaPublish/src/node/utils.spec.ts index 339100e822..84798a21ea 100644 --- a/extensions/pvaPublish/src/node/utils.spec.ts +++ b/extensions/pvaPublish/src/node/utils.spec.ts @@ -20,7 +20,7 @@ describe('it should return the proper PVA auth parameters for the base URL', () it('ppe', () => { const url = 'https://bots.ppe.customercareintelligence.net/api/botmanagement/v1'; - expect(getAuthCredentials(url)).toEqual(AUTH_CREDENTIALS.PPE); + expect(getAuthCredentials(url)).toEqual(AUTH_CREDENTIALS.INT); }); it('prod', () => { From cef0ea140d8520bd37e020d4377730474b46e2cc Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Tue, 8 Aug 2023 12:54:11 -0700 Subject: [PATCH 6/7] handle optional cluster category --- .../powerVirtualAgentsProvider.ts | 4 ++-- extensions/pvaPublish/src/node/publish.ts | 12 ++++++++---- extensions/pvaPublish/src/node/utils.ts | 10 ++++++---- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts b/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts index d0768a7eeb..e32431e877 100644 --- a/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts +++ b/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts @@ -22,7 +22,7 @@ export const PVA_GOV_APP_ID = '9315aedd-209b-43b3-b149-2abff6a95d59'; export const PVA_GCC_HIGH_APP_ID = '69c6e40c-465f-4154-987d-da5cba10734e'; export type PowerVirtualAgentsMetadata = IContentProviderMetadata & { - clusterCategory: + clusterCategory?: | 'Dev' | 'Prv' | 'Test' @@ -199,7 +199,7 @@ export class PowerVirtualAgentsProvider extends ExternalContentProvider { const host = new URL(baseUrl).host; clusterCategory = (process.env.COMPOSER_PVA_CLUSTER as ClusterCategory) ?? clusterCategory; - if (['Test', 'Preprod', 'Dev'].includes(clusterCategory) || host === 'bots.int.customercareintelligence.net') { - logger.log('Using INT / PPE auth credentials.'); - return AUTH_CREDENTIALS.INT; - } else if (host === 'bots.ppe.customercareintelligence.net') { + if ( + ['Test', 'Preprod', 'Dev'].includes(clusterCategory) || + host.includes('.int.') || + host.includes('.ppe.') || + host.includes('.test.') + ) { logger.log('Using INT / PPE auth credentials.'); return AUTH_CREDENTIALS.INT; } else if (['Gov'].includes(clusterCategory) || host === 'gcc.api.powerva.microsoft.us') { From c9f877b10239d66a6131674d8918060648a2dca3 Mon Sep 17 00:00:00 2001 From: Eugene Olonov Date: Tue, 8 Aug 2023 13:41:52 -0700 Subject: [PATCH 7/7] make ts happy --- .../powerVirtualAgentsProvider.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts b/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts index e32431e877..36fc6dfd43 100644 --- a/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts +++ b/Composer/packages/server/src/externalContentProvider/powerVirtualAgentsProvider.ts @@ -49,7 +49,7 @@ const getAuthCredentials = (baseUrl: string, metadata: PowerVirtualAgentsMetadat (process.env.COMPOSER_PVA_CLUSTER as typeof metadata.clusterCategory) ?? metadata.clusterCategory; const url = new URL(baseUrl); if ( - ['Test', 'Preprod', 'Dev'].includes(clusterCategory) || + (clusterCategory && ['Test', 'Preprod', 'Dev'].includes(clusterCategory)) || url.hostname.includes('.int.') || url.hostname.includes('.ppe.') || url.hostname.includes('.test.') @@ -60,14 +60,20 @@ const getAuthCredentials = (baseUrl: string, metadata: PowerVirtualAgentsMetadat scopes: [`${PVA_TEST_APP_ID}/.default`], targetResource: PVA_TEST_APP_ID, }; - } else if (['Gov'].includes(clusterCategory) || url.hostname.includes('gcc.api.powerva.microsoft.us')) { + } else if ( + (clusterCategory && ['Gov'].includes(clusterCategory)) || + url.hostname.includes('gcc.api.powerva.microsoft.us') + ) { log('Using GCC auth credentials.'); return { clientId: COMPOSER_1P_APP_ID, scopes: [`${PVA_GOV_APP_ID}/.default`], targetResource: PVA_GOV_APP_ID, }; - } else if (['High'].includes(clusterCategory) || url.hostname.includes('high.api.powerva.microsoft.us')) { + } else if ( + (clusterCategory && ['High'].includes(clusterCategory)) || + url.hostname.includes('high.api.powerva.microsoft.us') + ) { log('Using GCC High auth credentials.'); return { authority: `https://login.microsoftonline.us/${metadata.tenantId}`,