diff --git a/README.md b/README.md index 102e9c2e..2df1a622 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ This readme file is used mostly to document project dependencies and conventions
   - axios
   - clsx
+  - dompurify
   - react-icons
   - react-router
   - react-toastify
diff --git a/rsconcept/frontend/package-lock.json b/rsconcept/frontend/package-lock.json
index 5b822424..c35473c2 100644
--- a/rsconcept/frontend/package-lock.json
+++ b/rsconcept/frontend/package-lock.json
@@ -22,6 +22,7 @@
         "class-variance-authority": "^0.7.1",
         "clsx": "^2.1.1",
         "cmdk": "^1.1.1",
+        "dompurify": "^3.3.0",
         "global": "^4.4.0",
         "js-file-download": "^0.4.12",
         "lucide-react": "^0.548.0",
@@ -4498,6 +4499,13 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/@types/trusted-types": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+      "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+      "license": "MIT",
+      "optional": true
+    },
     "node_modules/@types/yargs": {
       "version": "17.0.34",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.34.tgz",
@@ -6479,6 +6487,15 @@
       "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
       "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
     },
+    "node_modules/dompurify": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz",
+      "integrity": "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==",
+      "license": "(MPL-2.0 OR Apache-2.0)",
+      "optionalDependencies": {
+        "@types/trusted-types": "^2.0.7"
+      }
+    },
     "node_modules/dunder-proto": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
diff --git a/rsconcept/frontend/package.json b/rsconcept/frontend/package.json
index b79ff994..ef40b7a6 100644
--- a/rsconcept/frontend/package.json
+++ b/rsconcept/frontend/package.json
@@ -28,6 +28,7 @@
     "class-variance-authority": "^0.7.1",
     "clsx": "^2.1.1",
     "cmdk": "^1.1.1",
+    "dompurify": "^3.3.0",
     "global": "^4.4.0",
     "js-file-download": "^0.4.12",
     "lucide-react": "^0.548.0",
diff --git a/rsconcept/frontend/src/components/info-error.tsx b/rsconcept/frontend/src/components/info-error.tsx
index 52475ed4..3aaf8d48 100644
--- a/rsconcept/frontend/src/components/info-error.tsx
+++ b/rsconcept/frontend/src/components/info-error.tsx
@@ -1,4 +1,5 @@
 import clsx from 'clsx';
+import DOMPurify from 'dompurify';
 import { ZodError } from 'zod';
 
 import { type AxiosError, isAxiosError } from '@/backend/api-transport';
@@ -18,11 +19,17 @@ export function DescribeError({ error }: { error: ErrorData }) {
   } else if (typeof error === 'string') {
     return 

{error}

; } else if (error instanceof ZodError) { + let errorData: unknown; + try { + /* eslint-disable-next-line @typescript-eslint/no-base-to-string */ + errorData = JSON.parse(error.toString()); + } catch { + errorData = { message: error.message, issues: error.issues }; + } return (

Ошибка валидации данных

- {/* eslint-disable-next-line @typescript-eslint/no-base-to-string */} - ; +
); } else if (!isAxiosError(error)) { @@ -60,6 +67,12 @@ export function DescribeError({ error }: { error: ErrorData }) { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const isHtml = isResponseHtml(error.response); + let sanitizedHtml: string | null = null; + if (isHtml) { + sanitizedHtml = DOMPurify.sanitize(error.response.data as string, { + USE_PROFILES: { html: true } + }); + } return (

Ошибка

@@ -67,8 +80,11 @@ export function DescribeError({ error }: { error: ErrorData }) { {error.response.data && ( <>

Описание

- {isHtml ?
: null} - {!isHtml ? : null} + {isHtml && sanitizedHtml ? ( +
+ ) : ( + + )} )}