@microsoft/omnichannel-chat-widget 1.8.1-main.20b15cc → 1.8.1-main.3ee330c

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 (47) hide show
  1. package/lib/cjs/common/facades/FacadeChatSDK.js +42 -0
  2. package/lib/cjs/common/telemetry/TelemetryConstants.js +4 -0
  3. package/lib/cjs/common/telemetry/TelemetryManager.js +4 -4
  4. package/lib/cjs/common/telemetry/loggers/appInsightsLogger.js +4 -5
  5. package/lib/cjs/common/utils/xssUtils.js +79 -0
  6. package/lib/cjs/common/utils.js +3 -0
  7. package/lib/cjs/components/confirmationpanestateful/ConfirmationPaneStateful.js +7 -3
  8. package/lib/cjs/components/errorboundary/ErrorBoundary.js +68 -0
  9. package/lib/cjs/components/livechatwidget/LiveChatWidget.js +15 -4
  10. package/lib/cjs/components/livechatwidget/common/liveChatConfigUtils.js +1 -1
  11. package/lib/cjs/components/livechatwidget/common/persistentChatHelper.js +12 -5
  12. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +4 -0
  13. package/lib/cjs/components/livechatwidget/common/startChat.js +3 -9
  14. package/lib/cjs/components/livechatwidget/common/startChatErrorHandler.js +30 -1
  15. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +31 -19
  16. package/lib/cjs/components/ooohpanestateful/OOOHPaneStateful.js +23 -2
  17. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +14 -5
  18. package/lib/cjs/components/postchatsurveypanestateful/enums/CustomerVoiceEvents.js +1 -0
  19. package/lib/esm/common/facades/FacadeChatSDK.js +42 -0
  20. package/lib/esm/common/telemetry/TelemetryConstants.js +4 -0
  21. package/lib/esm/common/telemetry/TelemetryManager.js +4 -4
  22. package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +4 -5
  23. package/lib/esm/common/utils/xssUtils.js +72 -0
  24. package/lib/esm/common/utils.js +3 -0
  25. package/lib/esm/components/confirmationpanestateful/ConfirmationPaneStateful.js +7 -3
  26. package/lib/esm/components/errorboundary/ErrorBoundary.js +59 -0
  27. package/lib/esm/components/livechatwidget/LiveChatWidget.js +16 -5
  28. package/lib/esm/components/livechatwidget/common/liveChatConfigUtils.js +1 -1
  29. package/lib/esm/components/livechatwidget/common/persistentChatHelper.js +12 -5
  30. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +4 -0
  31. package/lib/esm/components/livechatwidget/common/startChat.js +3 -9
  32. package/lib/esm/components/livechatwidget/common/startChatErrorHandler.js +28 -0
  33. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +31 -19
  34. package/lib/esm/components/ooohpanestateful/OOOHPaneStateful.js +23 -2
  35. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +14 -5
  36. package/lib/esm/components/postchatsurveypanestateful/enums/CustomerVoiceEvents.js +1 -0
  37. package/lib/types/common/facades/FacadeChatSDK.d.ts +1 -0
  38. package/lib/types/common/telemetry/TelemetryConstants.d.ts +4 -0
  39. package/lib/types/common/telemetry/loggers/appInsightsLogger.d.ts +1 -1
  40. package/lib/types/common/utils/xssUtils.d.ts +29 -0
  41. package/lib/types/components/errorboundary/ErrorBoundary.d.ts +14 -0
  42. package/lib/types/components/livechatwidget/common/liveChatConfigUtils.d.ts +1 -1
  43. package/lib/types/components/livechatwidget/common/persistentChatHelper.d.ts +2 -1
  44. package/lib/types/components/livechatwidget/common/startChatErrorHandler.d.ts +1 -0
  45. package/lib/types/components/postchatsurveypanestateful/enums/CustomerVoiceEvents.d.ts +2 -1
  46. package/lib/types/components/postchatsurveypanestateful/interfaces/IPostChatSurveyPaneStatefulProps.d.ts +1 -0
  47. package/package.json +2 -2
@@ -52,7 +52,6 @@ var _initCallingSdk = require("../common/initCallingSdk");
52
52
  var _initConfirmationPropsComposer = require("../common/initConfirmationPropsComposer");
53
53
  var _initWebChatComposer = require("../common/initWebChatComposer");
54
54
  var _defaultCacheManager = require("../../../common/storage/default/defaultCacheManager");
55
- var _registerTelemetryLoggers = require("../common/registerTelemetryLoggers");
56
55
  var _setPostChatContextAndLoadSurvey = require("../common/setPostChatContextAndLoadSurvey");
57
56
  var _startProactiveChat = require("../common/startProactiveChat");
58
57
  var _useChatAdapterStore = _interopRequireDefault(require("../../../hooks/useChatAdapterStore"));
@@ -64,7 +63,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
64
63
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
65
64
  let uiTimer;
