@microsoft/omnichannel-chat-widget 1.0.4-main.6e79f24 → 1.0.4-main.d4abfe6

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.
@@ -112,6 +112,9 @@ _defineProperty(Constants, "SessionCacheSuffix", "session");
112
112
  _defineProperty(Constants, "PopoutCacheSuffix", "popout");
113
113
  // Visibility timeout for conversation details
114
114
  _defineProperty(Constants, "LWICheckOnVisibilityTimeout", 3 * 60 * 1000);
115
+ // 3 minute
116
+ // Popup mode custom context response event message name
117
+ _defineProperty(Constants, "InitContextParamsResponse", "initContextParamsResponse");
115
118
  const Regex = (_class = class Regex {}, _defineProperty(_class, "EmailRegex", "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"), _class);
116
119
  exports.Regex = Regex;
117
120
  class HtmlIdNames {}
@@ -107,7 +107,7 @@ exports.TelemetryEvent = TelemetryEvent;
107
107
  TelemetryEvent["ChatVisibilityChanged"] = "ChatVisibilityChanged";
108
108
  TelemetryEvent["EndChatSucceeded"] = "EndChatSucceeded";
109
109
  TelemetryEvent["EndChatFailed"] = "EndChatFailed";
110
- TelemetryEvent["SetCustomContext"] = "SetCustomContext";
110
+ TelemetryEvent["SettingCustomContext"] = "SettingCustomContext";
111
111
  TelemetryEvent["WebChatLoaded"] = "WebChatLoaded";
112
112
  TelemetryEvent["LCWChatButtonClicked"] = "LCWChatButtonClicked";
113
113
  TelemetryEvent["LCWChatButtonShow"] = "LCWChatButtonShow";
@@ -9,8 +9,6 @@ var _NotificationScenarios = require("../../webchatcontainerstateful/webchatcont
9
9
  var _NotificationHandler = require("../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler");
10
10
  var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
11
11
  var _TelemetryConstants = require("../../../common/telemetry/TelemetryConstants");
12
- var _dompurify = _interopRequireDefault(require("dompurify"));
13
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
12
  const processDisplayName = displayName => {
15
13
  // if displayname matches "teamsvisitor:<some alphanumeric string>", we replace it with "Customer"
16
14
  const displayNameRegex = ".+:.+";
@@ -66,8 +64,6 @@ const processContent = (transcriptContent, isAgentChat, renderMarkDown) => {
66
64
  }
67
65
  if (renderMarkDown) {
68
66
  transcriptContent = renderMarkDown(transcriptContent);
69
- } else {
70
- transcriptContent = _dompurify.default.sanitize(transcriptContent);
71
67
  }
72
68
  return transcriptContent;
73
69
  };
@@ -125,18 +125,12 @@ const endChat = async function (props, chatSDK, state, dispatch, setAdapter, set
125
125
  }
126
126
  });
127
127
  } finally {
128
- var _state$appStates3;
129
128
  dispatch({
130
129
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_UNREAD_MESSAGE_COUNT,
131
130
  payload: 0
132
131
  });
133
- //Always allow to close the chat for embedded mode irrespective of end chat errors
134
- if (!(state !== null && state !== void 0 && (_state$appStates3 = state.appStates) !== null && _state$appStates3 !== void 0 && _state$appStates3.hideStartChatButton)) {
135
- dispatch({
136
- type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
137
- payload: _ConversationState.ConversationState.Closed
138
- });
139
- }
132
+ // Always allow to close the chat for embedded mode irrespective of end chat errors
133
+ closeChatWidget(dispatch, props, state);
140
134
  }
141
135
  }
