@microsoft/omnichannel-chat-widget 0.1.0-main.8e79cb8 → 0.1.0-main.9e62ed8

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 (55) hide show
  1. package/README.md +32 -0
  2. package/lib/cjs/common/Constants.js +12 -0
  3. package/lib/cjs/common/telemetry/TelemetryConstants.js +14 -2
  4. package/lib/cjs/common/utils.js +1 -1
  5. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +15 -3
  6. package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +10 -1
  7. package/lib/cjs/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +7 -1
  8. package/lib/cjs/components/livechatwidget/common/endChat.js +3 -3
  9. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +8 -3
  10. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +129 -36
  11. package/lib/cjs/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +16 -0
  12. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +80 -0
  13. package/lib/cjs/components/webchatcontainerstateful/interfaces/IBotMagicCodeConfig.js +1 -0
  14. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/BotMagicCodeStore.js +14 -0
  15. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +16 -2
  16. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.js +52 -0
  17. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.spec.js +98 -0
  18. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware.js +117 -0
  19. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +2 -0
  20. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +2 -1
  21. package/lib/cjs/contexts/createReducer.js +8 -0
  22. package/lib/cjs/controller/componentController.js +1 -1
  23. package/lib/esm/common/Constants.js +12 -0
  24. package/lib/esm/common/telemetry/TelemetryConstants.js +14 -2
  25. package/lib/esm/common/utils.js +1 -1
  26. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +17 -6
  27. package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +8 -2
  28. package/lib/esm/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +7 -1
  29. package/lib/esm/components/livechatwidget/common/endChat.js +3 -2
  30. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +7 -4
  31. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +120 -35
  32. package/lib/esm/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +16 -0
  33. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +72 -0
  34. package/lib/esm/components/webchatcontainerstateful/interfaces/IBotMagicCodeConfig.js +1 -0
  35. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/BotMagicCodeStore.js +5 -0
  36. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +16 -2
  37. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.js +41 -0
  38. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.spec.js +94 -0
  39. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware.js +107 -0
  40. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +2 -0
  41. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +2 -1
  42. package/lib/esm/contexts/createReducer.js +8 -0
  43. package/lib/esm/controller/componentController.js +1 -1
  44. package/lib/types/common/Constants.d.ts +6 -0
  45. package/lib/types/common/interfaces/IContextDataStore.d.ts +1 -1
  46. package/lib/types/common/telemetry/TelemetryConstants.d.ts +15 -3
  47. package/lib/types/components/webchatcontainerstateful/interfaces/IBotMagicCodeConfig.d.ts +4 -0
  48. package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +2 -0
  49. package/lib/types/components/webchatcontainerstateful/webchatcontroller/BotMagicCodeStore.d.ts +3 -0
  50. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.d.ts +2 -0
  51. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.spec.d.ts +1 -0
  52. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware.d.ts +5 -0
  53. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  54. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +3 -1
  55. package/package.json +2 -2
@@ -316,7 +316,9 @@ export const dummyDefaultProps = {
316
316
  hideChatTextContainer: false,
317
317
  hideChatSubtitle: false,
318
318
  hideChatTitle: false,
319
- hideNotificationBubble: true
319
+ hideNotificationBubble: true,
320
+ unreadMessageString: "new messages",
321
+ largeUnreadMessageString: "99+"
320
322
  },
321
323
  styleProps: {
322
324
  generalStyleProps: {
@@ -1676,6 +1678,10 @@ export const dummyDefaultProps = {
1676
1678
  MIDDLEWARE_MESSAGE_RETRY: "Retry",
1677
1679
  PRECHAT_REQUIRED_FIELD_MISSING_MESSAGE: "{0} field is required",
1678
1680
  MARKDOWN_EXTERNAL_LINK_ALT: "Opens in a new window; external."
1681
+ },
1682
+ botMagicCode: {
1683
+ disabled: false,
1684
+ fwdUrl: ""
1679
1685
  }
1680
1686
  },
1681
1687
  telemetryConfig: undefined
@@ -91,8 +91,9 @@ const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, a
91
91
  type: LiveChatWidgetActionType.SET_AUDIO_NOTIFICATION,
92
92
  payload: null
93
93
  });
