@microsoft/omnichannel-chat-widget 1.2.3-main.f8e3363 → 1.2.3

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 (18) hide show
  1. package/lib/cjs/common/telemetry/TelemetryConstants.js +1 -0
  2. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +4 -1
  3. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +12 -7
  4. package/lib/cjs/components/livechatwidget/common/startChat.js +6 -5
  5. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -15
  6. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +6 -3
  7. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.spec.js +190 -0
  8. package/lib/esm/common/telemetry/TelemetryConstants.js +1 -0
  9. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +4 -1
  10. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +12 -7
  11. package/lib/esm/components/livechatwidget/common/startChat.js +6 -5
  12. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -15
  13. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +6 -3
  14. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.spec.js +188 -0
  15. package/lib/types/common/telemetry/TelemetryConstants.d.ts +1 -0
  16. package/lib/types/components/livechatwidget/common/reconnectChatHelper.d.ts +1 -1
  17. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.spec.d.ts +1 -0
  18. package/package.json +1 -1
@@ -164,6 +164,7 @@ exports.TelemetryEvent = TelemetryEvent;
164
164
  TelemetryEvent["SetBotAuthProviderHideCard"] = "SetBotAuthProviderHideCard";
165
165
  TelemetryEvent["SetBotAuthProviderDisplayCard"] = "SetBotAuthProviderDisplayCard";
166
166
  TelemetryEvent["SetBotAuthProviderNotFound"] = "SetBotAuthProviderNotFound";
167
+ TelemetryEvent["BotAuthActivityUndefinedSignInId"] = "BotAuthActivityUndefinedSignInId";
167
168
  TelemetryEvent["ThirdPartyCookiesBlocked"] = "ThirdPartyCookiesBlocked";
168
169
  TelemetryEvent["ProcessingHTMLTextMiddlewareFailed"] = "ProcessingHTMLTextMiddlewareFailed";
169
170
  TelemetryEvent["ProcessingSanitizationMiddlewareFailed"] = "ProcessingSanitizationMiddlewareFailed";
@@ -83,7 +83,10 @@ class BotAuthActivitySubscriber {
83
83
  const signInUrl = attachment.content.buttons[0].value;
84
84
  const signInId = extractSignInId(signInUrl);
85
85
  if (!signInId) {
86
- return;
86
+ _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
87
+ Event: _TelemetryConstants.TelemetryEvent.BotAuthActivityUndefinedSignInId
88
+ });
89
+ return activity;
87
90
  }
88
91
  if (this.signInCardSeen.has(signInId)) {
89
92
  // Prevents duplicate auth
@@ -13,10 +13,11 @@ var _Constants = require("../../../common/Constants");
13
13
  var _ConversationState = require("../../../contexts/common/ConversationState");
14
14
  var _LiveChatWidgetActionType = require("../../../contexts/common/LiveChatWidgetActionType");
15
15
  var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
16
+ // Return value: should start normal chat flow when reconnect is enabled
16
17
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
18
  const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initStartChat, state) => {
18
19
  var _props$chatConfig, _props$chatConfig$Liv;
19
- if (!isReconnectEnabled(props.chatConfig) || isPersistentEnabled(props.chatConfig)) return;
20
+ if (!isReconnectEnabled(props.chatConfig) || isPersistentEnabled(props.chatConfig)) return false;
20
21
 
21
22
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
23
  const isAuthenticatedChat = (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
@@ -28,14 +29,14 @@ const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initSta
28
29
  if (reconnectChatContext !== null && reconnectChatContext !== void 0 && reconnectChatContext.redirectURL) {
29
30
  var _props$reconnectChatP;
30
31
  redirectPage(reconnectChatContext.redirectURL, (_props$reconnectChatP = props.reconnectChatPaneProps) === null || _props$reconnectChatP === void 0 ? void 0 : _props$reconnectChatP.redirectInSameWindow);
31
- return;
32
+ return false;
32
33
  }
33
34
  if (hasReconnectId(reconnectChatContext)) {
34
35
  var _props$reconnectChatP2, _props$reconnectChatP3;
35
36
  //if reconnect id is provided in props, don't show reconnect pane
36
37
  if ((_props$reconnectChatP2 = props.reconnectChatPaneProps) !== null && _props$reconnectChatP2 !== void 0 && _props$reconnectChatP2.reconnectId && !(0, _utils.isNullOrEmptyString)((_props$reconnectChatP3 = props.reconnectChatPaneProps) === null || _props$reconnectChatP3 === void 0 ? void 0 : _props$reconnectChatP3.reconnectId)) {
37
- await setReconnectIdAndStartChat(isAuthenticatedChat, chatSDK, props, dispatch, setAdapter, reconnectChatContext.reconnectId ?? "", initStartChat);
38
- return;
38
+ await setReconnectIdAndStartChat(isAuthenticatedChat, chatSDK, state, props, dispatch, setAdapter, reconnectChatContext.reconnectId ?? "", initStartChat);
39
+ return false;
39
40
  }
40
41
 
41
42
  //show reconnect pane
@@ -48,8 +49,12 @@ const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initSta
48
49
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
49
50
  payload: _ConversationState.ConversationState.ReconnectChat
50
51
  });
51
- return;
52
+ return false;
52
53
  }
