@microsoft/omnichannel-chat-widget 1.0.4 → 1.0.5-main.53e6741

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 (22) hide show
  1. package/lib/cjs/common/telemetry/TelemetryHelper.js +3 -2
  2. package/lib/cjs/common/telemetry/defaultConfigs/defaultTelemetryInternalData.js +1 -1
  3. package/lib/cjs/common/telemetry/loggers/ariaTelemetryLogger.js +22 -2
  4. package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +4 -0
  5. package/lib/cjs/components/livechatwidget/common/endChat.js +1 -1
  6. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +12 -1
  7. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +3 -2
  8. package/lib/cjs/components/livechatwidget/common/startChat.js +23 -9
  9. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +8 -0
  10. package/lib/esm/common/telemetry/TelemetryHelper.js +3 -2
  11. package/lib/esm/common/telemetry/defaultConfigs/defaultTelemetryInternalData.js +1 -1
  12. package/lib/esm/common/telemetry/loggers/ariaTelemetryLogger.js +22 -2
  13. package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +3 -0
  14. package/lib/esm/components/livechatwidget/common/endChat.js +1 -1
  15. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +12 -1
  16. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +3 -2
  17. package/lib/esm/components/livechatwidget/common/startChat.js +23 -9
  18. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +8 -0
  19. package/lib/types/common/telemetry/TelemetryHelper.d.ts +3 -3
  20. package/lib/types/common/telemetry/definitions/Payload.d.ts +1 -0
  21. package/lib/types/components/livechatwidget/common/renderSurveyHelpers.d.ts +1 -1
  22. package/package.json +2 -2
@@ -5,9 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.TelemetryHelper = void 0;
7
7
  var _TelemetryConstants = require("./TelemetryConstants");
8
- var _utils = require("../utils");
9
- var _TelemetryManager = require("./TelemetryManager");
10
8
  var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
