Skip to content

Commit

Permalink
fix: get microsoftAppPassword from profile appPasswordHint (microsoft…
Browse files Browse the repository at this point in the history
…#6471)

* add key valut token get

* add auth before doing kv update

* refactor the get alias and generate profile code

* add azure key vault logic and set policy process

* fix generated profile not work

* fix build

* add exception handling

* fix comments

* fix ut

* Fix lint, comment-out unusued imports

* open modal refactor

* alias & profile for open bot

* api

* fix lint

* alias

* set alias

* Fix lint

* ut

* publish notification

Co-authored-by: Qi Kang <[email protected]>
Co-authored-by: Lu Han <[email protected]>
Co-authored-by: Chris Whitten <[email protected]>
Co-authored-by: Chris Whitten <[email protected]>
Co-authored-by: Long Alan <[email protected]>
Co-authored-by: Dong Lei <[email protected]>
  • Loading branch information
7 people authored Mar 26, 2021
1 parent b30d209 commit c396f86
Show file tree
Hide file tree
Showing 28 changed files with 451 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Sticky, StickyPositionType } from 'office-ui-fabric-react/lib/Sticky';
import { BotTemplate, QnABotTemplateId } from '@bfc/shared';
import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';
import { NeutralColors } from '@uifabric/fluent-theme';
import { RouteComponentProps } from '@reach/router';
import { WindowLocation } from '@reach/router';
import { useRecoilValue } from 'recoil';
import { mergeStyles } from 'office-ui-fabric-react/lib/Styling';

Expand Down Expand Up @@ -115,14 +115,15 @@ const optionKeys = {
type CreateBotProps = {
isOpen: boolean;
templates: BotTemplate[];
location?: WindowLocation | undefined;
onDismiss: () => void;
onNext: (data: string) => void;
} & RouteComponentProps<{}>;
};