94
- BroadcastService.postMessage({
95
- eventName: BroadcastEvent.EndChat
94
+ dispatch({
95
+ type: LiveChatWidgetActionType.SET_UNREAD_MESSAGE_COUNT,
96
+ payload: 0
96
97
  });
97
98
 
98
99
  if (postMessageToOtherTab) {
@@ -26,10 +26,12 @@ 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";
31
+ import createMessageTimeStampMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
32
 
31
33
  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;
34
+ 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
35
 
34
36
  const localizedTexts = { ...defaultMiddlewareLocalizedTexts,
35
37
  ...((_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : _props$webChatContain.localizedTexts)
@@ -91,7 +93,7 @@ export const initWebChatComposer = (props, chatSDK, state, dispatch, setWebChatS
91
93
  };
92
94
 
93
95
  webChatStore = createStore({}, //initial state
94
- preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l5 = state.domainStates.liveChatConfig) === null || _state$domainStates$l5 === void 0 ? void 0 : _state$domainStates$l5.allowedFileExtensions, (_state$domainStates$l6 = state.domainStates.liveChatConfig) === null || _state$domainStates$l6 === void 0 ? void 0 : _state$domainStates$l6.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l7 = state.domainStates.liveChatConfig) === null || _state$domainStates$l7 === void 0 ? void 0 : _state$domainStates$l7.DataMaskingInfo), gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware, createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware, // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
+ preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l5 = state.domainStates.liveChatConfig) === null || _state$domainStates$l5 === void 0 ? void 0 : _state$domainStates$l5.allowedFileExtensions, (_state$domainStates$l6 = state.domainStates.liveChatConfig) === null || _state$domainStates$l6 === void 0 ? void 0 : _state$domainStates$l6.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l7 = state.domainStates.liveChatConfig) === null || _state$domainStates$l7 === void 0 ? void 0 : _state$domainStates$l7.DataMaskingInfo), createMessageTimeStampMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware, createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware, // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
97
  ...(((_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.storeMiddlewares) ?? []));
96
98
  WebChatStoreLoader.store = webChatStore;
97
99
  } // Initialize the remaining Web Chat props
@@ -109,7 +111,8 @@ export const initWebChatComposer = (props, chatSDK, state, dispatch, setWebChatS
109
111
  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
112
  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
113
  onTelemetry: createWebChatTelemetry(),
112
- ...((_props$webChatContain21 = props.webChatContainerProps) === null || _props$webChatContain21 === void 0 ? void 0 : _props$webChatContain21.webChatProps)
114
+ cardActionMiddleware: createCardActionMiddleware(((_props$webChatContain21 = props.webChatContainerProps) === null || _props$webChatContain21 === void 0 ? void 0 : _props$webChatContain21.botMagicCode) || undefined),
115
+ ...((_props$webChatContain22 = props.webChatContainerProps) === null || _props$webChatContain22 === void 0 ? void 0 : _props$webChatContain22.webChatProps)
113
116
  };
114
117
  return webChatProps;
115
118
  };
@@ -68,6 +68,36 @@ export const LiveChatWidgetStateful = props => {
68
68
  TelemetryTimers.LcwLoadToChatButtonTimer = createTimer();
69
69
  const widgetElementId = ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.id) || "oc-lcw";
70
70
  const currentMessageCountRef = useRef(0);
