Skip to content

Commit

Permalink
Merge branch 'main' into beyackle/focusAfterLoad
Browse files Browse the repository at this point in the history
  • Loading branch information
cwhitten authored Mar 30, 2021
2 parents 73d71c0 + da1ac55 commit 7562ae4
Show file tree
Hide file tree
Showing 9 changed files with 361 additions and 254 deletions.
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"env": {
"NODE_ENV": "development",
"DEBUG": "composer*",
"COMPOSER_DEV_TOOLS": "true",
"COMPOSER_ENABLE_ONEAUTH": "false"
},
"outputCapture": "std",
Expand Down
26 changes: 25 additions & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
"command": "yarn build",
"options": {
"cwd": "Composer/packages/server"
},
"presentation": {
"echo": true,
"reveal": "silent",
"focus": false,
"panel": "shared",
"showReuseMessage": false,
"clear": false
}
},
{
Expand All @@ -18,7 +26,15 @@
"options": {
"cwd": "Composer/packages/electron-server"
},
"dependsOn": ["server: build", "client: ping"]
"dependsOn": ["server: build", "client: ping"],
"presentation": {
"echo": true,
"reveal": "silent",
"focus": false,
"panel": "shared",
"showReuseMessage": false,
"clear": false
}
},
{
"label": "client: ping",
Expand All @@ -27,6 +43,14 @@
"args": ["-t", "300000", "http://localhost:3000"],
"options": {
"cwd": "Composer"
},
"presentation": {
"echo": true,
"reveal": "silent",
"focus": false,
"panel": "shared",
"showReuseMessage": false,
"clear": false
}
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import TelemetryClient from '../../../telemetry/TelemetryClient';
import { AuthClient } from '../../../utils/authClient';
import { graphScopes } from '../../../constants';
import { dispatcherState } from '../../../recoilModel';
import { createNotification } from '../../../recoilModel/dispatchers/notification';

import { ProfileFormDialog } from './ProfileFormDialog';

Expand All @@ -43,7 +44,7 @@ export const PublishProfileDialog: React.FC<PublishProfileDialogProps> = (props)

const [page, setPage] = useState(Page.ProfileForm);
const [publishSurfaceStyles, setStyles] = useState(defaultPublishSurface);
const { provisionToTarget } = useRecoilValue(dispatcherState);
const { provisionToTarget, addNotification } = useRecoilValue(dispatcherState);

const [dialogTitle, setTitle] = useState({
title: current ? formatMessage('Edit a publishing profile') : formatMessage('Add a publishing profile'),
Expand Down Expand Up @@ -157,15 +158,24 @@ export const PublishProfileDialog: React.FC<PublishProfileDialogProps> = (props)
};
PluginAPI.publish.startProvision = async (config) => {
const fullConfig = { ...config, name: name, type: targetType };

let arm, graph;
if (!isGetTokenFromUser()) {
// login or get token implicit
let tenantId = getTenantIdFromCache();
const tenantId = getTenantIdFromCache();
// require tenant id to be set by plugin (handles multiple tenant scenario)
if (!tenantId) {
const tenants = await AuthClient.getTenants();
tenantId = tenants?.[0]?.tenantId;
setTenantId(tenantId);
const notification = createNotification({
type: 'error',
title: formatMessage('Error provisioning.'),
description: formatMessage(
'An Azure tenant must be set in order to provision resources. Try recreating the publish profile and try again.'
),
});
addNotification(notification);
return;
}

// login or get token implicit
arm = await AuthClient.getARMTokenForTenant(tenantId);
graph = await AuthClient.getAccessToken(graphScopes);
} else {
Expand Down
86 changes: 55 additions & 31 deletions Composer/packages/client/src/pages/publish/Publish.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useState, useEffect, useMemo, Fragment, useRef } from 'react';
import { RouteComponentProps } from '@reach/router';
import formatMessage from 'format-message';
import { useRecoilValue } from 'recoil';
import { PublishResult } from '@bfc/shared';
import { PublishResult, PublishTarget } from '@bfc/shared';

import { dispatcherState, localBotPublishHistorySelector, localBotsDataSelector } from '../../recoilModel';
import { AuthDialog } from '../../components/Auth/AuthDialog';
Expand Down Expand Up @@ -234,40 +234,63 @@ const Publish: React.FC<RouteComponentProps<{ projectId: string; targetName?: st
navigateTo(url);
};

const isPublishingToAzure = (items: BotStatus[]) => {
for (const bot of items) {
const setting = botPropertyData[bot.id].setting;
const publishTargets = botPropertyData[bot.id].publishTargets;
if (!(bot.publishTarget && publishTargets && setting)) {
continue;
}
if (bot.publishTarget && publishTargets) {
const selectedTarget = publishTargets.find((target) => target.name === bot.publishTarget);
if (selectedTarget?.type === 'azurePublish' || selectedTarget?.type === 'azureFunctionsPublish') {
return true;
}
}
}
return false;
const isPublishingToAzure = (target?: PublishTarget) => {
return target?.type === 'azurePublish' || target?.type === 'azureFunctionsPublish';
};

const publish = async (items: BotStatus[]) => {
const tenantTokenMap = new Map<string, string>();
// get token
let token = '';
if (isPublishingToAzure(items)) {
// TODO: this logic needs to be moved into the Azure publish extensions
if (isGetTokenFromUser()) {
token = getTokenFromCache('accessToken');
} else {
let tenant = getTenantIdFromCache();
if (!tenant) {
const tenants = await AuthClient.getTenants();
tenant = tenants?.[0]?.tenantId;
setTenantId(tenant);
const getTokenForTarget = async (target?: PublishTarget) => {
let token = '';
if (target && isPublishingToAzure(target)) {
const { tenantId } = JSON.parse(target.configuration);

if (tenantId) {
token = tenantTokenMap.get(tenantId) ?? (await AuthClient.getARMTokenForTenant(tenantId));
tenantTokenMap.set(tenantId, token);
} else if (isGetTokenFromUser()) {
token = getTokenFromCache('accessToken');
// old publish profile without tenant id
} else {
let tenant = getTenantIdFromCache();
let tenants;
if (!tenant) {
try {
tenants = await AuthClient.getTenants();

tenant = tenants?.[0]?.tenantId;
setTenantId(tenant);

token = tenantTokenMap.get(tenant) ?? (await AuthClient.getARMTokenForTenant(tenant));
} catch (err) {
let notification;
if (err?.message.includes('does not exist in tenant') && tenants.length > 1) {
notification = createNotification({
type: 'error',
title: formatMessage('Unsupported publishing profile'),
description: formatMessage(
"This publishing profile ({ profileName }) is no longer supported. You are a member of multiple Azure tenants and the profile needs to have a tenant id associated with it. You can either edit the profile by adding the `tenantId` property to it's configuration or create a new one.",
{ profileName: target.name }
),
});
} else {
notification = createNotification({
type: 'error',
title: formatMessage('Authentication Error'),
description: formatMessage('There was an error accessing your Azure account: {errorMsg}', {
errorMsg: err.message,
}),
});
}
addNotification(notification);
}
}
}
token = await AuthClient.getARMTokenForTenant(tenant);
}
}

return token;
};

setPublishDialogVisiblity(false);
// notifications
Expand All @@ -286,11 +309,12 @@ const Publish: React.FC<RouteComponentProps<{ projectId: string; targetName?: st
if (!(bot.publishTarget && publishTargets && setting)) {
return;
}
if (bot.publishTarget && publishTargets) {
const selectedTarget = publishTargets.find((target) => target.name === bot.publishTarget);
const selectedTarget = publishTargets.find((target) => target.name === bot.publishTarget);
if (selectedTarget) {
const botProjectId = bot.id;
setting.qna.subscriptionKey && (await setQnASettings(botProjectId, setting.qna.subscriptionKey));
const sensitiveSettings = getSensitiveProperties(setting);
const token = await getTokenForTarget(selectedTarget);
await publishToTarget(botProjectId, selectedTarget, { comment: bot.comment }, sensitiveSettings, token);

// update the target with a lastPublished date
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import formatMessage from 'format-message';
import { CallbackInterface, useRecoilCallback } from 'recoil';
import { defaultPublishConfig, isSkillHostUpdateRequired, PublishResult } from '@bfc/shared';
import { defaultPublishConfig, isSkillHostUpdateRequired, PublishResult, PublishTarget } from '@bfc/shared';

import {
publishTypesState,
Expand Down Expand Up @@ -182,7 +182,7 @@ export const publisherDispatcher = () => {
const publishToTarget = useRecoilCallback(
(callbackHelpers: CallbackInterface) => async (
projectId: string,
target: any,
target: PublishTarget,
metadata: any,
sensitiveSettings,
token = ''
Expand Down
Loading

0 comments on commit 7562ae4

Please sign in to comment.