66
65
  const LiveChatWidgetStateful = props => {
67
- var _props$webChatContain, _props$styleProps, _props$webChatContain2, _props$webChatContain3, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain7, _state$appStates14, _props$webChatContain9, _props$webChatContain10, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _props$webChatContain11, _props$webChatContain12, _props$webChatContain13, _props$webChatContain14, _props$webChatContain15, _props$webChatContain16, _props$webChatContain17, _props$webChatContain18, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
66
+ var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _props$webChatContain7, _props$webChatContain8, _props$webChatContain9, _props$styleProps, _props$webChatContain10, _props$webChatContain11, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain15, _state$appStates14, _props$webChatContain17, _props$webChatContain18, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
68
67
  (0, _react2.useEffect)(() => {
69
68
  uiTimer = (0, _utils.createTimer)();
70
69
  _TelemetryHelper.TelemetryHelper.logLoadingEventToAllTelemetry(_TelemetryConstants.LogLevel.INFO, {
@@ -83,10 +82,13 @@ const LiveChatWidgetStateful = props => {
83
82
  const [facadeChatSDK] = (0, _useFacadeChatSDKStore.default)();
84
83
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
84
  const [voiceVideoCallingSDK, setVoiceVideoCallingSDK] = (0, _react2.useState)(undefined);
85
+ const [conversationId, setConversationId] = (0, _react2.useState)("");
86
86
  const {
87
87
  Composer
88
88
  } = _botframeworkWebchat.Components;
89
89
  const canStartProactiveChat = (0, _react2.useRef)(true);
90
+ const bubbleBackground = ((_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : (_props$webChatContain3 = _props$webChatContain2.webChatStyles) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.bubbleBackground) ?? ((_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : (_props$webChatContain5 = _props$webChatContain4.adaptiveCardStyles) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.background) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.background;
91
+ const bubbleTextColor = ((_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : (_props$webChatContain7 = _props$webChatContain6.webChatStyles) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.bubbleTextColor) ?? ((_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : (_props$webChatContain9 = _props$webChatContain8.adaptiveCardStyles) === null || _props$webChatContain9 === void 0 ? void 0 : _props$webChatContain9.color) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.color;
90
92
 
91
93
  // Process general styles
92
94
  const generalStyles = {
@@ -95,7 +97,7 @@ const LiveChatWidgetStateful = props => {
95
97
 
96
98
  //Scrollbar styles
97
99
  const scrollbarProps = Object.assign({}, _defaultScrollBarProps.defaultScrollBarProps, props === null || props === void 0 ? void 0 : props.scrollBarProps);
98
- const sendBoxTextArea = props === null || props === void 0 ? void 0 : (_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : (_props$webChatContain3 = _props$webChatContain2.sendBoxTextBox) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.textarea;
100
+ const sendBoxTextArea = props === null || props === void 0 ? void 0 : (_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : (_props$webChatContain11 = _props$webChatContain10.sendBoxTextBox) === null || _props$webChatContain11 === void 0 ? void 0 : _props$webChatContain11.textarea;
99
101
 
100
102
  // In case the broadcast channel is already initialized elsewhere; One tab can only hold 1 instance
101
103
  if ((props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.skipBroadcastChannelInit) !== true) {
@@ -228,7 +230,6 @@ const LiveChatWidgetStateful = props => {
228
230
  state.domainStates.confirmationPaneConfirmedOptionClicked = false;
229
231
  state.domainStates.confirmationState = _Constants.ConfirmationState.NotSet;
230
232
  setupClientDataStore();
231
- (0, _registerTelemetryLoggers.registerTelemetryLoggers)(props, dispatch);
232
233
  (0, _createInternetConnectionChangeHandler.createInternetConnectionChangeHandler)(state);
233
234
  dispatch({
234
235
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_WIDGET_ELEMENT_ID,
@@ -578,6 +579,14 @@ const LiveChatWidgetStateful = props => {
578
579
  });
579
580
  });
580
581
 
582
+ // Retrieve convId
583
+ _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.UpdateConversationDataForTelemetry).subscribe(msg => {
584
+ var _msg$payload11, _msg$payload11$liveWo;
585
+ if ((_msg$payload11 = msg.payload) !== null && _msg$payload11 !== void 0 && (_msg$payload11$liveWo = _msg$payload11.liveWorkItem) !== null && _msg$payload11$liveWo !== void 0 && _msg$payload11$liveWo.conversationId) {
586
+ setConversationId(msg.payload.liveWorkItem.conversationId);
587
+ }
588
+ });
589
+
581
590
  // Check for TPC and log in telemetry if blocked
582
591
  (0, _defaultClientDataStoreProvider.isCookieAllowed)();
583
592
  return () => {
@@ -624,8 +633,8 @@ const LiveChatWidgetStateful = props => {
624
633
  });
625
634
  }
626
635
  if (state.appStates.conversationState === _ConversationState.ConversationState.InActive) {
627
- var _props$webChatContain4, _props$webChatContain5;
628
- if ((props === null || props === void 0 ? void 0 : (_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : (_props$webChatContain5 = _props$webChatContain4.renderingMiddlewareProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.hideSendboxOnConversationEnd) !== false) {
636
+ var _props$webChatContain12, _props$webChatContain13;
637
+ if ((props === null || props === void 0 ? void 0 : (_props$webChatContain12 = props.webChatContainerProps) === null || _props$webChatContain12 === void 0 ? void 0 : (_props$webChatContain13 = _props$webChatContain12.renderingMiddlewareProps) === null || _props$webChatContain13 === void 0 ? void 0 : _props$webChatContain13.hideSendboxOnConversationEnd) !== false) {
629
638
  setWebChatStyles(styles => {
630
639
  return {
631
640
  ...styles,
@@ -669,12 +678,12 @@ const LiveChatWidgetStateful = props => {
669
678
  }
670
679
  }, [state.appStates.unreadMessageCount]);
671
680
  (0, _react2.useEffect)(() => {
672
- var _props$webChatContain6;
681
+ var _props$webChatContain14;
673
682
  setWebChatStyles({
674
683
  ...webChatStyles,
675
- ...((_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.webChatStyles)
684
+ ...((_props$webChatContain14 = props.webChatContainerProps) === null || _props$webChatContain14 === void 0 ? void 0 : _props$webChatContain14.webChatStyles)
676
685
  });
677
- }, [(_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.webChatStyles]);
686
+ }, [(_props$webChatContain15 = props.webChatContainerProps) === null || _props$webChatContain15 === void 0 ? void 0 : _props$webChatContain15.webChatStyles]);
678
687
  (0, _react2.useEffect)(() => {
679
688
  //Confirmation pane dismissing through OK option, so proceed with end chat
680
689
  if (state.domainStates.confirmationState === _Constants.ConfirmationState.Ok) {
@@ -773,12 +782,12 @@ const LiveChatWidgetStateful = props => {
773
782
 
774
783
  // if props state gets updates we need to update the renderingMiddlewareProps in the state
775
784
  (0, _react2.useEffect)(() => {
776
- var _props$webChatContain8;
785
+ var _props$webChatContain16;
777
786
  dispatch({
778
787
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
779
- payload: (_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : _props$webChatContain8.renderingMiddlewareProps
788
+ payload: (_props$webChatContain16 = props.webChatContainerProps) === null || _props$webChatContain16 === void 0 ? void 0 : _props$webChatContain16.renderingMiddlewareProps
780
789
  });
781
- }, [(_props$webChatContain9 = props.webChatContainerProps) === null || _props$webChatContain9 === void 0 ? void 0 : _props$webChatContain9.renderingMiddlewareProps]);
790
+ }, [(_props$webChatContain17 = props.webChatContainerProps) === null || _props$webChatContain17 === void 0 ? void 0 : _props$webChatContain17.renderingMiddlewareProps]);
782
791
  (0, _react2.useEffect)(() => {
783
792
  _TelemetryHelper.TelemetryHelper.logLoadingEventToAllTelemetry(_TelemetryConstants.LogLevel.INFO, {
784
793
  Event: _TelemetryConstants.TelemetryEvent.UXLiveChatWidgetCompleted,
@@ -821,7 +830,7 @@ const LiveChatWidgetStateful = props => {
821
830
  const webChatProps = (0, _initWebChatComposer.initWebChatComposer)(props, state, dispatch, facadeChatSDK, endChatRelay);
822
831
  const downloadTranscriptProps = (0, _createDownloadTranscriptProps.default)(props.downloadTranscriptProps, {
823
832
  ...(_defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps === null || _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps === void 0 ? void 0 : _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatStyles),
824
- ...((_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatStyles)
833
+ ...((_props$webChatContain18 = props.webChatContainerProps) === null || _props$webChatContain18 === void 0 ? void 0 : _props$webChatContain18.webChatStyles)
825
834
  }, props.webChatContainerProps);
826
835
  const livechatProps = {
827
836
  ...props,
@@ -847,6 +856,11 @@ const LiveChatWidgetStateful = props => {
847
856
  (0, _utils.setOcUserAgent)(facadeChatSDK.getChatSDK());
848
857
  const directLine = ((_livechatProps$webCha = livechatProps.webChatContainerProps) === null || _livechatProps$webCha === void 0 ? void 0 : _livechatProps$webCha.directLine) ?? adapter ?? _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.directLine;
849
858
  const userID = directLine.getState ? directLine === null || directLine === void 0 ? void 0 : directLine.getState("acs.userId") : "teamsvisitor";
859
+ const styleOptions = _react2.default.useMemo(() => ({
860
+ ...webChatStyles,
861
+ bubbleBackground,
862
+ bubbleTextColor
863
+ }), [webChatStyles, bubbleBackground, bubbleTextColor]);
850
864
 
851
865
  // WebChat's Composer can only be rendered if a directLine object is defined
852
866
  return directLine && /*#__PURE__*/_react2.default.createElement(_react2.default.Fragment, null, /*#__PURE__*/_react2.default.createElement("style", null, `
@@ -885,11 +899,7 @@ const LiveChatWidgetStateful = props => {
885
899
  }`}
886
900
  `), /*#__PURE__*/_react2.default.createElement(_DraggableChatWidget.default, chatWidgetDraggableConfig, /*#__PURE__*/_react2.default.createElement(Composer, _extends({}, webChatProps, {
887
901
  userID: userID,
888
- styleOptions: {
889
- ...webChatStyles,
890
- bubbleBackground: ((_props$webChatContain11 = props.webChatContainerProps) === null || _props$webChatContain11 === void 0 ? void 0 : (_props$webChatContain12 = _props$webChatContain11.webChatStyles) === null || _props$webChatContain12 === void 0 ? void 0 : _props$webChatContain12.bubbleBackground) ?? ((_props$webChatContain13 = props.webChatContainerProps) === null || _props$webChatContain13 === void 0 ? void 0 : (_props$webChatContain14 = _props$webChatContain13.adaptiveCardStyles) === null || _props$webChatContain14 === void 0 ? void 0 : _props$webChatContain14.background) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.background,
891
- bubbleTextColor: ((_props$webChatContain15 = props.webChatContainerProps) === null || _props$webChatContain15 === void 0 ? void 0 : (_props$webChatContain16 = _props$webChatContain15.webChatStyles) === null || _props$webChatContain16 === void 0 ? void 0 : _props$webChatContain16.bubbleTextColor) ?? ((_props$webChatContain17 = props.webChatContainerProps) === null || _props$webChatContain17 === void 0 ? void 0 : (_props$webChatContain18 = _props$webChatContain17.adaptiveCardStyles) === null || _props$webChatContain18 === void 0 ? void 0 : _props$webChatContain18.color) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.color
892
- },
902
+ styleOptions: styleOptions,
893
903
  directLine: directLine
894
904
  }), /*#__PURE__*/_react2.default.createElement(_react.Stack, {
895
905
  id: widgetElementId,
@@ -920,7 +930,9 @@ const LiveChatWidgetStateful = props => {
920
930
  }, livechatProps.callingContainerProps)), !((_livechatProps$contro11 = livechatProps.controlProps) !== null && _livechatProps$contro11 !== void 0 && _livechatProps$contro11.hideWebChatContainer) && (0, _componentController.shouldShowWebChatContainer)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon9 = livechatProps.componentOverrides) === null || _livechatProps$compon9 === void 0 ? void 0 : _livechatProps$compon9.webChatContainer) || /*#__PURE__*/_react2.default.createElement(_WebChatContainerStateful.default, livechatProps)), !((_livechatProps$contro12 = livechatProps.controlProps) !== null && _livechatProps$contro12 !== void 0 && _livechatProps$contro12.hideConfirmationPane) && (0, _componentController.shouldShowConfirmationPane)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon10 = livechatProps.componentOverrides) === null || _livechatProps$compon10 === void 0 ? void 0 : _livechatProps$compon10.confirmationPane) || /*#__PURE__*/_react2.default.createElement(_ConfirmationPaneStateful.default, _extends({}, confirmationPaneProps, {
921
931
  setPostChatContext: setPostChatContextRelay,
922
932
  prepareEndChat: prepareEndChatRelay
923
- }))), !((_livechatProps$contro13 = livechatProps.controlProps) !== null && _livechatProps$contro13 !== void 0 && _livechatProps$contro13.hidePostChatLoadingPane) && (0, _componentController.shouldShowPostChatLoadingPane)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon11 = livechatProps.componentOverrides) === null || _livechatProps$compon11 === void 0 ? void 0 : _livechatProps$compon11.postChatLoadingPane) || /*#__PURE__*/_react2.default.createElement(_PostChatLoadingPaneStateful.default, livechatProps.postChatLoadingPaneProps)), (0, _componentController.shouldShowPostChatSurveyPane)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon12 = livechatProps.componentOverrides) === null || _livechatProps$compon12 === void 0 ? void 0 : _livechatProps$compon12.postChatSurveyPane) || /*#__PURE__*/_react2.default.createElement(_PostChatSurveyPaneStateful.default, _extends({}, livechatProps.postChatSurveyPaneProps, livechatProps.chatSDK))), (0, _createFooter.createFooter)(livechatProps, state), (0, _componentController.shouldShowEmailTranscriptPane)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon13 = livechatProps.componentOverrides) === null || _livechatProps$compon13 === void 0 ? void 0 : _livechatProps$compon13.emailTranscriptPane) || /*#__PURE__*/_react2.default.createElement(_EmailTranscriptPaneStateful.default, livechatProps.emailTranscriptPane))))));
933
+ }))), !((_livechatProps$contro13 = livechatProps.controlProps) !== null && _livechatProps$contro13 !== void 0 && _livechatProps$contro13.hidePostChatLoadingPane) && (0, _componentController.shouldShowPostChatLoadingPane)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon11 = livechatProps.componentOverrides) === null || _livechatProps$compon11 === void 0 ? void 0 : _livechatProps$compon11.postChatLoadingPane) || /*#__PURE__*/_react2.default.createElement(_PostChatLoadingPaneStateful.default, livechatProps.postChatLoadingPaneProps)), (0, _componentController.shouldShowPostChatSurveyPane)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon12 = livechatProps.componentOverrides) === null || _livechatProps$compon12 === void 0 ? void 0 : _livechatProps$compon12.postChatSurveyPane) || /*#__PURE__*/_react2.default.createElement(_PostChatSurveyPaneStateful.default, _extends({}, livechatProps.postChatSurveyPaneProps, livechatProps.chatSDK, {
934
+ customerVoiceSurveyCorrelationId: conversationId
935
+ }))), (0, _createFooter.createFooter)(livechatProps, state), (0, _componentController.shouldShowEmailTranscriptPane)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon13 = livechatProps.componentOverrides) === null || _livechatProps$compon13 === void 0 ? void 0 : _livechatProps$compon13.emailTranscriptPane) || /*#__PURE__*/_react2.default.createElement(_EmailTranscriptPaneStateful.default, livechatProps.emailTranscriptPane))))));
924
936
  };
925
937
  exports.LiveChatWidgetStateful = LiveChatWidgetStateful;
926
938
  var _default = LiveChatWidgetStateful;
@@ -7,15 +7,16 @@ exports.default = exports.OutOfOfficeHoursPaneStateful = void 0;
7
7
  var _TelemetryConstants = require("../../common/telemetry/TelemetryConstants");
8
8
  var _react = _interopRequireWildcard(require("react"));
9
9
  var _utils = require("../../common/utils");
10
- var _dompurify = _interopRequireDefault(require("dompurify"));
11
10
  var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
12
11
  var _TelemetryHelper = require("../../common/telemetry/TelemetryHelper");
13
12
  var _defaultgeneralOOOHPaneStyleProps = require("./common/defaultStyleProps/defaultgeneralOOOHPaneStyleProps");
13
+ var _xssUtils = require("../../common/utils/xssUtils");
14
14
  var _useChatContextStore = _interopRequireDefault(require("../../hooks/useChatContextStore"));
15
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
16
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
17
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
18
18
  let uiTimer;
19
+ const OOOHPaneTitleText = "Thanks for contacting us. You have reached us outside of our operating hours. An agent will respond when we open.";
19
20
  const OutOfOfficeHoursPaneStateful = props => {
20
21
  var _props$styleProps;
21
22
  (0, _react.useEffect)(() => {
@@ -54,8 +55,28 @@ const OutOfOfficeHoursPaneStateful = props => {
54
55
  ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
55
56
  });
56
57
  }, []);
58
+
59
+ // Enhanced titleText sanitization
57
60
  if (controlProps !== null && controlProps !== void 0 && controlProps.titleText) {
58
- controlProps.titleText = _dompurify.default.sanitize(controlProps.titleText);
61
+ const {
62
+ cleanText,
63
+ isXSSDetected
64
+ } = (0, _xssUtils.detectAndCleanXSS)(controlProps.titleText);
65
+ if (!isXSSDetected) {
66
+ // replace with the sanitized text
67
+ controlProps.titleText = cleanText;
68
+ } else {
69
+ _TelemetryHelper.TelemetryHelper.logLoadingEventToAllTelemetry(_TelemetryConstants.LogLevel.WARN, {
70
+ Event: _TelemetryConstants.TelemetryEvent.XSSTextDetected,
71
+ Description: "Potential XSS attempt detected in titleText",
72
+ CustomProperties: {
73
+ originalText: controlProps.titleText.substring(0, 100),
74
+ // Log first 100 chars for analysis
75
+ cleanedText: cleanText.substring(0, 100)
76
+ }
77
+ });
78
+ controlProps.titleText = OOOHPaneTitleText;
79
+ }
59
80
  }
60
81
  return /*#__PURE__*/_react.default.createElement(_omnichannelChatComponents.OutOfOfficeHoursPane, {
61
82
  componentOverrides: props.componentOverrides,
@@ -18,13 +18,14 @@ var _isValidSurveyUrl = _interopRequireDefault(require("./common/isValidSurveyUr
18
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
19
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
20
20
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
- const generateSurveyInviteLink = function (surveyInviteLink, isEmbed, locale, compact) {
22
- let showMultiLingual = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
21
+ const generateSurveyInviteLink = function (surveyInviteLink, isEmbed, locale, compact, customerVoiceSurveyCorrelationId) {
22
+ let showMultiLingual = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
23
23
  const surveyLinkParams = new URLSearchParams({
24
24
  embed: isEmbed.toString(),
25
25
  compact: (compact ?? true).toString(),
26
26
  lang: locale ?? "en-us",
27
- showmultilingual: (showMultiLingual ?? false).toString()
27
+ showmultilingual: (showMultiLingual ?? false).toString(),
28
+ cvResponsePageRequestId: customerVoiceSurveyCorrelationId
28
29
  });
29
30
  return `${surveyInviteLink}&${surveyLinkParams.toString()}`;
30
31
  };
@@ -40,9 +41,9 @@ const PostChatSurveyPaneStateful = props => {
40
41
  // Bot survey enabled
41
42
  state.appStates.postChatParticipantType === _Constants.ParticipantType.Bot) {
42
43
  // Only Bot has engaged
43
- surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.botSurveyInviteLink, surveyMode, state.domainStates.postChatContext.botFormsProLocale, props.isCustomerVoiceSurveyCompact ?? true);
44
+ surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.botSurveyInviteLink, surveyMode, state.domainStates.postChatContext.botFormsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
44
45
  } else {
45
- surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.surveyInviteLink, surveyMode, state.domainStates.postChatContext.formsProLocale, props.isCustomerVoiceSurveyCompact ?? true);
46
+ surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.surveyInviteLink, surveyMode, state.domainStates.postChatContext.formsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
46
47
  }
47
48
  if (props.copilotSurveyContext) {
48
49
  surveyInviteLink = `${surveyInviteLink}&mcs_additionalcontext=${JSON.stringify(props.copilotSurveyContext)}`;
@@ -105,6 +106,14 @@ const PostChatSurveyPaneStateful = props => {
105
106
  message: "Customer Voice form response error."
106
107
  }
107
108
  });
109
+ } else if (typeof data === "string" && data.startsWith(_CustomerVoiceEvents.CustomerVoiceEvents.FormsError)) {
110
+ _TelemetryHelper.TelemetryHelper.logActionEventToAllTelemetry(_TelemetryConstants.LogLevel.ERROR, {
111
+ Event: _TelemetryConstants.TelemetryEvent.CustomerVoiceFormsError,
112
+ Description: "Customer Voice failed to load with forms error.",
113
+ ExceptionDetails: {
114
+ message: `Customer Voice forms error details: ${data}`
115
+ }
116
+ });
108
117
  }
109
118
  });
110
119
  }, []);
@@ -10,4 +10,5 @@ exports.CustomerVoiceEvents = CustomerVoiceEvents;
10
10
  CustomerVoiceEvents["ResponsePageLoaded"] = "ResponsePageLoaded";
11
11
  CustomerVoiceEvents["FormResponseSubmitted"] = "FormResponseSubmitted";
12
12
  CustomerVoiceEvents["FormResponseError"] = "FormResponseError";
13
+ CustomerVoiceEvents["FormsError"] = "FormsError";
13
14
  })(CustomerVoiceEvents || (exports.CustomerVoiceEvents = CustomerVoiceEvents = {}));
@@ -439,6 +439,48 @@ export let FacadeChatSDK = /*#__PURE__*/function () {
439
439
  let optionalParams = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
440
440
  return this.validateAndExecuteCall("getAgentAvailability", () => this.chatSDK.getAgentAvailability(optionalParams));
441
441
  }
442
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
443
+ }, {
444
+ key: "getReconnectableChats",
445
+ value: async function getReconnectableChats() {
446
+ let reconnectableChatsParams = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
447
+ /**
448
+ *
449
+ * This is a particular case, we dont expose getReconnectableChats in the SDK,
450
+ * The only way to use is by tunneling directly from the SDK to OCSDK,
451
+ *
452
+ * In case of prechat, the function is called before any formal authentication is made,
453
+ * this is an specific case for persistent chats, to prevent the survey be loaded again for an on going chat,
454
+ *
455
+ * In this case, we check for existance of the token , otherwise we perform the authentication, error is propagated in case of issues.
456
+ *
457
+ * Once the token is obtained , this will be added to the params to call the function.
458
+ *
459
+ * This is a particular case, should not be taken as pattern.
460
+ *
461
+ */
462
+
463
+ if (this.token === null || this.token === "") {
464
+ // If token is not set, try to get it using tokenRing
465
+ const pingResponse = await this.tokenRing();
466
+ if (pingResponse.result === false) {
467
+ const errorMessage = `Authentication failed: Process to get a token failed for getReconnectableChats, ${pingResponse.message}`;
468
+ //telemetry is already logged in tokenRing, so no need to log again, just return the error and communicate to the console
469
+ console.error(errorMessage);
470
+ BroadcastService.postMessage({
471
+ eventName: BroadcastEvent.OnWidgetError,
472
+ payload: {
473
+ errorMessage: errorMessage
474
+ }
475
+ });
476
+ throw new Error(errorMessage);
477
+ }
478
+ }
479
+
480
+ // Always override the token in params regardless of how getReconnectableChats was called
481
+ reconnectableChatsParams.authenticatedUserToken = this.token;
482
+ return this.validateAndExecuteCall("getReconnectableChats", () => this.chatSDK.OCClient.getReconnectableChats(reconnectableChatsParams));
483
+ }
442
484
  }]);
443
485
  return FacadeChatSDK;
444
486
  }();
@@ -106,6 +106,8 @@ export let TelemetryEvent;
106
106
  TelemetryEvent["DisconnectEndChatSDKCallFailed"] = "DisconnectEndChatSDKCallFailed";
107
107
  TelemetryEvent["GetChatReconnectContextSDKCallStarted"] = "GetChatReconnectContextSDKCallStarted";
108
108
  TelemetryEvent["GetChatReconnectContextSDKCallFailed"] = "GetChatReconnectContextSDKCallFailed";
109
+ TelemetryEvent["CheckContactIdError"] = "checkContactIdError";
110
+ TelemetryEvent["GetChatReconnectContextSDKCallSucceeded"] = "GetChatReconnectContextSDKCallSucceeded";
109
111
  TelemetryEvent["ParseAdaptiveCardFailed"] = "ParseAdaptiveCardFailed";
110
112
  TelemetryEvent["ClientDataStoreProviderFailed"] = "ClientDataStoreProviderFailed";
111
113
  TelemetryEvent["InMemoryDataStoreFailed"] = "InMemoryDataStoreFailed";
@@ -173,6 +175,7 @@ export let TelemetryEvent;
173
175
  TelemetryEvent["CustomerVoiceResponsePageLoaded"] = "CustomerVoiceResponsePageLoaded";
174
176
  TelemetryEvent["CustomerVoiceFormResponseSubmitted"] = "CustomerVoiceFormResponseSubmitted";
175
177
  TelemetryEvent["CustomerVoiceFormResponseError"] = "CustomerVoiceFormResponseError";
178
+ TelemetryEvent["CustomerVoiceFormsError"] = "CustomerVoiceFormsError";
176
179
  TelemetryEvent["BotAuthActivityEmptySasUrl"] = "BotAuthActivityEmptySasUrl";
177
180
  TelemetryEvent["SetBotAuthProviderFetchConfig"] = "SetBotAuthProviderFetchConfig";
178
181
  TelemetryEvent["SetBotAuthProviderHideCard"] = "SetBotAuthProviderHideCard";
@@ -250,6 +253,7 @@ export let TelemetryEvent;
250
253
  TelemetryEvent["UXNotificationPaneCompleted"] = "UXNotificationPaneCompleted";
251
254
  TelemetryEvent["UXOutOfOfficeHoursPaneStart"] = "UXOutOfOfficeHoursPaneStart";
252
255
  TelemetryEvent["UXOutOfOfficeHoursPaneCompleted"] = "UXOutOfOfficeHoursPaneCompleted";
256
+ TelemetryEvent["XSSTextDetected"] = "XSSTextDetected";
253
257
  TelemetryEvent["UXPostChatLoadingPaneStart"] = "UXPostChatLoadingPaneStart";
254
258
  TelemetryEvent["UXPostChatLoadingPaneCompleted"] = "UXPostChatLoadingPaneCompleted";
255
259
  TelemetryEvent["UXPrechatPaneStart"] = "UXPrechatPaneStart";
@@ -6,11 +6,11 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typ
6
6
  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); }
7
7
  import { LogLevel, ScenarioType, TelemetryConstants, TelemetryEvent } from "./TelemetryConstants";
8
8
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
9
+ import { TelemetryHelper } from "./TelemetryHelper";
10
+ import { appInsightsLogger } from "./loggers/appInsightsLogger";
9
11
  import { ariaTelemetryLogger } from "./loggers/ariaTelemetryLogger";
10
12
  import { consoleLogger } from "./loggers/consoleLogger";
11
13
  import { defaultAriaConfig } from "./defaultConfigs/defaultAriaConfig";
12
- import { TelemetryHelper } from "./TelemetryHelper";
13
- import { appInsightsLogger } from "./loggers/appInsightsLogger";
14
14
  export let TelemetryTimers = /*#__PURE__*/_createClass(function TelemetryTimers() {
15
15
  _classCallCheck(this, TelemetryTimers);
16
16
  });
@@ -55,8 +55,8 @@ export const RegisterLoggers = () => {
55
55
  if (((_TelemetryManager$Int22 = TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int22 === void 0 ? void 0 : (_TelemetryManager$Int23 = _TelemetryManager$Int22.appInsightsConfig) === null || _TelemetryManager$Int23 === void 0 ? void 0 : _TelemetryManager$Int23.appInsightsDisabled) === false) {
56
56
  var _TelemetryManager$Int24;
57
57
  if ((_TelemetryManager$Int24 = TelemetryManager.InternalTelemetryData) !== null && _TelemetryManager$Int24 !== void 0 && _TelemetryManager$Int24.appInsightsConfig.appInsightsKey) {
58
- var _TelemetryManager$Int25, _TelemetryManager$Int26, _TelemetryManager$Int27;
59
- loggers.push(appInsightsLogger((_TelemetryManager$Int25 = TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int25 === void 0 ? void 0 : _TelemetryManager$Int25.appInsightsConfig.appInsightsKey, ((_TelemetryManager$Int26 = TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int26 === void 0 ? void 0 : (_TelemetryManager$Int27 = _TelemetryManager$Int26.ariaConfig) === null || _TelemetryManager$Int27 === void 0 ? void 0 : _TelemetryManager$Int27.disableCookieUsage) ?? defaultAriaConfig.disableCookieUsage));
58
+ var _TelemetryManager$Int25;
59
+ loggers.push(appInsightsLogger((_TelemetryManager$Int25 = TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int25 === void 0 ? void 0 : _TelemetryManager$Int25.appInsightsConfig.appInsightsKey));
60
60
  }
61
61
  }
62
62
  }
@@ -16,14 +16,14 @@ var AllowedKeys;
16
16
  AllowedKeys["ElapsedTimeInMilliseconds"] = "DurationInMilliseconds";
17
17
  })(AllowedKeys || (AllowedKeys = {}));
18
18
  let initializationPromise = null;
19
- export const appInsightsLogger = (appInsightsKey, disableCookiesUsage) => {
19
+ export const appInsightsLogger = appInsightsKey => {
20
20
  const isValidKey = key => {
21
21
  const INSTRUMENTATION_KEY_PATTERN = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}";
22
22
  const INSTRUMENTATION_KEY_REGEX = new RegExp(`^${INSTRUMENTATION_KEY_PATTERN}$`);
23
23
  const CONNECTION_STRING_REGEX = new RegExp(`^InstrumentationKey=${INSTRUMENTATION_KEY_PATTERN};IngestionEndpoint=https://[a-zA-Z0-9\\-\\.]+\\.applicationinsights\\.azure\\.com/.*`);
24
24
  return INSTRUMENTATION_KEY_REGEX.test(key) || CONNECTION_STRING_REGEX.test(key);
25
25
  };
26
- const initializeAppInsights = async (appInsightsKey, disableCookiesUsage) => {
26
+ const initializeAppInsights = async appInsightsKey => {
27
27
  if (!window.appInsights && appInsightsKey) {
28
28
  if (!isValidKey(appInsightsKey)) {
29
29
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
@@ -45,8 +45,7 @@ export const appInsightsLogger = (appInsightsKey, disableCookiesUsage) => {
45
45
  connectionString: appInsightsKey
46
46
  } : {
47
47
  instrumentationKey: appInsightsKey
48
- }),
49
- disableCookiesUsage: disableCookiesUsage
48
+ })
50
49
  };
51
50
 
52
51
  // Initialize Application Insights instance
@@ -73,7 +72,7 @@ export const appInsightsLogger = (appInsightsKey, disableCookiesUsage) => {
73
72
  };
74
73
  const logger = async () => {
75
74
  if (!initializationPromise) {
76
- initializationPromise = initializeAppInsights(appInsightsKey, disableCookiesUsage);
75
+ initializationPromise = initializeAppInsights(appInsightsKey);
77
76
  }
78
77
  await initializationPromise;
79
78
  return window.appInsights;
@@ -0,0 +1,72 @@
1
+ import DOMPurify from "dompurify";
2
+
3
+ /**
4
+ * Detects potential Cross-Site Scripting (XSS) attacks in text input and sanitizes the content.
5
+ *
6
+ * This function performs comprehensive XSS detection using pattern matching for common attack vectors
7
+ * and then sanitizes the input using DOMPurify with strict configuration. It's designed to protect
8
+ * against various XSS techniques including script injection, event handler injection, style-based
9
+ * attacks, and encoded payloads.
10
+ *
11
+ * Security patterns detected:
12
+ * - JavaScript protocol URLs (javascript:)
13
+ * - HTML event handlers (onmouseover, onclick, etc.)
14
+ * - Script tags (<script>)
15
+ * - CSS expression() functions
16
+ * - CSS url() functions
17
+ * - Position-based CSS attacks (position: fixed/absolute)
18
+ * - VBScript protocol URLs
19
+ * - Data URLs with HTML content
20
+ * - Fragment identifiers with escaped quotes
21
+ * - HTML entity-encoded angle brackets
22
+ *
23
+ * @param text - The input text to be analyzed and sanitized
24
+ * @returns An object containing:
25
+ * - cleanText: The sanitized version of the input text with all HTML tags and attributes removed
26
+ * - isXSSDetected: Boolean flag indicating whether potential XSS patterns were found in the original text
27
+ */
28
+ export const detectAndCleanXSS = text => {
29
+ // Comprehensive array of regular expressions to detect common XSS attack patterns
30
+ const xssPatterns = [/javascript\s*:/gi,
31
+ // JavaScript protocol URLs (with optional spaces)
32
+ /vbscript\s*:/gi,
33
+ // VBScript protocol URLs (with optional spaces)
34
+ /on\w+\s*=/gi,
35
+ // HTML event handlers (onmouseover, onclick, onload, etc.)
36
+ /<\s*script/gi,
37
+ // Script tag opening (with optional spaces)
38
+ /expression\s*\(/gi,
39
+ // CSS expression() function (IE-specific)
40
+ /url\s*\(/gi,
41
+ // CSS url() function
42
+ /style\s*=.*position\s*:\s*fixed/gi,
43
+ // CSS position fixed attacks
44
+ /style\s*=.*position\s*:\s*absolute/gi,
45
+ // CSS position absolute attacks
46
+ /data\s*:\s*text\s*\/\s*html/gi,
47
+ // Data URLs containing HTML
48
+ /#.*\\"/gi,
49
+ // Fragment identifiers with escaped quotes
50
+ /&gt;.*&lt;/gi // HTML entity-encoded angle brackets indicating tag structure
51
+ ];
52
+
53
+ // Check if any XSS patterns are detected in the input text
54
+ const isXSSDetected = xssPatterns.some(pattern => pattern.test(text));
55
+
56
+ // Clean the text using DOMPurify with strict config
57
+ const cleanText = DOMPurify.sanitize(text, {
58
+ ALLOWED_TAGS: [],
59
+ // No HTML tags allowed in title
60
+ ALLOWED_ATTR: [],
61
+ KEEP_CONTENT: true,
62
+ // Keep text content
63
+ ALLOW_DATA_ATTR: false,
64
+ ALLOW_UNKNOWN_PROTOCOLS: false,
65
+ SANITIZE_DOM: true,
66
+ FORCE_BODY: false
67
+ });
68
+ return {
69
+ cleanText,
70
+ isXSSDetected
71
+ };
72
+ };
@@ -385,6 +385,9 @@ export const getConversationDetailsCall = async function (facadeChatSDK) {
385
385
 
386
386
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
387
387
  export const checkContactIdError = e => {
388
+ TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
389
+ Event: TelemetryEvent.CheckContactIdError
390
+ });
388
391
  if ((e === null || e === void 0 ? void 0 : e.message) === ChatSDKErrorName.AuthContactIdNotFoundFailure) {
389
392
  const contactIdNotFoundErrorEvent = {
390
393
  eventName: BroadcastEvent.ContactIdNotFound,
@@ -75,9 +75,13 @@ export const ConfirmationPaneStateful = props => {
75
75
  useEffect(() => {
76
76
  preventFocusToMoveOutOfElement(controlProps.id);
77
77
  const focusableElements = findAllFocusableElement(`#${controlProps.id}`);
78
- if (focusableElements) {
79
- focusableElements[0].focus();
80
- }
78
+ requestAnimationFrame(() => {
79
+ if (focusableElements && focusableElements.length > 0 && focusableElements[0]) {
80
+ focusableElements[0].focus({
81
+ preventScroll: true
82
+ });
83
+ }
84
+ });
81
85
  elements = findParentFocusableElementsWithoutChildContainer(controlProps.id);
82
86
  setTabIndices(elements, initialTabIndexMap, false);
83
87
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
@@ -0,0 +1,59 @@
1
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
3
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
4
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
5
+ 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); }
6
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
7
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
8
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
9
+ function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
10
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
11
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
12
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
13
+ import React, { Component } from 'react';
14
+ const RenderChildrenFunction = _ref => {
15
+ let {
16
+ children
17
+ } = _ref;
18
+ return typeof children === 'function' ? children() : children;
19
+ };
20
+ let ErrorBoundary = /*#__PURE__*/function (_Component) {
21
+ _inherits(ErrorBoundary, _Component);
22
+ var _super = _createSuper(ErrorBoundary);
23
+ function ErrorBoundary(props) {
24
+ var _this;
25
+ _classCallCheck(this, ErrorBoundary);
26
+ _this = _super.call(this, props);
27
+ _this.state = {
28
+ hasError: false
29
+ };
30
+ return _this;
31
+ }
32
+ _createClass(ErrorBoundary, [{
33
+ key: "componentDidCatch",
34
+ value: function componentDidCatch(error) {
35
+ const {
36
+ onError
37
+ } = this.props;
38
+ this.setState({
39
+ hasError: true
40
+ });
41
+ if (onError) {
42
+ onError(error);
43
+ }
44
+ }
45
+ }, {
46
+ key: "render",
47
+ value: function render() {
48
+ const {
49
+ children
50
+ } = this.props;
51
+ const {
52
+ hasError
53
+ } = this.state;
54
+ return !hasError && /*#__PURE__*/React.createElement(RenderChildrenFunction, null, children);
55
+ }
56
+ }]);
57
+ return ErrorBoundary;
58
+ }(Component);
59
+ export default ErrorBoundary;
@@ -1,7 +1,8 @@
1
- import React, { useReducer, useState } from "react";
1
+ import React, { useEffect, useReducer, useState } from "react";
2
2
  import { ChatAdapterStore } from "../../contexts/ChatAdapterStore";
3
3
  import { ChatContextStore } from "../../contexts/ChatContextStore";
4
4
  import { ChatSDKStore } from "../../contexts/ChatSDKStore";
5
+ import ErrorBoundary from "../errorboundary/ErrorBoundary";
5
6
  import { FacadeChatSDK } from "../../common/facades/FacadeChatSDK";
6
7
  import { FacadeChatSDKStore } from "../../contexts/FacadeChatSDKStore";
7
8
  import LiveChatWidgetStateful from "./livechatwidgetstateful/LiveChatWidgetStateful";
@@ -9,9 +10,12 @@ import { createReducer } from "../../contexts/createReducer";
9
10
  import { getLiveChatWidgetContextInitialState } from "../../contexts/common/LiveChatWidgetContextInitialState";
10
11
  import { getMockChatSDKIfApplicable } from "./common/getMockChatSDKIfApplicable";
11
12
  import { isNullOrUndefined } from "../../common/utils";
13
+ import { isPersistentChatEnabled } from "./common/liveChatConfigUtils";
14
+ import { logWidgetLoadWithUnexpectedError } from "./common/startChatErrorHandler";
12
15
  import overridePropsOnMockIfApplicable from "./common/overridePropsOnMockIfApplicable";
16
+ import { registerTelemetryLoggers } from "./common/registerTelemetryLoggers";
13
17
  export const LiveChatWidget = props => {
14
- var _props$mock, _props$featureConfigP, _props$chatConfig, _props$chatConfig$Liv;
18
+ var _props$mock, _props$featureConfigP, _props$chatConfig, _props$chatConfig$Liv, _props$chatConfig2, _props$chatConfig2$Li;
15
19
  const reducer = createReducer();
16
20
  const [state, dispatch] = useReducer(reducer, getLiveChatWidgetContextInitialState(props));
17
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -25,7 +29,7 @@ export const LiveChatWidget = props => {
25
29
  }
26
30
 
27
31
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- 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);
32
+ 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) || isPersistentChatEnabled((_props$chatConfig2 = props.chatConfig) === null || _props$chatConfig2 === void 0 ? void 0 : (_props$chatConfig2$Li = _props$chatConfig2.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig2$Li === void 0 ? void 0 : _props$chatConfig2$Li.msdyn_conversationmode);
29
33
  if (!facadeChatSDK) {
30
34
  var _props$mock2;
31
35
  setFacadeChatSDK(new FacadeChatSDK({
@@ -37,7 +41,14 @@ export const LiveChatWidget = props => {
37
41
  "isSDKMocked": !isNullOrUndefined(props === null || props === void 0 ? void 0 : (_props$mock2 = props.mock) === null || _props$mock2 === void 0 ? void 0 : _props$mock2.type)
38
42
  }, disableReauthentication));
39
43
  }
40
- return /*#__PURE__*/React.createElement(FacadeChatSDKStore.Provider, {
44
+ useEffect(() => {
45
+ registerTelemetryLoggers(props, dispatch);
46
+ }, [dispatch]);
47
+ return /*#__PURE__*/React.createElement(ErrorBoundary, {
48
+ onError: error => {
49
+ logWidgetLoadWithUnexpectedError(error);
50
+ }
51
+ }, /*#__PURE__*/React.createElement(FacadeChatSDKStore.Provider, {
41
52
  value: [facadeChatSDK, setFacadeChatSDK]
42
53
  }, /*#__PURE__*/React.createElement(ChatSDKStore.Provider, {
43
54
  value: chatSDK
@@ -45,6 +56,6 @@ export const LiveChatWidget = props => {
45
56
  value: [adapter, setAdapter]
46
57
  }, /*#__PURE__*/React.createElement(ChatContextStore.Provider, {
47
58
  value: [state, dispatch]
48
- }, /*#__PURE__*/React.createElement(LiveChatWidgetStateful, props)))));
59
+ }, /*#__PURE__*/React.createElement(LiveChatWidgetStateful, props))))));
49
60
  };
50
61
  export default LiveChatWidget;