@microsoft/omnichannel-chat-components 1.1.15 → 1.1.17-0
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 -1
- package/lib/cjs/common/utils.js +34 -6
- package/lib/cjs/components/inputvalidationpane/InputValidationPane.js +11 -12
- package/lib/esm/common/Constants.js +1 -1
- package/lib/esm/common/utils.js +33 -5
- package/lib/esm/components/inputvalidationpane/InputValidationPane.js +11 -12
- package/package.json +1 -1
|
@@ -23,7 +23,7 @@ const HiddenTextStyles = {
|
|
|
23
23
|
exports.HiddenTextStyles = HiddenTextStyles;
|
|
24
24
|
const KeyCodes = (_class = class KeyCodes {}, _defineProperty(_class, "ENTER", "Enter"), _defineProperty(_class, "ESCAPE", "Escape"), _defineProperty(_class, "SPACE", "Space"), _defineProperty(_class, "DeclineCallHotKey", "D"), _defineProperty(_class, "AcceptAudioCallHotKey", "S"), _defineProperty(_class, "AcceptVideoCallHotKey", "A"), _defineProperty(_class, "ToggleMicHotKey", "M"), _defineProperty(_class, "ToggleCameraHotKey", "O"), _defineProperty(_class, "EndCallHotKey", "H"), _class);
|
|
25
25
|
exports.KeyCodes = KeyCodes;
|
|
26
|
-
const Regex = (_class2 = class Regex {}, _defineProperty(_class2, "EmailRegex", "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"), _defineProperty(_class2, "URLRegex", /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi), _class2);
|
|
26
|
+
const Regex = (_class2 = class Regex {}, _defineProperty(_class2, "EmailRegex", "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"), _defineProperty(_class2, "URLRegex", /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,}|mailto:[^\s]+|tel:[^\s]+|sms:[^\s]+)/gi), _class2);
|
|
27
27
|
exports.Regex = Regex;
|
|
28
28
|
let ElementType;
|
|
29
29
|
exports.ElementType = ElementType;
|
package/lib/cjs/common/utils.js
CHANGED
|
@@ -131,20 +131,48 @@ const addNoreferrerNoopenerTag = htmlNode => {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
};
|
|
134
|
+
}; // Escape HTML special characters to prevent XSS in string concatenation
|
|
135
|
+
|
|
135
136
|
|
|
136
137
|
exports.addNoreferrerNoopenerTag = addNoreferrerNoopenerTag;
|
|
137
138
|
|
|
139
|
+
const escapeHTML = str => {
|
|
140
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
141
|
+
}; // Escape only characters dangerous in href attribute context
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
const escapeHrefAttribute = url => {
|
|
145
|
+
return url.replace(/"/g, """).replace(/'/g, "'");
|
|
146
|
+
}; // Validate and sanitize URL to prevent javascript: and data: protocols
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
const isValidURL = url => {
|
|
150
|
+
const trimmedUrl = url.trim().toLowerCase(); // Block dangerous protocols
|
|
151
|
+
|
|
152
|
+
if (trimmedUrl.startsWith("javascript:") || trimmedUrl.startsWith("data:") || trimmedUrl.startsWith("vbscript:") || trimmedUrl.startsWith("file:")) {
|
|
153
|
+
return false;
|
|
154
|
+
} // Allow http, https, protocol-relative URLs, and safe contact schemes
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
return trimmedUrl.startsWith("http://") || trimmedUrl.startsWith("https://") || trimmedUrl.startsWith("www.") || trimmedUrl.startsWith("mailto:") || trimmedUrl.startsWith("tel:") || trimmedUrl.startsWith("sms:");
|
|
158
|
+
};
|
|
159
|
+
|
|
138
160
|
const replaceURLWithAnchor = (text, openInNewTab) => {
|
|
139
161
|
if (text) {
|
|
140
162
|
const modifiedText = text.replace(_Constants.Regex.URLRegex, function (url) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return
|
|
144
|
-
}
|
|
163
|
+
// Validate URL to prevent dangerous protocols
|
|
164
|
+
if (!isValidURL(url)) {
|
|
165
|
+
return escapeHTML(url); // Return escaped text, not a link
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const escapedUrl = escapeHrefAttribute(url);
|
|
169
|
+
const displayText = escapeHTML(url);
|
|
145
170
|
|
|
171
|
+
if (openInNewTab) {
|
|
172
|
+
return `<a href="${escapedUrl}" rel="noreferrer noopener" target="_blank">${displayText}</a>`;
|
|
173
|
+
}
|
|
146
174
|
|
|
147
|
-
return
|
|
175
|
+
return `<a href="${escapedUrl}">${displayText}</a>`;
|
|
148
176
|
});
|
|
149
177
|
return modifiedText;
|
|
150
178
|
}
|
|
@@ -48,7 +48,7 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
|
|
|
48
48
|
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
49
|
|
|
50
50
|
function InputValidationPane(props) {
|
|
51
|
-
var _props$controlProps, _props$styleProps, _props$styleProps2, _props$styleProps3, _props$styleProps4, _props$controlProps14, _props$styleProps5, _props$styleProps6, _props$styleProps7, _props$styleProps8, _props$styleProps9, _props$styleProps10, _props$styleProps11, _props$styleProps12, _props$styleProps13, _props$styleProps14, _props$styleProps15, _props$styleProps16, _props$controlProps15, _props$styleProps17, _props$styleProps17$c, _props$controlProps16, _props$controlProps17, _props$styleProps18, _props$styleProps18$c, _props$controlProps18, _props$componentOverr, _props$styleProps19, _props$styleProps19$c, _props$controlProps19, _props$controlProps20, _props$componentOverr2, _props$styleProps20, _props$styleProps20$c, _props$controlProps21, _props$controlProps22, _props$componentOverr3, _props$styleProps21, _props$styleProps21$c, _props$controlProps23, _props$controlProps24, _props$controlProps25, _props$componentOverr4, _props$styleProps22, _props$styleProps22$c, _props$controlProps26, _props$controlProps27, _props$
|
|
51
|
+
var _props$controlProps, _props$styleProps, _props$styleProps2, _props$styleProps3, _props$styleProps4, _props$controlProps14, _props$styleProps5, _props$styleProps6, _props$styleProps7, _props$styleProps8, _props$styleProps9, _props$styleProps10, _props$styleProps11, _props$styleProps12, _props$styleProps13, _props$styleProps14, _props$styleProps15, _props$styleProps16, _props$controlProps15, _props$styleProps17, _props$styleProps17$c, _props$controlProps16, _props$controlProps17, _props$styleProps18, _props$styleProps18$c, _props$controlProps18, _props$componentOverr, _props$styleProps19, _props$styleProps19$c, _props$controlProps19, _props$controlProps20, _props$componentOverr2, _props$styleProps20, _props$styleProps20$c, _props$controlProps21, _props$controlProps22, _props$componentOverr3, _props$styleProps21, _props$styleProps21$c, _props$controlProps23, _props$controlProps24, _props$controlProps25, _props$componentOverr4, _props$styleProps22, _props$styleProps22$c, _props$controlProps26, _props$controlProps27, _props$styleProps23, _props$styleProps23$c, _props$controlProps28, _props$componentOverr5, _props$styleProps24, _props$styleProps24$c, _props$controlProps29, _props$controlProps30, _props$controlProps31, _props$controlProps32, _props$componentOverr6, _props$styleProps25, _props$styleProps25$c, _props$controlProps33, _props$controlProps34, _props$controlProps35;
|
|
52
52
|
|
|
53
53
|
const elementId = ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.id) ?? _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.id;
|
|
54
54
|
const [inputValue, setInputValue] = (0, _react2.useState)("");
|
|
@@ -247,35 +247,34 @@ function InputValidationPane(props) {
|
|
|
247
247
|
})), isInvalidInput && ((0, _decodeComponentString.decodeComponentString)((_props$componentOverr4 = props.componentOverrides) === null || _props$componentOverr4 === void 0 ? void 0 : _props$componentOverr4.invalidInputErrorMessage) || /*#__PURE__*/_react2.default.createElement(_react.Stack, {
|
|
248
248
|
className: (_props$styleProps22 = props.styleProps) === null || _props$styleProps22 === void 0 ? void 0 : (_props$styleProps22$c = _props$styleProps22.classNames) === null || _props$styleProps22$c === void 0 ? void 0 : _props$styleProps22$c.invalidInputErrorMessageClassName,
|
|
249
249
|
styles: invalidInputErrorMessageStyles,
|
|
250
|
-
"aria-label": ((_props$controlProps26 = props.controlProps) === null || _props$controlProps26 === void 0 ? void 0 : _props$controlProps26.invalidInputErrorMessageText) || _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.invalidInputErrorMessageText,
|
|
251
250
|
tabIndex: -1,
|
|
252
251
|
role: "alert",
|
|
253
252
|
id: elementId + "-invalidinputerrormessage"
|
|
254
|
-
}, ((_props$
|
|
255
|
-
horizontal: ((_props$
|
|
253
|
+
}, ((_props$controlProps26 = props.controlProps) === null || _props$controlProps26 === void 0 ? void 0 : _props$controlProps26.invalidInputErrorMessageText) || _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.invalidInputErrorMessageText))), /*#__PURE__*/_react2.default.createElement(_react.Stack, {
|
|
254
|
+
horizontal: ((_props$controlProps27 = props.controlProps) === null || _props$controlProps27 === void 0 ? void 0 : _props$controlProps27.isButtonGroupHorizontal) ?? _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.isButtonGroupHorizontal,
|
|
256
255
|
className: (_props$styleProps23 = props.styleProps) === null || _props$styleProps23 === void 0 ? void 0 : (_props$styleProps23$c = _props$styleProps23.classNames) === null || _props$styleProps23$c === void 0 ? void 0 : _props$styleProps23$c.buttonGroupClassName,
|
|
257
256
|
styles: buttonGroupStyles,
|
|
258
257
|
tabIndex: -1,
|
|
259
258
|
id: elementId + "-buttongroup"
|
|
260
|
-
}, !((_props$
|
|
259
|
+
}, !((_props$controlProps28 = props.controlProps) !== null && _props$controlProps28 !== void 0 && _props$controlProps28.hideSendButton) && ((0, _decodeComponentString.decodeComponentString)((_props$componentOverr5 = props.componentOverrides) === null || _props$componentOverr5 === void 0 ? void 0 : _props$componentOverr5.sendButton) || /*#__PURE__*/_react2.default.createElement(_Button.PrimaryButton, {
|
|
261
260
|
className: (_props$styleProps24 = props.styleProps) === null || _props$styleProps24 === void 0 ? void 0 : (_props$styleProps24$c = _props$styleProps24.classNames) === null || _props$styleProps24$c === void 0 ? void 0 : _props$styleProps24$c.sendButtonClassName,
|
|
262
261
|
styles: sendButtonStyles,
|
|
263
|
-
title: ((_props$
|
|
262
|
+
title: ((_props$controlProps29 = props.controlProps) === null || _props$controlProps29 === void 0 ? void 0 : _props$controlProps29.sendButtonText) || _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.sendButtonText,
|
|
264
263
|
tabIndex: 0,
|
|
265
264
|
disabled: !isSendButtonEnabled,
|
|
266
|
-
text: ((_props$
|
|
265
|
+
text: ((_props$controlProps30 = props.controlProps) === null || _props$controlProps30 === void 0 ? void 0 : _props$controlProps30.sendButtonText) || _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.sendButtonText,
|
|
267
266
|
onClick: handleSendClick,
|
|
268
267
|
id: elementId + "-sendbutton",
|
|
269
|
-
ariaLabel: ((_props$
|
|
270
|
-
})), !((_props$
|
|
268
|
+
ariaLabel: ((_props$controlProps31 = props.controlProps) === null || _props$controlProps31 === void 0 ? void 0 : _props$controlProps31.sendButtonAriaLabel) || _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.sendButtonAriaLabel
|
|
269
|
+
})), !((_props$controlProps32 = props.controlProps) !== null && _props$controlProps32 !== void 0 && _props$controlProps32.hideCancelButton) && ((0, _decodeComponentString.decodeComponentString)((_props$componentOverr6 = props.componentOverrides) === null || _props$componentOverr6 === void 0 ? void 0 : _props$componentOverr6.cancelButton) || /*#__PURE__*/_react2.default.createElement(_Button.DefaultButton, {
|
|
271
270
|
className: (_props$styleProps25 = props.styleProps) === null || _props$styleProps25 === void 0 ? void 0 : (_props$styleProps25$c = _props$styleProps25.classNames) === null || _props$styleProps25$c === void 0 ? void 0 : _props$styleProps25$c.cancelButtonClassName,
|
|
272
271
|
styles: cancelButtonStyles,
|
|
273
|
-
title: ((_props$
|
|
272
|
+
title: ((_props$controlProps33 = props.controlProps) === null || _props$controlProps33 === void 0 ? void 0 : _props$controlProps33.cancelButtonText) || _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.cancelButtonText,
|
|
274
273
|
tabIndex: 0,
|
|
275
|
-
text: ((_props$
|
|
274
|
+
text: ((_props$controlProps34 = props.controlProps) === null || _props$controlProps34 === void 0 ? void 0 : _props$controlProps34.cancelButtonText) || _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.cancelButtonText,
|
|
276
275
|
onClick: handleCancelClick,
|
|
277
276
|
id: elementId + "-cancelbutton",
|
|
278
|
-
ariaLabel: ((_props$
|
|
277
|
+
ariaLabel: ((_props$controlProps35 = props.controlProps) === null || _props$controlProps35 === void 0 ? void 0 : _props$controlProps35.cancelButtonAriaLabel) || _defaultInputValidationPaneControlProps.defaultInputValidationPaneControlProps.cancelButtonAriaLabel
|
|
279
278
|
})))));
|
|
280
279
|
}
|
|
281
280
|
|
|
@@ -13,7 +13,7 @@ export const HiddenTextStyles = {
|
|
|
13
13
|
whiteSpace: "nowrap"
|
|
14
14
|
};
|
|
15
15
|
export const KeyCodes = (_class = class KeyCodes {}, _defineProperty(_class, "ENTER", "Enter"), _defineProperty(_class, "ESCAPE", "Escape"), _defineProperty(_class, "SPACE", "Space"), _defineProperty(_class, "DeclineCallHotKey", "D"), _defineProperty(_class, "AcceptAudioCallHotKey", "S"), _defineProperty(_class, "AcceptVideoCallHotKey", "A"), _defineProperty(_class, "ToggleMicHotKey", "M"), _defineProperty(_class, "ToggleCameraHotKey", "O"), _defineProperty(_class, "EndCallHotKey", "H"), _class);
|
|
16
|
-
export const Regex = (_class2 = class Regex {}, _defineProperty(_class2, "EmailRegex", "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"), _defineProperty(_class2, "URLRegex", /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi), _class2);
|
|
16
|
+
export const Regex = (_class2 = class Regex {}, _defineProperty(_class2, "EmailRegex", "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"), _defineProperty(_class2, "URLRegex", /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,}|mailto:[^\s]+|tel:[^\s]+|sms:[^\s]+)/gi), _class2);
|
|
17
17
|
export let ElementType;
|
|
18
18
|
|
|
19
19
|
(function (ElementType) {
|
package/lib/esm/common/utils.js
CHANGED
|
@@ -93,17 +93,45 @@ export const addNoreferrerNoopenerTag = htmlNode => {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
+
}; // Escape HTML special characters to prevent XSS in string concatenation
|
|
97
|
+
|
|
98
|
+
const escapeHTML = str => {
|
|
99
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
100
|
+
}; // Escape only characters dangerous in href attribute context
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
const escapeHrefAttribute = url => {
|
|
104
|
+
return url.replace(/"/g, """).replace(/'/g, "'");
|
|
105
|
+
}; // Validate and sanitize URL to prevent javascript: and data: protocols
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
const isValidURL = url => {
|
|
109
|
+
const trimmedUrl = url.trim().toLowerCase(); // Block dangerous protocols
|
|
110
|
+
|
|
111
|
+
if (trimmedUrl.startsWith("javascript:") || trimmedUrl.startsWith("data:") || trimmedUrl.startsWith("vbscript:") || trimmedUrl.startsWith("file:")) {
|
|
112
|
+
return false;
|
|
113
|
+
} // Allow http, https, protocol-relative URLs, and safe contact schemes
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
return trimmedUrl.startsWith("http://") || trimmedUrl.startsWith("https://") || trimmedUrl.startsWith("www.") || trimmedUrl.startsWith("mailto:") || trimmedUrl.startsWith("tel:") || trimmedUrl.startsWith("sms:");
|
|
96
117
|
};
|
|
118
|
+
|
|
97
119
|
export const replaceURLWithAnchor = (text, openInNewTab) => {
|
|
98
120
|
if (text) {
|
|
99
121
|
const modifiedText = text.replace(Regex.URLRegex, function (url) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return
|
|
103
|
-
}
|
|
122
|
+
// Validate URL to prevent dangerous protocols
|
|
123
|
+
if (!isValidURL(url)) {
|
|
124
|
+
return escapeHTML(url); // Return escaped text, not a link
|
|
125
|
+
}
|
|
104
126
|
|
|
127
|
+
const escapedUrl = escapeHrefAttribute(url);
|
|
128
|
+
const displayText = escapeHTML(url);
|
|
129
|
+
|
|
130
|
+
if (openInNewTab) {
|
|
131
|
+
return `<a href="${escapedUrl}" rel="noreferrer noopener" target="_blank">${displayText}</a>`;
|
|
132
|
+
}
|
|
105
133
|
|
|
106
|
-
return
|
|
134
|
+
return `<a href="${escapedUrl}">${displayText}</a>`;
|
|
107
135
|
});
|
|
108
136
|
return modifiedText;
|
|
109
137
|
}
|
|
@@ -19,7 +19,7 @@ import { defaultInputValidationPaneTitleStyles } from "./common/default/defaultS
|
|
|
19
19
|
import { generateEventName } from "../../common/utils";
|
|
20
20
|
|
|
21
21
|
function InputValidationPane(props) {
|
|
22
|
-
var _props$controlProps, _props$styleProps, _props$styleProps2, _props$styleProps3, _props$styleProps4, _props$controlProps14, _props$styleProps5, _props$styleProps6, _props$styleProps7, _props$styleProps8, _props$styleProps9, _props$styleProps10, _props$styleProps11, _props$styleProps12, _props$styleProps13, _props$styleProps14, _props$styleProps15, _props$styleProps16, _props$controlProps15, _props$styleProps17, _props$styleProps17$c, _props$controlProps16, _props$controlProps17, _props$styleProps18, _props$styleProps18$c, _props$controlProps18, _props$componentOverr, _props$styleProps19, _props$styleProps19$c, _props$controlProps19, _props$controlProps20, _props$componentOverr2, _props$styleProps20, _props$styleProps20$c, _props$controlProps21, _props$controlProps22, _props$componentOverr3, _props$styleProps21, _props$styleProps21$c, _props$controlProps23, _props$controlProps24, _props$controlProps25, _props$componentOverr4, _props$styleProps22, _props$styleProps22$c, _props$controlProps26, _props$controlProps27, _props$
|
|
22
|
+
var _props$controlProps, _props$styleProps, _props$styleProps2, _props$styleProps3, _props$styleProps4, _props$controlProps14, _props$styleProps5, _props$styleProps6, _props$styleProps7, _props$styleProps8, _props$styleProps9, _props$styleProps10, _props$styleProps11, _props$styleProps12, _props$styleProps13, _props$styleProps14, _props$styleProps15, _props$styleProps16, _props$controlProps15, _props$styleProps17, _props$styleProps17$c, _props$controlProps16, _props$controlProps17, _props$styleProps18, _props$styleProps18$c, _props$controlProps18, _props$componentOverr, _props$styleProps19, _props$styleProps19$c, _props$controlProps19, _props$controlProps20, _props$componentOverr2, _props$styleProps20, _props$styleProps20$c, _props$controlProps21, _props$controlProps22, _props$componentOverr3, _props$styleProps21, _props$styleProps21$c, _props$controlProps23, _props$controlProps24, _props$controlProps25, _props$componentOverr4, _props$styleProps22, _props$styleProps22$c, _props$controlProps26, _props$controlProps27, _props$styleProps23, _props$styleProps23$c, _props$controlProps28, _props$componentOverr5, _props$styleProps24, _props$styleProps24$c, _props$controlProps29, _props$controlProps30, _props$controlProps31, _props$controlProps32, _props$componentOverr6, _props$styleProps25, _props$styleProps25$c, _props$controlProps33, _props$controlProps34, _props$controlProps35;
|
|
23
23
|
|
|
24
24
|
const elementId = ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.id) ?? defaultInputValidationPaneControlProps.id;
|
|
25
25
|
const [inputValue, setInputValue] = useState("");
|
|
@@ -214,35 +214,34 @@ function InputValidationPane(props) {
|
|
|
214
214
|
})), isInvalidInput && (decodeComponentString((_props$componentOverr4 = props.componentOverrides) === null || _props$componentOverr4 === void 0 ? void 0 : _props$componentOverr4.invalidInputErrorMessage) || /*#__PURE__*/React.createElement(Stack, {
|
|
215
215
|
className: (_props$styleProps22 = props.styleProps) === null || _props$styleProps22 === void 0 ? void 0 : (_props$styleProps22$c = _props$styleProps22.classNames) === null || _props$styleProps22$c === void 0 ? void 0 : _props$styleProps22$c.invalidInputErrorMessageClassName,
|
|
216
216
|
styles: invalidInputErrorMessageStyles,
|
|
217
|
-
"aria-label": ((_props$controlProps26 = props.controlProps) === null || _props$controlProps26 === void 0 ? void 0 : _props$controlProps26.invalidInputErrorMessageText) || defaultInputValidationPaneControlProps.invalidInputErrorMessageText,
|
|
218
217
|
tabIndex: -1,
|
|
219
218
|
role: "alert",
|
|
220
219
|
id: elementId + "-invalidinputerrormessage"
|
|
221
|
-
}, ((_props$
|
|
222
|
-
horizontal: ((_props$
|
|
220
|
+
}, ((_props$controlProps26 = props.controlProps) === null || _props$controlProps26 === void 0 ? void 0 : _props$controlProps26.invalidInputErrorMessageText) || defaultInputValidationPaneControlProps.invalidInputErrorMessageText))), /*#__PURE__*/React.createElement(Stack, {
|
|
221
|
+
horizontal: ((_props$controlProps27 = props.controlProps) === null || _props$controlProps27 === void 0 ? void 0 : _props$controlProps27.isButtonGroupHorizontal) ?? defaultInputValidationPaneControlProps.isButtonGroupHorizontal,
|
|
223
222
|
className: (_props$styleProps23 = props.styleProps) === null || _props$styleProps23 === void 0 ? void 0 : (_props$styleProps23$c = _props$styleProps23.classNames) === null || _props$styleProps23$c === void 0 ? void 0 : _props$styleProps23$c.buttonGroupClassName,
|
|
224
223
|
styles: buttonGroupStyles,
|
|
225
224
|
tabIndex: -1,
|
|
226
225
|
id: elementId + "-buttongroup"
|
|
227
|
-
}, !((_props$
|
|
226
|
+
}, !((_props$controlProps28 = props.controlProps) !== null && _props$controlProps28 !== void 0 && _props$controlProps28.hideSendButton) && (decodeComponentString((_props$componentOverr5 = props.componentOverrides) === null || _props$componentOverr5 === void 0 ? void 0 : _props$componentOverr5.sendButton) || /*#__PURE__*/React.createElement(PrimaryButton, {
|
|
228
227
|
className: (_props$styleProps24 = props.styleProps) === null || _props$styleProps24 === void 0 ? void 0 : (_props$styleProps24$c = _props$styleProps24.classNames) === null || _props$styleProps24$c === void 0 ? void 0 : _props$styleProps24$c.sendButtonClassName,
|
|
229
228
|
styles: sendButtonStyles,
|
|
230
|
-
title: ((_props$
|
|
229
|
+
title: ((_props$controlProps29 = props.controlProps) === null || _props$controlProps29 === void 0 ? void 0 : _props$controlProps29.sendButtonText) || defaultInputValidationPaneControlProps.sendButtonText,
|
|
231
230
|
tabIndex: 0,
|
|
232
231
|
disabled: !isSendButtonEnabled,
|
|
233
|
-
text: ((_props$
|
|
232
|
+
text: ((_props$controlProps30 = props.controlProps) === null || _props$controlProps30 === void 0 ? void 0 : _props$controlProps30.sendButtonText) || defaultInputValidationPaneControlProps.sendButtonText,
|
|
234
233
|
onClick: handleSendClick,
|
|
235
234
|
id: elementId + "-sendbutton",
|
|
236
|
-
ariaLabel: ((_props$
|
|
237
|
-
})), !((_props$
|
|
235
|
+
ariaLabel: ((_props$controlProps31 = props.controlProps) === null || _props$controlProps31 === void 0 ? void 0 : _props$controlProps31.sendButtonAriaLabel) || defaultInputValidationPaneControlProps.sendButtonAriaLabel
|
|
236
|
+
})), !((_props$controlProps32 = props.controlProps) !== null && _props$controlProps32 !== void 0 && _props$controlProps32.hideCancelButton) && (decodeComponentString((_props$componentOverr6 = props.componentOverrides) === null || _props$componentOverr6 === void 0 ? void 0 : _props$componentOverr6.cancelButton) || /*#__PURE__*/React.createElement(DefaultButton, {
|
|
238
237
|
className: (_props$styleProps25 = props.styleProps) === null || _props$styleProps25 === void 0 ? void 0 : (_props$styleProps25$c = _props$styleProps25.classNames) === null || _props$styleProps25$c === void 0 ? void 0 : _props$styleProps25$c.cancelButtonClassName,
|
|
239
238
|
styles: cancelButtonStyles,
|
|
240
|
-
title: ((_props$
|
|
239
|
+
title: ((_props$controlProps33 = props.controlProps) === null || _props$controlProps33 === void 0 ? void 0 : _props$controlProps33.cancelButtonText) || defaultInputValidationPaneControlProps.cancelButtonText,
|
|
241
240
|
tabIndex: 0,
|
|
242
|
-
text: ((_props$
|
|
241
|
+
text: ((_props$controlProps34 = props.controlProps) === null || _props$controlProps34 === void 0 ? void 0 : _props$controlProps34.cancelButtonText) || defaultInputValidationPaneControlProps.cancelButtonText,
|
|
243
242
|
onClick: handleCancelClick,
|
|
244
243
|
id: elementId + "-cancelbutton",
|
|
245
|
-
ariaLabel: ((_props$
|
|
244
|
+
ariaLabel: ((_props$controlProps35 = props.controlProps) === null || _props$controlProps35 === void 0 ? void 0 : _props$controlProps35.cancelButtonAriaLabel) || defaultInputValidationPaneControlProps.cancelButtonAriaLabel
|
|
246
245
|
})))));
|
|
247
246
|
}
|
|
248
247
|
|