142
136
  if (postMessageToOtherTab && !(0, _utils.isNullOrEmptyString)(uwid)) {
@@ -150,10 +144,6 @@ const endChat = async function (props, chatSDK, state, dispatch, setAdapter, set
150
144
  exports.endChat = endChat;
151
145
  const endChatStateCleanUp = async dispatch => {
152
146
  // Need to clear these states immediately when chat ended from OC.
153
- dispatch({
154
- type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CUSTOM_CONTEXT,
155
- payload: undefined
156
- });
157
147
  dispatch({
158
148
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
159
149
  payload: undefined
@@ -202,6 +192,27 @@ const closeChatStateCleanUp = async dispatch => {
202
192
  }
203
193
  });
204
194
  };
195
+ const closeChatWidget = (dispatch, props, state) => {
196
+ var _state$appStates3;
197
+ if (state !== null && state !== void 0 && (_state$appStates3 = state.appStates) !== null && _state$appStates3 !== void 0 && _state$appStates3.hideStartChatButton) {
198
+ var _props$controlProps2, _props$controlProps3;
199
+ // Only close chat if header is enabled for popout
200
+ // TODO : This condition needs to be removed eventually when the filler UX is ready for popout, removing this condition would show a blank screen for OOB Widget
201
+ if ((props === null || props === void 0 ? void 0 : (_props$controlProps2 = props.controlProps) === null || _props$controlProps2 === void 0 ? void 0 : _props$controlProps2.hideHeader) === undefined || (props === null || props === void 0 ? void 0 : (_props$controlProps3 = props.controlProps) === null || _props$controlProps3 === void 0 ? void 0 : _props$controlProps3.hideHeader) === false) {
202
+ dispatch({
203
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
204
+ payload: _ConversationState.ConversationState.Closed
205
+ });
206
+ }
207
+ return;
208
+ }
209
+
210
+ // Embedded chat
211
+ dispatch({
212
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
213
+ payload: _ConversationState.ConversationState.Closed
214
+ });
215
+ };
205
216
 
206
217
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
207
218
  const handleAuthenticationIfEnabled = async (props, chatSDK) => {
@@ -239,8 +250,8 @@ const chatTokenCleanUp = async dispatch => {
239
250
 
240
251
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
241
252
  const getEndChatEventName = async (chatSDK, props) => {
242
- var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _props$controlProps2;
243
- return (0, _utils.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, (props === null || props === void 0 ? void 0 : (_props$controlProps2 = props.controlProps) === null || _props$controlProps2 === void 0 ? void 0 : _props$controlProps2.widgetInstanceId) ?? "");
253
+ var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _props$controlProps4;
254
+ return (0, _utils.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, (props === null || props === void 0 ? void 0 : (_props$controlProps4 = props.controlProps) === null || _props$controlProps4 === void 0 ? void 0 : _props$controlProps4.widgetInstanceId) ?? "");
244
255
  };
245
256
 
246
257
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -35,7 +35,6 @@ var _messageTimestampMiddleware = _interopRequireDefault(require("../../webchatc
35
35
  var _Constants = require("../../../common/Constants");
36
36
  var _endChat = require("./endChat");
37
37
  var _HyperlinkTextOverrideRenderer = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer"));
38
- var _dompurify = _interopRequireDefault(require("dompurify"));
39
38
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
40
39
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
40
  const initWebChatComposer = (props, state, dispatch, chatSDK) => {
@@ -92,8 +91,6 @@ const initWebChatComposer = (props, state, dispatch, chatSDK) => {
92
91
  markdownRenderers.forEach(renderer => {
93
92
  text = renderer.render(text);
94
93
  });
95
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
- text = _dompurify.default.sanitize(text);
97
94
  return text;
98
95
  };
99
96
 
@@ -130,7 +130,7 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
130
130
  try {
131
131
  var _window$Microsoft, _window$Microsoft$Dyn, _window$Microsoft$Dyn2, _window$Microsoft$Dyn3;
132
132
  // Set custom context params
133
- setCustomContextParams(props);
133
+ await setCustomContextParams(props);
134
134
  const defaultOptionalParams = {
135
135
  sendDefaultInitContext: true,
136
136
  isProactiveChat: !!(params !== null && params !== void 0 && params.isProactiveChat),
@@ -286,7 +286,7 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
286
286
  };
287
287
 
288
288
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
289
- const setCustomContextParams = props => {
289
+ const setCustomContextParams = async props => {
290
290
  var _props$chatConfig, _props$chatConfig$Liv, _persistedState$domai8;
291
291
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
292
292
  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;
@@ -299,15 +299,22 @@ const setCustomContextParams = props => {
299
299
  }
300
300
  // Add custom context only for unauthenticated chat
301
301
  const persistedState = (0, _utils.getStateFromCache)(widgetInstanceId);
302
- if (!(0, _utils.isUndefinedOrEmpty)(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai8 = persistedState.domainStates) === null || _persistedState$domai8 === void 0 ? void 0 : _persistedState$domai8.customContext)) {
303
- var _persistedState$domai9;
302
+ const customContextLocal = (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai8 = persistedState.domainStates) === null || _persistedState$domai8 === void 0 ? void 0 : _persistedState$domai8.customContext) ?? (props === null || props === void 0 ? void 0 : props.initialCustomContext);
303
+ if (customContextLocal) {
304
304
  _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
305
- Event: _TelemetryConstants.TelemetryEvent.SetCustomContext,
306
- Description: "Setting custom context for unauthenicated chat"
305
+ Event: _TelemetryConstants.TelemetryEvent.SettingCustomContext,
306
+ Description: "Setting custom context for unauthenticated chat"
307
307
  });
308
308
  optionalParams = Object.assign({}, optionalParams, {
309
- customContext: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai9 = persistedState.domainStates) === null || _persistedState$domai9 === void 0 ? void 0 : _persistedState$domai9.customContext
309
+ customContext: customContextLocal
310
310
  });
311
+ } else {
312
+ const customContextFromParent = await getInitContextParamsForPopout();
313
+ if (!(0, _utils.isUndefinedOrEmpty)(customContextFromParent === null || customContextFromParent === void 0 ? void 0 : customContextFromParent.contextVariables)) {
314
+ optionalParams = Object.assign({}, optionalParams, {
315
+ customContext: customContextFromParent.contextVariables
316
+ });
317
+ }
311
318
  }
312
319
  };
313
320
  const canStartPopoutChat = async props => {
@@ -316,9 +323,9 @@ const canStartPopoutChat = async props => {
316
323
  }
317
324
  popoutWidgetInstanceId = (0, _utils.getWidgetCacheIdfromProps)(props, true);
318
325
  if (!(0, _utils.isNullOrEmptyString)(popoutWidgetInstanceId)) {
319
- var _persistedState$domai10, _persistedState$appSt2;
326
+ var _persistedState$domai9, _persistedState$appSt2;
320
327
  const persistedState = (0, _utils.getStateFromCache)(popoutWidgetInstanceId);
321
- if (persistedState && !(0, _utils.isUndefinedOrEmpty)(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai10 = persistedState.domainStates) === null || _persistedState$domai10 === void 0 ? void 0 : _persistedState$domai10.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt2 = persistedState.appStates) === null || _persistedState$appSt2 === void 0 ? void 0 : _persistedState$appSt2.conversationState) === _ConversationState.ConversationState.Active) {
328
+ if (persistedState && !(0, _utils.isUndefinedOrEmpty)(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai9 = persistedState.domainStates) === null || _persistedState$domai9 === void 0 ? void 0 : _persistedState$domai9.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt2 = persistedState.appStates) === null || _persistedState$appSt2 === void 0 ? void 0 : _persistedState$appSt2.conversationState) === _ConversationState.ConversationState.Active) {
322
329
  // Initiate popout chat
323
330
  _omnichannelChatComponents.BroadcastService.postMessage({
324
331
  eventName: _TelemetryConstants.BroadcastEvent.InitiateStartChatInPopoutMode
@@ -369,4 +376,34 @@ const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
369
376
  return false;
370
377
  }
371
378
  };
372
- exports.checkIfConversationStillValid = checkIfConversationStillValid;
379
+
380
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
381
+ exports.checkIfConversationStillValid = checkIfConversationStillValid;
382
+ const getInitContextParamsForPopout = async () => {
383
+ return window.opener ? await getInitContextParamForPopoutFromOuterScope(window.opener) : null;
384
+ };
385
+
386
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
387
+ const getInitContextParamForPopoutFromOuterScope = async scope => {
388
+ let payload;
389
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
390
+ let waitPromiseResolve;
391
+ const waitPromise = new Promise((res, rej) => {
392
+ waitPromiseResolve = res;
393
+ setTimeout(() => rej("Failed to find method in outer scope"), 5000);
394
+ }).catch(rej => console.warn(rej));
395
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
396
+ const getInitContextParamsFromParent = e => {
397
+ if (e.data && e.data.messageName == _Constants.Constants.InitContextParamsResponse) {
398
+ payload = e.data.payload;
399
+ waitPromiseResolve();
400
+ }
401
+ };
402
+ window.addEventListener("message", getInitContextParamsFromParent, false);
403
+ scope.postMessage({
404
+ messageName: _Constants.Constants.InitContextParamsResponse
405
+ }, "*");
406
+ await waitPromise;
407
+ window.removeEventListener("message", getInitContextParamsFromParent, false);
408
+ return payload;
409
+ };
@@ -105,6 +105,9 @@ _defineProperty(Constants, "SessionCacheSuffix", "session");
105
105
  _defineProperty(Constants, "PopoutCacheSuffix", "popout");
106
106
  // Visibility timeout for conversation details
107
107
  _defineProperty(Constants, "LWICheckOnVisibilityTimeout", 3 * 60 * 1000);
108
+ // 3 minute
109
+ // Popup mode custom context response event message name
110
+ _defineProperty(Constants, "InitContextParamsResponse", "initContextParamsResponse");
108
111
  export const Regex = (_class = class Regex {}, _defineProperty(_class, "EmailRegex", "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"), _class);
109
112
  export class HtmlIdNames {}
110
113
  _defineProperty(HtmlIdNames, "MSLiveChatWidget", "MSLiveChatWidget");
@@ -101,7 +101,7 @@ export let TelemetryEvent;
101
101
  TelemetryEvent["ChatVisibilityChanged"] = "ChatVisibilityChanged";
102
102
  TelemetryEvent["EndChatSucceeded"] = "EndChatSucceeded";
103
103
  TelemetryEvent["EndChatFailed"] = "EndChatFailed";
104
- TelemetryEvent["SetCustomContext"] = "SetCustomContext";
104
+ TelemetryEvent["SettingCustomContext"] = "SettingCustomContext";
105
105
  TelemetryEvent["WebChatLoaded"] = "WebChatLoaded";
106
106
  TelemetryEvent["LCWChatButtonClicked"] = "LCWChatButtonClicked";
107
107
  TelemetryEvent["LCWChatButtonShow"] = "LCWChatButtonShow";
@@ -3,7 +3,6 @@ import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcon
3
3
  import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler";
4
4
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
5
5
  import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
6
- import DOMPurify from "dompurify";
7
6
  const processDisplayName = displayName => {
8
7
  // if displayname matches "teamsvisitor:<some alphanumeric string>", we replace it with "Customer"
9
8
  const displayNameRegex = ".+:.+";
@@ -59,8 +58,6 @@ const processContent = (transcriptContent, isAgentChat, renderMarkDown) => {
59
58
  }
60
59
  if (renderMarkDown) {
61
60
  transcriptContent = renderMarkDown(transcriptContent);
62
- } else {
63
- transcriptContent = DOMPurify.sanitize(transcriptContent);
64
61
  }
65
62
  return transcriptContent;
66
63
  };
@@ -119,18 +119,12 @@ const endChat = async function (props, chatSDK, state, dispatch, setAdapter, set
119
119
  }
120
120
  });
121
121
  } finally {
122
- var _state$appStates3;
123
122
  dispatch({
124
123
  type: LiveChatWidgetActionType.SET_UNREAD_MESSAGE_COUNT,
125
124
  payload: 0
126
125
  });
127
- //Always allow to close the chat for embedded mode irrespective of end chat errors
128
- if (!(state !== null && state !== void 0 && (_state$appStates3 = state.appStates) !== null && _state$appStates3 !== void 0 && _state$appStates3.hideStartChatButton)) {
129
- dispatch({
130
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
131
- payload: ConversationState.Closed
132
- });
133
- }
126
+ // Always allow to close the chat for embedded mode irrespective of end chat errors
127
+ closeChatWidget(dispatch, props, state);
134
128
  }
135
129
  }
136
130
  if (postMessageToOtherTab && !isNullOrEmptyString(uwid)) {
@@ -143,10 +137,6 @@ const endChat = async function (props, chatSDK, state, dispatch, setAdapter, set
143
137
  };
144
138
  const endChatStateCleanUp = async dispatch => {
145
139
  // Need to clear these states immediately when chat ended from OC.
146
- dispatch({
147
- type: LiveChatWidgetActionType.SET_CUSTOM_CONTEXT,
148
- payload: undefined
149
- });
150
140
  dispatch({
151
141
  type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
152
142
  payload: undefined
@@ -195,6 +185,27 @@ const closeChatStateCleanUp = async dispatch => {
195
185
  }
196
186
  });
197
187
  };
188
+ const closeChatWidget = (dispatch, props, state) => {
189
+ var _state$appStates3;
190
+ if (state !== null && state !== void 0 && (_state$appStates3 = state.appStates) !== null && _state$appStates3 !== void 0 && _state$appStates3.hideStartChatButton) {
191
+ var _props$controlProps2, _props$controlProps3;
192
+ // Only close chat if header is enabled for popout
193
+ // TODO : This condition needs to be removed eventually when the filler UX is ready for popout, removing this condition would show a blank screen for OOB Widget
194
+ if ((props === null || props === void 0 ? void 0 : (_props$controlProps2 = props.controlProps) === null || _props$controlProps2 === void 0 ? void 0 : _props$controlProps2.hideHeader) === undefined || (props === null || props === void 0 ? void 0 : (_props$controlProps3 = props.controlProps) === null || _props$controlProps3 === void 0 ? void 0 : _props$controlProps3.hideHeader) === false) {
195
+ dispatch({
196
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
197
+ payload: ConversationState.Closed
198
+ });
199
+ }
200
+ return;
201
+ }
202
+
203
+ // Embedded chat
204
+ dispatch({
205
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
206
+ payload: ConversationState.Closed
207
+ });
208
+ };
198
209
 
199
210
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
200
211
  const handleAuthenticationIfEnabled = async (props, chatSDK) => {
@@ -232,8 +243,8 @@ const chatTokenCleanUp = async dispatch => {
232
243
 
233
244
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
234
245
  const getEndChatEventName = async (chatSDK, props) => {
235
- var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _props$controlProps2;
236
- return 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, (props === null || props === void 0 ? void 0 : (_props$controlProps2 = props.controlProps) === null || _props$controlProps2 === void 0 ? void 0 : _props$controlProps2.widgetInstanceId) ?? "");
246
+ var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _props$controlProps4;
247
+ return 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, (props === null || props === void 0 ? void 0 : (_props$controlProps4 = props.controlProps) === null || _props$controlProps4 === void 0 ? void 0 : _props$controlProps4.widgetInstanceId) ?? "");
237
248
  };
238
249
 
239
250
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -29,7 +29,6 @@ import createMessageTimeStampMiddleware from "../../webchatcontainerstateful/web
29
29
  import { ConversationEndEntity, ParticipantType } from "../../../common/Constants";
30
30
  import { getConversationDetails } from "./endChat";
31
31
  import HyperlinkTextOverrideRenderer from "../../webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer";
32
- import DOMPurify from "dompurify";
33
32
 
34
33
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
34
  export const initWebChatComposer = (props, state, dispatch, chatSDK) => {
@@ -86,8 +85,6 @@ export const initWebChatComposer = (props, state, dispatch, chatSDK) => {
86
85
  markdownRenderers.forEach(renderer => {
87
86
  text = renderer.render(text);
88
87
  });
89
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
- text = DOMPurify.sanitize(text);
91
88
  return text;
92
89
  };
93
90
 
@@ -1,5 +1,5 @@
1
1
  import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
- import { ChatSDKError, LiveWorkItemState } from "../../../common/Constants";
2
+ import { ChatSDKError, Constants, LiveWorkItemState } from "../../../common/Constants";
3
3
  import { createTimer, getStateFromCache, getWidgetCacheIdfromProps, isNullOrEmptyString, isUndefinedOrEmpty } from "../../../common/utils";
4
4
  import { getAuthClientFunction, handleAuthentication } from "./authHelper";
5
5
  import { ActivityStreamHandler } from "./ActivityStreamHandler";
@@ -123,7 +123,7 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
123
123
  try {
124
124
  var _window$Microsoft, _window$Microsoft$Dyn, _window$Microsoft$Dyn2, _window$Microsoft$Dyn3;
125
125
  // Set custom context params
126
- setCustomContextParams(props);
126
+ await setCustomContextParams(props);
127
127
  const defaultOptionalParams = {
128
128
  sendDefaultInitContext: true,
129
129
  isProactiveChat: !!(params !== null && params !== void 0 && params.isProactiveChat),
@@ -278,7 +278,7 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
278
278
  };
279
279
 
280
280
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
281
- const setCustomContextParams = props => {
281
+ const setCustomContextParams = async props => {
282
282
  var _props$chatConfig, _props$chatConfig$Liv, _persistedState$domai8;
283
283
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
284
284
  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;
@@ -291,15 +291,22 @@ const setCustomContextParams = props => {
291
291
  }
292
292
  // Add custom context only for unauthenticated chat
293
293
  const persistedState = getStateFromCache(widgetInstanceId);
294
- if (!isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai8 = persistedState.domainStates) === null || _persistedState$domai8 === void 0 ? void 0 : _persistedState$domai8.customContext)) {
295
- var _persistedState$domai9;
294
+ const customContextLocal = (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai8 = persistedState.domainStates) === null || _persistedState$domai8 === void 0 ? void 0 : _persistedState$domai8.customContext) ?? (props === null || props === void 0 ? void 0 : props.initialCustomContext);
295
+ if (customContextLocal) {
296
296
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
297
- Event: TelemetryEvent.SetCustomContext,
298
- Description: "Setting custom context for unauthenicated chat"
297
+ Event: TelemetryEvent.SettingCustomContext,
298
+ Description: "Setting custom context for unauthenticated chat"
299
299
  });
300
300
  optionalParams = Object.assign({}, optionalParams, {
301
- customContext: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai9 = persistedState.domainStates) === null || _persistedState$domai9 === void 0 ? void 0 : _persistedState$domai9.customContext
301
+ customContext: customContextLocal
302
302
  });
303
+ } else {
304
+ const customContextFromParent = await getInitContextParamsForPopout();
305
+ if (!isUndefinedOrEmpty(customContextFromParent === null || customContextFromParent === void 0 ? void 0 : customContextFromParent.contextVariables)) {
306
+ optionalParams = Object.assign({}, optionalParams, {
307
+ customContext: customContextFromParent.contextVariables
308
+ });
309
+ }
303
310
  }
304
311
  };