71
+ let widgetStateEventName = "";
72
+
73
+ const initiateEndChatOnBrowserUnload = () => {
74
+ var _DataStoreManager$cli;
75
+
76
+ const persistedState = getStateFromCache(); // End chat if the chat is still active and browser closed
77
+
78
+ if (persistedState.appStates.conversationState === ConversationState.Active) {
79
+ //Browser close scenario/no room for PCS/so just end chat and notify agent immidiately
80
+ endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, false);
81
+ } // Clean local storage
82
+
83
+
84
+ (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.removeData(widgetStateEventName, "localStorage");
85
+ BroadcastService.postMessage({
86
+ eventName: BroadcastEvent.ChatEnded
87
+ });
88
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
+
90
+
91
+ const getStateFromCache = () => {
92
+ var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _DataStoreManager$cli2;
93
+
94
+ // Getting updated state from cache
95
+ 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) ?? "");
96
+ const widgetStateFromCache = (_DataStoreManager$cli2 = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli2 === void 0 ? void 0 : _DataStoreManager$cli2.getData(widgetStateEventName, "localStorage");
97
+ const persistedState = widgetStateFromCache ? JSON.parse(widgetStateFromCache) : undefined;
98
+ return persistedState;
99
+ };
100
+
71
101
  useEffect(() => {
72
102
  var _props$controlProps2, _props$controlProps3, _props$reconnectChatP, _props$controlProps4, _props$chatConfig, _props$chatConfig$Cha, _state$domainStates;
73
103
 
@@ -114,11 +144,16 @@ export const LiveChatWidgetStateful = props => {
114
144
  };
115
145
  initStartChat(chatSDK, dispatch, setAdapter, optionalParams);
116
146
  }
117
- }, []);
147
+ }, []); // useEffect for when skip chat button rendering
148
+
118
149
  useEffect(() => {
119
150
  if (state.appStates.skipChatButtonRendering) {
120
151
  var _props$reconnectChatP3;
121
152
 
153
+ BroadcastService.postMessage({
154
+ eventName: BroadcastEvent.ChatInitiated
155
+ });
156
+
122
157
  if ((_props$reconnectChatP3 = props.reconnectChatPaneProps) !== null && _props$reconnectChatP3 !== void 0 && _props$reconnectChatP3.reconnectId && !state.appStates.reconnectId) {
123
158
  var _props$reconnectChatP4, _props$reconnectChatP5;
124
159
 
@@ -148,9 +183,10 @@ export const LiveChatWidgetStateful = props => {
148
183
  });
149
184
  }
150
185
  }
151
- }, [state.appStates.skipChatButtonRendering]);
186
+ }, [state.appStates.skipChatButtonRendering]); // useEffect for when skip chat button rendering
187
+
152
188
  useEffect(() => {
153
- var _chatSDK$omnichannelC, _chatSDK$omnichannelC2;
189
+ var _chatSDK$omnichannelC3, _chatSDK$omnichannelC4;
154
190
 
155
191
  // Add the custom context on receiving the SetCustomContext event
156
192
  BroadcastService.getMessageByEventName(BroadcastEvent.SetCustomContext).subscribe(msg => {
@@ -163,7 +199,7 @@ export const LiveChatWidgetStateful = props => {
163
199
  payload: msg === null || msg === void 0 ? void 0 : msg.payload
164
200
  });
165
201
  });
166
- BroadcastService.getMessageByEventName("StartProactiveChat").subscribe(msg => {
202
+ BroadcastService.getMessageByEventName(BroadcastEvent.StartProactiveChat).subscribe(msg => {
167
203
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
168
204
  Event: TelemetryEvent.StartProactiveChatEventReceived,
169
205
  Description: "Start proactive chat event received."
@@ -179,30 +215,46 @@ export const LiveChatWidgetStateful = props => {
179
215
  Description: "Start proactive chat method called, when chat was already triggered."
180
216
  });
181
217
  }
182
- }); // start chat from SDK Event
218
+ }); // Start chat from SDK Event
183
219
 
184
- BroadcastService.getMessageByEventName("StartChat").subscribe(() => {
220
+ BroadcastService.getMessageByEventName(BroadcastEvent.StartChat).subscribe(() => {
185
221
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
186
222
  Event: TelemetryEvent.StartChatEventRecevied,
187
223
  Description: "Start chat event received."
188
224
  });
225
+ const persistedState = getStateFromCache();
226
+
227
+ if (persistedState && (persistedState.appStates.conversationState === ConversationState.Closed || persistedState.appStates.conversationState === ConversationState.InActive || persistedState.appStates.conversationState === ConversationState.Postchat)) {
228
+ // Embedded mode
229
+ BroadcastService.postMessage({
230
+ eventName: BroadcastEvent.ChatInitiated
231
+ });
232
+ prepareStartChat(props, chatSDK, state, dispatch, setAdapter);
233
+ } else if (!persistedState) {
234
+ // Popout chat
235
+ BroadcastService.postMessage({
236
+ eventName: BroadcastEvent.ChatInitiated
237
+ });
238
+ prepareStartChat(props, chatSDK, state, dispatch, setAdapter);
239
+ } else {
240
+ var _persistedState$domai, _persistedState$domai2, _persistedState$domai3, _persistedState$domai4;
189
241
 
190
- if (state.appStates.isMinimized) {
242
+ // Minimize to Maximize
191
243
  dispatch({
192
244
  type: LiveChatWidgetActionType.SET_MINIMIZED,
193
245
  payload: false
194
246
  });
195
- } else {
196
- prepareStartChat(props, chatSDK, state, dispatch, setAdapter);
247
+ BroadcastService.postMessage({
248
+ eventName: BroadcastEvent.MaximizeChat,
249
+ payload: {
250
+ height: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai = persistedState.domainStates) === null || _persistedState$domai === void 0 ? void 0 : (_persistedState$domai2 = _persistedState$domai.widgetSize) === null || _persistedState$domai2 === void 0 ? void 0 : _persistedState$domai2.height,
251
+ width: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai3 = persistedState.domainStates) === null || _persistedState$domai3 === void 0 ? void 0 : (_persistedState$domai4 = _persistedState$domai3.widgetSize) === null || _persistedState$domai4 === void 0 ? void 0 : _persistedState$domai4.width
252
+ }
253
+ });
197
254
  }
198
- }); // end chat from SDK Event
199
-
200
- BroadcastService.getMessageByEventName("EndChat").subscribe(async () => {
201
- TelemetryHelper.logActionEvent(LogLevel.INFO, {
202
- Event: TelemetryEvent.EndChatEventReceived,
203
- Description: "End chat event received."
204
- });
255
+ }); // End chat
205
256
 
