', true).then((token: string) => {
+ const { connectionName, tokenExchangeResource } = content;
+ const { tokenId } = tokenExchangeResource;
+
+ if (token) {
+ postActivity({
+ channelData: { invokeId },
+ type: 'invoke',
+ name: 'signin/tokenExchange',
+ value: {
+ id: tokenId,
+ connectionName,
+ token,
+ },
+ });
+ }
+ });
+ });
+ } catch (error) {
+ dismissNotification(id);
+ setNotification({
+ id: 'traditionalbotauthentication',
+ data: { content },
+ level: 'error',
+ message: 'Authenticating the bot failed.',
+ });
+ }
+ }, [dismissNotification, postActivity, setNotification]);
+
+ return (
+
+
+ {'Allow the bot to access your account? '}
+ {
+
+ {' '}
+
+
+ }
+
+ );
+};
diff --git a/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/components/Notification/TraditionalBotAuthenticationToast.tsx b/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/components/Notification/TraditionalBotAuthenticationToast.tsx
new file mode 100644
index 000000000..013e85273
--- /dev/null
+++ b/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/components/Notification/TraditionalBotAuthenticationToast.tsx
@@ -0,0 +1,37 @@
+import { useCallback } from 'react';
+import { hooks } from 'botframework-webchat';
+import { Icon } from 'office-ui-fabric-react/lib/Icon';
+
+import './index.css';
+import * as React from 'react';
+
+const { useDismissNotification, usePerformCardAction } = hooks;
+
+export interface ITraditionalBotAuthenticationToastProps {
+ notification: any;
+}
+
+export const TraditionalBotAuthenticationToast: React.FunctionComponent = ({
+ notification,
+}) => {
+ const id = notification.id;
+ const signin = notification.data.content.buttons[0];
+
+ const dismissNotification = useDismissNotification();
+ const performCardAction = usePerformCardAction();
+
+ const handleClick = useCallback(() => {
+ dismissNotification(id);
+ performCardAction(signin);
+ }, [dismissNotification, id, performCardAction, signin]);
+
+ return (
+
+
+ {'Please sign in to the bot directly.'}
+
+
+ );
+};
diff --git a/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/components/Notification/index.css b/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/components/Notification/index.css
new file mode 100644
index 000000000..5335e2617
--- /dev/null
+++ b/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/components/Notification/index.css
@@ -0,0 +1,42 @@
+.ms-Icon-Old {
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ display: inline-block;
+ font-style: normal;
+ font-weight: normal;
+ speak: none;
+}
+
+.app__signInNotification {
+ align-items: center;
+ color: #105e7d;
+ display: flex;
+ font-family: 'Calibri', 'Helvetica Neue', 'Arial', 'sans-serif';
+ font-size: 14px;
+ height: 100%;
+}
+
+.app__signInNotification__icon {
+ text-align: center;
+ width: 36px;
+}
+
+.app__signInNotification__button {
+ appearance: none;
+ background-color: rgba(255, 255, 255, 0.8);
+ border: solid 1px rgba(0, 0, 0, 0.3);
+ border-radius: 3px;
+ color: initial;
+ font-family: inherit;
+ font-size: inherit;
+ margin: 0 0 0 4px;
+ outline: 0;
+}
+
+.app__signInNotification__button:hover {
+ background-color: rgba(0, 0, 0, 0.12);
+}
+
+.app__signInNotification__button:focus {
+ border-color: rgba(0, 0, 0, 0.7);
+}
diff --git a/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/loc/en-us.js b/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/loc/en-us.js
new file mode 100644
index 000000000..69b489e57
--- /dev/null
+++ b/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/loc/en-us.js
@@ -0,0 +1,8 @@
+define([], function() {
+ return {
+ "PropertyPaneDescription": "Set up bot configuration.",
+ "BasicGroupName": "Config",
+ "BotEndpointLabel": "Bot Endpoint (For example: https://YOUR_BOT.azurewebsites.net)",
+ "BotName": "Bot"
+ }
+});
\ No newline at end of file
diff --git a/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/loc/mystrings.d.ts b/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/loc/mystrings.d.ts
new file mode 100644
index 000000000..2436aa4f8
--- /dev/null
+++ b/samples/react-bot-framework-sso/webpart/src/webparts/botFrameworkChatSSO/loc/mystrings.d.ts
@@ -0,0 +1,11 @@
+declare interface IBotFrameworkChatSSOWebPartStrings {
+ PropertyPaneDescription: string;
+ BasicGroupName: string;
+ BotEndpointLabel: string;
+ BotName: string;
+}
+
+declare module 'BotFrameworkChatSSOWebPartStrings' {
+ const strings: IBotFrameworkChatSSOWebPartStrings;
+ export = strings;
+}
diff --git a/samples/react-bot-framework-sso/webpart/tsconfig.json b/samples/react-bot-framework-sso/webpart/tsconfig.json
new file mode 100644
index 000000000..9e39a8ba7
--- /dev/null
+++ b/samples/react-bot-framework-sso/webpart/tsconfig.json
@@ -0,0 +1,40 @@
+{
+ "extends": "./node_modules/@microsoft/rush-stack-compiler-3.3/includes/tsconfig-web.json",
+ "compilerOptions": {
+ "target": "es5",
+ "forceConsistentCasingInFileNames": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "jsx": "react",
+ "declaration": true,
+ "sourceMap": true,
+ "experimentalDecorators": true,
+ "skipLibCheck": true,
+ "outDir": "lib",
+ "inlineSources": false,
+ "strictNullChecks": false,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "typeRoots": [
+ "./node_modules/@types",
+ "./node_modules/@microsoft"
+ ],
+ "types": [
+ "es6-promise",
+ "webpack-env"
+ ],
+ "lib": [
+ "es5",
+ "dom",
+ "es2015.collection"
+ ]
+ },
+ "include": [
+ "src/**/*.ts",
+ "src/**/*.tsx"
+ ],
+ "exclude": [
+ "node_modules",
+ "lib"
+ ]
+}
\ No newline at end of file
diff --git a/samples/react-bot-framework-sso/webpart/tslint.json b/samples/react-bot-framework-sso/webpart/tslint.json
new file mode 100644
index 000000000..23fa2aa43
--- /dev/null
+++ b/samples/react-bot-framework-sso/webpart/tslint.json
@@ -0,0 +1,30 @@
+{
+ "extends": "@microsoft/sp-tslint-rules/base-tslint.json",
+ "rules": {
+ "class-name": false,
+ "export-name": false,
+ "forin": false,
+ "label-position": false,
+ "member-access": true,
+ "no-arg": false,
+ "no-console": false,
+ "no-construct": false,
+ "no-duplicate-variable": true,
+ "no-eval": false,
+ "no-function-expression": true,
+ "no-internal-module": true,
+ "no-shadowed-variable": true,
+ "no-switch-case-fall-through": true,
+ "no-unnecessary-semicolons": true,
+ "no-unused-expression": true,
+ "no-use-before-declare": true,
+ "no-with-statement": true,
+ "semicolon": true,
+ "trailing-comma": false,
+ "typedef": false,
+ "typedef-whitespace": false,
+ "use-named-parameter": true,
+ "variable-name": false,
+ "whitespace": false
+ }
+}
\ No newline at end of file