54
+
55
+ // If we have reached this point, it means there is no valid reconnect id or redirectUrl
56
+ // This is a unauth reconnect refresh scenario - returns true so that we can start normal hydration process
57
+ return true;
53
58
  };
54
59
 
55
60
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -88,7 +93,7 @@ const getChatReconnectContext = async (chatSDK, chatConfig, props, isAuthenticat
88
93
 
89
94
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
95
  exports.getChatReconnectContext = getChatReconnectContext;
91
- const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, props, dispatch, setAdapter, reconnectId, initStartChat) => {
96
+ const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, state, props, dispatch, setAdapter, reconnectId, initStartChat) => {
92
97
  if (!isAuthenticatedChat) {
93
98
  const startUnauthenticatedReconnectChat = {
94
99
  eventName: _TelemetryConstants.BroadcastEvent.StartUnauthenticatedReconnectChat
@@ -106,7 +111,7 @@ const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, props, d
106
111
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
107
112
  payload: _ConversationState.ConversationState.Loading
108
113
  });
109
- await initStartChat(chatSDK, dispatch, setAdapter, props, optionalParams);
114
+ await initStartChat(chatSDK, dispatch, setAdapter, state, props, optionalParams);
110
115
  };
111
116
  const redirectPage = (redirectURL, redirectInSameWindow) => {
112
117
  const redirectPageRequest = {
@@ -303,16 +303,17 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
303
303
 
304
304
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
305
305
  const setCustomContextParams = async (state, props) => {
306
- var _props$chatConfig, _props$chatConfig$Liv, _persistedState$domai8;
306
+ var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates, _persistedState$domai8;
307
307
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
308
308
  const isAuthenticatedChat = props !== null && props !== void 0 && (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
309
309
  //Should not set custom context for auth chat
310
310
  if (isAuthenticatedChat) {
311
311
  return;
312
312
  }
313
- if (state !== null && state !== void 0 && state.domainStates.customContext) {
313
+ if (state !== null && state !== void 0 && (_state$domainStates = state.domainStates) !== null && _state$domainStates !== void 0 && _state$domainStates.customContext) {
314
+ var _state$domainStates2;
314
315
  optionalParams = Object.assign({}, optionalParams, {
315
- customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : state.domainStates.customContext))
316
+ customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.customContext))
316
317
  });
317
318
  return;
318
319
  }
@@ -360,8 +361,8 @@ const canStartPopoutChat = async props => {
360
361
 
361
362
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
362
363
  const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
363
- var _state$domainStates, _state$domainStates$l;
364
- const requestIdFromCache = (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$l = _state$domainStates.liveChatContext) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.requestId;
364
+ var _state$domainStates3, _state$domainStates3$;
365
+ const requestIdFromCache = (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.liveChatContext) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.requestId;
365
366
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
366
367
  let conversationDetails = undefined;
367
368
 
@@ -116,6 +116,16 @@ const LiveChatWidgetStateful = props => {
116
116
 
117
117
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
118
  const startChat = async (props, localState) => {
119
+ const isReconnectTriggered = async () => {
120
+ if ((0, _reconnectChatHelper.isReconnectEnabled)(props.chatConfig) === true && !(0, _reconnectChatHelper.isPersistentEnabled)(props.chatConfig)) {
121
+ const noValidReconnectId = await (0, _reconnectChatHelper.handleChatReconnect)(chatSDK, props, dispatch, setAdapter, _startChat.initStartChat, state);
122
+ // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
123
+ if (!noValidReconnectId && (state.appStates.conversationState === _ConversationState.ConversationState.Active || state.appStates.conversationState === _ConversationState.ConversationState.ReconnectChat)) {
124
+ return true;
125
+ }
126
+ }
127
+ return false;
128
+ };
119
129
  let isChatValid = false;
120
130
  //Start a chat from cache/reconnectid
121
131
  if (activeCachedChatExist === true) {
@@ -130,29 +140,20 @@ const LiveChatWidgetStateful = props => {
130
140
  //Check if conversation state is not in wrapup or closed state
131
141
  isChatValid = await (0, _startChat.checkIfConversationStillValid)(chatSDK, dispatch, state);
132
142
  if (isChatValid === true) {
133
- //Check if reconnect enabled
134
- if ((0, _reconnectChatHelper.isReconnectEnabled)(props.chatConfig) === true && !(0, _reconnectChatHelper.isPersistentEnabled)(props.chatConfig)) {
135
- await (0, _reconnectChatHelper.handleChatReconnect)(chatSDK, props, dispatch, setAdapter, _startChat.initStartChat, state);
136
- // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
137
- if (state.appStates.conversationState === _ConversationState.ConversationState.Active || state.appStates.conversationState === _ConversationState.ConversationState.ReconnectChat) {
138
- return;
139
- }
143
+ const reconnectTriggered = await isReconnectTriggered();
144
+ if (!reconnectTriggered) {
145
+ await (0, _startChat.initStartChat)(chatSDK, dispatch, setAdapter, state, props, optionalParams);
140
146
  }
141
- await (0, _startChat.initStartChat)(chatSDK, dispatch, setAdapter, state, props, optionalParams);
142
147
  return;
143
148
  }
144
149
  }
145
150
  if (isChatValid === false) {
146
151
  if (localState) {
147
152
  // adding the reconnect logic for the case when customer tries to reconnect from a new browser or InPrivate browser
148
- if ((0, _reconnectChatHelper.isReconnectEnabled)(props.chatConfig) === true && !(0, _reconnectChatHelper.isPersistentEnabled)(props.chatConfig)) {
149
- await (0, _reconnectChatHelper.handleChatReconnect)(chatSDK, props, dispatch, setAdapter, _startChat.initStartChat, state);
150
- // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
151
- if (state.appStates.conversationState === _ConversationState.ConversationState.Active || state.appStates.conversationState === _ConversationState.ConversationState.ReconnectChat) {
152
- return;
153
- }
153
+ const reconnectTriggered = await isReconnectTriggered();
154
+ if (!reconnectTriggered) {
155
+ await (0, _startChat.setPreChatAndInitiateChat)(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
154
156
  }
155
- await (0, _startChat.setPreChatAndInitiateChat)(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
156
157
  return;
157
158
  } else {
158
159
  var _state$appStates4;
@@ -51,12 +51,15 @@ const handleSystemMessage = (next, args, card, systemMessageStyleProps) => {
51
51
  return () => false;
52
52
  }
53
53
 
54
- // eslint-disable-next-line react/display-name, @typescript-eslint/no-explicit-any
54
+ // eslint-disable-next-line react/display-name
55
55
  return () => /*#__PURE__*/_react.default.createElement("div", {
56
56
  key: card.activity.id,
57
57
  style: systemMessageStyles,
58
- "aria-hidden": "true"
59
- }, card.activity.text);
58
+ "aria-hidden": "true",
59
+ dangerouslySetInnerHTML: {
60
+ __html: (0, _utils.escapeHtml)(card.activity.text)
61
+ }
62
+ });
60
63
  };
61
64
 
62
65
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+
3
+ var _Constants = require("../../../../../common/Constants");
4
+ var _DirectLineActivityType = require("../../enums/DirectLineActivityType");
5
+ var _DirectLineSenderRole = require("../../enums/DirectLineSenderRole");
6
+ var _MessageType = require("../../enums/MessageType");
7
+ var _TelemetryHelper = require("../../../../../common/telemetry/TelemetryHelper");
8
+ var _activityMiddleware = require("./activityMiddleware");
9
+ describe("activityMiddleware test", () => {
10
+ it("createActivityMiddleware() with Channel role sender should returns nothing", () => {
11
+ spyOn(_TelemetryHelper.TelemetryHelper, "logActionEvent").and.callFake(() => false);
12
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
13
+ const args = {
14
+ activity: {
15
+ channelData: {
16
+ type: _MessageType.MessageTypes.Thread
17
+ },
18
+ from: {
19
+ role: _DirectLineSenderRole.DirectLineSenderRole.Channel
20
+ }
21
+ }
22
+ };
23
+ const results = (0, _activityMiddleware.createActivityMiddleware)()()(next)(args);
24
+ expect(results()).toEqual(false);
25
+ expect(_TelemetryHelper.TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(1);
26
+ });
27
+ it("createActivityMiddleware() with Hidden tag should return nothing", () => {
28
+ spyOn(_TelemetryHelper.TelemetryHelper, "logActionEvent").and.callFake(() => false);
29
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
30
+ const args = {
31
+ activity: {
32
+ channelData: {
33
+ tags: [_Constants.Constants.hiddenTag]
34
+ },
35
+ from: {
36
+ role: _DirectLineSenderRole.DirectLineSenderRole.User
37
+ }
38
+ }
39
+ };
40
+ const results = (0, _activityMiddleware.createActivityMiddleware)()()(next)(args);
41
+ expect(results()).toEqual(false);
42
+ expect(_TelemetryHelper.TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(0);
43
+ });
44
+ it("createActivityMiddleware() with System tag should return system message", () => {
45
+ var _results$props, _results$props$danger;
46
+ spyOn(_TelemetryHelper.TelemetryHelper, "logActionEvent").and.callFake(() => false);
47
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
48
+ const systemMessage = "system message";
49
+ const args = {
50
+ activity: {
51
+ text: systemMessage,
52
+ channelData: {
53
+ tags: [_Constants.Constants.systemMessageTag]
54
+ },
55
+ from: {
56
+ role: _DirectLineSenderRole.DirectLineSenderRole.User
57
+ }
58
+ }
59
+ };
60
+ const results = (0, _activityMiddleware.createActivityMiddleware)()()(next)(args);
61
+ expect(_TelemetryHelper.TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(0);
62
+ expect((_results$props = results().props) === null || _results$props === void 0 ? void 0 : (_results$props$danger = _results$props.dangerouslySetInnerHTML) === null || _results$props$danger === void 0 ? void 0 : _results$props$danger.__html).toEqual(systemMessage);
63
+ });
64
+ it("createActivityMiddleware() should escape html texts to prevent XSS attacks", () => {
65
+ var _results$props2, _results$props2$dange;
66
+ spyOn(_TelemetryHelper.TelemetryHelper, "logActionEvent").and.callFake(() => false);
67
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
68
+ const systemMessage = "<img src='' onerror=\"alert('XSS attack')\"/>";
69
+ const args = {
70
+ activity: {
71
+ text: systemMessage,
72
+ channelData: {
73
+ tags: [_Constants.Constants.systemMessageTag]
74
+ },
75
+ from: {
76
+ role: _DirectLineSenderRole.DirectLineSenderRole.User
77
+ }
78
+ }
79
+ };
80
+ const results = (0, _activityMiddleware.createActivityMiddleware)()()(next)(args);
81
+ expect(_TelemetryHelper.TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(0);
82
+ expect((_results$props2 = results().props) === null || _results$props2 === void 0 ? void 0 : (_results$props2$dange = _results$props2.dangerouslySetInnerHTML) === null || _results$props2$dange === void 0 ? void 0 : _results$props2$dange.__html).toEqual("&lt;img src=&#39;&#39; onerror=&quot;alert(&#39;XSS attack&#39;)&quot;&#x2F;&gt;");
83
+ });
84
+ it("createActivityMiddleware() with QueuePosition tag should log QueuePosition message", () => {
85
+ spyOn(_TelemetryHelper.TelemetryHelper, "logActionEvent").and.callFake(() => false);
86
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
87
+ const systemMessage = "system message";
88
+ const args = {
89
+ activity: {
90
+ text: systemMessage,
91
+ channelData: {
92
+ tags: [_Constants.Constants.systemMessageTag, _Constants.Constants.queuePositionMessageTag]
93
+ },
94
+ from: {
95
+ role: _DirectLineSenderRole.DirectLineSenderRole.User
96
+ }
97
+ }
98
+ };
99
+ (0, _activityMiddleware.createActivityMiddleware)()()(next)(args);
100
+ expect(_TelemetryHelper.TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(1);
101
+ });
102
+ it("createActivityMiddleware() with same clientmessageid with next activity should return nothing", () => {
103
+ spyOn(_TelemetryHelper.TelemetryHelper, "logActionEvent").and.callFake(() => false);
104
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
105
+ const systemMessage = "system message";
106
+ const args = {
107
+ activity: {
108
+ text: systemMessage,
109
+ channelData: {
110
+ tags: [_Constants.Constants.systemMessageTag],
111
+ clientmessageid: "1234"
112
+ },
113
+ from: {
114
+ role: _DirectLineSenderRole.DirectLineSenderRole.User
115
+ }
116
+ },
117
+ nextVisibleActivity: {
118
+ channelData: {
119
+ clientmessageid: "1234"
120
+ }
121
+ }
122
+ };
123
+ const results = (0, _activityMiddleware.createActivityMiddleware)()()(next)(args);
124
+ expect(results()).toEqual(false);
125
+ });
126
+ it("createActivityMiddleware() with same messageid with next activity should return nothing", () => {
127
+ spyOn(_TelemetryHelper.TelemetryHelper, "logActionEvent").and.callFake(() => false);
128
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
129
+ const systemMessage = "system message";
130
+ const args = {
131
+ activity: {
132
+ text: systemMessage,
133
+ channelData: {
134
+ tags: [_Constants.Constants.systemMessageTag]
135
+ },
136
+ from: {
137
+ role: _DirectLineSenderRole.DirectLineSenderRole.User
138
+ },
139
+ messageid: "1234"
140
+ },
141
+ nextVisibleActivity: {
142
+ messageid: "1234"
143
+ }
144
+ };
145
+ const results = (0, _activityMiddleware.createActivityMiddleware)()()(next)(args);
146
+ expect(results()).toEqual(false);
147
+ });
148
+ it("createActivityMiddleware() should render normal user messages", () => {
149
+ var _results$props3, _results$props3$child, _results$props3$child2;
150
+ spyOn(_TelemetryHelper.TelemetryHelper, "logActionEvent").and.callFake(() => false);
151
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
152
+ const userMessage = "Hello World";
153
+ const args = {
154
+ activity: {
155
+ text: userMessage,
156
+ channelId: "webchat",
157
+ channelData: {
158
+ isHtmlEncoded: false
159
+ },
160
+ from: {
161
+ role: _DirectLineSenderRole.DirectLineSenderRole.User
162
+ },
163
+ type: _DirectLineActivityType.DirectLineActivityType.Message
164
+ }
165
+ };
166
+ const results = (0, _activityMiddleware.createActivityMiddleware)()()(next)(args);
167
+ expect((_results$props3 = results().props) === null || _results$props3 === void 0 ? void 0 : (_results$props3$child = _results$props3.children) === null || _results$props3$child === void 0 ? void 0 : (_results$props3$child2 = _results$props3$child.activity) === null || _results$props3$child2 === void 0 ? void 0 : _results$props3$child2.text).toEqual(userMessage);
168
+ });
169
+ it("createActivityMiddleware() should not render typing messages", () => {
170
+ var _results$activity;
171
+ spyOn(_TelemetryHelper.TelemetryHelper, "logActionEvent").and.callFake(() => false);
172
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
173
+ const userMessage = "Hello World";
174
+ const args = {
175
+ activity: {
176
+ text: userMessage,
177
+ channelId: "webchat",
178
+ channelData: {
179
+ isHtmlEncoded: false
180
+ },
181
+ from: {
182
+ role: _DirectLineSenderRole.DirectLineSenderRole.User
183
+ },
184
+ type: _DirectLineActivityType.DirectLineActivityType.Typing
185
+ }
186
+ };
187
+ const results = (0, _activityMiddleware.createActivityMiddleware)()()(next)(args);
188
+ expect((_results$activity = results().activity) === null || _results$activity === void 0 ? void 0 : _results$activity.text).toEqual(userMessage);
189
+ });
190
+ });
@@ -158,6 +158,7 @@ export let TelemetryEvent;
158
158
  TelemetryEvent["SetBotAuthProviderHideCard"] = "SetBotAuthProviderHideCard";
159
159
  TelemetryEvent["SetBotAuthProviderDisplayCard"] = "SetBotAuthProviderDisplayCard";
160
160
  TelemetryEvent["SetBotAuthProviderNotFound"] = "SetBotAuthProviderNotFound";
161
+ TelemetryEvent["BotAuthActivityUndefinedSignInId"] = "BotAuthActivityUndefinedSignInId";
161
162
  TelemetryEvent["ThirdPartyCookiesBlocked"] = "ThirdPartyCookiesBlocked";
162
163
  TelemetryEvent["ProcessingHTMLTextMiddlewareFailed"] = "ProcessingHTMLTextMiddlewareFailed";
163
164
  TelemetryEvent["ProcessingSanitizationMiddlewareFailed"] = "ProcessingSanitizationMiddlewareFailed";
@@ -79,7 +79,10 @@ export class BotAuthActivitySubscriber {
79
79
  const signInUrl = attachment.content.buttons[0].value;
80
80
  const signInId = extractSignInId(signInUrl);
81
81
  if (!signInId) {
82
- return;
82
+ TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
83
+ Event: TelemetryEvent.BotAuthActivityUndefinedSignInId
84
+ });
85
+ return activity;
83
86
  }
84
87
  if (this.signInCardSeen.has(signInId)) {
85
88
  // Prevents duplicate auth
@@ -8,10 +8,11 @@ import { ConversationState } from "../../../contexts/common/ConversationState";
8
8
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
9
9
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
10
10
 
11
+ // Return value: should start normal chat flow when reconnect is enabled
11
12
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
13
  const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initStartChat, state) => {
13
14
  var _props$chatConfig, _props$chatConfig$Liv;
14
- if (!isReconnectEnabled(props.chatConfig) || isPersistentEnabled(props.chatConfig)) return;
15
+ if (!isReconnectEnabled(props.chatConfig) || isPersistentEnabled(props.chatConfig)) return false;
15
16
 
16
17
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
18
  const isAuthenticatedChat = (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
@@ -23,14 +24,14 @@ const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initSta
23
24
  if (reconnectChatContext !== null && reconnectChatContext !== void 0 && reconnectChatContext.redirectURL) {
24
25
  var _props$reconnectChatP;
25
26
  redirectPage(reconnectChatContext.redirectURL, (_props$reconnectChatP = props.reconnectChatPaneProps) === null || _props$reconnectChatP === void 0 ? void 0 : _props$reconnectChatP.redirectInSameWindow);
26
- return;
27
+ return false;
27
28
  }
28
29
  if (hasReconnectId(reconnectChatContext)) {
29
30
  var _props$reconnectChatP2, _props$reconnectChatP3;
30
31
  //if reconnect id is provided in props, don't show reconnect pane
31
32
  if ((_props$reconnectChatP2 = props.reconnectChatPaneProps) !== null && _props$reconnectChatP2 !== void 0 && _props$reconnectChatP2.reconnectId && !isNullOrEmptyString((_props$reconnectChatP3 = props.reconnectChatPaneProps) === null || _props$reconnectChatP3 === void 0 ? void 0 : _props$reconnectChatP3.reconnectId)) {
32
- await setReconnectIdAndStartChat(isAuthenticatedChat, chatSDK, props, dispatch, setAdapter, reconnectChatContext.reconnectId ?? "", initStartChat);
33
- return;
33
+ await setReconnectIdAndStartChat(isAuthenticatedChat, chatSDK, state, props, dispatch, setAdapter, reconnectChatContext.reconnectId ?? "", initStartChat);
34
+ return false;
34
35
  }
35
36
 
36
37
  //show reconnect pane
@@ -43,8 +44,12 @@ const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initSta
43
44
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
44
45
  payload: ConversationState.ReconnectChat
45
46
  });
46
- return;
47
+ return false;
47
48
  }
49
+
50
+ // If we have reached this point, it means there is no valid reconnect id or redirectUrl
51
+ // This is a unauth reconnect refresh scenario - returns true so that we can start normal hydration process
52
+ return true;
48
53
  };
49
54
 
50
55
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -81,7 +86,7 @@ const getChatReconnectContext = async (chatSDK, chatConfig, props, isAuthenticat
81
86
  };
82
87
 
83
88
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
- const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, props, dispatch, setAdapter, reconnectId, initStartChat) => {
89
+ const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, state, props, dispatch, setAdapter, reconnectId, initStartChat) => {
85
90
  if (!isAuthenticatedChat) {
86
91
  const startUnauthenticatedReconnectChat = {
87
92
  eventName: BroadcastEvent.StartUnauthenticatedReconnectChat
@@ -99,7 +104,7 @@ const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, props, d
99
104
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
100
105
  payload: ConversationState.Loading
101
106
  });
102
- await initStartChat(chatSDK, dispatch, setAdapter, props, optionalParams);
107
+ await initStartChat(chatSDK, dispatch, setAdapter, state, props, optionalParams);
103
108
  };
104
109
  const redirectPage = (redirectURL, redirectInSameWindow) => {
105
110
  const redirectPageRequest = {
@@ -295,16 +295,17 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
295
295
 
296
296
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
297
297
  const setCustomContextParams = async (state, props) => {
298
- var _props$chatConfig, _props$chatConfig$Liv, _persistedState$domai8;
298
+ var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates, _persistedState$domai8;
299
299
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
300
300
  const isAuthenticatedChat = props !== null && props !== void 0 && (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
301
301
  //Should not set custom context for auth chat
302
302
  if (isAuthenticatedChat) {
303
303
  return;
304
304
  }
305
- if (state !== null && state !== void 0 && state.domainStates.customContext) {
305
+ if (state !== null && state !== void 0 && (_state$domainStates = state.domainStates) !== null && _state$domainStates !== void 0 && _state$domainStates.customContext) {
306
+ var _state$domainStates2;
306
307
  optionalParams = Object.assign({}, optionalParams, {
307
- customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : state.domainStates.customContext))
308
+ customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.customContext))
308
309
  });
309
310
  return;
310
311
  }
@@ -352,8 +353,8 @@ const canStartPopoutChat = async props => {
352
353
 
353
354
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
354
355
  const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
355
- var _state$domainStates, _state$domainStates$l;
356
- const requestIdFromCache = (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$l = _state$domainStates.liveChatContext) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.requestId;
356
+ var _state$domainStates3, _state$domainStates3$;
357
+ const requestIdFromCache = (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.liveChatContext) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.requestId;
357
358
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
358
359
  let conversationDetails = undefined;
359
360
 
@@ -108,6 +108,16 @@ export const LiveChatWidgetStateful = props => {
108
108
 
109
109
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
110
  const startChat = async (props, localState) => {
111
+ const isReconnectTriggered = async () => {
112
+ if (isReconnectEnabled(props.chatConfig) === true && !isPersistentEnabled(props.chatConfig)) {
113
+ const noValidReconnectId = await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
114
+ // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
115
+ if (!noValidReconnectId && (state.appStates.conversationState === ConversationState.Active || state.appStates.conversationState === ConversationState.ReconnectChat)) {
116
+ return true;
117
+ }
118
+ }
119
+ return false;
120
+ };
111
121
  let isChatValid = false;
112
122
  //Start a chat from cache/reconnectid
113
123
  if (activeCachedChatExist === true) {
@@ -122,29 +132,20 @@ export const LiveChatWidgetStateful = props => {
122
132
  //Check if conversation state is not in wrapup or closed state
123
133
  isChatValid = await checkIfConversationStillValid(chatSDK, dispatch, state);
124
134
  if (isChatValid === true) {
125
- //Check if reconnect enabled
126
- if (isReconnectEnabled(props.chatConfig) === true && !isPersistentEnabled(props.chatConfig)) {
127
- await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
128
- // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
129
- if (state.appStates.conversationState === ConversationState.Active || state.appStates.conversationState === ConversationState.ReconnectChat) {
130
- return;
131
- }
135
+ const reconnectTriggered = await isReconnectTriggered();
136
+ if (!reconnectTriggered) {
137
+ await initStartChat(chatSDK, dispatch, setAdapter, state, props, optionalParams);
132
138
  }
133
- await initStartChat(chatSDK, dispatch, setAdapter, state, props, optionalParams);
134
139
  return;
135
140
  }
136
141
  }
137
142
  if (isChatValid === false) {
138
143
  if (localState) {
139
144
  // adding the reconnect logic for the case when customer tries to reconnect from a new browser or InPrivate browser
140
- if (isReconnectEnabled(props.chatConfig) === true && !isPersistentEnabled(props.chatConfig)) {
141
- await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
142
- // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
143
- if (state.appStates.conversationState === ConversationState.Active || state.appStates.conversationState === ConversationState.ReconnectChat) {
144
- return;
145
- }
145
+ const reconnectTriggered = await isReconnectTriggered();
146
+ if (!reconnectTriggered) {
147
+ await setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
146
148
  }
147
- await setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
148
149
  return;
149
150
  } else {
150
151
  var _state$appStates4;
@@ -44,12 +44,15 @@ const handleSystemMessage = (next, args, card, systemMessageStyleProps) => {
44
44
  return () => false;
45
45
  }
46
46
 
47
- // eslint-disable-next-line react/display-name, @typescript-eslint/no-explicit-any
47
+ // eslint-disable-next-line react/display-name
48
48
  return () => /*#__PURE__*/React.createElement("div", {
49
49
  key: card.activity.id,
50
50
  style: systemMessageStyles,
51
- "aria-hidden": "true"
52
- }, card.activity.text);
51
+ "aria-hidden": "true",
52
+ dangerouslySetInnerHTML: {
53
+ __html: escapeHtml(card.activity.text)
54
+ }
55
+ });
53
56
  };
54
57
 
55
58
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -0,0 +1,188 @@
1
+ import { Constants } from "../../../../../common/Constants";
2
+ import { DirectLineActivityType } from "../../enums/DirectLineActivityType";
3
+ import { DirectLineSenderRole } from "../../enums/DirectLineSenderRole";
4
+ import { MessageTypes } from "../../enums/MessageType";
5
+ import { TelemetryHelper } from "../../../../../common/telemetry/TelemetryHelper";
6
+ import { createActivityMiddleware } from "./activityMiddleware";
7
+ describe("activityMiddleware test", () => {
8
+ it("createActivityMiddleware() with Channel role sender should returns nothing", () => {
9
+ spyOn(TelemetryHelper, "logActionEvent").and.callFake(() => false);
10
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
11
+ const args = {
12
+ activity: {
13
+ channelData: {
14
+ type: MessageTypes.Thread
15
+ },
16
+ from: {
17
+ role: DirectLineSenderRole.Channel
18
+ }
19
+ }
20
+ };
21
+ const results = createActivityMiddleware()()(next)(args);
22
+ expect(results()).toEqual(false);
23
+ expect(TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(1);
24
+ });
25
+ it("createActivityMiddleware() with Hidden tag should return nothing", () => {
26
+ spyOn(TelemetryHelper, "logActionEvent").and.callFake(() => false);
27
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
28
+ const args = {
29
+ activity: {
30
+ channelData: {
31
+ tags: [Constants.hiddenTag]
32
+ },
33
+ from: {
34
+ role: DirectLineSenderRole.User
35
+ }
36
+ }
37
+ };
38
+ const results = createActivityMiddleware()()(next)(args);
39
+ expect(results()).toEqual(false);
40
+ expect(TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(0);
41
+ });
42
+ it("createActivityMiddleware() with System tag should return system message", () => {
43
+ var _results$props, _results$props$danger;
44
+ spyOn(TelemetryHelper, "logActionEvent").and.callFake(() => false);
45
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
46
+ const systemMessage = "system message";
47
+ const args = {
48
+ activity: {
49
+ text: systemMessage,
50
+ channelData: {
51
+ tags: [Constants.systemMessageTag]
52
+ },
53
+ from: {
54
+ role: DirectLineSenderRole.User
55
+ }
56
+ }
57
+ };
58
+ const results = createActivityMiddleware()()(next)(args);
59
+ expect(TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(0);
60
+ expect((_results$props = results().props) === null || _results$props === void 0 ? void 0 : (_results$props$danger = _results$props.dangerouslySetInnerHTML) === null || _results$props$danger === void 0 ? void 0 : _results$props$danger.__html).toEqual(systemMessage);
61
+ });
62
+ it("createActivityMiddleware() should escape html texts to prevent XSS attacks", () => {
63
+ var _results$props2, _results$props2$dange;
64
+ spyOn(TelemetryHelper, "logActionEvent").and.callFake(() => false);
65
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
66
+ const systemMessage = "<img src='' onerror=\"alert('XSS attack')\"/>";
67
+ const args = {
68
+ activity: {
69
+ text: systemMessage,
70
+ channelData: {
71
+ tags: [Constants.systemMessageTag]
72
+ },
73
+ from: {
74
+ role: DirectLineSenderRole.User
75
+ }
76
+ }
77
+ };
78
+ const results = createActivityMiddleware()()(next)(args);
79
+ expect(TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(0);
80
+ expect((_results$props2 = results().props) === null || _results$props2 === void 0 ? void 0 : (_results$props2$dange = _results$props2.dangerouslySetInnerHTML) === null || _results$props2$dange === void 0 ? void 0 : _results$props2$dange.__html).toEqual("&lt;img src=&#39;&#39; onerror=&quot;alert(&#39;XSS attack&#39;)&quot;&#x2F;&gt;");
81
+ });
82
+ it("createActivityMiddleware() with QueuePosition tag should log QueuePosition message", () => {
83
+ spyOn(TelemetryHelper, "logActionEvent").and.callFake(() => false);
84
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
85
+ const systemMessage = "system message";
86
+ const args = {
87
+ activity: {
88
+ text: systemMessage,
89
+ channelData: {
90
+ tags: [Constants.systemMessageTag, Constants.queuePositionMessageTag]
91
+ },
92
+ from: {
93
+ role: DirectLineSenderRole.User
94
+ }
95
+ }
96
+ };
97
+ createActivityMiddleware()()(next)(args);
98
+ expect(TelemetryHelper.logActionEvent).toHaveBeenCalledTimes(1);
99
+ });
100
+ it("createActivityMiddleware() with same clientmessageid with next activity should return nothing", () => {
101
+ spyOn(TelemetryHelper, "logActionEvent").and.callFake(() => false);
102
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
103
+ const systemMessage = "system message";
104
+ const args = {
105
+ activity: {
106
+ text: systemMessage,
107
+ channelData: {
108
+ tags: [Constants.systemMessageTag],
109
+ clientmessageid: "1234"
110
+ },
111
+ from: {
112
+ role: DirectLineSenderRole.User
113
+ }
114
+ },
115
+ nextVisibleActivity: {
116
+ channelData: {
117
+ clientmessageid: "1234"
118
+ }
119
+ }
120
+ };
121
+ const results = createActivityMiddleware()()(next)(args);
122
+ expect(results()).toEqual(false);
123
+ });
124
+ it("createActivityMiddleware() with same messageid with next activity should return nothing", () => {
125
+ spyOn(TelemetryHelper, "logActionEvent").and.callFake(() => false);
126
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
127
+ const systemMessage = "system message";
128
+ const args = {
129
+ activity: {
130
+ text: systemMessage,
131
+ channelData: {
132
+ tags: [Constants.systemMessageTag]
133
+ },
134
+ from: {
135
+ role: DirectLineSenderRole.User
136
+ },
137
+ messageid: "1234"
138
+ },
139
+ nextVisibleActivity: {
140
+ messageid: "1234"
141
+ }
142
+ };
143
+ const results = createActivityMiddleware()()(next)(args);
144
+ expect(results()).toEqual(false);
145
+ });
146
+ it("createActivityMiddleware() should render normal user messages", () => {
147
+ var _results$props3, _results$props3$child, _results$props3$child2;
148
+ spyOn(TelemetryHelper, "logActionEvent").and.callFake(() => false);
149
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
150
+ const userMessage = "Hello World";
151
+ const args = {
152
+ activity: {
153
+ text: userMessage,
154
+ channelId: "webchat",
155
+ channelData: {
156
+ isHtmlEncoded: false
157
+ },
158
+ from: {
159
+ role: DirectLineSenderRole.User
160
+ },
161
+ type: DirectLineActivityType.Message
162
+ }
163
+ };
164
+ const results = createActivityMiddleware()()(next)(args);
165
+ expect((_results$props3 = results().props) === null || _results$props3 === void 0 ? void 0 : (_results$props3$child = _results$props3.children) === null || _results$props3$child === void 0 ? void 0 : (_results$props3$child2 = _results$props3$child.activity) === null || _results$props3$child2 === void 0 ? void 0 : _results$props3$child2.text).toEqual(userMessage);
166
+ });
167
+ it("createActivityMiddleware() should not render typing messages", () => {
168
+ var _results$activity;
169
+ spyOn(TelemetryHelper, "logActionEvent").and.callFake(() => false);
170
+ const next = args => () => args; // eslint-disable-line @typescript-eslint/no-explicit-any
171
+ const userMessage = "Hello World";
172
+ const args = {
173
+ activity: {
174
+ text: userMessage,
175
+ channelId: "webchat",
176
+ channelData: {
177
+ isHtmlEncoded: false
178
+ },
179
+ from: {
180
+ role: DirectLineSenderRole.User
181
+ },
182
+ type: DirectLineActivityType.Typing
183
+ }
184
+ };
185
+ const results = createActivityMiddleware()()(next)(args);
186
+ expect((_results$activity = results().activity) === null || _results$activity === void 0 ? void 0 : _results$activity.text).toEqual(userMessage);
187
+ });
188
+ });
@@ -151,6 +151,7 @@ export declare enum TelemetryEvent {
151
151
  SetBotAuthProviderHideCard = "SetBotAuthProviderHideCard",
152
152
  SetBotAuthProviderDisplayCard = "SetBotAuthProviderDisplayCard",
153
153
  SetBotAuthProviderNotFound = "SetBotAuthProviderNotFound",
154
+ BotAuthActivityUndefinedSignInId = "BotAuthActivityUndefinedSignInId",
154
155
  ThirdPartyCookiesBlocked = "ThirdPartyCookiesBlocked",
155
156
  ProcessingHTMLTextMiddlewareFailed = "ProcessingHTMLTextMiddlewareFailed",
156
157
  ProcessingSanitizationMiddlewareFailed = "ProcessingSanitizationMiddlewareFailed",
@@ -3,7 +3,7 @@ import ChatConfig from "@microsoft/omnichannel-chat-sdk/lib/core/ChatConfig";
3
3
  import { Dispatch } from "react";
4
4
  import { ILiveChatWidgetAction } from "../../../contexts/common/ILiveChatWidgetAction";
5
5
  import { ILiveChatWidgetContext } from "../../../contexts/common/ILiveChatWidgetContext";
6
- declare const handleChatReconnect: (chatSDK: any, props: any, dispatch: Dispatch<ILiveChatWidgetAction>, setAdapter: any, initStartChat: any, state: ILiveChatWidgetContext) => Promise<void>;
6
+ declare const handleChatReconnect: (chatSDK: any, props: any, dispatch: Dispatch<ILiveChatWidgetAction>, setAdapter: any, initStartChat: any, state: ILiveChatWidgetContext) => Promise<boolean>;
7
7
  declare const getChatReconnectContext: (chatSDK: any, chatConfig: ChatConfig, props: any, isAuthenticatedChat: boolean) => Promise<any>;
8
8
  declare const isReconnectEnabled: (chatConfig?: ChatConfig | undefined) => boolean;
9
9
  declare const isPersistentEnabled: (chatConfig?: ChatConfig | undefined) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.2.3-main.f8e3363",
3
+ "version": "1.2.3",
4
4
  "description": "Microsoft Omnichannel Chat Widget",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",