257
+ BroadcastService.getMessageByEventName(BroadcastEvent.InitiateEndChat).subscribe(async () => {
206
258
  if (canEndChat.current) {
207
259
  prepareEndChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state);
208
260
  } else {
@@ -210,22 +262,52 @@ export const LiveChatWidgetStateful = props => {
210
262
  const skipCloseChat = false;
211
263
  endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat);
212
264
  }
265
+
266
+ BroadcastService.postMessage({
267
+ eventName: BroadcastEvent.CloseChat
268
+ });
269
+ });
270
+ BroadcastService.getMessageByEventName(BroadcastEvent.InitiateEndChatOnBrowserUnload).subscribe(() => {
271
+ initiateEndChatOnBrowserUnload();
272
+ }); // reset proactive chat params
273
+
274
+ BroadcastService.getMessageByEventName(BroadcastEvent.ResetProactiveChatParams).subscribe(async () => {
275
+ dispatch({
276
+ type: LiveChatWidgetActionType.SET_PROACTIVE_CHAT_PARAMS,
277
+ payload: {
278
+ proactiveChatBodyTitle: "",
279
+ proactiveChatEnablePrechat: false,
280
+ proactiveChatInNewWindow: false
281
+ }
282
+ });
213
283
  }); // Listen to end chat event from other tabs
214
284
 
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);
285
+ const endChatEventName = getWidgetEndChatEventName(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC3 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC3 === void 0 ? void 0 : _chatSDK$omnichannelC3.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC4 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC4 === void 0 ? void 0 : _chatSDK$omnichannelC4.widgetId);
216
286
  BroadcastService.getMessageByEventName(endChatEventName).subscribe(async () => {
217
287
  endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, false);
218
- });
288
+ }); // Close popout window
289
+
219
290
  window.addEventListener("beforeunload", () => {
291
+ TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
292
+ Event: TelemetryEvent.WindowClosed,
293
+ Description: "Closed window."
294
+ });
220
295
  disposeTelemetryLoggers();
221
296
  });
222
297
 
223
298
  if (state.appStates.conversationEndedByAgent) {
224
299
  endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter);
225
- }
300
+ } //Listen to WidgetSize
301
+
302
+
303
+ BroadcastService.getMessageByEventName("WidgetSize").subscribe(msg => {
304
+ dispatch({
305
+ type: LiveChatWidgetActionType.SET_WIDGET_SIZE,
306
+ payload: msg === null || msg === void 0 ? void 0 : msg.payload
307
+ });
308
+ });
226
309
  }, []);
227
310
  useEffect(() => {
228
- canStartProactiveChat.current = state.appStates.conversationState === ConversationState.Closed;
229
311
  canEndChat.current = state.appStates.conversationState === ConversationState.Active;
230
312
 
231
313
  if (state.appStates.conversationState === ConversationState.Active) {
@@ -246,7 +328,10 @@ export const LiveChatWidgetStateful = props => {
246
328
  });
247
329
  });
248
330
  }
249
- }, [state.appStates.conversationState]); // Reset the UnreadMessageCount when minimized is toggled and broadcast it.
331
+ }, [state.appStates.conversationState]);
332
+ useEffect(() => {
333
+ canStartProactiveChat.current = state.appStates.conversationState === ConversationState.Closed && !state.appStates.proactiveChatStates.proactiveChatInNewWindow;
334
+ }, [state.appStates.conversationState, state.appStates.proactiveChatStates.proactiveChatInNewWindow]); // Reset the UnreadMessageCount when minimized is toggled and broadcast it.
250
335
 
