@microsoft/omnichannel-chat-widget 0.1.0-main.745305b → 0.1.0-main.78a2099

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +32 -0
  2. package/lib/cjs/common/Constants.js +8 -2
  3. package/lib/cjs/common/telemetry/TelemetryConstants.js +10 -2
  4. package/lib/cjs/common/utils.js +16 -2
  5. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +11 -3
  6. package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +11 -2
  7. package/lib/cjs/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +7 -1
  8. package/lib/cjs/components/livechatwidget/common/endChat.js +18 -4
  9. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +5 -2
  10. package/lib/cjs/components/livechatwidget/common/startChat.js +49 -10
  11. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +33 -4
  12. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +4 -5
  13. package/lib/cjs/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +16 -0
  14. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +80 -0
  15. package/lib/cjs/components/webchatcontainerstateful/interfaces/IBotMagicCodeConfig.js +1 -0
  16. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/BotMagicCodeStore.js +14 -0
  17. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +9 -3
  18. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.js +52 -0
  19. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.spec.js +98 -0
  20. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +1 -0
  21. package/lib/cjs/contexts/createReducer.js +1 -0
  22. package/lib/cjs/plugins/newMessageEventHandler.js +10 -13
  23. package/lib/esm/common/Constants.js +8 -2
  24. package/lib/esm/common/telemetry/TelemetryConstants.js +10 -2
  25. package/lib/esm/common/utils.js +7 -0
  26. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +12 -4
  27. package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +9 -3
  28. package/lib/esm/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +7 -1
  29. package/lib/esm/components/livechatwidget/common/endChat.js +15 -5
  30. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +5 -3
  31. package/lib/esm/components/livechatwidget/common/startChat.js +51 -14
  32. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +30 -5
  33. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +6 -7
  34. package/lib/esm/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +16 -0
  35. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +72 -0
  36. package/lib/esm/components/webchatcontainerstateful/interfaces/IBotMagicCodeConfig.js +1 -0
  37. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/BotMagicCodeStore.js +5 -0
  38. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +9 -3
  39. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.js +41 -0
  40. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.spec.js +94 -0
  41. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +1 -0
  42. package/lib/esm/contexts/createReducer.js +1 -0
  43. package/lib/esm/plugins/newMessageEventHandler.js +10 -12
  44. package/lib/types/common/Constants.d.ts +4 -1
  45. package/lib/types/common/telemetry/TelemetryConstants.d.ts +11 -3
  46. package/lib/types/common/telemetry/TelemetryHelper.d.ts +1 -0
  47. package/lib/types/common/telemetry/definitions/Payload.d.ts +12 -9
  48. package/lib/types/common/utils.d.ts +2 -0
  49. package/lib/types/components/livechatwidget/common/endChat.d.ts +1 -1
  50. package/lib/types/components/webchatcontainerstateful/interfaces/IBotMagicCodeConfig.d.ts +4 -0
  51. package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +2 -0
  52. package/lib/types/components/webchatcontainerstateful/webchatcontroller/BotMagicCodeStore.d.ts +3 -0
  53. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.d.ts +2 -0
  54. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.spec.d.ts +1 -0
  55. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +2 -1
  56. package/package.json +2 -2
@@ -7,8 +7,8 @@ import { WebChatStoreLoader } from "../../webchatcontainerstateful/webchatcontro
7
7
  import { defaultWebChatContainerStatefulProps } from "../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps";
8
8
  import { PostChatSurveyMode } from "../../postchatsurveypanestateful/enums/PostChatSurveyMode";
9
9
  import { Constants } from "../../../common/Constants";
10
+ import { getWidgetEndChatEventName } from "../../../common/utils"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
11
 
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
12
  const prepareEndChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state) => {
13
13
  var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _state$domainStates$l4;
14
14
 
@@ -19,7 +19,7 @@ const prepareEndChat = async (props, chatSDK, setAdapter, setWebChatStyles, disp
19
19
  if (isPostChatEnabled === "true" && (conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.canRenderPostChat) === Constants.truePascal) {
20
20
  const skipEndChatSDK = false;
21
21
  const skipCloseChat = true;
22
- await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat);
22
+ await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat, true);
23
23
 
24
24
  if (postChatSurveyMode === PostChatSurveyMode.Embed) {
25
25
  const loadPostChatEvent = {
@@ -33,12 +33,12 @@ const prepareEndChat = async (props, chatSDK, setAdapter, setWebChatStyles, disp
33
33
  });
34
34
  }
35
35
  } else {
36
- await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter);
36
+ await endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, true);
37
37
  }
38
38
  }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
39
 
40
40
 
41
- const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat) => {
41
+ const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat, postMessageToOtherTab) => {
42
42
  if (!skipEndChatSDK) {
43
43
  try {
44
44
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
@@ -61,6 +61,7 @@ const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, a
61
61
  exception: ex
62
62
  }
63
63
  });
64
+ postMessageToOtherTab = false;
64
65
  }
65
66
  }
66
67
 
@@ -91,8 +92,17 @@ const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, a
91
92
  payload: null
92
93
  });
93
94
  BroadcastService.postMessage({
94
- eventName: BroadcastEvent.EndChat
95
+ eventName: BroadcastEvent.ChatEnded
95
96
  });
