@nocios/crudify-ui 3.0.58 → 3.0.60
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/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +29 -6
- package/dist/index.mjs +29 -6
- package/package.json +3 -1
package/dist/index.d.mts
CHANGED
|
@@ -751,11 +751,13 @@ interface Notification {
|
|
|
751
751
|
severity: NotificationSeverity;
|
|
752
752
|
autoHideDuration?: number;
|
|
753
753
|
persistent?: boolean;
|
|
754
|
+
allowHtml?: boolean;
|
|
754
755
|
}
|
|
755
756
|
interface GlobalNotificationContextValue {
|
|
756
757
|
showNotification: (message: string, severity?: NotificationSeverity, options?: {
|
|
757
758
|
autoHideDuration?: number;
|
|
758
759
|
persistent?: boolean;
|
|
760
|
+
allowHtml?: boolean;
|
|
759
761
|
}) => string;
|
|
760
762
|
hideNotification: (id: string) => void;
|
|
761
763
|
clearAllNotifications: () => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -751,11 +751,13 @@ interface Notification {
|
|
|
751
751
|
severity: NotificationSeverity;
|
|
752
752
|
autoHideDuration?: number;
|
|
753
753
|
persistent?: boolean;
|
|
754
|
+
allowHtml?: boolean;
|
|
754
755
|
}
|
|
755
756
|
interface GlobalNotificationContextValue {
|
|
756
757
|
showNotification: (message: string, severity?: NotificationSeverity, options?: {
|
|
757
758
|
autoHideDuration?: number;
|
|
758
759
|
persistent?: boolean;
|
|
760
|
+
allowHtml?: boolean;
|
|
759
761
|
}) => string;
|
|
760
762
|
hideNotification: (id: string) => void;
|
|
761
763
|
clearAllNotifications: () => void;
|
package/dist/index.js
CHANGED
|
@@ -1401,8 +1401,24 @@ var isTokenExpired = (token) => {
|
|
|
1401
1401
|
var import_react6 = require("react");
|
|
1402
1402
|
var import_material = require("@mui/material");
|
|
1403
1403
|
var import_uuid = require("uuid");
|
|
1404
|
+
var import_dompurify = __toESM(require("dompurify"));
|
|
1404
1405
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1405
1406
|
var GlobalNotificationContext = (0, import_react6.createContext)(null);
|
|
1407
|
+
var sanitizeNotificationContent = (html) => {
|
|
1408
|
+
return import_dompurify.default.sanitize(html, {
|
|
1409
|
+
// Solo permitir tags seguros para notificaciones
|
|
1410
|
+
ALLOWED_TAGS: ["b", "i", "em", "strong", "br", "span"],
|
|
1411
|
+
ALLOWED_ATTR: ["class"],
|
|
1412
|
+
// Remover scripts y eventos
|
|
1413
|
+
FORBID_TAGS: ["script", "iframe", "object", "embed"],
|
|
1414
|
+
FORBID_ATTR: ["onload", "onerror", "onclick", "onmouseover", "onfocus", "onblur"],
|
|
1415
|
+
// Configuración adicional de seguridad
|
|
1416
|
+
WHOLE_DOCUMENT: false,
|
|
1417
|
+
RETURN_DOM: false,
|
|
1418
|
+
RETURN_DOM_FRAGMENT: false,
|
|
1419
|
+
RETURN_TRUSTED_TYPE: false
|
|
1420
|
+
});
|
|
1421
|
+
};
|
|
1406
1422
|
var GlobalNotificationProvider = ({
|
|
1407
1423
|
children,
|
|
1408
1424
|
maxNotifications = 5,
|
|
@@ -1417,13 +1433,23 @@ var GlobalNotificationProvider = ({
|
|
|
1417
1433
|
if (!enabled) {
|
|
1418
1434
|
return "";
|
|
1419
1435
|
}
|
|
1436
|
+
if (!message || typeof message !== "string") {
|
|
1437
|
+
console.warn("\u26A0\uFE0F GlobalNotificationProvider: Invalid message provided");
|
|
1438
|
+
return "";
|
|
1439
|
+
}
|
|
1440
|
+
if (message.length > 1e3) {
|
|
1441
|
+
console.warn("\u26A0\uFE0F GlobalNotificationProvider: Message too long, truncating");
|
|
1442
|
+
message = message.substring(0, 1e3) + "...";
|
|
1443
|
+
}
|
|
1420
1444
|
const id = (0, import_uuid.v4)();
|
|
1421
1445
|
const newNotification = {
|
|
1422
1446
|
id,
|
|
1423
1447
|
message,
|
|
1424
1448
|
severity,
|
|
1425
1449
|
autoHideDuration: options?.autoHideDuration ?? defaultAutoHideDuration,
|
|
1426
|
-
persistent: options?.persistent ?? false
|
|
1450
|
+
persistent: options?.persistent ?? false,
|
|
1451
|
+
allowHtml: options?.allowHtml ?? false
|
|
1452
|
+
// Por defecto NO permitir HTML
|
|
1427
1453
|
};
|
|
1428
1454
|
setNotifications((prev) => {
|
|
1429
1455
|
const updatedNotifications = prev.length >= maxNotifications ? prev.slice(-(maxNotifications - 1)) : prev;
|
|
@@ -1513,7 +1539,7 @@ var NotificationItem = ({ notification, onClose }) => {
|
|
|
1513
1539
|
maxWidth: "400px",
|
|
1514
1540
|
wordBreak: "break-word"
|
|
1515
1541
|
},
|
|
1516
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { dangerouslySetInnerHTML: { __html: notification.message } })
|
|
1542
|
+
children: notification.allowHtml ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { dangerouslySetInnerHTML: { __html: sanitizeNotificationContent(notification.message) } }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: notification.message })
|
|
1517
1543
|
}
|
|
1518
1544
|
)
|
|
1519
1545
|
}
|
|
@@ -4778,10 +4804,7 @@ var useCrudifyWithNotifications = (options = {}) => {
|
|
|
4778
4804
|
moduleKey = actionConfig.moduleKey;
|
|
4779
4805
|
}
|
|
4780
4806
|
}
|
|
4781
|
-
if (operation
|
|
4782
|
-
const message = getSafeTranslation("resetPassword.successMessage", "Contrase\xF1a restablecida exitosamente");
|
|
4783
|
-
showNotification(message, "success", { autoHideDuration });
|
|
4784
|
-
} else if (shouldShowSuccessNotification(operation, moduleKey)) {
|
|
4807
|
+
if (shouldShowSuccessNotification(operation, moduleKey)) {
|
|
4785
4808
|
const message = getSuccessMessage(operation, moduleKey, actionConfig);
|
|
4786
4809
|
showNotification(message, "success", { autoHideDuration });
|
|
4787
4810
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1328,8 +1328,24 @@ var isTokenExpired = (token) => {
|
|
|
1328
1328
|
import { useState as useState4, createContext as createContext4, useContext as useContext4, useCallback as useCallback2, useEffect as useEffect5 } from "react";
|
|
1329
1329
|
import { Snackbar, Alert, Box, Portal } from "@mui/material";
|
|
1330
1330
|
import { v4 as uuidv4 } from "uuid";
|
|
1331
|
+
import DOMPurify from "dompurify";
|
|
1331
1332
|
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
1332
1333
|
var GlobalNotificationContext = createContext4(null);
|
|
1334
|
+
var sanitizeNotificationContent = (html) => {
|
|
1335
|
+
return DOMPurify.sanitize(html, {
|
|
1336
|
+
// Solo permitir tags seguros para notificaciones
|
|
1337
|
+
ALLOWED_TAGS: ["b", "i", "em", "strong", "br", "span"],
|
|
1338
|
+
ALLOWED_ATTR: ["class"],
|
|
1339
|
+
// Remover scripts y eventos
|
|
1340
|
+
FORBID_TAGS: ["script", "iframe", "object", "embed"],
|
|
1341
|
+
FORBID_ATTR: ["onload", "onerror", "onclick", "onmouseover", "onfocus", "onblur"],
|
|
1342
|
+
// Configuración adicional de seguridad
|
|
1343
|
+
WHOLE_DOCUMENT: false,
|
|
1344
|
+
RETURN_DOM: false,
|
|
1345
|
+
RETURN_DOM_FRAGMENT: false,
|
|
1346
|
+
RETURN_TRUSTED_TYPE: false
|
|
1347
|
+
});
|
|
1348
|
+
};
|
|
1333
1349
|
var GlobalNotificationProvider = ({
|
|
1334
1350
|
children,
|
|
1335
1351
|
maxNotifications = 5,
|
|
@@ -1344,13 +1360,23 @@ var GlobalNotificationProvider = ({
|
|
|
1344
1360
|
if (!enabled) {
|
|
1345
1361
|
return "";
|
|
1346
1362
|
}
|
|
1363
|
+
if (!message || typeof message !== "string") {
|
|
1364
|
+
console.warn("\u26A0\uFE0F GlobalNotificationProvider: Invalid message provided");
|
|
1365
|
+
return "";
|
|
1366
|
+
}
|
|
1367
|
+
if (message.length > 1e3) {
|
|
1368
|
+
console.warn("\u26A0\uFE0F GlobalNotificationProvider: Message too long, truncating");
|
|
1369
|
+
message = message.substring(0, 1e3) + "...";
|
|
1370
|
+
}
|
|
1347
1371
|
const id = uuidv4();
|
|
1348
1372
|
const newNotification = {
|
|
1349
1373
|
id,
|
|
1350
1374
|
message,
|
|
1351
1375
|
severity,
|
|
1352
1376
|
autoHideDuration: options?.autoHideDuration ?? defaultAutoHideDuration,
|
|
1353
|
-
persistent: options?.persistent ?? false
|
|
1377
|
+
persistent: options?.persistent ?? false,
|
|
1378
|
+
allowHtml: options?.allowHtml ?? false
|
|
1379
|
+
// Por defecto NO permitir HTML
|
|
1354
1380
|
};
|
|
1355
1381
|
setNotifications((prev) => {
|
|
1356
1382
|
const updatedNotifications = prev.length >= maxNotifications ? prev.slice(-(maxNotifications - 1)) : prev;
|
|
@@ -1440,7 +1466,7 @@ var NotificationItem = ({ notification, onClose }) => {
|
|
|
1440
1466
|
maxWidth: "400px",
|
|
1441
1467
|
wordBreak: "break-word"
|
|
1442
1468
|
},
|
|
1443
|
-
children: /* @__PURE__ */ jsx4("span", { dangerouslySetInnerHTML: { __html: notification.message } })
|
|
1469
|
+
children: notification.allowHtml ? /* @__PURE__ */ jsx4("span", { dangerouslySetInnerHTML: { __html: sanitizeNotificationContent(notification.message) } }) : /* @__PURE__ */ jsx4("span", { children: notification.message })
|
|
1444
1470
|
}
|
|
1445
1471
|
)
|
|
1446
1472
|
}
|
|
@@ -4764,10 +4790,7 @@ var useCrudifyWithNotifications = (options = {}) => {
|
|
|
4764
4790
|
moduleKey = actionConfig.moduleKey;
|
|
4765
4791
|
}
|
|
4766
4792
|
}
|
|
4767
|
-
if (operation
|
|
4768
|
-
const message = getSafeTranslation("resetPassword.successMessage", "Contrase\xF1a restablecida exitosamente");
|
|
4769
|
-
showNotification(message, "success", { autoHideDuration });
|
|
4770
|
-
} else if (shouldShowSuccessNotification(operation, moduleKey)) {
|
|
4793
|
+
if (shouldShowSuccessNotification(operation, moduleKey)) {
|
|
4771
4794
|
const message = getSuccessMessage(operation, moduleKey, actionConfig);
|
|
4772
4795
|
showNotification(message, "success", { autoHideDuration });
|
|
4773
4796
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocios/crudify-ui",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.60",
|
|
4
4
|
"description": "Biblioteca de componentes UI para Crudify",
|
|
5
5
|
"author": "Nocios",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,8 +26,10 @@
|
|
|
26
26
|
"@mui/material": "^7.1.0",
|
|
27
27
|
"@mui/x-data-grid": "^8.5.1",
|
|
28
28
|
"@nocios/crudify-browser": "^2.0.6",
|
|
29
|
+
"@types/dompurify": "^3.0.5",
|
|
29
30
|
"@types/uuid": "^10.0.0",
|
|
30
31
|
"crypto-js": "^4.2.0",
|
|
32
|
+
"dompurify": "^3.2.7",
|
|
31
33
|
"i18next-browser-languagedetector": "^8.1.0",
|
|
32
34
|
"i18next-http-backend": "^3.0.2",
|
|
33
35
|
"react": "^19.1.0",
|