251
336
  useEffect(() => {
252
337
  currentMessageCountRef.current = -1;
@@ -278,7 +363,19 @@ export const LiveChatWidgetStateful = props => {
278
363
  setWebChatStyles({ ...webChatStyles,
279
364
  ...((_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : _props$webChatContain2.webChatStyles)
280
365
  });
281
- }, [(_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.webChatStyles]);
366
+ }, [(_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.webChatStyles]); // Publish chat widget state
367
+
368
+ useEffect(() => {
369
+ var _props$chatSDK, _props$chatSDK$omnich, _props$chatSDK2, _props$chatSDK2$omnic;
370
+
371
+ 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);
372
+ const chatWidgetStateChangeEvent = {
373
+ eventName: widgetStateEventName,
374
+ payload: { ...state
375
+ }
376
+ };
377
+ BroadcastService.postMessage(chatWidgetStateChangeEvent);
378
+ }, [state]);
282
379
  const webChatProps = initWebChatComposer(props, chatSDK, state, dispatch, setWebChatStyles);
283
380
 
284
381
  const setPostChatContextRelay = () => setPostChatContextAndLoadSurvey(chatSDK, dispatch); // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -294,19 +391,7 @@ export const LiveChatWidgetStateful = props => {
294
391
 
295
392
  const initStartChatRelay = (optionalParams, persistedState) => initStartChat(chatSDK, dispatch, setAdapter, optionalParams, persistedState);
296
393
 
297
- const confirmationPaneProps = initConfirmationPropsComposer(props); // publish chat widget state
298
-
299
- useEffect(() => {
300
- var _props$chatSDK, _props$chatSDK$omnich, _props$chatSDK2, _props$chatSDK2$omnic;
301
-
302
- 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);
303
- const chatWidgetStateChangeEvent = {
304
- eventName: widgetStateEventName,
305
- payload: { ...state
306
- }
307
- };
308
- BroadcastService.postMessage(chatWidgetStateChangeEvent);
309
- }, [state]);
394
+ const confirmationPaneProps = initConfirmationPropsComposer(props);
310
395
  return /*#__PURE__*/React.createElement(Composer, _extends({}, webChatProps, {
311
396
  styleOptions: webChatStyles,
312
397
  directLine: ((_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.directLine) ?? adapter ?? defaultWebChatContainerStatefulProps.directLine
@@ -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", "");
@@ -54,6 +54,16 @@ const handleSystemMessage = (next, args, card, systemMessageStyleProps) => {
54
54
  }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
55
 
56
56
 
57
+ const isTagIncluded = (card, tag) => {
58
+ return isDataTagsPresent(card) && card.activity.channelData.tags.includes(tag);
59
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
+
61
+
62
+ const isDataTagsPresent = card => {
63
+ return card && card.activity && card.activity.channelData && card.activity.channelData.tags && card.activity.channelData.tags.length > 0;
64
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+
66
+
57
67
  export const createActivityMiddleware = (systemMessageStyleProps, userMessageStyleProps) => () => next => function () {
58
68
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
59
69
  args[_key] = arguments[_key];
@@ -62,7 +72,7 @@ export const createActivityMiddleware = (systemMessageStyleProps, userMessageSty
62
72
  const [card] = args;
63
73
 
64
74
  if (card.activity) {
65
- var _card$activity$from, _card$activity$channe4, _card$activity$channe5;
75
+ var _card$activity$from;
66
76
 
67
77
  if (((_card$activity$from = card.activity.from) === null || _card$activity$from === void 0 ? void 0 : _card$activity$from.role) === DirectLineSenderRole.Channel) {
68
78
  var _card$activity$channe3;
@@ -77,7 +87,11 @@ export const createActivityMiddleware = (systemMessageStyleProps, userMessageSty
77
87
  return () => false;
78
88
  }
79
89
 
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)) {
90
+ if (isTagIncluded(card, Constants.hiddenTag)) {
91
+ return () => false;
92
+ }
93
+
94
+ if (isTagIncluded(card, Constants.systemMessageTag)) {
81
95
  return handleSystemMessage(next, args, card, systemMessageStyleProps);
82
96
  } else if (card.activity.text && card.activity.type === DirectLineActivityType.Message) {
83
97
  if (!card.activity.channelData.isHtmlEncoded && card.activity.channelId === Constants.webchatChannelId) {
@@ -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
+ });