@microsoft/omnichannel-chat-widget 1.7.7-main.bdac0a6 → 1.7.8-main.29ce174
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.
- package/lib/cjs/common/Constants.js +1 -0
- package/lib/cjs/common/facades/FacadeChatSDK.js +2 -1
- package/lib/cjs/common/telemetry/TelemetryConstants.js +2 -0
- package/lib/cjs/common/utils.js +14 -2
- package/lib/cjs/components/livechatwidget/common/authHelper.js +15 -0
- package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +10 -4
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +14 -8
- package/lib/cjs/components/ooohpanestateful/OOOHPaneStateful.js +4 -0
- package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +15 -0
- package/lib/cjs/components/postchatsurveypanestateful/common/isValidSurveyUrl.js +28 -0
- package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +13 -1
- package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +6 -2
- package/lib/cjs/plugins/createChatTranscript.js +9 -5
- package/lib/cjs/plugins/newMessageEventHandler.js +2 -2
- package/lib/esm/common/Constants.js +1 -0
- package/lib/esm/common/facades/FacadeChatSDK.js +2 -1
- package/lib/esm/common/telemetry/TelemetryConstants.js +2 -0
- package/lib/esm/common/utils.js +11 -1
- package/lib/esm/components/livechatwidget/common/authHelper.js +15 -0
- package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +10 -4
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +14 -8
- package/lib/esm/components/ooohpanestateful/OOOHPaneStateful.js +4 -0
- package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +15 -0
- package/lib/esm/components/postchatsurveypanestateful/common/isValidSurveyUrl.js +21 -0
- package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +15 -3
- package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +6 -2
- package/lib/esm/plugins/createChatTranscript.js +9 -5
- package/lib/esm/plugins/newMessageEventHandler.js +2 -2
- package/lib/types/common/Constants.d.ts +1 -0
- package/lib/types/common/facades/FacadeChatSDK.d.ts +1 -1
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +2 -0
- package/lib/types/common/telemetry/TelemetryHelper.d.ts +1 -0
- package/lib/types/common/utils.d.ts +1 -0
- package/lib/types/components/postchatsurveypanestateful/common/isValidSurveyUrl.d.ts +2 -0
- package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +1 -0
- package/package.json +2 -2
|
@@ -132,6 +132,7 @@ class HtmlClassNames {}
|
|
|
132
132
|
exports.HtmlClassNames = HtmlClassNames;
|
|
133
133
|
_defineProperty(HtmlClassNames, "webChatBannerCloseButton", "webchat__toast__dismissButton");
|
|
134
134
|
_defineProperty(HtmlClassNames, "webChatBannerExpandButton", "webchat__toaster__expandIcon");
|
|
135
|
+
_defineProperty(HtmlClassNames, "webChatHistoryContainer", "webchat__basic-transcript");
|
|
135
136
|
class HtmlElementSelectors {}
|
|
136
137
|
exports.HtmlElementSelectors = HtmlElementSelectors;
|
|
137
138
|
_defineProperty(HtmlElementSelectors, "sendBoxSelector", "textarea[data-id=\"webchat-sendbox-input\"]");
|
|
@@ -149,6 +149,7 @@ class FacadeChatSDK {
|
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
async tokenRing() {
|
|
152
|
+
var _this$chatSDK$chatSDK;
|
|
152
153
|
if (this.disableReauthentication === true) {
|
|
153
154
|
// facade feature is disabled, so we are bypassing the re authentication and let it fail.
|
|
154
155
|
return {
|
|
@@ -176,7 +177,7 @@ class FacadeChatSDK {
|
|
|
176
177
|
message: "Token is valid"
|
|
177
178
|
};
|
|
178
179
|
}
|
|
179
|
-
if (this.getAuthToken === undefined) {
|
|
180
|
+
if (this.getAuthToken === undefined && ((_this$chatSDK$chatSDK = this.chatSDK.chatSDKConfig) === null || _this$chatSDK$chatSDK === void 0 ? void 0 : _this$chatSDK$chatSDK.getAuthToken) === undefined) {
|
|
180
181
|
_TelemetryHelper.TelemetryHelper.logFacadeChatSDKEvent(_TelemetryConstants.LogLevel.ERROR, {
|
|
181
182
|
Event: _TelemetryConstants.TelemetryEvent.NewTokenFailed,
|
|
182
183
|
Description: "GetAuthToken function is not present",
|
|
@@ -219,6 +219,8 @@ exports.TelemetryEvent = TelemetryEvent;
|
|
|
219
219
|
TelemetryEvent["PostChatContextCallFailed"] = "PostChatContextCallFailed";
|
|
220
220
|
TelemetryEvent["PostChatSurveyLoadingPaneLoaded"] = "PostChatSurveyLoadingPaneLoaded";
|
|
221
221
|
TelemetryEvent["PostChatSurveyLoaded"] = "PostChatSurveyLoaded";
|
|
222
|
+
TelemetryEvent["PostChatSurveyUrlValidationCompleted"] = "PostChatSurveyUrlValidationCompleted";
|
|
223
|
+
TelemetryEvent["PostChatSurveyUrlValidationFailed"] = "PostChatSurveyUrlValidationFailed";
|
|
222
224
|
TelemetryEvent["ChatDisconnectThreadEventReceived"] = "ChatDisconnectThreadEventReceived";
|
|
223
225
|
TelemetryEvent["HiddenAdaptiveCardMessageReceived"] = "HiddenAdaptiveCardMessageReceived";
|
|
224
226
|
TelemetryEvent["EndingAdapterAfterDisconnectionError"] = "EndingAdapterAfterDisconnectionError";
|
package/lib/cjs/common/utils.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.getConversationDetailsCall = exports.getBroadcastChannelName = exports.formatTemplateString = exports.findParentFocusableElementsWithoutChildContainer = exports.findAllFocusableElement = exports.extractPreChatSurveyResponseValues = exports.escapeHtml = exports.debounceLeading = exports.createTimer = exports.createFileAndDownload = exports.checkContactIdError = exports.changeLanguageCodeFormatForWebChat = exports.addDelayInMs = void 0;
|
|
7
|
+
exports.getDeviceType = getDeviceType;
|
|
8
|
+
exports.setTabIndices = exports.setOcUserAgent = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseLowerCaseString = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isUndefinedOrEmpty = exports.isThisSessionPopout = exports.isNullOrUndefined = exports.isNullOrEmptyString = exports.getWidgetEndChatEventName = exports.getWidgetCacheIdfromProps = exports.getWidgetCacheId = exports.getTimestampHourMinute = exports.getStateFromCache = exports.getLocaleDirection = exports.getIconText = exports.getDomain = void 0;
|
|
7
9
|
var _Constants = require("./Constants");
|
|
8
10
|
var _TelemetryConstants = require("./telemetry/TelemetryConstants");
|
|
9
11
|
var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
|
|
@@ -479,4 +481,14 @@ const setOcUserAgent = chatSDK => {
|
|
|
479
481
|
}
|
|
480
482
|
}
|
|
481
483
|
};
|
|
482
|
-
exports.setOcUserAgent = setOcUserAgent;
|
|
484
|
+
exports.setOcUserAgent = setOcUserAgent;
|
|
485
|
+
function getDeviceType() {
|
|
486
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
487
|
+
if (/android/.test(userAgent)) {
|
|
488
|
+
return "android";
|
|
489
|
+
} else if (/iphone|ipad|ipod/.test(userAgent)) {
|
|
490
|
+
return "ios";
|
|
491
|
+
} else {
|
|
492
|
+
return "standard";
|
|
493
|
+
}
|
|
494
|
+
}
|
|
@@ -18,6 +18,7 @@ const getAuthClientFunction = chatConfig => {
|
|
|
18
18
|
};
|
|
19
19
|
exports.getAuthClientFunction = getAuthClientFunction;
|
|
20
20
|
const handleAuthentication = async (chatSDK, chatConfig, getAuthToken) => {
|
|
21
|
+
var _chatSDK$chatSDKConfi;
|
|
21
22
|
const authClientFunction = getAuthClientFunction(chatConfig);
|
|
22
23
|
if (getAuthToken && authClientFunction) {
|
|
23
24
|
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
@@ -41,6 +42,20 @@ const handleAuthentication = async (chatSDK, chatConfig, getAuthToken) => {
|
|
|
41
42
|
});
|
|
42
43
|
throw new Error(_Constants.WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
|
|
43
44
|
}
|
|
45
|
+
} else if (chatSDK !== null && chatSDK !== void 0 && (_chatSDK$chatSDKConfi = chatSDK.chatSDKConfig) !== null && _chatSDK$chatSDKConfi !== void 0 && _chatSDK$chatSDKConfi.getAuthToken) {
|
|
46
|
+
var _chatSDK$chatSDKConfi2;
|
|
47
|
+
const token = await ((_chatSDK$chatSDKConfi2 = chatSDK.chatSDKConfig) === null || _chatSDK$chatSDKConfi2 === void 0 ? void 0 : _chatSDK$chatSDKConfi2.getAuthToken());
|
|
48
|
+
if ((0, _utils.isNullOrEmptyString)(token)) {
|
|
49
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
|
|
50
|
+
Event: _TelemetryConstants.TelemetryEvent.ReceivedNullOrEmptyToken,
|
|
51
|
+
Description: "getAuthToken in chat SDK returns empty string"
|
|
52
|
+
});
|
|
53
|
+
throw new Error(_Constants.WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
"result": true,
|
|
57
|
+
token
|
|
58
|
+
};
|
|
44
59
|
}
|
|
45
60
|
return {
|
|
46
61
|
"result": false,
|
|
@@ -11,6 +11,8 @@ var _NotificationHandler = require("../../webchatcontainerstateful/webchatcontro
|
|
|
11
11
|
var _NotificationScenarios = require("../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios");
|
|
12
12
|
var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
|
|
13
13
|
var _defaultMiddlewareLocalizedTexts = require("../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts");
|
|
14
|
+
var _createReducer = require("../../../contexts/createReducer");
|
|
15
|
+
var _LiveChatWidgetActionType = require("../../../contexts/common/LiveChatWidgetActionType");
|
|
14
16
|
const isInternetConnected = async () => {
|
|
15
17
|
try {
|
|
16
18
|
const response = await fetch(_Constants.Constants.internetConnectionTestUrl);
|
|
@@ -23,18 +25,22 @@ const isInternetConnected = async () => {
|
|
|
23
25
|
const createInternetConnectionChangeHandler = async state => {
|
|
24
26
|
const handler = async () => {
|
|
25
27
|
const connected = await isInternetConnected();
|
|
28
|
+
const inMemoryState = (0, _createReducer.executeReducer)(state, {
|
|
29
|
+
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
30
|
+
payload: null
|
|
31
|
+
});
|
|
26
32
|
if (!connected) {
|
|
27
|
-
var
|
|
33
|
+
var _inMemoryState$domain, _inMemoryState$domain2;
|
|
28
34
|
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.WARN, {
|
|
29
35
|
Event: _TelemetryConstants.TelemetryEvent.NetworkDisconnected
|
|
30
36
|
});
|
|
31
|
-
_NotificationHandler.NotificationHandler.notifyError(_NotificationScenarios.NotificationScenarios.InternetConnection, (
|
|
37
|
+
_NotificationHandler.NotificationHandler.notifyError(_NotificationScenarios.NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain = inMemoryState.domainStates) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.middlewareLocalizedTexts) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
|
|
32
38
|
} else {
|
|
33
|
-
var
|
|
39
|
+
var _inMemoryState$domain3, _inMemoryState$domain4;
|
|
34
40
|
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.WARN, {
|
|
35
41
|
Event: _TelemetryConstants.TelemetryEvent.NetworkReconnected
|
|
36
42
|
});
|
|
37
|
-
_NotificationHandler.NotificationHandler.notifySuccess(_NotificationScenarios.NotificationScenarios.InternetConnection, (
|
|
43
|
+
_NotificationHandler.NotificationHandler.notifySuccess(_NotificationScenarios.NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.middlewareLocalizedTexts) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
|
|
38
44
|
_omnichannelChatComponents.BroadcastService.postMessage({
|
|
39
45
|
eventName: _TelemetryConstants.BroadcastEvent.NetworkReconnected
|
|
40
46
|
});
|
|
@@ -417,7 +417,7 @@ const LiveChatWidgetStateful = props => {
|
|
|
417
417
|
|
|
418
418
|
// Start chat from SDK Event
|
|
419
419
|
_omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.StartChat).subscribe(msg => {
|
|
420
|
-
var _props$chatConfig5, _props$chatConfig5$Li, _props$chatConfig6, _props$chatConfig6$Li, _msg$payload5, _msg$payload6, _msg$payload7, _msg$payload9, _inMemoryState$appSta2, _inMemoryState$appSta3
|
|
420
|
+
var _props$chatConfig5, _props$chatConfig5$Li, _props$chatConfig6, _props$chatConfig6$Li, _msg$payload5, _msg$payload6, _msg$payload7, _msg$payload9, _inMemoryState$appSta2, _inMemoryState$appSta3;
|
|
421
421
|
// If chat is out of operating hours chat widget sets the conversation state to OutOfOffice.
|
|
422
422
|
if (typeof (props === null || props === void 0 ? void 0 : (_props$chatConfig5 = props.chatConfig) === null || _props$chatConfig5 === void 0 ? void 0 : (_props$chatConfig5$Li = _props$chatConfig5.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig5$Li === void 0 ? void 0 : _props$chatConfig5$Li.OutOfOperatingHours) === "string" && (props === null || props === void 0 ? void 0 : (_props$chatConfig6 = props.chatConfig) === null || _props$chatConfig6 === void 0 ? void 0 : (_props$chatConfig6$Li = _props$chatConfig6.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig6$Li === void 0 ? void 0 : _props$chatConfig6$Li.OutOfOperatingHours.toLowerCase()) === "true") {
|
|
423
423
|
(state === null || state === void 0 ? void 0 : state.appStates.isMinimized) && dispatch({
|
|
@@ -455,8 +455,14 @@ const LiveChatWidgetStateful = props => {
|
|
|
455
455
|
});
|
|
456
456
|
inMemoryState.domainStates.customContext = msg === null || msg === void 0 ? void 0 : (_msg$payload9 = msg.payload) === null || _msg$payload9 === void 0 ? void 0 : _msg$payload9.customContext;
|
|
457
457
|
|
|
458
|
-
|
|
459
|
-
|
|
458
|
+
/*
|
|
459
|
+
* If the conversation is in closed state then we start a new chat,
|
|
460
|
+
* else if the conversation is in active state then we maximize the chat
|
|
461
|
+
* If the conversation is in inactive or postchat state then we maximize the chat.
|
|
462
|
+
*
|
|
463
|
+
* To start a new chat, it needs to be called via the close button or close chat via SDK.
|
|
464
|
+
**/
|
|
465
|
+
if (((_inMemoryState$appSta2 = inMemoryState.appStates) === null || _inMemoryState$appSta2 === void 0 ? void 0 : _inMemoryState$appSta2.conversationState) === _ConversationState.ConversationState.Closed) {
|
|
460
466
|
_omnichannelChatComponents.BroadcastService.postMessage({
|
|
461
467
|
eventName: _TelemetryConstants.BroadcastEvent.ChatInitiated
|
|
462
468
|
});
|
|
@@ -465,7 +471,7 @@ const LiveChatWidgetStateful = props => {
|
|
|
465
471
|
}
|
|
466
472
|
|
|
467
473
|
// If minimized, maximize the chat
|
|
468
|
-
if ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
474
|
+
if ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta3 = inMemoryState.appStates) === null || _inMemoryState$appSta3 === void 0 ? void 0 : _inMemoryState$appSta3.isMinimized) === true) {
|
|
469
475
|
var _inMemoryState$domain, _inMemoryState$domain2, _inMemoryState$domain3, _inMemoryState$domain4;
|
|
470
476
|
dispatch({
|
|
471
477
|
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_MINIMIZED,
|
|
@@ -593,12 +599,12 @@ const LiveChatWidgetStateful = props => {
|
|
|
593
599
|
disablePolling: true
|
|
594
600
|
});
|
|
595
601
|
facadeChatSDK === null || facadeChatSDK === void 0 ? void 0 : facadeChatSDK.onAgentEndSession(event => {
|
|
596
|
-
var _inMemoryState$
|
|
602
|
+
var _inMemoryState$appSta4;
|
|
597
603
|
const inMemoryState = (0, _createReducer.executeReducer)(state, {
|
|
598
604
|
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
599
605
|
payload: null
|
|
600
606
|
});
|
|
601
|
-
if ("participantsRemoved" in event && (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
607
|
+
if ("participantsRemoved" in event && (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta4 = inMemoryState.appStates) === null || _inMemoryState$appSta4 === void 0 ? void 0 : _inMemoryState$appSta4.conversationState) === _ConversationState.ConversationState.Active) {
|
|
602
608
|
setWebChatStyles(styles => {
|
|
603
609
|
return {
|
|
604
610
|
...styles,
|
|
@@ -741,13 +747,13 @@ const LiveChatWidgetStateful = props => {
|
|
|
741
747
|
|
|
742
748
|
// Handle Chat disconnect cases
|
|
743
749
|
(0, _react2.useEffect)(() => {
|
|
744
|
-
var _inMemoryState$
|
|
750
|
+
var _inMemoryState$appSta5;
|
|
745
751
|
const inMemoryState = (0, _createReducer.executeReducer)(state, {
|
|
746
752
|
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
747
753
|
payload: null
|
|
748
754
|
});
|
|
749
755
|
(0, _chatDisconnectHelper.handleChatDisconnect)(props, inMemoryState, setWebChatStyles);
|
|
750
|
-
const chatDisconnectState = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
756
|
+
const chatDisconnectState = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta5 = inMemoryState.appStates) === null || _inMemoryState$appSta5 === void 0 ? void 0 : _inMemoryState$appSta5.chatDisconnectEventReceived;
|
|
751
757
|
if (chatDisconnectState && adapter) {
|
|
752
758
|
try {
|
|
753
759
|
adapter.end();
|
|
@@ -11,6 +11,7 @@ var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components
|
|
|
11
11
|
var _TelemetryHelper = require("../../common/telemetry/TelemetryHelper");
|
|
12
12
|
var _defaultgeneralOOOHPaneStyleProps = require("./common/defaultStyleProps/defaultgeneralOOOHPaneStyleProps");
|
|
13
13
|
var _useChatContextStore = _interopRequireDefault(require("../../hooks/useChatContextStore"));
|
|
14
|
+
var _dompurify = _interopRequireDefault(require("dompurify"));
|
|
14
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
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); }
|
|
16
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; }
|
|
@@ -49,6 +50,9 @@ const OutOfOfficeHoursPaneStateful = props => {
|
|
|
49
50
|
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
50
51
|
});
|
|
51
52
|
}, []);
|
|
53
|
+
if (controlProps !== null && controlProps !== void 0 && controlProps.titleText) {
|
|
54
|
+
controlProps.titleText = _dompurify.default.sanitize(controlProps.titleText);
|
|
55
|
+
}
|
|
52
56
|
return /*#__PURE__*/_react.default.createElement(_omnichannelChatComponents.OutOfOfficeHoursPane, {
|
|
53
57
|
componentOverrides: props.componentOverrides,
|
|
54
58
|
controlProps: controlProps,
|
|
@@ -14,6 +14,7 @@ var _TelemetryHelper = require("../../common/telemetry/TelemetryHelper");
|
|
|
14
14
|
var _defaultgeneralPostChatSurveyPaneStyleProps = require("./common/defaultStyleProps/defaultgeneralPostChatSurveyPaneStyleProps");
|
|
15
15
|
var _utils = require("../../common/utils");
|
|
16
16
|
var _useChatContextStore = _interopRequireDefault(require("../../hooks/useChatContextStore"));
|
|
17
|
+
var _isValidSurveyUrl = _interopRequireDefault(require("./common/isValidSurveyUrl"));
|
|
17
18
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
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); }
|
|
19
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; }
|
|
@@ -54,6 +55,20 @@ const PostChatSurveyPaneStateful = props => {
|
|
|
54
55
|
surveyURL: ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.surveyURL) ?? surveyInviteLink,
|
|
55
56
|
...props.controlProps
|
|
56
57
|
};
|
|
58
|
+
if (controlProps.surveyURL) {
|
|
59
|
+
if (!(0, _isValidSurveyUrl.default)(controlProps.surveyURL)) {
|
|
60
|
+
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.ERROR, {
|
|
61
|
+
Event: _TelemetryConstants.TelemetryEvent.PostChatSurveyUrlValidationFailed,
|
|
62
|
+
Description: `${controlProps.surveyURL} is not a valid Survey URL`
|
|
63
|
+
});
|
|
64
|
+
controlProps.surveyURL = "";
|
|
65
|
+
} else {
|
|
66
|
+
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
67
|
+
Event: _TelemetryConstants.TelemetryEvent.PostChatSurveyUrlValidationCompleted,
|
|
68
|
+
Description: `${controlProps.surveyURL} is a valid Survey URL`
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
57
72
|
|
|
58
73
|
// Move focus to the first button
|
|
59
74
|
(0, _react.useEffect)(() => {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _utils = require("../../../common/utils");
|
|
8
|
+
const validRootDomains = ["microsoft.com", "microsoft.us", "appsplatform.us", "powervirtualagents.cn"];
|
|
9
|
+
const isValidSurveyUrl = url => {
|
|
10
|
+
if ((0, _utils.isNullOrEmptyString)(url)) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const objectUrl = new URL(url);
|
|
15
|
+
if (!objectUrl.origin || objectUrl.origin === "null") {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
const validDomain = validRootDomains.find(domain => objectUrl.origin.endsWith(domain));
|
|
19
|
+
if (validDomain) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
} catch (error) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
};
|
|
27
|
+
var _default = isValidSurveyUrl;
|
|
28
|
+
exports.default = _default;
|
|
@@ -145,11 +145,6 @@ const PreChatSurveyPaneStateful = props => {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
// Move focus to the first button
|
|
149
|
-
const firstElement = (0, _utils.findAllFocusableElement)(`#${controlProps.id}`);
|
|
150
|
-
if (firstElement && firstElement[0]) {
|
|
151
|
-
firstElement[0].focus();
|
|
152
|
-
}
|
|
153
148
|
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
154
149
|
Event: _TelemetryConstants.TelemetryEvent.PrechatSurveyLoaded
|
|
155
150
|
});
|
|
@@ -158,6 +153,16 @@ const PreChatSurveyPaneStateful = props => {
|
|
|
158
153
|
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
159
154
|
});
|
|
160
155
|
}, []);
|
|
156
|
+
|
|
157
|
+
// Set focus to the first element
|
|
158
|
+
(0, _react.useEffect)(() => {
|
|
159
|
+
if (!state.appStates.isMinimized) {
|
|
160
|
+
const firstElement = (0, _utils.findAllFocusableElement)(`#${controlProps.id}`);
|
|
161
|
+
if (firstElement && firstElement[0]) {
|
|
162
|
+
firstElement[0].focus();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}, [state.appStates.isMinimized]);
|
|
161
166
|
return /*#__PURE__*/_react.default.createElement(_omnichannelChatComponents.PreChatSurveyPane, {
|
|
162
167
|
controlProps: controlProps,
|
|
163
168
|
styleProps: styleProps
|
|
@@ -83,7 +83,12 @@ const WebChatContainerStateful = props => {
|
|
|
83
83
|
};
|
|
84
84
|
(0, _react2.useEffect)(() => {
|
|
85
85
|
var _props$webChatContain, _props$webChatContain2;
|
|
86
|
-
(0, _utils.
|
|
86
|
+
if ((0, _utils.getDeviceType)() !== "standard" && (webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.webChatHistoryMobileAccessibilityLabel) !== undefined) {
|
|
87
|
+
const chatHistoryElement = document.querySelector(`.${_Constants.HtmlClassNames.webChatHistoryContainer}`);
|
|
88
|
+
if (chatHistoryElement) {
|
|
89
|
+
chatHistoryElement.setAttribute(_Constants.HtmlAttributeNames.ariaLabel, webChatContainerProps.webChatHistoryMobileAccessibilityLabel);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
87
92
|
dispatch({
|
|
88
93
|
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
|
|
89
94
|
payload: webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.renderingMiddlewareProps
|
|
@@ -164,6 +169,13 @@ const WebChatContainerStateful = props => {
|
|
|
164
169
|
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
165
170
|
});
|
|
166
171
|
}, []);
|
|
172
|
+
|
|
173
|
+
// Set focus to the sendbox
|
|
174
|
+
(0, _react2.useEffect)(() => {
|
|
175
|
+
if (!state.appStates.isMinimized) {
|
|
176
|
+
(0, _utils.setFocusOnSendBox)();
|
|
177
|
+
}
|
|
178
|
+
}, [state.appStates.isMinimized]);
|
|
167
179
|
return /*#__PURE__*/_react2.default.createElement(_react2.default.Fragment, null, /*#__PURE__*/_react2.default.createElement("style", null, `
|
|
168
180
|
.webchat__stacked-layout__content .ac-pushButton {
|
|
169
181
|
cursor: pointer;
|
|
@@ -31,15 +31,28 @@ const DeliveredTimestamp = _ref => {
|
|
|
31
31
|
timestamp
|
|
32
32
|
}
|
|
33
33
|
} = args;
|
|
34
|
+
const getTimeElement = timestamp => {
|
|
35
|
+
const timeString = (0, _utils.getTimestampHourMinute)(timestamp);
|
|
36
|
+
const isAmPmFormat = timeString.toLowerCase().includes("am") || timeString.toLowerCase().includes("pm");
|
|
37
|
+
|
|
38
|
+
// For clients that use languages that are written right-to-left, but still use AM/PM time format, we need to
|
|
39
|
+
// make sure the "rtl" direction doesn't produce "PM 1:23", but remains "1:23 PM"
|
|
40
|
+
if (dir === "rtl" && isAmPmFormat) {
|
|
41
|
+
return /*#__PURE__*/_react.default.createElement("span", {
|
|
42
|
+
dir: "ltr"
|
|
43
|
+
}, (0, _utils.getTimestampHourMinute)(timestamp));
|
|
44
|
+
}
|
|
45
|
+
return timeString;
|
|
46
|
+
};
|
|
34
47
|
return /*#__PURE__*/_react.default.createElement(_react2.Stack, {
|
|
35
48
|
style: contentStyles,
|
|
36
49
|
dir: dir
|
|
37
50
|
}, role === _DirectLineSenderRole.DirectLineSenderRole.Bot && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
|
|
38
51
|
dir: dir,
|
|
39
52
|
"aria-hidden": "false"
|
|
40
|
-
}, name, " - ", (
|
|
53
|
+
}, name, " - ", getTimeElement(timestamp))), role === _DirectLineSenderRole.DirectLineSenderRole.User && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
|
|
41
54
|
"aria-hidden": "false",
|
|
42
55
|
dir: dir
|
|
43
|
-
}, " ", (
|
|
56
|
+
}, " ", getTimeElement(timestamp), " - ", ((_state$domainStates$m = state.domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_MESSAGE_DELIVERED) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_MESSAGE_DELIVERED)));
|
|
44
57
|
};
|
|
45
58
|
exports.DeliveredTimestamp = DeliveredTimestamp;
|
|
@@ -41,6 +41,7 @@ const convertTextToHtmlNode = text => {
|
|
|
41
41
|
|
|
42
42
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
43
|
const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
|
|
44
|
+
var _htmlNode$tagName;
|
|
44
45
|
const htmlNode = convertTextToHtmlNode(text);
|
|
45
46
|
const aNodes = htmlNode.getElementsByTagName(_Constants.HtmlAttributeNames.aTagName);
|
|
46
47
|
if ((aNodes === null || aNodes === void 0 ? void 0 : aNodes.length) > 0) {
|
|
@@ -70,8 +71,6 @@ const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
|
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
|
-
|
|
74
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
75
74
|
action = (0, _simpleUpdateIn.default)(action, [_Constants.Constants.payload, _Constants.Constants.activity, _Constants.Constants.text], () => htmlNode.innerHTML);
|
|
76
75
|
} catch (e) {
|
|
77
76
|
let errorMessage = "Failed to apply action: ";
|
|
@@ -89,6 +88,11 @@ const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
|
|
|
89
88
|
});
|
|
90
89
|
}
|
|
91
90
|
}
|
|
91
|
+
|
|
92
|
+
// if empty div tag after sanitization
|
|
93
|
+
if (((_htmlNode$tagName = htmlNode.tagName) === null || _htmlNode$tagName === void 0 ? void 0 : _htmlNode$tagName.toLowerCase()) === _Constants.HtmlAttributeNames.div && htmlNode.children.length === 0 && htmlNode.innerHTML.trim() === "") {
|
|
94
|
+
action = (0, _simpleUpdateIn.default)(action, [_Constants.Constants.payload, _Constants.Constants.activity, _Constants.Constants.text], () => "");
|
|
95
|
+
}
|
|
92
96
|
return action;
|
|
93
97
|
};
|
|
94
98
|
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _utils = require("../common/utils");
|
|
8
8
|
var _defaultLibraryScripts = _interopRequireDefault(require("../components/footerstateful/downloadtranscriptstateful/common/defaultLibraryScripts"));
|
|
9
|
+
var _dompurify = _interopRequireDefault(require("dompurify"));
|
|
9
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
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; }
|
|
11
12
|
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
@@ -172,7 +173,7 @@ class TranscriptHTMLBuilder {
|
|
|
172
173
|
<script>
|
|
173
174
|
class Translator {
|
|
174
175
|
static convertTranscriptMessageToActivity(message) {
|
|
175
|
-
const {created, OriginalMessageId, id, isControlMessage, content, tags, from, attachments, amsMetadata, amsReferences} = message;
|
|
176
|
+
const {created, OriginalMessageId, id, isControlMessage, content, tags, from, attachments, amsMetadata, amsReferences, amsreferences} = message;
|
|
176
177
|
|
|
177
178
|
//it's required to convert the id to a number, otherwise the webchat will not render the messages in the correct order
|
|
178
179
|
// if the OrginalMessageId is not present, we can use the id as the sequence id, which is always present.
|
|
@@ -219,7 +220,7 @@ class TranscriptHTMLBuilder {
|
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
// Attachments
|
|
222
|
-
if (amsReferences && amsMetadata) {
|
|
223
|
+
if ((amsReferences || amsreferences) && amsMetadata) {
|
|
223
224
|
const metadata = JSON.parse(amsMetadata);
|
|
224
225
|
const { fileName } = metadata[0];
|
|
225
226
|
const text = \`${this.attachmentMessage}\${fileName}\`;
|
|
@@ -243,7 +244,7 @@ class TranscriptHTMLBuilder {
|
|
|
243
244
|
// Message
|
|
244
245
|
if (content) {
|
|
245
246
|
// Adaptive card formatting
|
|
246
|
-
if (content.includes('"
|
|
247
|
+
if (content.includes('"attachments"') || content.includes('"suggestedActions"')) {
|
|
247
248
|
try {
|
|
248
249
|
const partialActivity = JSON.parse(content);
|
|
249
250
|
return {
|
|
@@ -674,12 +675,15 @@ const createChatTranscript = async function (transcript, facadeChatSDK) {
|
|
|
674
675
|
reader.readAsDataURL(blob);
|
|
675
676
|
});
|
|
676
677
|
};
|
|
677
|
-
let messages = transcriptMessages
|
|
678
|
+
let messages = transcriptMessages.filter(message => {
|
|
679
|
+
message.content = _dompurify.default.sanitize(message.content);
|
|
680
|
+
return message;
|
|
681
|
+
});
|
|
678
682
|
if (renderAttachments) {
|
|
679
683
|
messages = await Promise.all(transcriptMessages.map(async message => {
|
|
680
684
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
681
685
|
const {
|
|
682
|
-
amsReferences,
|
|
686
|
+
amsReferences = message.amsreferences,
|
|
683
687
|
amsMetadata
|
|
684
688
|
} = message;
|
|
685
689
|
if (amsReferences && amsMetadata) {
|
|
@@ -89,7 +89,7 @@ const createOnNewAdapterActivityHandler = (chatId, userId) => {
|
|
|
89
89
|
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
90
90
|
Event: _TelemetryConstants.TelemetryEvent.MessageReceived,
|
|
91
91
|
Description: "New message received",
|
|
92
|
-
|
|
92
|
+
CustomProperties: payload
|
|
93
93
|
});
|
|
94
94
|
} else {
|
|
95
95
|
if (!isHistoryMessageReceivedEventRasied) {
|
|
@@ -97,7 +97,7 @@ const createOnNewAdapterActivityHandler = (chatId, userId) => {
|
|
|
97
97
|
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
98
98
|
Event: _TelemetryConstants.TelemetryEvent.RehydrateMessageReceived,
|
|
99
99
|
Description: "History message received",
|
|
100
|
-
|
|
100
|
+
CustomProperties: payload
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
103
|
}
|
|
@@ -122,6 +122,7 @@ _defineProperty(HtmlIdNames, "MSLiveChatWidget", "MSLiveChatWidget");
|
|
|
122
122
|
export class HtmlClassNames {}
|
|
123
123
|
_defineProperty(HtmlClassNames, "webChatBannerCloseButton", "webchat__toast__dismissButton");
|
|
124
124
|
_defineProperty(HtmlClassNames, "webChatBannerExpandButton", "webchat__toaster__expandIcon");
|
|
125
|
+
_defineProperty(HtmlClassNames, "webChatHistoryContainer", "webchat__basic-transcript");
|
|
125
126
|
export class HtmlElementSelectors {}
|
|
126
127
|
_defineProperty(HtmlElementSelectors, "sendBoxSelector", "textarea[data-id=\"webchat-sendbox-input\"]");
|
|
127
128
|
export class HtmlAttributeNames {}
|
|
@@ -143,6 +143,7 @@ export class FacadeChatSDK {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
async tokenRing() {
|
|
146
|
+
var _this$chatSDK$chatSDK;
|
|
146
147
|
if (this.disableReauthentication === true) {
|
|
147
148
|
// facade feature is disabled, so we are bypassing the re authentication and let it fail.
|
|
148
149
|
return {
|
|
@@ -170,7 +171,7 @@ export class FacadeChatSDK {
|
|
|
170
171
|
message: "Token is valid"
|
|
171
172
|
};
|
|
172
173
|
}
|
|
173
|
-
if (this.getAuthToken === undefined) {
|
|
174
|
+
if (this.getAuthToken === undefined && ((_this$chatSDK$chatSDK = this.chatSDK.chatSDKConfig) === null || _this$chatSDK$chatSDK === void 0 ? void 0 : _this$chatSDK$chatSDK.getAuthToken) === undefined) {
|
|
174
175
|
TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
|
|
175
176
|
Event: TelemetryEvent.NewTokenFailed,
|
|
176
177
|
Description: "GetAuthToken function is not present",
|
|
@@ -213,6 +213,8 @@ export let TelemetryEvent;
|
|
|
213
213
|
TelemetryEvent["PostChatContextCallFailed"] = "PostChatContextCallFailed";
|
|
214
214
|
TelemetryEvent["PostChatSurveyLoadingPaneLoaded"] = "PostChatSurveyLoadingPaneLoaded";
|
|
215
215
|
TelemetryEvent["PostChatSurveyLoaded"] = "PostChatSurveyLoaded";
|
|
216
|
+
TelemetryEvent["PostChatSurveyUrlValidationCompleted"] = "PostChatSurveyUrlValidationCompleted";
|
|
217
|
+
TelemetryEvent["PostChatSurveyUrlValidationFailed"] = "PostChatSurveyUrlValidationFailed";
|
|
216
218
|
TelemetryEvent["ChatDisconnectThreadEventReceived"] = "ChatDisconnectThreadEventReceived";
|
|
217
219
|
TelemetryEvent["HiddenAdaptiveCardMessageReceived"] = "HiddenAdaptiveCardMessageReceived";
|
|
218
220
|
TelemetryEvent["EndingAdapterAfterDisconnectionError"] = "EndingAdapterAfterDisconnectionError";
|
package/lib/esm/common/utils.js
CHANGED
|
@@ -440,4 +440,14 @@ export const setOcUserAgent = chatSDK => {
|
|
|
440
440
|
console.warn(error);
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
|
-
};
|
|
443
|
+
};
|
|
444
|
+
export function getDeviceType() {
|
|
445
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
446
|
+
if (/android/.test(userAgent)) {
|
|
447
|
+
return "android";
|
|
448
|
+
} else if (/iphone|ipad|ipod/.test(userAgent)) {
|
|
449
|
+
return "ios";
|
|
450
|
+
} else {
|
|
451
|
+
return "standard";
|
|
452
|
+
}
|
|
453
|
+
}
|
|
@@ -11,6 +11,7 @@ const getAuthClientFunction = chatConfig => {
|
|
|
11
11
|
return authClientFunction;
|
|
12
12
|
};
|
|
13
13
|
const handleAuthentication = async (chatSDK, chatConfig, getAuthToken) => {
|
|
14
|
+
var _chatSDK$chatSDKConfi;
|
|
14
15
|
const authClientFunction = getAuthClientFunction(chatConfig);
|
|
15
16
|
if (getAuthToken && authClientFunction) {
|
|
16
17
|
TelemetryHelper.logActionEvent(LogLevel.INFO, {
|
|
@@ -34,6 +35,20 @@ const handleAuthentication = async (chatSDK, chatConfig, getAuthToken) => {
|
|
|
34
35
|
});
|
|
35
36
|
throw new Error(WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
|
|
36
37
|
}
|
|
38
|
+
} else if (chatSDK !== null && chatSDK !== void 0 && (_chatSDK$chatSDKConfi = chatSDK.chatSDKConfig) !== null && _chatSDK$chatSDKConfi !== void 0 && _chatSDK$chatSDKConfi.getAuthToken) {
|
|
39
|
+
var _chatSDK$chatSDKConfi2;
|
|
40
|
+
const token = await ((_chatSDK$chatSDKConfi2 = chatSDK.chatSDKConfig) === null || _chatSDK$chatSDKConfi2 === void 0 ? void 0 : _chatSDK$chatSDKConfi2.getAuthToken());
|
|
41
|
+
if (isNullOrEmptyString(token)) {
|
|
42
|
+
TelemetryHelper.logActionEvent(LogLevel.ERROR, {
|
|
43
|
+
Event: TelemetryEvent.ReceivedNullOrEmptyToken,
|
|
44
|
+
Description: "getAuthToken in chat SDK returns empty string"
|
|
45
|
+
});
|
|
46
|
+
throw new Error(WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
"result": true,
|
|
50
|
+
token
|
|
51
|
+
};
|
|
37
52
|
}
|
|
38
53
|
return {
|
|
39
54
|
"result": false,
|
|
@@ -5,6 +5,8 @@ import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontr
|
|
|
5
5
|
import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios";
|
|
6
6
|
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
7
7
|
import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
|
|
8
|
+
import { executeReducer } from "../../../contexts/createReducer";
|
|
9
|
+
import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
|
|
8
10
|
const isInternetConnected = async () => {
|
|
9
11
|
try {
|
|
10
12
|
const response = await fetch(Constants.internetConnectionTestUrl);
|
|
@@ -17,18 +19,22 @@ const isInternetConnected = async () => {
|
|
|
17
19
|
export const createInternetConnectionChangeHandler = async state => {
|
|
18
20
|
const handler = async () => {
|
|
19
21
|
const connected = await isInternetConnected();
|
|
22
|
+
const inMemoryState = executeReducer(state, {
|
|
23
|
+
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
24
|
+
payload: null
|
|
25
|
+
});
|
|
20
26
|
if (!connected) {
|
|
21
|
-
var
|
|
27
|
+
var _inMemoryState$domain, _inMemoryState$domain2;
|
|
22
28
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
23
29
|
Event: TelemetryEvent.NetworkDisconnected
|
|
24
30
|
});
|
|
25
|
-
NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (
|
|
31
|
+
NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain = inMemoryState.domainStates) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.middlewareLocalizedTexts) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
|
|
26
32
|
} else {
|
|
27
|
-
var
|
|
33
|
+
var _inMemoryState$domain3, _inMemoryState$domain4;
|
|
28
34
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
29
35
|
Event: TelemetryEvent.NetworkReconnected
|
|
30
36
|
});
|
|
31
|
-
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (
|
|
37
|
+
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.middlewareLocalizedTexts) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
|
|
32
38
|
BroadcastService.postMessage({
|
|
33
39
|
eventName: BroadcastEvent.NetworkReconnected
|
|
34
40
|
});
|
|
@@ -409,7 +409,7 @@ export const LiveChatWidgetStateful = props => {
|
|
|
409
409
|
|
|
410
410
|
// Start chat from SDK Event
|
|
411
411
|
BroadcastService.getMessageByEventName(BroadcastEvent.StartChat).subscribe(msg => {
|
|
412
|
-
var _props$chatConfig5, _props$chatConfig5$Li, _props$chatConfig6, _props$chatConfig6$Li, _msg$payload5, _msg$payload6, _msg$payload7, _msg$payload9, _inMemoryState$appSta2, _inMemoryState$appSta3
|
|
412
|
+
var _props$chatConfig5, _props$chatConfig5$Li, _props$chatConfig6, _props$chatConfig6$Li, _msg$payload5, _msg$payload6, _msg$payload7, _msg$payload9, _inMemoryState$appSta2, _inMemoryState$appSta3;
|
|
413
413
|
// If chat is out of operating hours chat widget sets the conversation state to OutOfOffice.
|
|
414
414
|
if (typeof (props === null || props === void 0 ? void 0 : (_props$chatConfig5 = props.chatConfig) === null || _props$chatConfig5 === void 0 ? void 0 : (_props$chatConfig5$Li = _props$chatConfig5.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig5$Li === void 0 ? void 0 : _props$chatConfig5$Li.OutOfOperatingHours) === "string" && (props === null || props === void 0 ? void 0 : (_props$chatConfig6 = props.chatConfig) === null || _props$chatConfig6 === void 0 ? void 0 : (_props$chatConfig6$Li = _props$chatConfig6.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig6$Li === void 0 ? void 0 : _props$chatConfig6$Li.OutOfOperatingHours.toLowerCase()) === "true") {
|
|
415
415
|
(state === null || state === void 0 ? void 0 : state.appStates.isMinimized) && dispatch({
|
|
@@ -447,8 +447,14 @@ export const LiveChatWidgetStateful = props => {
|
|
|
447
447
|
});
|
|
448
448
|
inMemoryState.domainStates.customContext = msg === null || msg === void 0 ? void 0 : (_msg$payload9 = msg.payload) === null || _msg$payload9 === void 0 ? void 0 : _msg$payload9.customContext;
|
|
449
449
|
|
|
450
|
-
|
|
451
|
-
|
|
450
|
+
/*
|
|
451
|
+
* If the conversation is in closed state then we start a new chat,
|
|
452
|
+
* else if the conversation is in active state then we maximize the chat
|
|
453
|
+
* If the conversation is in inactive or postchat state then we maximize the chat.
|
|
454
|
+
*
|
|
455
|
+
* To start a new chat, it needs to be called via the close button or close chat via SDK.
|
|
456
|
+
**/
|
|
457
|
+
if (((_inMemoryState$appSta2 = inMemoryState.appStates) === null || _inMemoryState$appSta2 === void 0 ? void 0 : _inMemoryState$appSta2.conversationState) === ConversationState.Closed) {
|
|
452
458
|
BroadcastService.postMessage({
|
|
453
459
|
eventName: BroadcastEvent.ChatInitiated
|
|
454
460
|
});
|
|
@@ -457,7 +463,7 @@ export const LiveChatWidgetStateful = props => {
|
|
|
457
463
|
}
|
|
458
464
|
|
|
459
465
|
// If minimized, maximize the chat
|
|
460
|
-
if ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
466
|
+
if ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta3 = inMemoryState.appStates) === null || _inMemoryState$appSta3 === void 0 ? void 0 : _inMemoryState$appSta3.isMinimized) === true) {
|
|
461
467
|
var _inMemoryState$domain, _inMemoryState$domain2, _inMemoryState$domain3, _inMemoryState$domain4;
|
|
462
468
|
dispatch({
|
|
463
469
|
type: LiveChatWidgetActionType.SET_MINIMIZED,
|
|
@@ -585,12 +591,12 @@ export const LiveChatWidgetStateful = props => {
|
|
|
585
591
|
disablePolling: true
|
|
586
592
|
});
|
|
587
593
|
facadeChatSDK === null || facadeChatSDK === void 0 ? void 0 : facadeChatSDK.onAgentEndSession(event => {
|
|
588
|
-
var _inMemoryState$
|
|
594
|
+
var _inMemoryState$appSta4;
|
|
589
595
|
const inMemoryState = executeReducer(state, {
|
|
590
596
|
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
591
597
|
payload: null
|
|
592
598
|
});
|
|
593
|
-
if ("participantsRemoved" in event && (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
599
|
+
if ("participantsRemoved" in event && (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta4 = inMemoryState.appStates) === null || _inMemoryState$appSta4 === void 0 ? void 0 : _inMemoryState$appSta4.conversationState) === ConversationState.Active) {
|
|
594
600
|
setWebChatStyles(styles => {
|
|
595
601
|
return {
|
|
596
602
|
...styles,
|
|
@@ -733,13 +739,13 @@ export const LiveChatWidgetStateful = props => {
|
|
|
733
739
|
|
|
734
740
|
// Handle Chat disconnect cases
|
|
735
741
|
useEffect(() => {
|
|
736
|
-
var _inMemoryState$
|
|
742
|
+
var _inMemoryState$appSta5;
|
|
737
743
|
const inMemoryState = executeReducer(state, {
|
|
738
744
|
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
739
745
|
payload: null
|
|
740
746
|
});
|
|
741
747
|
handleChatDisconnect(props, inMemoryState, setWebChatStyles);
|
|
742
|
-
const chatDisconnectState = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
748
|
+
const chatDisconnectState = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta5 = inMemoryState.appStates) === null || _inMemoryState$appSta5 === void 0 ? void 0 : _inMemoryState$appSta5.chatDisconnectEventReceived;
|
|
743
749
|
if (chatDisconnectState && adapter) {
|
|
744
750
|
try {
|
|
745
751
|
adapter.end();
|
|
@@ -5,6 +5,7 @@ import { OutOfOfficeHoursPane } from "@microsoft/omnichannel-chat-components";
|
|
|
5
5
|
import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
|
|
6
6
|
import { defaultGeneralStyleProps } from "./common/defaultStyleProps/defaultgeneralOOOHPaneStyleProps";
|
|
7
7
|
import useChatContextStore from "../../hooks/useChatContextStore";
|
|
8
|
+
import DOMPurify from "dompurify";
|
|
8
9
|
let uiTimer;
|
|
9
10
|
export const OutOfOfficeHoursPaneStateful = props => {
|
|
10
11
|
var _props$styleProps;
|
|
@@ -40,6 +41,9 @@ export const OutOfOfficeHoursPaneStateful = props => {
|
|
|
40
41
|
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
41
42
|
});
|
|
42
43
|
}, []);
|
|
44
|
+
if (controlProps !== null && controlProps !== void 0 && controlProps.titleText) {
|
|
45
|
+
controlProps.titleText = DOMPurify.sanitize(controlProps.titleText);
|
|
46
|
+
}
|
|
43
47
|
return /*#__PURE__*/React.createElement(OutOfOfficeHoursPane, {
|
|
44
48
|
componentOverrides: props.componentOverrides,
|
|
45
49
|
controlProps: controlProps,
|
|
@@ -8,6 +8,7 @@ import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
|
|
|
8
8
|
import { defaultGeneralPostChatSurveyPaneStyleProps } from "./common/defaultStyleProps/defaultgeneralPostChatSurveyPaneStyleProps";
|
|
9
9
|
import { findAllFocusableElement } from "../../common/utils";
|
|
10
10
|
import useChatContextStore from "../../hooks/useChatContextStore";
|
|
11
|
+
import isValidSurveyUrl from "./common/isValidSurveyUrl";
|
|
11
12
|
const generateSurveyInviteLink = function (surveyInviteLink, isEmbed, locale, compact) {
|
|
12
13
|
let showMultiLingual = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
13
14
|
const surveyLink = `${surveyInviteLink}
|
|
@@ -45,6 +46,20 @@ export const PostChatSurveyPaneStateful = props => {
|
|
|
45
46
|
surveyURL: ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.surveyURL) ?? surveyInviteLink,
|
|
46
47
|
...props.controlProps
|
|
47
48
|
};
|
|
49
|
+
if (controlProps.surveyURL) {
|
|
50
|
+
if (!isValidSurveyUrl(controlProps.surveyURL)) {
|
|
51
|
+
TelemetryHelper.logLoadingEvent(LogLevel.ERROR, {
|
|
52
|
+
Event: TelemetryEvent.PostChatSurveyUrlValidationFailed,
|
|
53
|
+
Description: `${controlProps.surveyURL} is not a valid Survey URL`
|
|
54
|
+
});
|
|
55
|
+
controlProps.surveyURL = "";
|
|
56
|
+
} else {
|
|
57
|
+
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
58
|
+
Event: TelemetryEvent.PostChatSurveyUrlValidationCompleted,
|
|
59
|
+
Description: `${controlProps.surveyURL} is a valid Survey URL`
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
48
63
|
|
|
49
64
|
// Move focus to the first button
|
|
50
65
|
useEffect(() => {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isNullOrEmptyString } from "../../../common/utils";
|
|
2
|
+
const validRootDomains = ["microsoft.com", "microsoft.us", "appsplatform.us", "powervirtualagents.cn"];
|
|
3
|
+
const isValidSurveyUrl = url => {
|
|
4
|
+
if (isNullOrEmptyString(url)) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
try {
|
|
8
|
+
const objectUrl = new URL(url);
|
|
9
|
+
if (!objectUrl.origin || objectUrl.origin === "null") {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
const validDomain = validRootDomains.find(domain => objectUrl.origin.endsWith(domain));
|
|
13
|
+
if (validDomain) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
} catch (error) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
};
|
|
21
|
+
export default isValidSurveyUrl;
|
|
@@ -136,11 +136,6 @@ export const PreChatSurveyPaneStateful = props => {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
// Move focus to the first button
|
|
140
|
-
const firstElement = findAllFocusableElement(`#${controlProps.id}`);
|
|
141
|
-
if (firstElement && firstElement[0]) {
|
|
142
|
-
firstElement[0].focus();
|
|
143
|
-
}
|
|
144
139
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
145
140
|
Event: TelemetryEvent.PrechatSurveyLoaded
|
|
146
141
|
});
|
|
@@ -149,6 +144,16 @@ export const PreChatSurveyPaneStateful = props => {
|
|
|
149
144
|
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
150
145
|
});
|
|
151
146
|
}, []);
|
|
147
|
+
|
|
148
|
+
// Set focus to the first element
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (!state.appStates.isMinimized) {
|
|
151
|
+
const firstElement = findAllFocusableElement(`#${controlProps.id}`);
|
|
152
|
+
if (firstElement && firstElement[0]) {
|
|
153
|
+
firstElement[0].focus();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}, [state.appStates.isMinimized]);
|
|
152
157
|
return /*#__PURE__*/React.createElement(PreChatSurveyPane, {
|
|
153
158
|
controlProps: controlProps,
|
|
154
159
|
styleProps: styleProps
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import { Stack } from "@fluentui/react";
|
|
4
4
|
import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
|
|
5
5
|
import React, { useEffect } from "react";
|
|
6
|
-
import { createTimer, setFocusOnSendBox } from "../../common/utils";
|
|
6
|
+
import { createTimer, getDeviceType, setFocusOnSendBox } from "../../common/utils";
|
|
7
7
|
import { BotMagicCodeStore } from "./webchatcontroller/BotMagicCodeStore";
|
|
8
8
|
import { Components } from "botframework-webchat";
|
|
9
|
-
import { Constants } from "../../common/Constants";
|
|
9
|
+
import { Constants, HtmlAttributeNames, HtmlClassNames } from "../../common/Constants";
|
|
10
10
|
import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
|
|
11
11
|
import { NotificationHandler } from "./webchatcontroller/notification/NotificationHandler";
|
|
12
12
|
import { NotificationScenarios } from "./webchatcontroller/enums/NotificationScenarios";
|
|
@@ -75,7 +75,12 @@ export const WebChatContainerStateful = props => {
|
|
|
75
75
|
};
|
|
76
76
|
useEffect(() => {
|
|
77
77
|
var _props$webChatContain, _props$webChatContain2;
|
|
78
|
-
|
|
78
|
+
if (getDeviceType() !== "standard" && (webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.webChatHistoryMobileAccessibilityLabel) !== undefined) {
|
|
79
|
+
const chatHistoryElement = document.querySelector(`.${HtmlClassNames.webChatHistoryContainer}`);
|
|
80
|
+
if (chatHistoryElement) {
|
|
81
|
+
chatHistoryElement.setAttribute(HtmlAttributeNames.ariaLabel, webChatContainerProps.webChatHistoryMobileAccessibilityLabel);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
79
84
|
dispatch({
|
|
80
85
|
type: LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
|
|
81
86
|
payload: webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.renderingMiddlewareProps
|
|
@@ -156,6 +161,13 @@ export const WebChatContainerStateful = props => {
|
|
|
156
161
|
ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
|
|
157
162
|
});
|
|
158
163
|
}, []);
|
|
164
|
+
|
|
165
|
+
// Set focus to the sendbox
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
if (!state.appStates.isMinimized) {
|
|
168
|
+
setFocusOnSendBox();
|
|
169
|
+
}
|
|
170
|
+
}, [state.appStates.isMinimized]);
|
|
159
171
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("style", null, `
|
|
160
172
|
.webchat__stacked-layout__content .ac-pushButton {
|
|
161
173
|
cursor: pointer;
|
|
@@ -25,14 +25,27 @@ export const DeliveredTimestamp = _ref => {
|
|
|
25
25
|
timestamp
|
|
26
26
|
}
|
|
27
27
|
} = args;
|
|
28
|
+
const getTimeElement = timestamp => {
|
|
29
|
+
const timeString = getTimestampHourMinute(timestamp);
|
|
30
|
+
const isAmPmFormat = timeString.toLowerCase().includes("am") || timeString.toLowerCase().includes("pm");
|
|
31
|
+
|
|
32
|
+
// For clients that use languages that are written right-to-left, but still use AM/PM time format, we need to
|
|
33
|
+
// make sure the "rtl" direction doesn't produce "PM 1:23", but remains "1:23 PM"
|
|
34
|
+
if (dir === "rtl" && isAmPmFormat) {
|
|
35
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
36
|
+
dir: "ltr"
|
|
37
|
+
}, getTimestampHourMinute(timestamp));
|
|
38
|
+
}
|
|
39
|
+
return timeString;
|
|
40
|
+
};
|
|
28
41
|
return /*#__PURE__*/React.createElement(Stack, {
|
|
29
42
|
style: contentStyles,
|
|
30
43
|
dir: dir
|
|
31
44
|
}, role === DirectLineSenderRole.Bot && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
32
45
|
dir: dir,
|
|
33
46
|
"aria-hidden": "false"
|
|
34
|
-
}, name, " - ",
|
|
47
|
+
}, name, " - ", getTimeElement(timestamp))), role === DirectLineSenderRole.User && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
35
48
|
"aria-hidden": "false",
|
|
36
49
|
dir: dir
|
|
37
|
-
}, " ",
|
|
50
|
+
}, " ", getTimeElement(timestamp), " - ", ((_state$domainStates$m = state.domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_MESSAGE_DELIVERED) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_MESSAGE_DELIVERED)));
|
|
38
51
|
};
|
|
@@ -35,6 +35,7 @@ const convertTextToHtmlNode = text => {
|
|
|
35
35
|
|
|
36
36
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
37
|
const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
|
|
38
|
+
var _htmlNode$tagName;
|
|
38
39
|
const htmlNode = convertTextToHtmlNode(text);
|
|
39
40
|
const aNodes = htmlNode.getElementsByTagName(HtmlAttributeNames.aTagName);
|
|
40
41
|
if ((aNodes === null || aNodes === void 0 ? void 0 : aNodes.length) > 0) {
|
|
@@ -64,8 +65,6 @@ const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
|
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
68
|
action = updateIn(action, [Constants.payload, Constants.activity, Constants.text], () => htmlNode.innerHTML);
|
|
70
69
|
} catch (e) {
|
|
71
70
|
let errorMessage = "Failed to apply action: ";
|
|
@@ -83,6 +82,11 @@ const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
|
|
|
83
82
|
});
|
|
84
83
|
}
|
|
85
84
|
}
|
|
85
|
+
|
|
86
|
+
// if empty div tag after sanitization
|
|
87
|
+
if (((_htmlNode$tagName = htmlNode.tagName) === null || _htmlNode$tagName === void 0 ? void 0 : _htmlNode$tagName.toLowerCase()) === HtmlAttributeNames.div && htmlNode.children.length === 0 && htmlNode.innerHTML.trim() === "") {
|
|
88
|
+
action = updateIn(action, [Constants.payload, Constants.activity, Constants.text], () => "");
|
|
89
|
+
}
|
|
86
90
|
return action;
|
|
87
91
|
};
|
|
88
92
|
|
|
@@ -5,6 +5,7 @@ function _toPrimitive(input, hint) { if (typeof input !== "object" || input ===
|
|
|
5
5
|
|
|
6
6
|
import { createFileAndDownload } from "../common/utils";
|
|
7
7
|
import defaultLibraryScripts from "../components/footerstateful/downloadtranscriptstateful/common/defaultLibraryScripts";
|
|
8
|
+
import DOMPurify from "dompurify";
|
|
8
9
|
class TranscriptHTMLBuilder {
|
|
9
10
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
10
11
|
|
|
@@ -167,7 +168,7 @@ class TranscriptHTMLBuilder {
|
|
|
167
168
|
<script>
|
|
168
169
|
class Translator {
|
|
169
170
|
static convertTranscriptMessageToActivity(message) {
|
|
170
|
-
const {created, OriginalMessageId, id, isControlMessage, content, tags, from, attachments, amsMetadata, amsReferences} = message;
|
|
171
|
+
const {created, OriginalMessageId, id, isControlMessage, content, tags, from, attachments, amsMetadata, amsReferences, amsreferences} = message;
|
|
171
172
|
|
|
172
173
|
//it's required to convert the id to a number, otherwise the webchat will not render the messages in the correct order
|
|
173
174
|
// if the OrginalMessageId is not present, we can use the id as the sequence id, which is always present.
|
|
@@ -214,7 +215,7 @@ class TranscriptHTMLBuilder {
|
|
|
214
215
|
}
|
|
215
216
|
|
|
216
217
|
// Attachments
|
|
217
|
-
if (amsReferences && amsMetadata) {
|
|
218
|
+
if ((amsReferences || amsreferences) && amsMetadata) {
|
|
218
219
|
const metadata = JSON.parse(amsMetadata);
|
|
219
220
|
const { fileName } = metadata[0];
|
|
220
221
|
const text = \`${this.attachmentMessage}\${fileName}\`;
|
|
@@ -238,7 +239,7 @@ class TranscriptHTMLBuilder {
|
|
|
238
239
|
// Message
|
|
239
240
|
if (content) {
|
|
240
241
|
// Adaptive card formatting
|
|
241
|
-
if (content.includes('"
|
|
242
|
+
if (content.includes('"attachments"') || content.includes('"suggestedActions"')) {
|
|
242
243
|
try {
|
|
243
244
|
const partialActivity = JSON.parse(content);
|
|
244
245
|
return {
|
|
@@ -669,12 +670,15 @@ const createChatTranscript = async function (transcript, facadeChatSDK) {
|
|
|
669
670
|
reader.readAsDataURL(blob);
|
|
670
671
|
});
|
|
671
672
|
};
|
|
672
|
-
let messages = transcriptMessages
|
|
673
|
+
let messages = transcriptMessages.filter(message => {
|
|
674
|
+
message.content = DOMPurify.sanitize(message.content);
|
|
675
|
+
return message;
|
|
676
|
+
});
|
|
673
677
|
if (renderAttachments) {
|
|
674
678
|
messages = await Promise.all(transcriptMessages.map(async message => {
|
|
675
679
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
676
680
|
const {
|
|
677
|
-
amsReferences,
|
|
681
|
+
amsReferences = message.amsreferences,
|
|
678
682
|
amsMetadata
|
|
679
683
|
} = message;
|
|
680
684
|
if (amsReferences && amsMetadata) {
|
|
@@ -83,7 +83,7 @@ export const createOnNewAdapterActivityHandler = (chatId, userId) => {
|
|
|
83
83
|
TelemetryHelper.logActionEvent(LogLevel.INFO, {
|
|
84
84
|
Event: TelemetryEvent.MessageReceived,
|
|
85
85
|
Description: "New message received",
|
|
86
|
-
|
|
86
|
+
CustomProperties: payload
|
|
87
87
|
});
|
|
88
88
|
} else {
|
|
89
89
|
if (!isHistoryMessageReceivedEventRasied) {
|
|
@@ -91,7 +91,7 @@ export const createOnNewAdapterActivityHandler = (chatId, userId) => {
|
|
|
91
91
|
TelemetryHelper.logActionEvent(LogLevel.INFO, {
|
|
92
92
|
Event: TelemetryEvent.RehydrateMessageReceived,
|
|
93
93
|
Description: "History message received",
|
|
94
|
-
|
|
94
|
+
CustomProperties: payload
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -104,6 +104,7 @@ export declare class HtmlIdNames {
|
|
|
104
104
|
export declare class HtmlClassNames {
|
|
105
105
|
static readonly webChatBannerCloseButton = "webchat__toast__dismissButton";
|
|
106
106
|
static readonly webChatBannerExpandButton = "webchat__toaster__expandIcon";
|
|
107
|
+
static readonly webChatHistoryContainer = "webchat__basic-transcript";
|
|
107
108
|
}
|
|
108
109
|
export declare class HtmlElementSelectors {
|
|
109
110
|
static readonly sendBoxSelector = "textarea[data-id=\"webchat-sendbox-input\"]";
|
|
@@ -57,7 +57,7 @@ export declare class FacadeChatSDK {
|
|
|
57
57
|
getCallingToken(): Promise<string>;
|
|
58
58
|
getMessages(): Promise<IMessage[] | OmnichannelMessage[] | undefined>;
|
|
59
59
|
getDataMaskingRules(): Promise<MaskingRules>;
|
|
60
|
-
sendMessage(message: ChatSDKMessage): Promise<void>;
|
|
60
|
+
sendMessage(message: ChatSDKMessage): Promise<void | OmnichannelMessage>;
|
|
61
61
|
onNewMessage(onNewMessageCallback: CallableFunction, optionalParams?: OnNewMessageOptionalParams): Promise<void>;
|
|
62
62
|
sendTypingEvent(): Promise<void>;
|
|
63
63
|
onTypingEvent(onTypingEventCallback: CallableFunction): Promise<void>;
|
|
@@ -206,6 +206,8 @@ export declare enum TelemetryEvent {
|
|
|
206
206
|
PostChatContextCallFailed = "PostChatContextCallFailed",
|
|
207
207
|
PostChatSurveyLoadingPaneLoaded = "PostChatSurveyLoadingPaneLoaded",
|
|
208
208
|
PostChatSurveyLoaded = "PostChatSurveyLoaded",
|
|
209
|
+
PostChatSurveyUrlValidationCompleted = "PostChatSurveyUrlValidationCompleted",
|
|
210
|
+
PostChatSurveyUrlValidationFailed = "PostChatSurveyUrlValidationFailed",
|
|
209
211
|
ChatDisconnectThreadEventReceived = "ChatDisconnectThreadEventReceived",
|
|
210
212
|
HiddenAdaptiveCardMessageReceived = "HiddenAdaptiveCardMessageReceived",
|
|
211
213
|
EndingAdapterAfterDisconnectionError = "EndingAdapterAfterDisconnectionError",
|
|
@@ -46,3 +46,4 @@ export declare const createFileAndDownload: (fileName: string, blobData: string,
|
|
|
46
46
|
export declare const formatTemplateString: (templateMessage: string, values: any) => string;
|
|
47
47
|
export declare const parseLowerCaseString: (property: string | boolean | undefined) => string;
|
|
48
48
|
export declare const setOcUserAgent: (chatSDK: any) => void;
|
|
49
|
+
export declare function getDeviceType(): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/omnichannel-chat-widget",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.8-main.29ce174",
|
|
4
4
|
"description": "Microsoft Omnichannel Chat Widget",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"types": "lib/types/index.d.ts",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@azure/core-tracing": "^1.2.0",
|
|
80
80
|
"@microsoft/omnichannel-chat-components": "1.1.8",
|
|
81
|
-
"@microsoft/omnichannel-chat-sdk": "^1.10.
|
|
81
|
+
"@microsoft/omnichannel-chat-sdk": "^1.10.17",
|
|
82
82
|
"@opentelemetry/api": "^1.9.0",
|
|
83
83
|
"abort-controller-es5": "^2.0.1",
|
|
84
84
|
"dompurify": "^3.2.4",
|