export function CreateBot(props: CreateBotProps) {
const [option, setOption] = useState(optionKeys.createFromScratch);
const [disabled, setDisabled] = useState(true);
const { templates, onDismiss, onNext, isOpen } = props;
const { templates, location, onDismiss, onNext, isOpen } = props;
const [currentTemplate, setCurrentTemplate] = useState('');
const [emptyBotKey, setEmptyBotKey] = useState('');
const creationFlowType = useRecoilValue(creationFlowTypeState);
Expand Down Expand Up @@ -169,8 +170,8 @@ export function CreateBot(props: CreateBotProps) {
if (option === optionKeys.createFromQnA) {
routeToTemplate = QnABotTemplateId;
}
if (props.location?.search) {
routeToTemplate += props.location.search;
if (location?.search) {
routeToTemplate += location.search;
}

TelemetryClient.track('CreateNewBotProjectNextButton', { template: routeToTemplate });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { CreateBot } from './CreateBot';
type CreateOptionsProps = {
templates: BotTemplate[];
onDismiss: () => void;
onJumpToOpenModal: () => void;
onJumpToOpenModal: (search?: string) => void;
onNext: (data: string) => void;
} & RouteComponentProps<{}>;

Expand All @@ -47,19 +47,20 @@ export function CreateOptions(props: CreateOptionsProps) {
const decoded = decodeURIComponent(props.location.search);
const { source, payload } = querystring.parse(decoded);
if (typeof source === 'string' && typeof payload === 'string') {
const alias = getAliasFromPayload(source, payload);
// check to see if Composer currently has a bot project corresponding to the alias
axios
.get<any>(`/api/projects/alias/${alias}`)
.then((aliasRes) => {
if (aliasRes.status === 200) {
getAliasFromPayload(source, payload).then((alias) => {
// check to see if Composer currently has a bot project corresponding to the alias
axios
.get<any>(`/api/projects/alias/${alias}`)
.then((aliasRes) => {
if (aliasRes.status === 200) {
navigate(`/bot/${aliasRes.data.id}`);
return;
}
})
.catch((e) => {
setIsOpenOptionsModal(true);
return;
}
})
.catch((e) => {
setIsOpenCreateModal(true);
});
});
});
return;
}
}
Expand All @@ -80,7 +81,7 @@ export function CreateOptions(props: CreateOptionsProps) {
if (option === 'Create') {
setIsOpenCreateModal(true);
} else {
onJumpToOpenModal();
onJumpToOpenModal(props.location?.search);
}
};

Expand All @@ -98,7 +99,13 @@ export function CreateOptions(props: CreateOptionsProps) {
<DefaultButton text={formatMessage('Cancel')} onClick={onDismiss} />
</DialogFooter>
</DialogWrapper>
<CreateBot isOpen={isOpenCreateModal} templates={templates} onDismiss={onDismiss} onNext={onNext} />
<CreateBot
isOpen={isOpenCreateModal}
location={props.location}
templates={templates}
onDismiss={onDismiss}
onNext={onNext}
/>
</Fragment>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,22 @@ const CreationFlow: React.FC<CreationFlowProps> = (props: CreationFlowProps) =>
navigate(`/home`);
};

const handleJumpToOpenModal = () => {
const handleJumpToOpenModal = (search) => {
setCreationFlowStatus(CreationFlowStatus.OPEN);
navigate('./open');
navigate(`./open${search}`);
};

const openBot = async (botFolder) => {
const openBot = async (formData) => {
setCreationFlowStatus(CreationFlowStatus.CLOSE);
await openProject(botFolder, 'default', true, (projectId) => {
TelemetryClient.track('BotProjectOpened', { method: 'toolbar', projectId });
});
await openProject(
formData.path,
'default',
true,
{ profile: formData.profile, source: formData.source, alias: formData.alias },
(projectId) => {
TelemetryClient.track('BotProjectOpened', { method: 'toolbar', projectId });
}
);
};

const handleCreateNew = async (formData, templateId: string) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ const DefineConversation: React.FC<DefineConversationProps> = (props) => {
}, [focusedStorageFolder]);

const handleSubmit = useCallback(
(e) => {
async (e) => {
e.preventDefault();
if (hasErrors) {
return;
Expand Down Expand Up @@ -246,7 +246,7 @@ const DefineConversation: React.FC<DefineConversationProps> = (props) => {
if (payload && typeof payload === 'string' && typeof source === 'string') {
dataToSubmit.profile = JSON.parse(payload);
dataToSubmit.source = source;
dataToSubmit.alias = getAliasFromPayload(source, payload);
dataToSubmit.alias = await getAliasFromPayload(source, payload);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,47 @@ import { DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
import { DefaultButton } from 'office-ui-fabric-react/lib/Button';
import formatMessage from 'format-message';
import { RouteComponentProps } from '@reach/router';
import querystring from 'query-string';
import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';

import { StorageFolder } from '../../recoilModel/types';
import { DialogCreationCopy } from '../../constants';
import { getAliasFromPayload, Profile } from '../../utils/electronUtil';

import { LocationSelectContent } from './LocationSelectContent';

interface OpenProjectFormData {
path: string;
storage: string;

profile?: Profile; // abs payload to create bot
source?: string; // where the payload come from
alias?: string; // identifier that is used to track bots between imports
}

interface OpenProjectProps extends RouteComponentProps<{}> {
focusedStorageFolder: StorageFolder;
onOpen: (path: string, storage: string) => void;
onOpen: (formData: OpenProjectFormData) => void;
onCurrentPathUpdate: (newPath?: string, storageId?: string) => void;
onDismiss: () => void;
}

export const OpenProject: React.FC<OpenProjectProps> = (props) => {
const { onOpen, onDismiss, onCurrentPathUpdate, focusedStorageFolder } = props;
const { onOpen, onDismiss, onCurrentPathUpdate, focusedStorageFolder, location } = props;
const handleOpen = async (path: string, storage: string) => {
const dataToOpen: OpenProjectFormData = { path, storage };
dataToOpen.path = path;
if (location?.search) {
const decoded = decodeURIComponent(location.search);
const { source, payload } = querystring.parse(decoded);
if (payload && typeof payload === 'string' && typeof source === 'string') {
dataToOpen.profile = JSON.parse(payload);
dataToOpen.source = source;
dataToOpen.alias = await getAliasFromPayload(source, payload);
}
}
onOpen(dataToOpen);
};

return (
<DialogWrapper
Expand All @@ -39,7 +65,7 @@ export const OpenProject: React.FC<OpenProjectProps> = (props) => {
write: false,
}}
onCurrentPathUpdate={onCurrentPathUpdate}
onOpen={onOpen}
onOpen={handleOpen}
/>
<DialogFooter>
<DefaultButton text={formatMessage('Cancel')} onClick={onDismiss} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
import { BotTemplate, QnABotTemplateId } from '@bfc/shared';
import { DialogWrapper, DialogTypes, LoadingSpinner } from '@bfc/ui-shared';
import { NeutralColors } from '@uifabric/fluent-theme';
import { RouteComponentProps } from '@reach/router';
import { WindowLocation } from '@reach/router';
import { IPivotItemProps, Pivot, PivotItem } from 'office-ui-fabric-react/lib/Pivot';
import { Link } from 'office-ui-fabric-react/lib/Link';
import { FontIcon } from 'office-ui-fabric-react/lib/Icon';
Expand Down Expand Up @@ -118,11 +118,12 @@ const defaultTemplateId = '@microsoft/generator-microsoft-bot-empty';
type CreateBotProps = {
isOpen: boolean;
templates: BotTemplate[];
location?: WindowLocation | undefined;
onDismiss: () => void;
onNext: (templateName: string, urlData?: string) => void;
fetchTemplates: (feedUrls?: string[]) => Promise<void>;
fetchReadMe: (moduleName: string) => {};
} & RouteComponentProps<{}>;
};

export function CreateBotV2(props: CreateBotProps) {
const [option] = useState(optionKeys.createFromTemplate);
Expand Down Expand Up @@ -158,8 +159,8 @@ export function CreateBotV2(props: CreateBotProps) {

TelemetryClient.track('CreateNewBotProjectNextButton', { template: routeToTemplate });

if (props.location && props.location.search) {
onNext(routeToTemplate, props.location.search);
if (location?.search) {
onNext(routeToTemplate, location.search);
} else {
onNext(routeToTemplate);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ChoiceGroup, IChoiceGroupOption } from 'office-ui-fabric-react/lib/Choi
import { DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
import { BotTemplate } from '@bfc/shared';
import { DialogWrapper, DialogTypes } from '@bfc/ui-shared';
import { RouteComponentProps } from '@reach/router';
import { navigate, RouteComponentProps } from '@reach/router';
import querystring from 'query-string';
import axios from 'axios';

Expand All @@ -24,7 +24,7 @@ type CreateOptionsProps = {
templates: BotTemplate[];
onDismiss: () => void;
onNext: (data: string) => void;
onJumpToOpenModal: () => void;
onJumpToOpenModal: (search?: string) => void;
fetchTemplates: (feedUrls?: string[]) => Promise<void>;
fetchReadMe: (moduleName: string) => {};
} & RouteComponentProps<{}>;
Expand All @@ -47,12 +47,12 @@ export function CreateOptionsV2(props: CreateOptionsProps) {
.get<any>(`/api/projects/alias/${alias}`)
.then((aliasRes) => {
if (aliasRes.status === 200) {
setIsOpenOptionsModal(true);
navigate(`/bot/${aliasRes.data.id}`);
return;
}
})
.catch((e) => {
setIsOpenCreateModal(true);
setIsOpenOptionsModal(true);
});
return;
}
Expand All @@ -74,7 +74,7 @@ export function CreateOptionsV2(props: CreateOptionsProps) {
if (option === 'Create') {
setIsOpenCreateModal(true);
} else {
onJumpToOpenModal();
onJumpToOpenModal(props.location?.search);
}
};

Expand All @@ -96,6 +96,7 @@ export function CreateOptionsV2(props: CreateOptionsProps) {
fetchReadMe={fetchReadMe}
fetchTemplates={fetchTemplates}
isOpen={isOpenCreateModal}
location={props.location}
templates={templates}
onDismiss={onDismiss}
onNext={onNext}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,22 @@ const CreationFlowV2: React.FC<CreationFlowProps> = () => {
navigate(`/home`);
};

const handleJumpToOpenModal = () => {
const handleJumpToOpenModal = (search) => {
setCreationFlowStatus(CreationFlowStatus.OPEN);
navigate('./open');
navigate(`./open${search}`);
};

const openBot = async (botFolder) => {
const openBot = async (formData) => {
setCreationFlowStatus(CreationFlowStatus.CLOSE);
await openProject(botFolder, 'default', true, (projectId) => {
TelemetryClient.track('BotProjectOpened', { method: 'toolbar', projectId });
});
await openProject(
formData.path,
'default',
true,
{ profile: formData.profile, source: formData.source, alias: formData.alias },
(projectId) => {
TelemetryClient.track('BotProjectOpened', { method: 'toolbar', projectId });
}
);
};

const handleCreateNew = async (formData, templateId: string, qnaKbUrls?: string[]) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ const DefineConversationV2: React.FC<DefineConversationProps> = (props) => {
}, [focusedStorageFolder]);

const handleSubmit = useCallback(
(e) => {
async (e) => {
e.preventDefault();
if (hasErrors) {
return;
Expand Down Expand Up @@ -275,7 +275,7 @@ const DefineConversationV2: React.FC<DefineConversationProps> = (props) => {
if (payload && typeof payload === 'string' && typeof source === 'string') {
dataToSubmit.profile = JSON.parse(payload);
dataToSubmit.source = source;
dataToSubmit.alias = getAliasFromPayload(source, payload);
dataToSubmit.alias = await getAliasFromPayload(source, payload);
}
}

Expand Down
4 changes: 4 additions & 0 deletions Composer/packages/client/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,10 @@ export const graphScopes = {
scopes: ['https://graph.microsoft.com/Application.ReadWrite.All'],
targetResource: 'https://graph.microsoft.com/',
};
export const vaultScopes = {
scopes: ['https://vault.azure.net/user_impersonation'],
targetResource: 'https://vault.azure.net/',
};

export const authUrl = `https://login.microsoftonline.com/${authConfig.tenantId}/oauth2/v2.0/authorize`;

Expand Down
4 changes: 2 additions & 2 deletions Composer/packages/client/src/pages/home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const Home: React.FC<RouteComponentProps> = () => {

const onItemChosen = async (item) => {
if (item?.path) {
await openProject(item.path, 'default', true, (projectId) => {
await openProject(item.path, 'default', true, null, (projectId) => {
TelemetryClient.track('BotProjectOpened', { method: 'list', projectId });
});
}
Expand Down Expand Up @@ -188,7 +188,7 @@ const Home: React.FC<RouteComponentProps> = () => {
styles={home.latestBotItem}
title={''}
onClick={async () => {
await openProject(recentProjects[0].path, 'default', true, (projectId) => {
await openProject(recentProjects[0].path, 'default', true, null, (projectId) => {
TelemetryClient.track('BotProjectOpened', { method: 'callToAction', projectId });
});
}}
Expand Down
7 changes: 6 additions & 1 deletion Composer/packages/client/src/pages/publish/Publish.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
setTenantId,
getTenantIdFromCache,
} from '../../utils/auth';
// import { vaultScopes } from '../../constants';
import { AuthClient } from '../../utils/authClient';
import TelemetryClient from '../../telemetry/TelemetryClient';
import { ApiStatus, PublishStatusPollingUpdater, pollingUpdaterList } from '../../utils/publishStatusPollingUpdater';
Expand Down Expand Up @@ -181,6 +182,10 @@ const Publish: React.FC<RouteComponentProps<{ projectId: string; targetName?: st
const updater = pollingUpdaterList.find((i) => i.isSameUpdater(botProjectId, targetName));
const updatedBot = botList.find((bot) => bot.id === botProjectId);
if (!updatedBot || !updater) return;
if (!apiResponse) {
stopUpdater(updater);
return;
}
const responseData = apiResponse.data;

if (responseData.status !== ApiStatus.Publishing) {
Expand All @@ -203,7 +208,7 @@ const Publish: React.FC<RouteComponentProps<{ projectId: string; targetName?: st

const updateUpdaterStatus = (payload) => {
const { botProjectId, targetName, apiResponse } = payload;
const pending = apiResponse.data.status === ApiStatus.Publishing;
const pending = apiResponse && apiResponse.data.status === ApiStatus.Publishing;
setUpdaterStatus({
...updaterStatus,
[`${botProjectId}/${targetName}`]: pending,
Expand Down
Loading

0 comments on commit c396f86

Please sign in to comment.