97
+
98
+ if (postMessageToOtherTab) {
99
+ var _chatSDK$omnichannelC, _chatSDK$omnichannelC2;
100
+
101
+ const endChatEventName = getWidgetEndChatEventName(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC === void 0 ? void 0 : _chatSDK$omnichannelC.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC2 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC2 === void 0 ? void 0 : _chatSDK$omnichannelC2.widgetId);
102
+ BroadcastService.postMessage({
103
+ eventName: endChatEventName
104
+ });
105
+ }
96
106
  } catch (error) {
97
107
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
98
108
  Event: TelemetryEvent.CloseChatMethodException,
@@ -26,10 +26,11 @@ import gifUploadMiddleware from "../../webchatcontainerstateful/webchatcontrolle
26
26
  import htmlPlayerMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlPlayerMiddleware";
27
27
  import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware";
28
28
  import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
29
- import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
30
+ import { createCardActionMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
31
 
31
32
  export const initWebChatComposer = (props, chatSDK, state, dispatch, setWebChatStyles) => {
32
- var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _state$domainStates$l4, _state$domainStates$l8, _state$domainStates$l9, _props$webChatContain7, _props$webChatContain8, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain9, _props$webChatContain10, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain11, _props$webChatContain12, _defaultWebChatContai, _props$webChatContain13, _props$webChatContain14, _props$webChatContain15, _props$webChatContain16, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain17, _props$webChatContain18, _defaultWebChatContai2, _props$webChatContain19, _props$webChatContain20, _defaultWebChatContai3, _props$webChatContain21;
33
+ var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _state$domainStates$l4, _state$domainStates$l8, _state$domainStates$l9, _props$webChatContain7, _props$webChatContain8, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain9, _props$webChatContain10, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain11, _props$webChatContain12, _defaultWebChatContai, _props$webChatContain13, _props$webChatContain14, _props$webChatContain15, _props$webChatContain16, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain17, _props$webChatContain18, _defaultWebChatContai2, _props$webChatContain19, _props$webChatContain20, _defaultWebChatContai3, _props$webChatContain21, _props$webChatContain22;
33
34
 
34
35
  const localizedTexts = { ...defaultMiddlewareLocalizedTexts,
35
36
  ...((_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : _props$webChatContain.localizedTexts)
@@ -109,7 +110,8 @@ export const initWebChatComposer = (props, chatSDK, state, dispatch, setWebChatS
109
110
  groupActivitiesMiddleware: (_props$webChatContain17 = props.webChatContainerProps) !== null && _props$webChatContain17 !== void 0 && (_props$webChatContain18 = _props$webChatContain17.renderingMiddlewareProps) !== null && _props$webChatContain18 !== void 0 && _props$webChatContain18.disableGroupActivitiesMiddleware ? undefined : (_defaultWebChatContai2 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.groupActivitiesMiddleware,
110
111
  typingIndicatorMiddleware: (_props$webChatContain19 = props.webChatContainerProps) !== null && _props$webChatContain19 !== void 0 && (_props$webChatContain20 = _props$webChatContain19.renderingMiddlewareProps) !== null && _props$webChatContain20 !== void 0 && _props$webChatContain20.disableTypingIndicatorMiddleware ? undefined : (_defaultWebChatContai3 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai3 === void 0 ? void 0 : _defaultWebChatContai3.typingIndicatorMiddleware,
111
112
  onTelemetry: createWebChatTelemetry(),
112
- ...((_props$webChatContain21 = props.webChatContainerProps) === null || _props$webChatContain21 === void 0 ? void 0 : _props$webChatContain21.webChatProps)
113
+ cardActionMiddleware: createCardActionMiddleware(((_props$webChatContain21 = props.webChatContainerProps) === null || _props$webChatContain21 === void 0 ? void 0 : _props$webChatContain21.botMagicCode) || undefined),
114
+ ...((_props$webChatContain22 = props.webChatContainerProps) === null || _props$webChatContain22 === void 0 ? void 0 : _props$webChatContain22.webChatProps)
113
115
  };
114
116
  return webChatProps;
115
117
  };
@@ -1,5 +1,5 @@
1
- import { ChatSDKError, Constants } from "../../../common/Constants";
2
- import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
1
+ import { ChatSDKError } from "../../../common/Constants";
2
+ import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
3
3
  import { ConversationState } from "../../../contexts/common/ConversationState";
4
4
  import { DataStoreManager } from "../../../common/contextDataStore/DataStoreManager";
5
5
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
@@ -9,10 +9,13 @@ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
9
9
  import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
10
10
  import { createAdapter } from "./createAdapter";
11
11
  import { createOnNewAdapterActivityHandler } from "../../../plugins/newMessageEventHandler";
12
- import { createTimer } from "../../../common/utils";
12
+ import { createTimer, getWidgetCacheId } from "../../../common/utils";
13
13
  import { getReconnectIdForAuthenticatedChat, handleRedirectUnauthenticatedReconnectChat } from "./reconnectChatHelper";
14
14
  import { setPostChatContextAndLoadSurvey } from "./setPostChatContextAndLoadSurvey";
15
- import { updateSessionDataForTelemetry } from "./updateSessionDataForTelemetry"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ import { updateSessionDataForTelemetry } from "./updateSessionDataForTelemetry";
16
+ import { BroadcastService } from "@microsoft/omnichannel-chat-components"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+
18
+ let optionalParams = {}; // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
19
 
17
20
  const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) => {
18
21
  var _props$reconnectChatP;
@@ -52,11 +55,13 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
52
55
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
53
56
  payload: ConversationState.Prechat
54
57
  });
58
+ setCustomContextParams(props, state);
55
59
  } else {
56
60
  dispatch({
57
61
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
58
62
  payload: ConversationState.Loading
59
63
  });
64
+ setCustomContextParams(props, state);
60
65
  await initStartChat(chatSDK, dispatch, setAdapter);
61
66
  }
62
67
  }
@@ -67,12 +72,29 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, params, persistedSta
67
72
  try {
68
73
  var _newAdapter$activity$, _TelemetryTimers$Widg;
69
74
 
75
+ let isStartChatSuccessful = false;
76
+
77
+ if (persistedState || params !== null && params !== void 0 && params.liveChatContext) {
78
+ var _persistedState$domai, _persistedState$domai2, _persistedState$domai3, _persistedState$domai4, _persistedState$domai5;
79
+
80
+ // Broadcasting limited cached chat details
81
+ BroadcastService.postMessage({
82
+ eventName: BroadcastEvent.ChatRetrievedFromCache,
83
+ payload: {
84
+ chatId: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai = persistedState.domainStates) === null || _persistedState$domai === void 0 ? void 0 : (_persistedState$domai2 = _persistedState$domai.liveChatContext) === null || _persistedState$domai2 === void 0 ? void 0 : (_persistedState$domai3 = _persistedState$domai2.chatToken) === null || _persistedState$domai3 === void 0 ? void 0 : _persistedState$domai3.chatId,
85
+ requestId: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai4 = persistedState.domainStates) === null || _persistedState$domai4 === void 0 ? void 0 : (_persistedState$domai5 = _persistedState$domai4.liveChatContext) === null || _persistedState$domai5 === void 0 ? void 0 : _persistedState$domai5.requestId
86
+ }
87
+ });
88
+ }
89
+
70
90
  try {
71
91
  TelemetryTimers.WidgetLoadTimer = createTimer();
72
92
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
73
93
  Event: TelemetryEvent.StartChatSDKCall
74
94
  });