9
+ var _TelemetryManager = require("./TelemetryManager");
10
+ var _utils = require("../utils");
11
11
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
12
12
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
13
13
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
@@ -96,6 +96,7 @@ class TelemetryHelper {
96
96
  return TelemetryHelper.populate(level, payload, event => {
97
97
  var _TelemetryManager$Int11, _TelemetryManager$Int12, _TelemetryManager$Int13;
98
98
  event.Event = payload.Event;
99
+ event.Description = payload.Description;
99
100
  event.ResourcePath = payload.ResourcePath;
100
101
  event.WidgetState = payload.WidgetState;
101
102
  event.ChatState = payload.ChatState;
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.defaultInternalTelemetryData = void 0;
7
7
  const defaultInternalTelemetryData = {
8
- environmentVersion: "test",
8
+ environmentVersion: "prod",
9
9
  chatWidgetLocaleLCID: "1033",
10
10
  channelId: "lcw2.0"
11
11
  };
@@ -9,10 +9,29 @@ var _AriaSDK = require("@microsoft/omnichannel-chat-sdk/lib/external/aria/webjs/
9
9
  var _Enums = require("@microsoft/omnichannel-chat-sdk/lib/external/aria/common/Enums");
10
10
  var _Constants = require("../../Constants");
11
11
  var _TelemetryManager = require("../TelemetryManager");
12
+ const AWTDefaultConfiguration = {
13
+ collectorUri: "https://browser.pipe.aria.microsoft.com/Collector/3.0/",
14
+ cacheMemorySizeLimitInNumberOfEvents: 10000,
15
+ disableCookiesUsage: false,
16
+ canSendStatEvent: eventName => {
17
+ return true;
18
+ },
19
+ // eslint-disable-line @typescript-eslint/no-unused-vars
20
+ clockSkewRefreshDurationInMins: 0
21
+ };
12
22
  const ariaTelemetryLogger = (ariaTelemetryKey, disabledCookieUsage, collectiorUriForTelemetry, ariaTelemetryApplicationName) => {
13
23
  let _logger;
24
+
25
+ // AWTLogManager is a global variable. Reset after a logEvent() is required to prevent collisions with other components using AWTLogManager.
26
+ const resetAriaLogger = function () {
27
+ let configuration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : AWTDefaultConfiguration;
28
+ _AriaSDK.AWTLogManager.flushAndTeardown();
29
+ _AriaSDK.AWTLogManager._isInitialized = false; // eslint-disable-line @typescript-eslint/no-explicit-any
30
+ _AriaSDK.AWTLogManager._isDestroyed = false; // eslint-disable-line @typescript-eslint/no-explicit-any
31
+ _logger = _AriaSDK.AWTLogManager.initialize(ariaTelemetryKey, configuration);
32
+ };
14
33
  const logger = () => {
15
- if ((0, _utils.isNullOrUndefined)(_logger) && !(0, _utils.isNullOrEmptyString)(ariaTelemetryKey)) {
34
+ if (!(0, _utils.isNullOrEmptyString)(ariaTelemetryKey)) {
16
35
  const configuration = {
17
36
  disableCookiesUsage: disabledCookieUsage
18
37
  };
@@ -32,7 +51,7 @@ const ariaTelemetryLogger = (ariaTelemetryKey, disabledCookieUsage, collectiorUr
32
51
  }
33
52
  }
34
53
  try {
35
- _logger = _AriaSDK.AWTLogManager.initialize(ariaTelemetryKey, configuration);
54
+ resetAriaLogger(configuration);
36
55
  if (_logger === undefined) {
37
56
  _logger = _AriaSDK.AWTLogManager.getLogger(ariaTelemetryKey);
38
57
  }
@@ -74,6 +93,7 @@ const ariaTelemetryLogger = (ariaTelemetryKey, disabledCookieUsage, collectiorUr
74
93
  eventProperties.properties[ariaTelemetryApplicationName] = nameProperty;
75
94
  }
76
95
  logger() ? logger().logEvent(eventProperties) : console.log("Unable to initialize aria logger");
96
+ resetAriaLogger();
77
97
  } catch (error) {
78
98
  console.error("Error in logging telemetry to Aria logger:" + error);
79
99
  }
@@ -9,6 +9,8 @@ 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 }; }
12
14
  const processDisplayName = displayName => {
13
15
  // if displayname matches "teamsvisitor:<some alphanumeric string>", we replace it with "Customer"
14
16
  const displayNameRegex = ".+:.+";
@@ -64,6 +66,8 @@ const processContent = (transcriptContent, isAgentChat, renderMarkDown) => {
64
66
  }
65
67
  if (renderMarkDown) {
66
68
  transcriptContent = renderMarkDown(transcriptContent);
69
+ } else {
70
+ transcriptContent = _dompurify.default.sanitize(transcriptContent);
67
71
  }
68
72
  return transcriptContent;
69
73
  };
@@ -56,7 +56,7 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
56
56
 
57
57
  // Initiate post chat render
58
58
  if (state !== null && state !== void 0 && (_state$domainStates2 = state.domainStates) !== null && _state$domainStates2 !== void 0 && _state$domainStates2.postChatContext) {
59
- await (0, _renderSurveyHelpers.initiatePostChat)(props, conversationDetails, state, dispatch);
59
+ await (0, _renderSurveyHelpers.initiatePostChat)(props, conversationDetails, state, dispatch, postchatContext);
60
60
  return;
61
61
  }
62
62
  } catch (error) {
@@ -34,10 +34,13 @@ var _htmlPlayerMiddleware = _interopRequireDefault(require("../../webchatcontain
34
34
  var _htmlTextMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware"));
35
35
  var _preProcessingMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware"));
36
36
  var _sanitizationMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware"));
37
+ var _dompurify = _interopRequireDefault(require("dompurify"));
37
38
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
38
39
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
40
  const initWebChatComposer = (props, state, dispatch, chatSDK) => {
40
41
  var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _state$domainStates$l4, _state$domainStates$l5, _props$webChatContain9, _props$webChatContain10, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain11, _props$webChatContain12, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain13, _props$webChatContain14, _defaultWebChatContai, _props$webChatContain15, _props$webChatContain16, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain17, _props$webChatContain18, _defaultWebChatContai2, _props$webChatContain19, _props$webChatContain20, _defaultWebChatContai3, _props$webChatContain21, _props$webChatContain22;
42
+ // Add a hook to make all links open a new window
43
+ postDomPurifyActivities();
41
44
  const localizedTexts = {
42
45
  ..._defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts,
43
46
  ...((_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : _props$webChatContain.localizedTexts)
@@ -90,9 +93,17 @@ const initWebChatComposer = (props, state, dispatch, chatSDK) => {
90
93
  markdownRenderers.forEach(renderer => {
91
94
  text = renderer.render(text);
92
95
  });
96
+ text = _dompurify.default.sanitize(text);
93
97
  return text;
94
98
  };
95
-
99
+ function postDomPurifyActivities() {
100
+ _dompurify.default.addHook("afterSanitizeAttributes", function (node) {
101
+ // set all elements owning target to target=_blank
102
+ if ("target" in node) {
103
+ node.setAttribute("target", "_blank");
104
+ }
105
+ });
106
+ }
96
107
  // Initialize the remaining Web Chat props
97
108
  const webChatProps = {
98
109
  ..._defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatProps,
@@ -87,10 +87,11 @@ const embedModePostChatWorkflow = async (state, dispatch) => {
87
87
  };
88
88
 
89
89
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
- const initiatePostChat = async (props, conversationDetailsParam, state, dispatch) => {
90
+ const initiatePostChat = async (props, conversationDetailsParam, state, dispatch, postchatContext) => {
91
91
  var _conversationDetails;
92
92
  conversationDetails = conversationDetailsParam;
93
- await setSurveyMode(props, (_conversationDetails = conversationDetails) === null || _conversationDetails === void 0 ? void 0 : _conversationDetails.participantType, state, dispatch);
93
+ const participantType = ((_conversationDetails = conversationDetails) === null || _conversationDetails === void 0 ? void 0 : _conversationDetails.participantType) ?? postchatContext.participantType;
94
+ await setSurveyMode(props, participantType, state, dispatch);
94
95
  await renderSurvey(state, dispatch);
95
96
  };
96
97
 
@@ -99,7 +99,7 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
99
99
  const getAuthToken = props === null || props === void 0 ? void 0 : props.getAuthToken;
100
100
  const hideErrorUIPane = props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.hideErrorUIPane;
101
101
  try {
102
- var _newAdapter$activity$, _TelemetryTimers$Widg;
102
+ var _newAdapter$activity$, _TelemetryTimers$Widg2;
103
103
  //Start widget load timer
104
104
  _TelemetryManager.TelemetryTimers.WidgetLoadTimer = (0, _utils.createTimer)();
105
105
  _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
@@ -175,10 +175,16 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
175
175
  });
176
176
  }
177
177
  if (persistedState) {
178
+ var _TelemetryTimers$Widg;
178
179
  dispatch({
179
180
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_WIDGET_STATE,
180
181
  payload: persistedState
181
182
  });
183
+ _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
184
+ Event: _TelemetryConstants.TelemetryEvent.WidgetLoadComplete,
185
+ Description: "Widget load complete. Persisted state retrieved",
186
+ ElapsedTimeInMilliseconds: _TelemetryManager.TelemetryTimers === null || _TelemetryManager.TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg = _TelemetryManager.TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg === void 0 ? void 0 : _TelemetryTimers$Widg.milliSecondsElapsed
187
+ });
182
188
  await (0, _setPostChatContextAndLoadSurvey.setPostChatContextAndLoadSurvey)(chatSDK, dispatch, true);
183
189
  return;
184
190
  }
@@ -192,7 +198,7 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
192
198
  _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
193
199
  Event: _TelemetryConstants.TelemetryEvent.WidgetLoadComplete,
194
200
  Description: "Widget load complete",
195
- ElapsedTimeInMilliseconds: _TelemetryManager.TelemetryTimers === null || _TelemetryManager.TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg = _TelemetryManager.TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg === void 0 ? void 0 : _TelemetryTimers$Widg.milliSecondsElapsed
201
+ ElapsedTimeInMilliseconds: _TelemetryManager.TelemetryTimers === null || _TelemetryManager.TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg2 = _TelemetryManager.TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg2 === void 0 ? void 0 : _TelemetryTimers$Widg2.milliSecondsElapsed
196
202
  });
197
203
 
198
204
  // Set post chat context in state
@@ -202,15 +208,10 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
202
208
  // Updating chat session detail for telemetry
203
209
  await (0, _updateSessionDataForTelemetry.updateSessionDataForTelemetry)(chatSDK, dispatch);
204
210
  } catch (ex) {
205
- _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.ERROR, {
206
- Event: _TelemetryConstants.TelemetryEvent.WidgetLoadFailed,
207
- ExceptionDetails: {
208
- Exception: `Widget load Failed: ${ex}`
209
- }
210
- });
211
- _NotificationHandler.NotificationHandler.notifyError(_NotificationScenarios.NotificationScenarios.Connection, "Start Chat Failed: " + ex);
211
+ var _TelemetryTimers$Widg4;
212
212
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
213
213
  if (ex.message === _Constants.ChatSDKError.WidgetUseOutsideOperatingHour) {
214
+ var _TelemetryTimers$Widg3;
214
215
  dispatch({
215
216
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_OUTSIDE_OPERATING_HOURS,
216
217
  payload: true
@@ -219,8 +220,21 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
219
220
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
220
221
  payload: _ConversationState.ConversationState.OutOfOffice
221
222
  });
223
+ _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
224
+ Event: _TelemetryConstants.TelemetryEvent.WidgetLoadComplete,
225
+ Description: "Widget load complete. Widget is OOOH.",
226
+ ElapsedTimeInMilliseconds: _TelemetryManager.TelemetryTimers === null || _TelemetryManager.TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg3 = _TelemetryManager.TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg3 === void 0 ? void 0 : _TelemetryTimers$Widg3.milliSecondsElapsed
227
+ });
222
228
  return;
223
229
  }
230
+ _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.ERROR, {
231
+ Event: _TelemetryConstants.TelemetryEvent.WidgetLoadFailed,
232
+ ExceptionDetails: {
233
+ Exception: `Widget load Failed: ${ex}`
234
+ },
235
+ ElapsedTimeInMilliseconds: _TelemetryManager.TelemetryTimers === null || _TelemetryManager.TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg4 = _TelemetryManager.TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg4 === void 0 ? void 0 : _TelemetryTimers$Widg4.milliSecondsElapsed
236
+ });
237
+ _NotificationHandler.NotificationHandler.notifyError(_NotificationScenarios.NotificationScenarios.Connection, "Start Chat Failed: " + ex);
224
238
  dispatch({
225
239
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_START_CHAT_FAILING,
226
240
  payload: true
@@ -142,6 +142,14 @@ const LiveChatWidgetStateful = props => {
142
142
  }
143
143
  if (isChatValid === false) {
144
144
  if (localState) {
145
+ // adding the reconnect logic for the case when customer tries to reconnect from a new browser or InPrivate browser
146
+ if ((0, _reconnectChatHelper.isReconnectEnabled)(props.chatConfig) === true) {
147
+ await (0, _reconnectChatHelper.handleChatReconnect)(chatSDK, props, dispatch, setAdapter, _startChat.initStartChat, state);
148
+ // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
149
+ if (state.appStates.conversationState === _ConversationState.ConversationState.Active || state.appStates.conversationState === _ConversationState.ConversationState.ReconnectChat) {
150
+ return;
151
+ }
152
+ }
145
153
  await (0, _startChat.setPreChatAndInitiateChat)(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
146
154
  return;
147
155
  } else {
@@ -2,9 +2,9 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
2
2
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
3
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
4
  import { ScenarioType, TelemetryEvent } from "./TelemetryConstants";
5
- import { newGuid } from "../utils";
6
- import { TelemetryManager } from "./TelemetryManager";
7
5
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
6
+ import { TelemetryManager } from "./TelemetryManager";
7
+ import { newGuid } from "../utils";
8
8
  export class TelemetryHelper {
9
9
  static buildTelemetryEvent(level, input) {
10
10
  switch (input.scenarioType) {
@@ -90,6 +90,7 @@ export class TelemetryHelper {
90
90
  return TelemetryHelper.populate(level, payload, event => {
91
91
  var _TelemetryManager$Int11, _TelemetryManager$Int12, _TelemetryManager$Int13;
92
92
  event.Event = payload.Event;
93
+ event.Description = payload.Description;
93
94
  event.ResourcePath = payload.ResourcePath;
94
95
  event.WidgetState = payload.WidgetState;
95
96
  event.ChatState = payload.ChatState;
@@ -1,5 +1,5 @@
1
1
  export const defaultInternalTelemetryData = {
2
- environmentVersion: "test",
2
+ environmentVersion: "prod",
3
3
  chatWidgetLocaleLCID: "1033",
4
4
  channelId: "lcw2.0"
5
5
  };
@@ -3,10 +3,29 @@ import { AWTLogManager } from "@microsoft/omnichannel-chat-sdk/lib/external/aria
3
3
  import { AWTCustomerContentKind, AWTPiiKind, AWTPropertyType } from "@microsoft/omnichannel-chat-sdk/lib/external/aria/common/Enums";
4
4
  import { Constants, AriaTelemetryConstants, EnvironmentVersion } from "../../Constants";
5
5
  import { TelemetryManager } from "../TelemetryManager";
6
+ const AWTDefaultConfiguration = {
7
+ collectorUri: "https://browser.pipe.aria.microsoft.com/Collector/3.0/",
8
+ cacheMemorySizeLimitInNumberOfEvents: 10000,
9
+ disableCookiesUsage: false,
10
+ canSendStatEvent: eventName => {
11
+ return true;
12
+ },
13
+ // eslint-disable-line @typescript-eslint/no-unused-vars
14
+ clockSkewRefreshDurationInMins: 0
15
+ };
6
16
  export const ariaTelemetryLogger = (ariaTelemetryKey, disabledCookieUsage, collectiorUriForTelemetry, ariaTelemetryApplicationName) => {
7
17
  let _logger;
18
+
19
+ // AWTLogManager is a global variable. Reset after a logEvent() is required to prevent collisions with other components using AWTLogManager.
20
+ const resetAriaLogger = function () {
21
+ let configuration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : AWTDefaultConfiguration;
22
+ AWTLogManager.flushAndTeardown();
23
+ AWTLogManager._isInitialized = false; // eslint-disable-line @typescript-eslint/no-explicit-any
24
+ AWTLogManager._isDestroyed = false; // eslint-disable-line @typescript-eslint/no-explicit-any
25
+ _logger = AWTLogManager.initialize(ariaTelemetryKey, configuration);
26
+ };
8
27
  const logger = () => {
9
- if (isNullOrUndefined(_logger) && !isNullOrEmptyString(ariaTelemetryKey)) {
28
+ if (!isNullOrEmptyString(ariaTelemetryKey)) {
10
29
  const configuration = {
11
30
  disableCookiesUsage: disabledCookieUsage
12
31
  };
@@ -26,7 +45,7 @@ export const ariaTelemetryLogger = (ariaTelemetryKey, disabledCookieUsage, colle
26
45
  }
27
46
  }
28
47
  try {
29
- _logger = AWTLogManager.initialize(ariaTelemetryKey, configuration);
48
+ resetAriaLogger(configuration);
30
49
  if (_logger === undefined) {
31
50
  _logger = AWTLogManager.getLogger(ariaTelemetryKey);
32
51
  }
@@ -68,6 +87,7 @@ export const ariaTelemetryLogger = (ariaTelemetryKey, disabledCookieUsage, colle
68
87
  eventProperties.properties[ariaTelemetryApplicationName] = nameProperty;
69
88
  }
70
89
  logger() ? logger().logEvent(eventProperties) : console.log("Unable to initialize aria logger");
90
+ resetAriaLogger();
71
91
  } catch (error) {
72
92
  console.error("Error in logging telemetry to Aria logger:" + error);
73
93
  }
@@ -3,6 +3,7 @@ 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";
6
7
  const processDisplayName = displayName => {
7
8
  // if displayname matches "teamsvisitor:<some alphanumeric string>", we replace it with "Customer"
8
9
  const displayNameRegex = ".+:.+";
@@ -58,6 +59,8 @@ const processContent = (transcriptContent, isAgentChat, renderMarkDown) => {
58
59
  }
59
60
  if (renderMarkDown) {
60
61
  transcriptContent = renderMarkDown(transcriptContent);
62
+ } else {
63
+ transcriptContent = DOMPurify.sanitize(transcriptContent);
61
64
  }
62
65
  return transcriptContent;
63
66
  };
@@ -51,7 +51,7 @@ const prepareEndChat = async (props, chatSDK, state, dispatch, setAdapter, setWe
51
51
 
52
52
  // Initiate post chat render
53
53
  if (state !== null && state !== void 0 && (_state$domainStates2 = state.domainStates) !== null && _state$domainStates2 !== void 0 && _state$domainStates2.postChatContext) {
54
- await initiatePostChat(props, conversationDetails, state, dispatch);
54
+ await initiatePostChat(props, conversationDetails, state, dispatch, postchatContext);
55
55
  return;
56
56
  }
57
57
  } catch (error) {
@@ -28,10 +28,13 @@ import htmlPlayerMiddleware from "../../webchatcontainerstateful/webchatcontroll
28
28
  import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware";
29
29
  import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
30
30
  import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
31
+ import DOMPurify from "dompurify";
31
32
 
32
33
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
34
  export const initWebChatComposer = (props, state, dispatch, chatSDK) => {
34
35
  var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _state$domainStates$l4, _state$domainStates$l5, _props$webChatContain9, _props$webChatContain10, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain11, _props$webChatContain12, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain13, _props$webChatContain14, _defaultWebChatContai, _props$webChatContain15, _props$webChatContain16, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain17, _props$webChatContain18, _defaultWebChatContai2, _props$webChatContain19, _props$webChatContain20, _defaultWebChatContai3, _props$webChatContain21, _props$webChatContain22;
36
+ // Add a hook to make all links open a new window
37
+ postDomPurifyActivities();
35
38
  const localizedTexts = {
36
39
  ...defaultMiddlewareLocalizedTexts,
37
40
  ...((_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : _props$webChatContain.localizedTexts)
@@ -84,9 +87,17 @@ export const initWebChatComposer = (props, state, dispatch, chatSDK) => {
84
87
  markdownRenderers.forEach(renderer => {
85
88
  text = renderer.render(text);
86
89
  });
90
+ text = DOMPurify.sanitize(text);
87
91
  return text;
88
92
  };
89
-
93
+ function postDomPurifyActivities() {
94
+ DOMPurify.addHook("afterSanitizeAttributes", function (node) {
95
+ // set all elements owning target to target=_blank
96
+ if ("target" in node) {
97
+ node.setAttribute("target", "_blank");
98
+ }
99
+ });
100
+ }
90
101
  // Initialize the remaining Web Chat props
91
102
  const webChatProps = {
92
103
  ...defaultWebChatContainerStatefulProps.webChatProps,
@@ -81,10 +81,11 @@ const embedModePostChatWorkflow = async (state, dispatch) => {
81
81
  };
82
82
 
83
83
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
- const initiatePostChat = async (props, conversationDetailsParam, state, dispatch) => {
84
+ const initiatePostChat = async (props, conversationDetailsParam, state, dispatch, postchatContext) => {
85
85
  var _conversationDetails;
86
86
  conversationDetails = conversationDetailsParam;
87
- await setSurveyMode(props, (_conversationDetails = conversationDetails) === null || _conversationDetails === void 0 ? void 0 : _conversationDetails.participantType, state, dispatch);
87
+ const participantType = ((_conversationDetails = conversationDetails) === null || _conversationDetails === void 0 ? void 0 : _conversationDetails.participantType) ?? postchatContext.participantType;
88
+ await setSurveyMode(props, participantType, state, dispatch);
88
89
  await renderSurvey(state, dispatch);
89
90
  };
90
91
 
@@ -92,7 +92,7 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
92
92
  const getAuthToken = props === null || props === void 0 ? void 0 : props.getAuthToken;
93
93
  const hideErrorUIPane = props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.hideErrorUIPane;
94
94
  try {
95
- var _newAdapter$activity$, _TelemetryTimers$Widg;
95
+ var _newAdapter$activity$, _TelemetryTimers$Widg2;
96
96
  //Start widget load timer
97
97
  TelemetryTimers.WidgetLoadTimer = createTimer();
98
98
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
@@ -168,10 +168,16 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
168
168
  });
169
169
  }
170
170
  if (persistedState) {
171
+ var _TelemetryTimers$Widg;
171
172
  dispatch({
172
173
  type: LiveChatWidgetActionType.SET_WIDGET_STATE,
173
174
  payload: persistedState
174
175
  });
176
+ TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
177
+ Event: TelemetryEvent.WidgetLoadComplete,
178
+ Description: "Widget load complete. Persisted state retrieved",
179
+ ElapsedTimeInMilliseconds: TelemetryTimers === null || TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg = TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg === void 0 ? void 0 : _TelemetryTimers$Widg.milliSecondsElapsed
180
+ });
175
181
  await setPostChatContextAndLoadSurvey(chatSDK, dispatch, true);
176
182
  return;
177
183
  }
@@ -185,7 +191,7 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
185
191
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
186
192
  Event: TelemetryEvent.WidgetLoadComplete,
187
193
  Description: "Widget load complete",
188
- ElapsedTimeInMilliseconds: TelemetryTimers === null || TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg = TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg === void 0 ? void 0 : _TelemetryTimers$Widg.milliSecondsElapsed
194
+ ElapsedTimeInMilliseconds: TelemetryTimers === null || TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg2 = TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg2 === void 0 ? void 0 : _TelemetryTimers$Widg2.milliSecondsElapsed
189
195
  });
190
196
 
191
197
  // Set post chat context in state
@@ -195,15 +201,10 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
195
201
  // Updating chat session detail for telemetry
196
202
  await updateSessionDataForTelemetry(chatSDK, dispatch);
197
203
  } catch (ex) {
198
- TelemetryHelper.logLoadingEvent(LogLevel.ERROR, {
199
- Event: TelemetryEvent.WidgetLoadFailed,
200
- ExceptionDetails: {
201
- Exception: `Widget load Failed: ${ex}`
202
- }
203
- });
204
- NotificationHandler.notifyError(NotificationScenarios.Connection, "Start Chat Failed: " + ex);
204
+ var _TelemetryTimers$Widg4;
205
205
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
206
206
  if (ex.message === ChatSDKError.WidgetUseOutsideOperatingHour) {
207
+ var _TelemetryTimers$Widg3;
207
208
  dispatch({
208
209
  type: LiveChatWidgetActionType.SET_OUTSIDE_OPERATING_HOURS,
209
210
  payload: true
@@ -212,8 +213,21 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, props, params, persi
212
213
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
213
214
  payload: ConversationState.OutOfOffice
214
215
  });
216
+ TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
217
+ Event: TelemetryEvent.WidgetLoadComplete,
218
+ Description: "Widget load complete. Widget is OOOH.",
219
+ ElapsedTimeInMilliseconds: TelemetryTimers === null || TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg3 = TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg3 === void 0 ? void 0 : _TelemetryTimers$Widg3.milliSecondsElapsed
220
+ });
215
221
  return;
216
222
  }
223
+ TelemetryHelper.logLoadingEvent(LogLevel.ERROR, {
224
+ Event: TelemetryEvent.WidgetLoadFailed,
225
+ ExceptionDetails: {
226
+ Exception: `Widget load Failed: ${ex}`
227
+ },
228
+ ElapsedTimeInMilliseconds: TelemetryTimers === null || TelemetryTimers === void 0 ? void 0 : (_TelemetryTimers$Widg4 = TelemetryTimers.WidgetLoadTimer) === null || _TelemetryTimers$Widg4 === void 0 ? void 0 : _TelemetryTimers$Widg4.milliSecondsElapsed
229
+ });
230
+ NotificationHandler.notifyError(NotificationScenarios.Connection, "Start Chat Failed: " + ex);
217
231
  dispatch({
218
232
  type: LiveChatWidgetActionType.SET_START_CHAT_FAILING,
219
233
  payload: true
@@ -134,6 +134,14 @@ export const LiveChatWidgetStateful = props => {
134
134
  }
135
135
  if (isChatValid === false) {
136
136
  if (localState) {
137
+ // adding the reconnect logic for the case when customer tries to reconnect from a new browser or InPrivate browser
138
+ if (isReconnectEnabled(props.chatConfig) === true) {
139
+ await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
140
+ // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
141
+ if (state.appStates.conversationState === ConversationState.Active || state.appStates.conversationState === ConversationState.ReconnectChat) {
142
+ return;
143
+ }
144
+ }
137
145
  await setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
138
146
  return;
139
147
  } else {
@@ -1,11 +1,11 @@
1
- import { LogLevel, TelemetryEvent, TelemetryInput } from "./TelemetryConstants";
2
1
  import { BaseContract, TelemetryContract } from "./definitions/Contracts";
3
2
  import { TelemetryData } from "./definitions/Payload";
3
+ import { LogLevel, TelemetryEvent, TelemetryInput } from "./TelemetryConstants";
4
4
  import ChatConfig from "@microsoft/omnichannel-chat-sdk/lib/core/ChatConfig";
5
- import LiveChatContext from "@microsoft/omnichannel-chat-sdk/lib/core/LiveChatContext";
6
- import LiveWorkItemDetails from "@microsoft/omnichannel-chat-sdk/lib/core/LiveWorkItemDetails";
7
5
  import { IInternalTelemetryData } from "./interfaces/IInternalTelemetryData";
8
6
  import { ITelemetryConfig } from "./interfaces/ITelemetryConfig";
7
+ import LiveChatContext from "@microsoft/omnichannel-chat-sdk/lib/core/LiveChatContext";
8
+ import LiveWorkItemDetails from "@microsoft/omnichannel-chat-sdk/lib/core/LiveWorkItemDetails";
9
9
  export interface TelemetryEventWrapper {
10
10
  Event: TelemetryEvent;
11
11
  Description?: string;
@@ -22,6 +22,7 @@ export interface LoadTelemetryData extends BaseTelemetryData {
22
22
  OCChatSDKVersion?: string;
23
23
  OCChatWidgetVersion?: string;
24
24
  OCChatComponentsVersion?: string;
25
+ Description?: string;
25
26
  }
26
27
  export interface MessageProcessingErrorData extends BaseTelemetryData {
27
28
  Event: string;
@@ -2,7 +2,7 @@ import { Dispatch } from "react";
2
2
  import { ILiveChatWidgetAction } from "../../../contexts/common/ILiveChatWidgetAction";
3
3
  import { ILiveChatWidgetContext } from "../../../contexts/common/ILiveChatWidgetContext";
4
4
  import { ILiveChatWidgetProps } from "../interfaces/ILiveChatWidgetProps";
5
- declare const initiatePostChat: (props: ILiveChatWidgetProps, conversationDetailsParam: any, state: ILiveChatWidgetContext, dispatch: Dispatch<ILiveChatWidgetAction>) => Promise<void>;
5
+ declare const initiatePostChat: (props: ILiveChatWidgetProps, conversationDetailsParam: any, state: ILiveChatWidgetContext, dispatch: Dispatch<ILiveChatWidgetAction>, postchatContext: any) => Promise<void>;
6
6
  declare const isPostChatEnabled: (props: ILiveChatWidgetProps, state: ILiveChatWidgetContext) => boolean;
7
7
  declare const getPostChatContext: (chatSDK: any, state: ILiveChatWidgetContext, dispatch: Dispatch<ILiveChatWidgetAction>) => Promise<void>;
8
8
  declare const setWidgetStateToInactive: (dispatch: Dispatch<ILiveChatWidgetAction>) => Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.0.4",
3
+ "version": "1.0.5-main.53e6741",
4
4
  "description": "Microsoft Omnichannel Chat Widget",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",
@@ -75,7 +75,7 @@
75
75
  },
76
76
  "dependencies": {
77
77
  "@microsoft/omnichannel-chat-components": "^1.0.1",
78
- "@microsoft/omnichannel-chat-sdk": "1.4.1",
78
+ "@microsoft/omnichannel-chat-sdk": "1.4.2",
79
79
  "abort-controller-es5": "^2.0.1",
80
80
  "dompurify": "^2.3.4",
81
81
  "markdown-it": "^12.3.2",