@microsoft/omnichannel-chat-widget 1.0.2 → 1.0.3-main.527b216
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/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +2 -1
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +34 -16
- package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +1 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer.js +62 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/dataMaskingMiddleware.js +25 -12
- package/lib/esm/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +2 -1
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +34 -16
- package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +1 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer.js +54 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/dataMaskingMiddleware.js +25 -12
- package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +1 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer.d.ts +9 -0
- package/package.json +1 -1
|
@@ -32,24 +32,26 @@ var _preProcessingMiddleware = _interopRequireDefault(require("../../webchatcont
|
|
|
32
32
|
var _sanitizationMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware"));
|
|
33
33
|
var _cardActionMiddleware = require("../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware");
|
|
34
34
|
var _messageTimestampMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware"));
|
|
35
|
+
var _HyperlinkTextOverrideRenderer = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer"));
|
|
35
36
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
36
37
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
38
|
const initWebChatComposer = (props, chatSDK, setAdapter, state, dispatch, adapter, setWebChatStyles) => {
|
|
38
|
-
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _state$domainStates$l4, _state$domainStates$l5, _props$
|
|
39
|
+
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _state$domainStates$l4, _state$domainStates$l5, _props$webChatContain11, _props$webChatContain12, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain13, _props$webChatContain14, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain15, _props$webChatContain16, _defaultWebChatContai, _props$webChatContain17, _props$webChatContain18, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain19, _props$webChatContain20, _defaultWebChatContai2, _props$webChatContain21, _props$webChatContain22, _defaultWebChatContai3, _props$webChatContain23, _props$webChatContain24;
|
|
39
40
|
const localizedTexts = {
|
|
40
41
|
..._defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts,
|
|
41
42
|
...((_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : _props$webChatContain.localizedTexts)
|
|
42
43
|
};
|
|
43
|
-
const
|
|
44
|
+
const hyperlinkTextOverride = ((_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : _props$webChatContain2.hyperlinkTextOverride) ?? _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.hyperlinkTextOverride;
|
|
45
|
+
const disableNewLineMarkdownSupport = ((_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.disableNewLineMarkdownSupport) ?? _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.disableNewLineMarkdownSupport;
|
|
44
46
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
45
|
-
const markdown = (0, _createMarkdown.createMarkdown)(((_props$
|
|
47
|
+
const markdown = (0, _createMarkdown.createMarkdown)(((_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.disableMarkdownMessageFormatting) ?? _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.disableMarkdownMessageFormatting, disableNewLineMarkdownSupport);
|
|
46
48
|
// Initialize Web Chat's redux store
|
|
47
49
|
let webChatStore = _WebChatStoreLoader.WebChatStoreLoader.store;
|
|
48
50
|
if (!webChatStore) {
|
|
49
|
-
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$
|
|
51
|
+
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$webChatContain7;
|
|
50
52
|
const conversationEndCallback = async () => {
|
|
51
|
-
var _props$
|
|
52
|
-
if ((props === null || props === void 0 ? void 0 : (_props$
|
|
53
|
+
var _props$webChatContain5, _props$webChatContain6;
|
|
54
|
+
if ((props === null || props === void 0 ? void 0 : (_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : (_props$webChatContain6 = _props$webChatContain5.renderingMiddlewareProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.hideSendboxOnConversationEnd) !== false) {
|
|
53
55
|
setWebChatStyles(styles => {
|
|
54
56
|
return {
|
|
55
57
|
...styles,
|
|
@@ -70,9 +72,25 @@ const initWebChatComposer = (props, chatSDK, setAdapter, state, dispatch, adapte
|
|
|
70
72
|
//initial state
|
|
71
73
|
_preProcessingMiddleware.default, _attachmentProcessingMiddleware.default, (0, _attachmentUploadValidatorMiddleware.default)((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), _channelDataMiddleware.default, (0, _conversationEndMiddleware.default)(conversationEndCallback), (0, _dataMaskingMiddleware.default)((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), _messageTimestampMiddleware.default, _gifUploadMiddleware.default, _htmlPlayerMiddleware.default, _htmlTextMiddleware.default, (0, _maxMessageSizeValidator.default)(localizedTexts), _sanitizationMiddleware.default,
|
|
72
74
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
73
|
-
...(((_props$
|
|
75
|
+
...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
|
|
74
76
|
_WebChatStoreLoader.WebChatStoreLoader.store = webChatStore;
|
|
75
77
|
}
|
|
78
|
+
const hyperlinkTextOverrideRenderer = new _HyperlinkTextOverrideRenderer.default(hyperlinkTextOverride);
|
|
79
|
+
const markdownRenderers = [hyperlinkTextOverrideRenderer];
|
|
80
|
+
const renderMarkdown = text => {
|
|
81
|
+
var _props$webChatContain8, _props$webChatContain9;
|
|
82
|
+
if ((_props$webChatContain8 = props.webChatContainerProps) !== null && _props$webChatContain8 !== void 0 && (_props$webChatContain9 = _props$webChatContain8.webChatProps) !== null && _props$webChatContain9 !== void 0 && _props$webChatContain9.renderMarkdown) {
|
|
83
|
+
var _props$webChatContain10;
|
|
84
|
+
text = (_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatProps.renderMarkdown(text);
|
|
85
|
+
} else {
|
|
86
|
+
const render = disableNewLineMarkdownSupport ? markdown.renderInline.bind(markdown) : markdown.render.bind(markdown);
|
|
87
|
+
text = render(text);
|
|
88
|
+
}
|
|
89
|
+
markdownRenderers.forEach(renderer => {
|
|
90
|
+
text = renderer.render(text);
|
|
91
|
+
});
|
|
92
|
+
return text;
|
|
93
|
+
};
|
|
76
94
|
|
|
77
95
|
// Initialize the remaining Web Chat props
|
|
78
96
|
const webChatProps = {
|
|
@@ -80,17 +98,17 @@ const initWebChatComposer = (props, chatSDK, setAdapter, state, dispatch, adapte
|
|
|
80
98
|
dir: state.domainStates.globalDir,
|
|
81
99
|
locale: (0, _utils.changeLanguageCodeFormatForWebChat)((0, _omnichannelChatSdk.getLocaleStringFromId)((_state$domainStates$l4 = state.domainStates.liveChatConfig) === null || _state$domainStates$l4 === void 0 ? void 0 : (_state$domainStates$l5 = _state$domainStates$l4.ChatWidgetLanguage) === null || _state$domainStates$l5 === void 0 ? void 0 : _state$domainStates$l5.msdyn_localeid)),
|
|
82
100
|
store: webChatStore,
|
|
83
|
-
activityMiddleware: (_props$
|
|
84
|
-
attachmentMiddleware: (_props$
|
|
85
|
-
activityStatusMiddleware: (_props$
|
|
86
|
-
renderMarkdown
|
|
87
|
-
avatarMiddleware: (_props$
|
|
88
|
-
groupActivitiesMiddleware: (_props$
|
|
89
|
-
typingIndicatorMiddleware: (_props$
|
|
101
|
+
activityMiddleware: (_props$webChatContain11 = props.webChatContainerProps) !== null && _props$webChatContain11 !== void 0 && (_props$webChatContain12 = _props$webChatContain11.renderingMiddlewareProps) !== null && _props$webChatContain12 !== void 0 && _props$webChatContain12.disableActivityMiddleware ? undefined : (0, _activityMiddleware.createActivityMiddleware)((_state$domainStates$r = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r === void 0 ? void 0 : _state$domainStates$r.systemMessageStyleProps, (_state$domainStates$r2 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r2 === void 0 ? void 0 : _state$domainStates$r2.userMessageStyleProps),
|
|
102
|
+
attachmentMiddleware: (_props$webChatContain13 = props.webChatContainerProps) !== null && _props$webChatContain13 !== void 0 && (_props$webChatContain14 = _props$webChatContain13.renderingMiddlewareProps) !== null && _props$webChatContain14 !== void 0 && _props$webChatContain14.disableAttachmentMiddleware ? undefined : (0, _attachmentMiddleware.default)(((_state$domainStates$r3 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r3 === void 0 ? void 0 : (_state$domainStates$r4 = _state$domainStates$r3.attachmentProps) === null || _state$domainStates$r4 === void 0 ? void 0 : _state$domainStates$r4.enableInlinePlaying) ?? _defaultAttachmentProps.defaultAttachmentProps.enableInlinePlaying),
|
|
103
|
+
activityStatusMiddleware: (_props$webChatContain15 = props.webChatContainerProps) !== null && _props$webChatContain15 !== void 0 && (_props$webChatContain16 = _props$webChatContain15.renderingMiddlewareProps) !== null && _props$webChatContain16 !== void 0 && _props$webChatContain16.disableActivityStatusMiddleware ? undefined : (_defaultWebChatContai = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.activityStatusMiddleware,
|
|
104
|
+
renderMarkdown,
|
|
105
|
+
avatarMiddleware: (_props$webChatContain17 = props.webChatContainerProps) !== null && _props$webChatContain17 !== void 0 && (_props$webChatContain18 = _props$webChatContain17.renderingMiddlewareProps) !== null && _props$webChatContain18 !== void 0 && _props$webChatContain18.disableAvatarMiddleware ? undefined : (0, _avatarMiddleware.createAvatarMiddleware)((_state$domainStates$r5 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r5 === void 0 ? void 0 : _state$domainStates$r5.avatarStyleProps, (_state$domainStates$r6 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r6 === void 0 ? void 0 : _state$domainStates$r6.avatarTextStyleProps),
|
|
106
|
+
groupActivitiesMiddleware: (_props$webChatContain19 = props.webChatContainerProps) !== null && _props$webChatContain19 !== void 0 && (_props$webChatContain20 = _props$webChatContain19.renderingMiddlewareProps) !== null && _props$webChatContain20 !== void 0 && _props$webChatContain20.disableGroupActivitiesMiddleware ? undefined : (_defaultWebChatContai2 = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.groupActivitiesMiddleware,
|
|
107
|
+
typingIndicatorMiddleware: (_props$webChatContain21 = props.webChatContainerProps) !== null && _props$webChatContain21 !== void 0 && (_props$webChatContain22 = _props$webChatContain21.renderingMiddlewareProps) !== null && _props$webChatContain22 !== void 0 && _props$webChatContain22.disableTypingIndicatorMiddleware ? undefined : (_defaultWebChatContai3 = _defaultWebChatContainerStatefulProps.defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai3 === void 0 ? void 0 : _defaultWebChatContai3.typingIndicatorMiddleware,
|
|
90
108
|
onTelemetry: (0, _WebChatLogger.createWebChatTelemetry)(),
|
|
91
|
-
cardActionMiddleware: (0, _cardActionMiddleware.createCardActionMiddleware)(((_props$
|
|
109
|
+
cardActionMiddleware: (0, _cardActionMiddleware.createCardActionMiddleware)(((_props$webChatContain23 = props.webChatContainerProps) === null || _props$webChatContain23 === void 0 ? void 0 : _props$webChatContain23.botMagicCode) || undefined),
|
|
92
110
|
sendTypingIndicator: true,
|
|
93
|
-
...((_props$
|
|
111
|
+
...((_props$webChatContain24 = props.webChatContainerProps) === null || _props$webChatContain24 === void 0 ? void 0 : _props$webChatContain24.webChatProps)
|
|
94
112
|
};
|
|
95
113
|
return webChatProps;
|
|
96
114
|
};
|
|
@@ -16,6 +16,7 @@ const defaultWebChatContainerStatefulProps = {
|
|
|
16
16
|
containerStyles: _defaultWebChatStatefulContainerStyles.defaultWebChatStatefulContainerStyles,
|
|
17
17
|
disableNewLineMarkdownSupport: false,
|
|
18
18
|
disableMarkdownMessageFormatting: false,
|
|
19
|
+
hyperlinkTextOverride: false,
|
|
19
20
|
directLine: new _mockadapter.default(),
|
|
20
21
|
adaptiveCardStyles: _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles
|
|
21
22
|
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _dompurify = _interopRequireDefault(require("dompurify"));
|
|
8
|
+
var _Constants = require("../../../../common/Constants");
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
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
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
12
|
+
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); }
|
|
13
|
+
class HyperlinkTextOverrideRenderer {
|
|
14
|
+
constructor(hyperlinkTextOverride) {
|
|
15
|
+
_defineProperty(this, "hyperlinkTextOverride", void 0);
|
|
16
|
+
this.hyperlinkTextOverride = hyperlinkTextOverride;
|
|
17
|
+
}
|
|
18
|
+
convertTextToHtmlNode(text) {
|
|
19
|
+
const htmlNode = document.createElement(_Constants.HtmlAttributeNames.div);
|
|
20
|
+
try {
|
|
21
|
+
text = _dompurify.default.sanitize(text); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
22
|
+
htmlNode.innerHTML = text;
|
|
23
|
+
} catch {
|
|
24
|
+
return htmlNode;
|
|
25
|
+
}
|
|
26
|
+
return htmlNode;
|
|
27
|
+
}
|
|
28
|
+
processANode(htmlNode) {
|
|
29
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
30
|
+
const aTags = htmlNode.getElementsByTagName(_Constants.HtmlAttributeNames.aTagName);
|
|
31
|
+
for (let index = 0; index < aTags.length; index++) {
|
|
32
|
+
const aNode = aTags[index];
|
|
33
|
+
if (!aNode || !aNode.tagName || aNode.tagName.toLowerCase() !== _Constants.HtmlAttributeNames.aTagName || !aNode.href) continue;
|
|
34
|
+
if (aNode.href !== aNode.text.trim()) {
|
|
35
|
+
aNode.text = aNode.href;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
applicable(text) {
|
|
40
|
+
if (!this.hyperlinkTextOverride) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const htmlNode = this.convertTextToHtmlNode(text);
|
|
45
|
+
const aNodes = htmlNode.getElementsByTagName(_Constants.HtmlAttributeNames.aTagName);
|
|
46
|
+
return !!aNodes && aNodes.length && aNodes.length > 0;
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
render(text) {
|
|
52
|
+
if (!this.applicable(text)) {
|
|
53
|
+
return text;
|
|
54
|
+
}
|
|
55
|
+
const htmlNode = this.convertTextToHtmlNode(text);
|
|
56
|
+
this.processANode(htmlNode);
|
|
57
|
+
text = htmlNode.innerHTML;
|
|
58
|
+
return text;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
var _default = HyperlinkTextOverrideRenderer;
|
|
62
|
+
exports.default = _default;
|
|
@@ -28,22 +28,25 @@ const applyDataMasking = (action, regexCollection) => {
|
|
|
28
28
|
});
|
|
29
29
|
return action;
|
|
30
30
|
}
|
|
31
|
-
let isRuleMatched = false;
|
|
32
31
|
for (const ruleId of Object.keys(regexCollection)) {
|
|
33
32
|
const item = regexCollection[ruleId];
|
|
34
33
|
if (item) {
|
|
34
|
+
let ruleInfiniteException = false;
|
|
35
|
+
let ruleApplied = false;
|
|
35
36
|
try {
|
|
36
37
|
const regex = new RegExp(item, "gi");
|
|
37
38
|
let match;
|
|
38
39
|
// eslint-disable-next-line no-cond-assign
|
|
39
40
|
while (match = regex.exec(text)) {
|
|
40
41
|
const replaceStr = match[0].replace(/./gi, maskedChar);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
const modifiedText = text.replace(match[0], replaceStr);
|
|
43
|
+
if (modifiedText == text) {
|
|
44
|
+
ruleInfiniteException = true;
|
|
45
|
+
console.warn(`The data masking rule ${item} is ignored because it matches empty strings. Please modify this rule.`);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
ruleApplied = true;
|
|
49
|
+
text = modifiedText;
|
|
47
50
|
}
|
|
48
51
|
} catch (err) {
|
|
49
52
|
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
|
|
@@ -54,11 +57,21 @@ const applyDataMasking = (action, regexCollection) => {
|
|
|
54
57
|
}
|
|
55
58
|
});
|
|
56
59
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
if (ruleApplied) {
|
|
61
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
62
|
+
Event: _TelemetryConstants.TelemetryEvent.DataMaskingRuleApplied,
|
|
63
|
+
Description: `Data Masking Rule Id: ${ruleId} applied.`
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (ruleInfiniteException) {
|
|
67
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
|
|
68
|
+
Event: _TelemetryConstants.TelemetryEvent.DataMaskingRuleApplyFailed,
|
|
69
|
+
ExceptionDetails: {
|
|
70
|
+
RuleId: ruleId,
|
|
71
|
+
Exception: "The data masking rule matches empty strings."
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
62
75
|
}
|
|
63
76
|
}
|
|
64
77
|
action.payload.text = text;
|
|
@@ -26,24 +26,26 @@ import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontr
|
|
|
26
26
|
import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
|
|
27
27
|
import { createCardActionMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware";
|
|
28
28
|
import createMessageTimeStampMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware";
|
|
29
|
+
import HyperlinkTextOverrideRenderer from "../../webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer";
|
|
29
30
|
|
|
30
31
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
32
|
export const initWebChatComposer = (props, chatSDK, setAdapter, state, dispatch, adapter, setWebChatStyles) => {
|
|
32
|
-
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _state$domainStates$l4, _state$domainStates$l5, _props$
|
|
33
|
+
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _state$domainStates$l4, _state$domainStates$l5, _props$webChatContain11, _props$webChatContain12, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain13, _props$webChatContain14, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain15, _props$webChatContain16, _defaultWebChatContai, _props$webChatContain17, _props$webChatContain18, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain19, _props$webChatContain20, _defaultWebChatContai2, _props$webChatContain21, _props$webChatContain22, _defaultWebChatContai3, _props$webChatContain23, _props$webChatContain24;
|
|
33
34
|
const localizedTexts = {
|
|
34
35
|
...defaultMiddlewareLocalizedTexts,
|
|
35
36
|
...((_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : _props$webChatContain.localizedTexts)
|
|
36
37
|
};
|
|
37
|
-
const
|
|
38
|
+
const hyperlinkTextOverride = ((_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : _props$webChatContain2.hyperlinkTextOverride) ?? defaultWebChatContainerStatefulProps.hyperlinkTextOverride;
|
|
39
|
+
const disableNewLineMarkdownSupport = ((_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.disableNewLineMarkdownSupport) ?? defaultWebChatContainerStatefulProps.disableNewLineMarkdownSupport;
|
|
38
40
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
39
|
-
const markdown = createMarkdown(((_props$
|
|
41
|
+
const markdown = createMarkdown(((_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.disableMarkdownMessageFormatting) ?? defaultWebChatContainerStatefulProps.disableMarkdownMessageFormatting, disableNewLineMarkdownSupport);
|
|
40
42
|
// Initialize Web Chat's redux store
|
|
41
43
|
let webChatStore = WebChatStoreLoader.store;
|
|
42
44
|
if (!webChatStore) {
|
|
43
|
-
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$
|
|
45
|
+
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$webChatContain7;
|
|
44
46
|
const conversationEndCallback = async () => {
|
|
45
|
-
var _props$
|
|
46
|
-
if ((props === null || props === void 0 ? void 0 : (_props$
|
|
47
|
+
var _props$webChatContain5, _props$webChatContain6;
|
|
48
|
+
if ((props === null || props === void 0 ? void 0 : (_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : (_props$webChatContain6 = _props$webChatContain5.renderingMiddlewareProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.hideSendboxOnConversationEnd) !== false) {
|
|
47
49
|
setWebChatStyles(styles => {
|
|
48
50
|
return {
|
|
49
51
|
...styles,
|
|
@@ -64,9 +66,25 @@ export const initWebChatComposer = (props, chatSDK, setAdapter, state, dispatch,
|
|
|
64
66
|
//initial state
|
|
65
67
|
preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware, createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
|
|
66
68
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
67
|
-
...(((_props$
|
|
69
|
+
...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
|
|
68
70
|
WebChatStoreLoader.store = webChatStore;
|
|
69
71
|
}
|
|
72
|
+
const hyperlinkTextOverrideRenderer = new HyperlinkTextOverrideRenderer(hyperlinkTextOverride);
|
|
73
|
+
const markdownRenderers = [hyperlinkTextOverrideRenderer];
|
|
74
|
+
const renderMarkdown = text => {
|
|
75
|
+
var _props$webChatContain8, _props$webChatContain9;
|
|
76
|
+
if ((_props$webChatContain8 = props.webChatContainerProps) !== null && _props$webChatContain8 !== void 0 && (_props$webChatContain9 = _props$webChatContain8.webChatProps) !== null && _props$webChatContain9 !== void 0 && _props$webChatContain9.renderMarkdown) {
|
|
77
|
+
var _props$webChatContain10;
|
|
78
|
+
text = (_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatProps.renderMarkdown(text);
|
|
79
|
+
} else {
|
|
80
|
+
const render = disableNewLineMarkdownSupport ? markdown.renderInline.bind(markdown) : markdown.render.bind(markdown);
|
|
81
|
+
text = render(text);
|
|
82
|
+
}
|
|
83
|
+
markdownRenderers.forEach(renderer => {
|
|
84
|
+
text = renderer.render(text);
|
|
85
|
+
});
|
|
86
|
+
return text;
|
|
87
|
+
};
|
|
70
88
|
|
|
71
89
|
// Initialize the remaining Web Chat props
|
|
72
90
|
const webChatProps = {
|
|
@@ -74,17 +92,17 @@ export const initWebChatComposer = (props, chatSDK, setAdapter, state, dispatch,
|
|
|
74
92
|
dir: state.domainStates.globalDir,
|
|
75
93
|
locale: changeLanguageCodeFormatForWebChat(getLocaleStringFromId((_state$domainStates$l4 = state.domainStates.liveChatConfig) === null || _state$domainStates$l4 === void 0 ? void 0 : (_state$domainStates$l5 = _state$domainStates$l4.ChatWidgetLanguage) === null || _state$domainStates$l5 === void 0 ? void 0 : _state$domainStates$l5.msdyn_localeid)),
|
|
76
94
|
store: webChatStore,
|
|
77
|
-
activityMiddleware: (_props$
|
|
78
|
-
attachmentMiddleware: (_props$
|
|
79
|
-
activityStatusMiddleware: (_props$
|
|
80
|
-
renderMarkdown
|
|
81
|
-
avatarMiddleware: (_props$
|
|
82
|
-
groupActivitiesMiddleware: (_props$
|
|
83
|
-
typingIndicatorMiddleware: (_props$
|
|
95
|
+
activityMiddleware: (_props$webChatContain11 = props.webChatContainerProps) !== null && _props$webChatContain11 !== void 0 && (_props$webChatContain12 = _props$webChatContain11.renderingMiddlewareProps) !== null && _props$webChatContain12 !== void 0 && _props$webChatContain12.disableActivityMiddleware ? undefined : createActivityMiddleware((_state$domainStates$r = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r === void 0 ? void 0 : _state$domainStates$r.systemMessageStyleProps, (_state$domainStates$r2 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r2 === void 0 ? void 0 : _state$domainStates$r2.userMessageStyleProps),
|
|
96
|
+
attachmentMiddleware: (_props$webChatContain13 = props.webChatContainerProps) !== null && _props$webChatContain13 !== void 0 && (_props$webChatContain14 = _props$webChatContain13.renderingMiddlewareProps) !== null && _props$webChatContain14 !== void 0 && _props$webChatContain14.disableAttachmentMiddleware ? undefined : createAttachmentMiddleware(((_state$domainStates$r3 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r3 === void 0 ? void 0 : (_state$domainStates$r4 = _state$domainStates$r3.attachmentProps) === null || _state$domainStates$r4 === void 0 ? void 0 : _state$domainStates$r4.enableInlinePlaying) ?? defaultAttachmentProps.enableInlinePlaying),
|
|
97
|
+
activityStatusMiddleware: (_props$webChatContain15 = props.webChatContainerProps) !== null && _props$webChatContain15 !== void 0 && (_props$webChatContain16 = _props$webChatContain15.renderingMiddlewareProps) !== null && _props$webChatContain16 !== void 0 && _props$webChatContain16.disableActivityStatusMiddleware ? undefined : (_defaultWebChatContai = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.activityStatusMiddleware,
|
|
98
|
+
renderMarkdown,
|
|
99
|
+
avatarMiddleware: (_props$webChatContain17 = props.webChatContainerProps) !== null && _props$webChatContain17 !== void 0 && (_props$webChatContain18 = _props$webChatContain17.renderingMiddlewareProps) !== null && _props$webChatContain18 !== void 0 && _props$webChatContain18.disableAvatarMiddleware ? undefined : createAvatarMiddleware((_state$domainStates$r5 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r5 === void 0 ? void 0 : _state$domainStates$r5.avatarStyleProps, (_state$domainStates$r6 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r6 === void 0 ? void 0 : _state$domainStates$r6.avatarTextStyleProps),
|
|
100
|
+
groupActivitiesMiddleware: (_props$webChatContain19 = props.webChatContainerProps) !== null && _props$webChatContain19 !== void 0 && (_props$webChatContain20 = _props$webChatContain19.renderingMiddlewareProps) !== null && _props$webChatContain20 !== void 0 && _props$webChatContain20.disableGroupActivitiesMiddleware ? undefined : (_defaultWebChatContai2 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.groupActivitiesMiddleware,
|
|
101
|
+
typingIndicatorMiddleware: (_props$webChatContain21 = props.webChatContainerProps) !== null && _props$webChatContain21 !== void 0 && (_props$webChatContain22 = _props$webChatContain21.renderingMiddlewareProps) !== null && _props$webChatContain22 !== void 0 && _props$webChatContain22.disableTypingIndicatorMiddleware ? undefined : (_defaultWebChatContai3 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai3 === void 0 ? void 0 : _defaultWebChatContai3.typingIndicatorMiddleware,
|
|
84
102
|
onTelemetry: createWebChatTelemetry(),
|
|
85
|
-
cardActionMiddleware: createCardActionMiddleware(((_props$
|
|
103
|
+
cardActionMiddleware: createCardActionMiddleware(((_props$webChatContain23 = props.webChatContainerProps) === null || _props$webChatContain23 === void 0 ? void 0 : _props$webChatContain23.botMagicCode) || undefined),
|
|
86
104
|
sendTypingIndicator: true,
|
|
87
|
-
...((_props$
|
|
105
|
+
...((_props$webChatContain24 = props.webChatContainerProps) === null || _props$webChatContain24 === void 0 ? void 0 : _props$webChatContain24.webChatProps)
|
|
88
106
|
};
|
|
89
107
|
return webChatProps;
|
|
90
108
|
};
|
|
@@ -9,6 +9,7 @@ export const defaultWebChatContainerStatefulProps = {
|
|
|
9
9
|
containerStyles: defaultWebChatStatefulContainerStyles,
|
|
10
10
|
disableNewLineMarkdownSupport: false,
|
|
11
11
|
disableMarkdownMessageFormatting: false,
|
|
12
|
+
hyperlinkTextOverride: false,
|
|
12
13
|
directLine: new MockAdapter(),
|
|
13
14
|
adaptiveCardStyles: defaultAdaptiveCardStyles
|
|
14
15
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
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; }
|
|
2
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
3
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
4
|
+
import DOMPurify from "dompurify";
|
|
5
|
+
import { HtmlAttributeNames } from "../../../../common/Constants";
|
|
6
|
+
class HyperlinkTextOverrideRenderer {
|
|
7
|
+
constructor(hyperlinkTextOverride) {
|
|
8
|
+
_defineProperty(this, "hyperlinkTextOverride", void 0);
|
|
9
|
+
this.hyperlinkTextOverride = hyperlinkTextOverride;
|
|
10
|
+
}
|
|
11
|
+
convertTextToHtmlNode(text) {
|
|
12
|
+
const htmlNode = document.createElement(HtmlAttributeNames.div);
|
|
13
|
+
try {
|
|
14
|
+
text = DOMPurify.sanitize(text); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
15
|
+
htmlNode.innerHTML = text;
|
|
16
|
+
} catch {
|
|
17
|
+
return htmlNode;
|
|
18
|
+
}
|
|
19
|
+
return htmlNode;
|
|
20
|
+
}
|
|
21
|
+
processANode(htmlNode) {
|
|
22
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
23
|
+
const aTags = htmlNode.getElementsByTagName(HtmlAttributeNames.aTagName);
|
|
24
|
+
for (let index = 0; index < aTags.length; index++) {
|
|
25
|
+
const aNode = aTags[index];
|
|
26
|
+
if (!aNode || !aNode.tagName || aNode.tagName.toLowerCase() !== HtmlAttributeNames.aTagName || !aNode.href) continue;
|
|
27
|
+
if (aNode.href !== aNode.text.trim()) {
|
|
28
|
+
aNode.text = aNode.href;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
applicable(text) {
|
|
33
|
+
if (!this.hyperlinkTextOverride) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const htmlNode = this.convertTextToHtmlNode(text);
|
|
38
|
+
const aNodes = htmlNode.getElementsByTagName(HtmlAttributeNames.aTagName);
|
|
39
|
+
return !!aNodes && aNodes.length && aNodes.length > 0;
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
render(text) {
|
|
45
|
+
if (!this.applicable(text)) {
|
|
46
|
+
return text;
|
|
47
|
+
}
|
|
48
|
+
const htmlNode = this.convertTextToHtmlNode(text);
|
|
49
|
+
this.processANode(htmlNode);
|
|
50
|
+
text = htmlNode.innerHTML;
|
|
51
|
+
return text;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export default HyperlinkTextOverrideRenderer;
|
|
@@ -22,22 +22,25 @@ const applyDataMasking = (action, regexCollection) => {
|
|
|
22
22
|
});
|
|
23
23
|
return action;
|
|
24
24
|
}
|
|
25
|
-
let isRuleMatched = false;
|
|
26
25
|
for (const ruleId of Object.keys(regexCollection)) {
|
|
27
26
|
const item = regexCollection[ruleId];
|
|
28
27
|
if (item) {
|
|
28
|
+
let ruleInfiniteException = false;
|
|
29
|
+
let ruleApplied = false;
|
|
29
30
|
try {
|
|
30
31
|
const regex = new RegExp(item, "gi");
|
|
31
32
|
let match;
|
|
32
33
|
// eslint-disable-next-line no-cond-assign
|
|
33
34
|
while (match = regex.exec(text)) {
|
|
34
35
|
const replaceStr = match[0].replace(/./gi, maskedChar);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
const modifiedText = text.replace(match[0], replaceStr);
|
|
37
|
+
if (modifiedText == text) {
|
|
38
|
+
ruleInfiniteException = true;
|
|
39
|
+
console.warn(`The data masking rule ${item} is ignored because it matches empty strings. Please modify this rule.`);
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
ruleApplied = true;
|
|
43
|
+
text = modifiedText;
|
|
41
44
|
}
|
|
42
45
|
} catch (err) {
|
|
43
46
|
TelemetryHelper.logActionEvent(LogLevel.ERROR, {
|
|
@@ -48,11 +51,21 @@ const applyDataMasking = (action, regexCollection) => {
|
|
|
48
51
|
}
|
|
49
52
|
});
|
|
50
53
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
if (ruleApplied) {
|
|
55
|
+
TelemetryHelper.logActionEvent(LogLevel.INFO, {
|
|
56
|
+
Event: TelemetryEvent.DataMaskingRuleApplied,
|
|
57
|
+
Description: `Data Masking Rule Id: ${ruleId} applied.`
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (ruleInfiniteException) {
|
|
61
|
+
TelemetryHelper.logActionEvent(LogLevel.ERROR, {
|
|
62
|
+
Event: TelemetryEvent.DataMaskingRuleApplyFailed,
|
|
63
|
+
ExceptionDetails: {
|
|
64
|
+
RuleId: ruleId,
|
|
65
|
+
Exception: "The data masking rule matches empty strings."
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
56
69
|
}
|
|
57
70
|
}
|
|
58
71
|
action.payload.text = text;
|
package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts
CHANGED
|
@@ -16,5 +16,6 @@ export interface IWebChatContainerStatefulProps {
|
|
|
16
16
|
renderingMiddlewareProps?: IRenderingMiddlewareProps;
|
|
17
17
|
localizedTexts?: ILiveChatWidgetLocalizedTexts;
|
|
18
18
|
botMagicCode?: IBotMagicCodeConfig;
|
|
19
|
+
hyperlinkTextOverride?: boolean;
|
|
19
20
|
adaptiveCardStyles?: IAdaptiveCardStyles;
|
|
20
21
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare class HyperlinkTextOverrideRenderer {
|
|
2
|
+
private hyperlinkTextOverride;
|
|
3
|
+
constructor(hyperlinkTextOverride: boolean);
|
|
4
|
+
private convertTextToHtmlNode;
|
|
5
|
+
private processANode;
|
|
6
|
+
private applicable;
|
|
7
|
+
render(text: string): string;
|
|
8
|
+
}
|
|
9
|
+
export default HyperlinkTextOverrideRenderer;
|