75
- await chatSDK.startChat(params);
95
+ optionalParams = Object.assign({}, params, optionalParams);
96
+ await chatSDK.startChat(optionalParams);
97
+ isStartChatSuccessful = true;
76
98
  } catch (error) {
77
99
  TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
78
100
  Event: TelemetryEvent.StartChatMethodException,
@@ -80,6 +102,7 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, params, persistedSta
80
102
  exception: `Failed to setup startChat: ${error}`
81
103
  }
82
104
  });
105
+ isStartChatSuccessful = false;
83
106
  }
84
107
 
85
108
  const newAdapter = await createAdapter(chatSDK);
@@ -107,10 +130,12 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, params, persistedSta
107
130
  await setPostChatContextAndLoadSurvey(chatSDK, dispatch);
108
131
  await updateSessionDataForTelemetry(chatSDK, dispatch); // Set app state to Active
109
132
 
110
- dispatch({
111
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
112
- payload: ConversationState.Active
113
- });
133
+ if (isStartChatSuccessful) {
134
+ dispatch({
135
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
136
+ payload: ConversationState.Active
137
+ });
138
+ }
114
139
  } else {
115
140
  dispatch({
116
141
  type: LiveChatWidgetActionType.SET_WIDGET_STATE,
@@ -148,20 +173,21 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, params, persistedSta
148
173
 
149
174
 
150
175
  const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdapter) => {
151
- var _DataStoreManager$cli, _persistedState$domai;
176
+ var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _DataStoreManager$cli, _persistedState$domai6;
152
177
 
153
- const widgetStateFromCache = (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.getData(Constants.widgetStateDataKey, "localStorage");
178
+ const widgetStateEventName = getWidgetCacheId((chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC === void 0 ? void 0 : _chatSDK$omnichannelC.orgId) ?? "", (chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC2 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC2 === void 0 ? void 0 : _chatSDK$omnichannelC2.widgetId) ?? "");
179
+ const widgetStateFromCache = (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.getData(widgetStateEventName, "localStorage");
154
180
  const persistedState = widgetStateFromCache ? JSON.parse(widgetStateFromCache) : undefined;
155
181
 
156
- if (persistedState !== null && persistedState !== void 0 && (_persistedState$domai = persistedState.domainStates) !== null && _persistedState$domai !== void 0 && _persistedState$domai.liveChatContext) {
157
- var _persistedState$domai2;
182
+ if (persistedState !== null && persistedState !== void 0 && (_persistedState$domai6 = persistedState.domainStates) !== null && _persistedState$domai6 !== void 0 && _persistedState$domai6.liveChatContext) {
183
+ var _persistedState$domai7;
158
184
 
159
185
  dispatch({
160
186
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
161
187
  payload: ConversationState.Loading
162
188
  });
163
189
  const optionalParams = {
164
- liveChatContext: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai2 = persistedState.domainStates) === null || _persistedState$domai2 === void 0 ? void 0 : _persistedState$domai2.liveChatContext
190
+ liveChatContext: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai7 = persistedState.domainStates) === null || _persistedState$domai7 === void 0 ? void 0 : _persistedState$domai7.liveChatContext
165
191
  };
166
192
  await initStartChat(chatSDK, dispatch, setAdapter, optionalParams, persistedState);
167
193
  return true;
@@ -170,4 +196,15 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
170
196
  }
171
197
  };
172
198
 
199
+ const setCustomContextParams = (props, state) => {
200
+ var _props$chatConfig, _state$domainStates;
201
+
202
+ // Add custom context if any only for unauthenticated chat
203
+ if (!((_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && _props$chatConfig.LiveChatConfigAuthSettings) && (_state$domainStates = state.domainStates) !== null && _state$domainStates !== void 0 && _state$domainStates.customContext) {
204
+ optionalParams = Object.assign({}, optionalParams, {
205
+ customContext: state.domainStates.customContext
206
+ });
207
+ }
208
+ };
209
+
173
210
  export { prepareStartChat, initStartChat };
@@ -4,7 +4,7 @@ import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/teleme
4
4
  import { BroadcastService, decodeComponentString } from "@microsoft/omnichannel-chat-components";
5
5
  import { Stack } from "@fluentui/react";
6
6
  import React, { useEffect, useRef, useState } from "react";
7
- import { createTimer, getLocaleDirection } from "../../../common/utils";
7
+ import { createTimer, getLocaleDirection, getWidgetCacheId, getWidgetEndChatEventName } from "../../../common/utils";
8
8
  import { getReconnectIdForAuthenticatedChat, handleUnauthenticatedReconnectChat, startUnauthenticatedReconnectChat } from "../common/reconnectChatHelper";
9
9
  import { initStartChat, prepareStartChat } from "../common/startChat";
10
10
  import { shouldShowCallingContainer, shouldShowChatButton, shouldShowConfirmationPane, shouldShowEmailTranscriptPane, shouldShowHeader, shouldShowLoadingPane, shouldShowOutOfOfficeHoursPane, shouldShowPostChatLoadingPane, shouldShowPostChatSurveyPane, shouldShowPreChatSurveyPane, shouldShowProactiveChatPane, shouldShowReconnectChatPane, shouldShowWebChatContainer } from "../../../controller/componentController";
@@ -150,6 +150,8 @@ export const LiveChatWidgetStateful = props => {
150
150
  }
151
151
  }, [state.appStates.skipChatButtonRendering]);
152
152
  useEffect(() => {
153
+ var _chatSDK$omnichannelC, _chatSDK$omnichannelC2;
154
+
153
155
  // Add the custom context on receiving the SetCustomContext event
154
156
  BroadcastService.getMessageByEventName(BroadcastEvent.SetCustomContext).subscribe(msg => {
155
157
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
@@ -161,7 +163,7 @@ export const LiveChatWidgetStateful = props => {
161
163
  payload: msg === null || msg === void 0 ? void 0 : msg.payload
162
164
  });
163
165
  });
164
- BroadcastService.getMessageByEventName("StartProactiveChat").subscribe(msg => {
166
+ BroadcastService.getMessageByEventName(BroadcastEvent.StartProactiveChat).subscribe(msg => {
165
167
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
166
168
  Event: TelemetryEvent.StartProactiveChatEventReceived,
167
169
  Description: "Start proactive chat event received."
@@ -179,7 +181,7 @@ export const LiveChatWidgetStateful = props => {
179
181
  }
180
182
  }); // start chat from SDK Event
181
183
 
182
- BroadcastService.getMessageByEventName("StartChat").subscribe(() => {
184
+ BroadcastService.getMessageByEventName(BroadcastEvent.StartChat).subscribe(() => {
183
185
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
184
186
  Event: TelemetryEvent.StartChatEventRecevied,
185
187
  Description: "Start chat event received."
@@ -195,7 +197,7 @@ export const LiveChatWidgetStateful = props => {
195
197
  }
196
198
  }); // end chat from SDK Event
197
199
 
198
- BroadcastService.getMessageByEventName("EndChat").subscribe(async () => {
200
+ BroadcastService.getMessageByEventName(BroadcastEvent.EndChat).subscribe(async () => {
199
201
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
200
202
  Event: TelemetryEvent.EndChatEventReceived,
201
203
  Description: "End chat event received."
@@ -208,6 +210,26 @@ export const LiveChatWidgetStateful = props => {
208
210
  const skipCloseChat = false;
209
211
  endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat);
210
212
  }
213
+ }); // Listen to end chat event from other tabs
214
+
215
+ const endChatEventName = getWidgetEndChatEventName(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC === void 0 ? void 0 : _chatSDK$omnichannelC.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC2 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC2 === void 0 ? void 0 : _chatSDK$omnichannelC2.widgetId);
216
+ BroadcastService.getMessageByEventName(endChatEventName).subscribe(async () => {
217
+ endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, false);
218
+ }); // Close popout window
219
+
220
+ BroadcastService.getMessageByEventName(BroadcastEvent.ClosePopoutWindow).subscribe(() => {
221
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
222
+ Event: TelemetryEvent.ClosePopoutWindowEventRecevied,
223
+ Description: "Close popout window event received."
224
+ });
225
+ dispatch({
226
+ type: LiveChatWidgetActionType.SET_PROACTIVE_CHAT_PARAMS,
227
+ payload: {
228
+ proactiveChatBodyTitle: "",
229
+ proactiveChatEnablePrechat: false,
230
+ proactiveChatInNewWindow: false
231
+ }
232
+ });
211
233
  });
212
234
  window.addEventListener("beforeunload", () => {
213
235
  disposeTelemetryLoggers();
@@ -290,8 +312,11 @@ export const LiveChatWidgetStateful = props => {
290
312
  const confirmationPaneProps = initConfirmationPropsComposer(props); // publish chat widget state
291
313
 
292
314
  useEffect(() => {
315
+ var _props$chatSDK, _props$chatSDK$omnich, _props$chatSDK2, _props$chatSDK2$omnic;
316
+
317
+ const widgetStateEventName = getWidgetCacheId(props === null || props === void 0 ? void 0 : (_props$chatSDK = props.chatSDK) === null || _props$chatSDK === void 0 ? void 0 : (_props$chatSDK$omnich = _props$chatSDK.omnichannelConfig) === null || _props$chatSDK$omnich === void 0 ? void 0 : _props$chatSDK$omnich.orgId, props === null || props === void 0 ? void 0 : (_props$chatSDK2 = props.chatSDK) === null || _props$chatSDK2 === void 0 ? void 0 : (_props$chatSDK2$omnic = _props$chatSDK2.omnichannelConfig) === null || _props$chatSDK2$omnic === void 0 ? void 0 : _props$chatSDK2$omnic.widgetId);
293
318
  const chatWidgetStateChangeEvent = {
294
- eventName: BroadcastEvent.ChatWidgetStateChanged,
319
+ eventName: widgetStateEventName,
295
320
  payload: { ...state
296
321
  }
297
322
  };
@@ -1,7 +1,7 @@
1
- import { Constants, HtmlAttributeNames, Regex } from "../../common/Constants";
1
+ import { HtmlAttributeNames, Regex } from "../../common/Constants";
2
2
  import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
3
3
  import React, { useEffect } from "react";
4
- import { extractPreChatSurveyResponseValues, findAllFocusableElement, parseAdaptiveCardPayload } from "../../common/utils";
4
+ import { extractPreChatSurveyResponseValues, findAllFocusableElement, getWidgetCacheId, parseAdaptiveCardPayload } from "../../common/utils";
5
5
  import { ConversationState } from "../../contexts/common/ConversationState";
6
6
  import { DataStoreManager } from "../../common/contextDataStore/DataStoreManager";
7
7
  import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
@@ -67,9 +67,10 @@ export const PreChatSurveyPaneStateful = props => {
67
67
  });
68
68
 
69
69
  try {
70
- var _DataStoreManager$cli, _persistedState$domai;
70
+ var _state$domainStates, _state$domainStates$t, _state$domainStates$t2, _DataStoreManager$cli, _persistedState$domai;
71
71
 
72
- const widgetStateFromCache = (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.getData(Constants.widgetStateDataKey, "localStorage");
72
+ const widgetStateCacheId = getWidgetCacheId(((_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$t = _state$domainStates.telemetryInternalData) === null || _state$domainStates$t === void 0 ? void 0 : _state$domainStates$t.orgId) ?? "", ((_state$domainStates$t2 = state.domainStates.telemetryInternalData) === null || _state$domainStates$t2 === void 0 ? void 0 : _state$domainStates$t2.widgetId) ?? "");
73
+ const widgetStateFromCache = (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.getData(widgetStateCacheId, "localStorage");
73
74
  const persistedState = widgetStateFromCache ? JSON.parse(widgetStateFromCache) : undefined;
74
75
  let optionalParams = {};
75
76
 
@@ -83,9 +84,7 @@ export const PreChatSurveyPaneStateful = props => {
83
84
  } else {
84
85
  const prechatResponseValues = extractPreChatSurveyResponseValues(state.domainStates.preChatSurveyResponse, values);
85
86
  optionalParams = {
86
- initContext: {
87
- preChatResponse: prechatResponseValues
88
- }
87
+ preChatResponse: prechatResponseValues
89
88
  };
90
89
  setPreChatResponseEmail(values);
91
90
  await initStartChat(optionalParams);
@@ -24,6 +24,14 @@ export const ProactiveChatPaneStateful = props => {
24
24
  const handleProactiveChatInviteTimeout = () => {
25
25
  if (!timeoutRemoved) {
26
26
  setTimeoutRemoved(true);
27
+ dispatch({
28
+ type: LiveChatWidgetActionType.SET_PROACTIVE_CHAT_PARAMS,
29
+ payload: {
30
+ proactiveChatBodyTitle: "",
31
+ proactiveChatEnablePrechat: false,
32
+ proactiveChatInNewWindow: false
33
+ }
34
+ });
27
35
  dispatch({
28
36
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
29
37
  payload: ConversationState.Closed
@@ -81,6 +89,14 @@ export const ProactiveChatPaneStateful = props => {
81
89
  Event: TelemetryEvent.ProactiveChatClosed,
82
90
  Description: "Proactive chat closed."
83
91
  });
92
+ dispatch({
93
+ type: LiveChatWidgetActionType.SET_PROACTIVE_CHAT_PARAMS,
94
+ payload: {
95
+ proactiveChatBodyTitle: "",
96
+ proactiveChatEnablePrechat: false,
97
+ proactiveChatInNewWindow: false
98
+ }
99
+ });
84
100
  dispatch({
85
101
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
86
102
  payload: ConversationState.Closed
@@ -8,11 +8,45 @@ import { defaultMiddlewareLocalizedTexts } from "./common/defaultProps/defaultMi
8
8
  import { defaultWebChatContainerStatefulProps } from "./common/defaultProps/defaultWebChatContainerStatefulProps";
9
9
  import { setFocusOnSendBox } from "../../common/utils";
10
10
  import { useChatContextStore } from "../..";
11
+ import { WebChatActionType } from "./webchatcontroller/enums/WebChatActionType";
12
+ import { WebChatStoreLoader } from "./webchatcontroller/WebChatStoreLoader";
13
+ import { Constants } from "../../common/Constants";
14
+ import { BotMagicCodeStore } from "./webchatcontroller/BotMagicCodeStore";
15
+ const broadcastChannelMessageEvent = "message";
16
+
17
+ const postActivity = activity => {
18
+ // eslint-disable-line @typescript-eslint/no-explicit-any
19
+ return {
20
+ type: WebChatActionType.DIRECT_LINE_POST_ACTIVITY,
21
+ meta: {
22
+ method: "keyboard"
23
+ },
24
+ payload: {
25
+ activity: {
26
+ channelData: undefined,
27
+ text: "",
28
+ textFormat: "plain",
29
+ type: Constants.message,
30
+ ...activity
31
+ }
32
+ }
33
+ };
34
+ };
35
+
36
+ const createMagicCodeSuccessResponse = signin => {
37
+ return {
38
+ signin,
39
+ result: "Success"
40
+ };
41
+ };
42
+
11
43
  export const WebChatContainerStateful = props => {
12
44
  const {
13
45
  BasicWebChat
14
46
  } = Components;
15
47
  const [state, dispatch] = useChatContextStore();
48
+ const magicCodeBroadcastChannel = new BroadcastChannel(Constants.magicCodeBroadcastChannel);
49
+ const magicCodeResponseBroadcastChannel = new BroadcastChannel(Constants.magicCodeResponseBroadcastChannel);
16
50
  const containerStyles = {
17
51
  root: Object.assign({}, defaultWebChatContainerStatefulProps.containerStyles, props === null || props === void 0 ? void 0 : props.containerStyles, {
18
52
  display: state.appStates.isMinimized ? "none" : ""
@@ -36,6 +70,44 @@ export const WebChatContainerStateful = props => {
36
70
  Event: TelemetryEvent.WebChatLoaded
37
71
  });
38
72
  }, []);
73
+ useEffect(() => {
74
+ const eventListener = event => {
75
+ // eslint-disable-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-empty-function
76
+ const {
77
+ data
78
+ } = event;
79
+
80
+ if (BotMagicCodeStore.botOAuthSignInId === data.signin) {
81
+ const {
82
+ signin,
83
+ code
84
+ } = data;
85
+ const text = `${code}`;
86
+ const action = postActivity({
87
+ text,
88
+ channelData: {
89
+ tags: [Constants.hiddenTag]
90
+ }
91
+ });
92
+ WebChatStoreLoader.store.dispatch(action);
93
+ const response = createMagicCodeSuccessResponse(signin);
94
+ magicCodeResponseBroadcastChannel.postMessage(response);
95
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
96
+ Event: TelemetryEvent.SuppressBotMagicCodeSucceeded
97
+ });
98
+ BotMagicCodeStore.botOAuthSignInId = "";
99
+ magicCodeBroadcastChannel.close();
100
+ magicCodeResponseBroadcastChannel.close();
101
+ } else {
102
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
103
+ Event: TelemetryEvent.SuppressBotMagicCodeFailed,
104
+ Description: "Signin does not match"
105
+ });
106
+ }
107
+ };
108
+
109
+ magicCodeBroadcastChannel.addEventListener(broadcastChannelMessageEvent, eventListener);
110
+ }, []);
39
111
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("style", null, `
40
112
  .ms_lcw_webchat_received_message img.webchat__markdown__external-link-icon {
41
113
  background-image : url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik03LjI1MDEgNC41MDAxN0gxMC43NDk1QzExLjE2MzcgNC41MDAxNyAxMS40OTk1IDQuODM1OTYgMTEuNDk5NSA1LjI1MDE3QzExLjQ5OTUgNS42Mjk4NiAxMS4yMTczIDUuOTQzNjYgMTAuODUxMyA1Ljk5MzMyTDEwLjc0OTUgNi4wMDAxN0g3LjI0OTc0QzYuMDcwNzkgNS45OTk2MSA1LjEwMzQ5IDYuOTA2NTYgNS4wMDc4NiA4LjA2MTEyTDUuMDAwMjggOC4yMjAwM0w1LjAwMzEyIDE2Ljc1MDdDNS4wMDM0MyAxNy45NDE1IDUuOTI4ODUgMTguOTE2MSA3LjA5OTY2IDE4Ljk5NDlMNy4yNTM3MSAxOS4wMDAxTDE1Ljc1MTggMTguOTg4NEMxNi45NDE1IDE4Ljk4NjggMTcuOTE0NSAxOC4wNjIgMTcuOTkzNSAxNi44OTIzTDE3Ljk5ODcgMTYuNzM4NFYxMy4yMzIxQzE3Ljk5ODcgMTIuODE3OSAxOC4zMzQ1IDEyLjQ4MjEgMTguNzQ4NyAxMi40ODIxQzE5LjEyODQgMTIuNDgyMSAxOS40NDIyIDEyLjc2NDMgMTkuNDkxOCAxMy4xMzAzTDE5LjQ5ODcgMTMuMjMyMVYxNi43Mzg0QzE5LjQ5ODcgMTguNzQwNyAxNy45MjkzIDIwLjM3NjkgMTUuOTUyOCAyMC40ODI5TDE1Ljc1MzggMjAuNDg4NEw3LjI1ODI3IDIwLjUwMDFMNy4wNTQ5NSAyMC40OTQ5QzUuMTQyMzkgMjAuMzk1NCAzLjYwODk1IDE4Ljg2MjcgMy41MDgzNyAxNi45NTAyTDMuNTAzMTIgMTYuNzUxMUwzLjUwMDg5IDguMjUyN0wzLjUwNTI5IDguMDUwMkMzLjYwNTM5IDYuMTM3NDkgNS4xMzg2NyA0LjYwNDQ5IDcuMDUwOTYgNC41MDUyN0w3LjI1MDEgNC41MDAxN0gxMC43NDk1SDcuMjUwMVpNMTMuNzQ4MSAzLjAwMTQ2TDIwLjMwMTggMy4wMDE5N0wyMC40MDE0IDMuMDE1NzVMMjAuNTAyMiAzLjA0MzkzTDIwLjU1OSAzLjA2ODAzQzIwLjYxMjIgMy4wOTEyMiAyMC42NjM0IDMuMTIxNjMgMjAuNzExMSAzLjE1ODg1TDIwLjc4MDQgMy4yMjE1NkwyMC44NjQxIDMuMzIwMTRMMjAuOTE4MyAzLjQxMDI1TDIwLjk1NyAzLjUwMDU3TDIwLjk3NjIgMy41NjQ3NkwyMC45ODk4IDMuNjI4NjJMMjAuOTk5MiAzLjcyMjgyTDIwLjk5OTcgMTAuMjU1NEMyMC45OTk3IDEwLjY2OTYgMjAuNjYzOSAxMS4wMDU0IDIwLjI0OTcgMTEuMDA1NEMxOS44NyAxMS4wMDU0IDE5LjU1NjIgMTAuNzIzMiAxOS41MDY1IDEwLjM1NzFMMTkuNDk5NyAxMC4yNTU0TDE5LjQ5ODkgNS41NjE0N0wxMi4yNzk3IDEyLjc4NDdDMTIuMDEzNCAxMy4wNTEgMTEuNTk2OCAxMy4wNzUzIDExLjMwMzEgMTIuODU3NUwxMS4yMTkgMTIuNzg0OUMxMC45NTI3IDEyLjUxODcgMTAuOTI4NCAxMi4xMDIxIDExLjE0NjIgMTEuODA4NEwxMS4yMTg4IDExLjcyNDNMMTguNDM2OSA0LjUwMTQ2SDEzLjc0ODFDMTMuMzY4NCA0LjUwMTQ2IDEzLjA1NDYgNC4yMTkzMSAxMy4wMDUgMy44NTMyNEwxMi45OTgxIDMuNzUxNDZDMTIuOTk4MSAzLjM3MTc3IDEzLjI4MDMgMy4wNTc5NyAxMy42NDY0IDMuMDA4MzFMMTMuNzQ4MSAzLjAwMTQ2WiIgZmlsbD0iI0ZGRkZGRiIgLz48L3N2Zz4) !important;
@@ -0,0 +1,5 @@
1
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+
3
+ export class BotMagicCodeStore {}
4
+
5
+ _defineProperty(BotMagicCodeStore, "botOAuthSignInId", "");
@@ -62,7 +62,7 @@ export const createActivityMiddleware = (systemMessageStyleProps, userMessageSty
62
62
  const [card] = args;
63
63
 
64
64
  if (card.activity) {
65
- var _card$activity$from, _card$activity$channe4, _card$activity$channe5;
65
+ var _card$activity$from;
66
66
 
67
67
  if (((_card$activity$from = card.activity.from) === null || _card$activity$from === void 0 ? void 0 : _card$activity$from.role) === DirectLineSenderRole.Channel) {
68
68
  var _card$activity$channe3;
@@ -77,8 +77,14 @@ export const createActivityMiddleware = (systemMessageStyleProps, userMessageSty
77
77
  return () => false;
78
78
  }
79
79
 
80
- if ((_card$activity$channe4 = card.activity.channelData) !== null && _card$activity$channe4 !== void 0 && (_card$activity$channe5 = _card$activity$channe4.tags) !== null && _card$activity$channe5 !== void 0 && _card$activity$channe5.includes(Constants.systemMessageTag)) {
81
- return handleSystemMessage(next, args, card, systemMessageStyleProps);
80
+ if (card.activity.channelData.tags) {
81
+ if (card.activity.channelData.tags.includes(Constants.hiddenTag)) {
82
+ return () => false;
83
+ }
84
+
85
+ if (card.activity.channelData.tags.includes(Constants.systemMessageTag)) {
86
+ return handleSystemMessage(next, args, card, systemMessageStyleProps);
87
+ }
82
88
  } else if (card.activity.text && card.activity.type === DirectLineActivityType.Message) {
83
89
  if (!card.activity.channelData.isHtmlEncoded && card.activity.channelId === Constants.webchatChannelId) {
84
90
  card.activity.text = escapeHtml(card.activity.text);
@@ -0,0 +1,41 @@
1
+ import { BotMagicCodeStore } from "../../BotMagicCodeStore";
2
+ var CardActionType;
3
+
4
+ (function (CardActionType) {
5
+ CardActionType["OpenUrl"] = "openUrl";
6
+ CardActionType["SignIn"] = "signin";
7
+ })(CardActionType || (CardActionType = {}));
8
+
9
+ const validCardActionTypes = [CardActionType.OpenUrl, CardActionType.SignIn];
10
+ const botOauthUrlRegex = /[\S]+.botframework.com\/api\/oauth\/signin\?signin=([\S]+)/;
11
+ export const createCardActionMiddleware = botMagicCodeConfig => {
12
+ const cardActionMiddleware = () => next => function () {
13
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
14
+ args[_key] = arguments[_key];
15
+ }
16
+
17
+ // eslint-disable-line @typescript-eslint/no-explicit-any
18
+ const [card] = args;
19
+
20
+ if (card.cardAction && validCardActionTypes.indexOf(card.cardAction.type) >= 0 && card.cardAction.value) {
21
+ // Override signin url only if fwdUrl is valid & feature is enabled
22
+ if ((botMagicCodeConfig === null || botMagicCodeConfig === void 0 ? void 0 : botMagicCodeConfig.disabled) === true && botMagicCodeConfig !== null && botMagicCodeConfig !== void 0 && botMagicCodeConfig.fwdUrl) {
23
+ const baseUrl = window.location.origin;
24
+ const result = botOauthUrlRegex.exec(card.cardAction.value);
25
+
26
+ if (result) {
27
+ BotMagicCodeStore.botOAuthSignInId = `${result[1]}`;
28
+ } // fwdUrl must be on the same domain as the chat widget
29
+
30
+
31
+ if (botMagicCodeConfig !== null && botMagicCodeConfig !== void 0 && botMagicCodeConfig.fwdUrl.startsWith(baseUrl)) {
32
+ card.cardAction.value += `&fwdUrl=${botMagicCodeConfig.fwdUrl}`;
33
+ }
34
+ }
35
+ }
36
+
37
+ return next(...args);
38
+ };
39
+
40
+ return cardActionMiddleware;
41
+ };
@@ -0,0 +1,94 @@
1
+ import "@testing-library/jest-dom/extend-expect";
2
+ import { createCardActionMiddleware } from "./cardActionMiddleware";
3
+ describe("cardActionMiddleware test", () => {
4
+ it("createCardActionMiddleware() with undefined botMagicCodeConfig should not change the sign in card url", () => {
5
+ const next = args => args; // eslint-disable-line @typescript-eslint/no-explicit-any
6
+
7
+
8
+ const signInUrl = "https://token.botframework.com/api/oauth/signin?signin=[signin]";
9
+ const args = {
10
+ cardAction: {
11
+ type: "signin",
12
+ value: signInUrl
13
+ }
14
+ };
15
+ const results = createCardActionMiddleware(undefined)()(next)(args);
16
+ expect(signInUrl).toEqual(results.cardAction.value);
17
+ });
18
+ it("createCardActionMiddleware() with botMagicCode enabled should not change the sign in card url", () => {
19
+ const botMagicCodeConfig = {
20
+ disabled: false
21
+ };
22
+
23
+ const next = args => args; // eslint-disable-line @typescript-eslint/no-explicit-any
24
+
25
+
26
+ const signInUrl = "https://token.botframework.com/api/oauth/signin?signin=[signin]";
27
+ const args = {
28
+ cardAction: {
29
+ type: "signin",
30
+ value: signInUrl
31
+ }
32
+ };
33
+ const results = createCardActionMiddleware(botMagicCodeConfig)()(next)(args);
34
+ expect(args.cardAction.value).toEqual(results.cardAction.value);
35
+ });
36
+ it("createCardActionMiddleware() with botMagicCode disabled & no fwdUrl should not change the sign in card url", () => {
37
+ const botMagicCodeConfig = {
38
+ disabled: true
39
+ };
40
+
41
+ const next = args => args; // eslint-disable-line @typescript-eslint/no-explicit-any
42
+
43
+
44
+ const signInUrl = "https://token.botframework.com/api/oauth/signin?signin=[signin]";
45
+ const args = {
46
+ cardAction: {
47
+ type: "signin",
48
+ value: signInUrl
49
+ }
50
+ };
51
+ const results = createCardActionMiddleware(botMagicCodeConfig)()(next)(args);
52
+ expect(args.cardAction.value).toEqual(results.cardAction.value);
53
+ });
54
+ it("createCardActionMiddleware() with botMagicCode disabled & fwdUrl should append the fwdUrl in the sign in card url", () => {
55
+ const botMagicCodeConfig = {
56
+ disabled: true,
57
+ fwdUrl: "http://localhost/forwarder.html"
58
+ };
59
+
60
+ const next = args => args; // eslint-disable-line @typescript-eslint/no-explicit-any
61
+
62
+
63
+ const signInUrl = "https://token.botframework.com/api/oauth/signin?signin=[signin]";
64
+ const args = {
65
+ cardAction: {
66
+ type: "signin",
67
+ value: signInUrl
68
+ }
69
+ };
70
+ const results = createCardActionMiddleware(botMagicCodeConfig)()(next)(args);
71
+ expect(signInUrl === results.cardAction.value).toBe(false);
72
+ expect(results.cardAction.value === `${signInUrl}&fwdUrl=${botMagicCodeConfig.fwdUrl}`).toBe(true);
73
+ });
74
+ it("createCardActionMiddleware() should not append fwdUrl if fwdUrl & sign in card url are not in the same domain", () => {
75
+ const botMagicCodeConfig = {
76
+ disabled: true,
77
+ fwdUrl: "https://localhost/forwarder.html"
78
+ };
79
+
80
+ const next = args => args; // eslint-disable-line @typescript-eslint/no-explicit-any
81
+
82
+
83
+ const signInUrl = "https://token.botframework.com/api/oauth/signin?signin=[signin]";
84
+ const args = {
85
+ cardAction: {
86
+ type: "signin",
87
+ value: signInUrl
88
+ }
89
+ };
90
+ const results = createCardActionMiddleware(botMagicCodeConfig)()(next)(args);
91
+ expect(signInUrl === results.cardAction.value).toBe(true);
92
+ expect(results.cardAction.value === `${signInUrl}&fwdUrl=${botMagicCodeConfig.fwdUrl}`).toBe(false);
93
+ });
94
+ });