305
312
  const canStartPopoutChat = async props => {
@@ -308,9 +315,9 @@ const canStartPopoutChat = async props => {
308
315
  }
309
316
  popoutWidgetInstanceId = getWidgetCacheIdfromProps(props, true);
310
317
  if (!isNullOrEmptyString(popoutWidgetInstanceId)) {
311
- var _persistedState$domai10, _persistedState$appSt2;
318
+ var _persistedState$domai9, _persistedState$appSt2;
312
319
  const persistedState = getStateFromCache(popoutWidgetInstanceId);
313
- if (persistedState && !isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai10 = persistedState.domainStates) === null || _persistedState$domai10 === void 0 ? void 0 : _persistedState$domai10.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt2 = persistedState.appStates) === null || _persistedState$appSt2 === void 0 ? void 0 : _persistedState$appSt2.conversationState) === ConversationState.Active) {
320
+ if (persistedState && !isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai9 = persistedState.domainStates) === null || _persistedState$domai9 === void 0 ? void 0 : _persistedState$domai9.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt2 = persistedState.appStates) === null || _persistedState$appSt2 === void 0 ? void 0 : _persistedState$appSt2.conversationState) === ConversationState.Active) {
314
321
  // Initiate popout chat
315
322
  BroadcastService.postMessage({
316
323
  eventName: BroadcastEvent.InitiateStartChatInPopoutMode
@@ -361,4 +368,34 @@ const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
361
368
  return false;
362
369
  }
363
370
  };
371
+
372
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
373
+ const getInitContextParamsForPopout = async () => {
374
+ return window.opener ? await getInitContextParamForPopoutFromOuterScope(window.opener) : null;
375
+ };
376
+
377
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
378
+ const getInitContextParamForPopoutFromOuterScope = async scope => {
379
+ let payload;
380
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
381
+ let waitPromiseResolve;
382
+ const waitPromise = new Promise((res, rej) => {
383
+ waitPromiseResolve = res;
384
+ setTimeout(() => rej("Failed to find method in outer scope"), 5000);
385
+ }).catch(rej => console.warn(rej));
386
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
387
+ const getInitContextParamsFromParent = e => {
388
+ if (e.data && e.data.messageName == Constants.InitContextParamsResponse) {
389
+ payload = e.data.payload;
390
+ waitPromiseResolve();
391
+ }
392
+ };
393
+ window.addEventListener("message", getInitContextParamsFromParent, false);
394
+ scope.postMessage({
395
+ messageName: Constants.InitContextParamsResponse
396
+ }, "*");
397
+ await waitPromise;
398
+ window.removeEventListener("message", getInitContextParamsFromParent, false);
399
+ return payload;
400
+ };
364
401
  export { prepareStartChat, initStartChat, setPreChatAndInitiateChat, checkIfConversationStillValid };
@@ -84,6 +84,7 @@ export declare class Constants {
84
84
  static readonly SessionCacheSuffix = "session";
85
85
  static readonly PopoutCacheSuffix = "popout";
86
86
  static readonly LWICheckOnVisibilityTimeout: number;
87
+ static readonly InitContextParamsResponse = "initContextParamsResponse";
87
88
  }
88
89
  export declare const Regex: {
89
90
  new (): {};
@@ -94,7 +94,7 @@ export declare enum TelemetryEvent {
94
94
  ChatVisibilityChanged = "ChatVisibilityChanged",
95
95
  EndChatSucceeded = "EndChatSucceeded",
96
96
  EndChatFailed = "EndChatFailed",
97
- SetCustomContext = "SetCustomContext",
97
+ SettingCustomContext = "SettingCustomContext",
98
98
  WebChatLoaded = "WebChatLoaded",
99
99
  LCWChatButtonClicked = "LCWChatButtonClicked",
100
100
  LCWChatButtonShow = "LCWChatButtonShow",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.0.4-main.6e79f24",
3
+ "version": "1.0.4-main.d4abfe6",
4
4
  "description": "Microsoft Omnichannel Chat Widget",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",