fix(markdown): use htmlparser2 instead of DOMPurify for Web Worker compatibility (#2039)
Browse files- Replace isomorphic-dompurify with htmlparser2 (works in Web Workers)
- Add sanitizeHtmlForMultimedia() for video/audio/source tag allowlisting
- Update tests to expect escaped (not stripped) disallowed tags
- package-lock.json +115 -15
- package.json +1 -0
- src/lib/components/chat/MarkdownRenderer.svelte.test.ts +2 -2
- src/lib/utils/marked.spec.ts +2 -1
- src/lib/utils/marked.ts +106 -20
package-lock.json
CHANGED
|
@@ -24,6 +24,7 @@
|
|
| 24 |
"file-type": "^21.0.0",
|
| 25 |
"handlebars": "^4.7.8",
|
| 26 |
"highlight.js": "^11.7.0",
|
|
|
|
| 27 |
"husky": "^9.0.11",
|
| 28 |
"ip-address": "^9.0.5",
|
| 29 |
"jsdom": "^22.0.0",
|
|
@@ -680,6 +681,7 @@
|
|
| 680 |
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.927.0.tgz",
|
| 681 |
"integrity": "sha512-CasoHKKE/K+6YcVqjE+v5dVyKqKBtfzZyvGi669HvJ1f4EPHbVRPPLIb0eAYd/aEmwHsB/nn9VnyN9Wq5OppUQ==",
|
| 682 |
"license": "Apache-2.0",
|
|
|
|
| 683 |
"dependencies": {
|
| 684 |
"@aws-sdk/client-cognito-identity": "3.927.0",
|
| 685 |
"@aws-sdk/core": "3.927.0",
|
|
@@ -956,7 +958,6 @@
|
|
| 956 |
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
| 957 |
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
|
| 958 |
"license": "MIT",
|
| 959 |
-
"peer": true,
|
| 960 |
"dependencies": {
|
| 961 |
"@babel/helper-validator-identifier": "^7.27.1",
|
| 962 |
"js-tokens": "^4.0.0",
|
|
@@ -971,7 +972,6 @@
|
|
| 971 |
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
| 972 |
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
|
| 973 |
"license": "MIT",
|
| 974 |
-
"peer": true,
|
| 975 |
"engines": {
|
| 976 |
"node": ">=6.9.0"
|
| 977 |
}
|
|
@@ -1073,6 +1073,7 @@
|
|
| 1073 |
}
|
| 1074 |
],
|
| 1075 |
"license": "MIT",
|
|
|
|
| 1076 |
"engines": {
|
| 1077 |
"node": ">=18"
|
| 1078 |
},
|
|
@@ -1096,6 +1097,7 @@
|
|
| 1096 |
}
|
| 1097 |
],
|
| 1098 |
"license": "MIT",
|
|
|
|
| 1099 |
"engines": {
|
| 1100 |
"node": ">=18"
|
| 1101 |
}
|
|
@@ -3248,7 +3250,8 @@
|
|
| 3248 |
"version": "0.34.41",
|
| 3249 |
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz",
|
| 3250 |
"integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==",
|
| 3251 |
-
"license": "MIT"
|
|
|
|
| 3252 |
},
|
| 3253 |
"node_modules/@smithy/abort-controller": {
|
| 3254 |
"version": "4.2.4",
|
|
@@ -3861,6 +3864,7 @@
|
|
| 3861 |
"integrity": "sha512-EMYTY4+rNa7TaRZYzCqhQslEkACEZzWc363jOYuc90oJrgvlWTcgqTxcGSIJim48hPaXwYlHyatRnnMmTFf5tA==",
|
| 3862 |
"devOptional": true,
|
| 3863 |
"license": "MIT",
|
|
|
|
| 3864 |
"dependencies": {
|
| 3865 |
"@sveltejs/acorn-typescript": "^1.0.5",
|
| 3866 |
"@types/cookie": "^0.6.0",
|
|
@@ -3893,6 +3897,7 @@
|
|
| 3893 |
"integrity": "sha512-wojIS/7GYnJDYIg1higWj2ROA6sSRWvcR1PO/bqEyFr/5UZah26c8Cz4u0NaqjPeVltzsVpt2Tm8d2io0V+4Tw==",
|
| 3894 |
"devOptional": true,
|
| 3895 |
"license": "MIT",
|
|
|
|
| 3896 |
"dependencies": {
|
| 3897 |
"@sveltejs/vite-plugin-svelte-inspector": "^4.0.1",
|
| 3898 |
"debug": "^4.4.1",
|
|
@@ -3932,7 +3937,6 @@
|
|
| 3932 |
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
|
| 3933 |
"integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
|
| 3934 |
"license": "Apache-2.0",
|
| 3935 |
-
"peer": true,
|
| 3936 |
"dependencies": {
|
| 3937 |
"tslib": "^2.8.0"
|
| 3938 |
}
|
|
@@ -3978,7 +3982,6 @@
|
|
| 3978 |
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
|
| 3979 |
"integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
|
| 3980 |
"license": "MIT",
|
| 3981 |
-
"peer": true,
|
| 3982 |
"engines": {
|
| 3983 |
"node": ">=12",
|
| 3984 |
"npm": ">=6"
|
|
@@ -4024,8 +4027,7 @@
|
|
| 4024 |
"version": "5.0.4",
|
| 4025 |
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
| 4026 |
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
|
| 4027 |
-
"license": "MIT"
|
| 4028 |
-
"peer": true
|
| 4029 |
},
|
| 4030 |
"node_modules/@types/chai": {
|
| 4031 |
"version": "5.2.2",
|
|
@@ -4254,6 +4256,7 @@
|
|
| 4254 |
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
|
| 4255 |
"dev": true,
|
| 4256 |
"license": "BSD-2-Clause",
|
|
|
|
| 4257 |
"dependencies": {
|
| 4258 |
"@typescript-eslint/scope-manager": "6.21.0",
|
| 4259 |
"@typescript-eslint/types": "6.21.0",
|
|
@@ -4652,6 +4655,7 @@
|
|
| 4652 |
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
| 4653 |
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
| 4654 |
"license": "MIT",
|
|
|
|
| 4655 |
"bin": {
|
| 4656 |
"acorn": "bin/acorn"
|
| 4657 |
},
|
|
@@ -4835,7 +4839,6 @@
|
|
| 4835 |
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
| 4836 |
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
| 4837 |
"license": "Apache-2.0",
|
| 4838 |
-
"peer": true,
|
| 4839 |
"dependencies": {
|
| 4840 |
"dequal": "^2.0.3"
|
| 4841 |
}
|
|
@@ -5101,6 +5104,7 @@
|
|
| 5101 |
}
|
| 5102 |
],
|
| 5103 |
"license": "MIT",
|
|
|
|
| 5104 |
"dependencies": {
|
| 5105 |
"caniuse-lite": "^1.0.30001718",
|
| 5106 |
"electron-to-chromium": "^1.5.160",
|
|
@@ -5770,8 +5774,45 @@
|
|
| 5770 |
"version": "0.5.16",
|
| 5771 |
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
| 5772 |
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5773 |
"license": "MIT",
|
| 5774 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5775 |
},
|
| 5776 |
"node_modules/domexception": {
|
| 5777 |
"version": "4.0.0",
|
|
@@ -5786,6 +5827,21 @@
|
|
| 5786 |
"node": ">=12"
|
| 5787 |
}
|
| 5788 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5789 |
"node_modules/dompurify": {
|
| 5790 |
"version": "3.3.0",
|
| 5791 |
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz",
|
|
@@ -5796,6 +5852,20 @@
|
|
| 5796 |
"@types/trusted-types": "^2.0.7"
|
| 5797 |
}
|
| 5798 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5799 |
"node_modules/dotenv": {
|
| 5800 |
"version": "16.5.0",
|
| 5801 |
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
|
|
@@ -5845,6 +5915,7 @@
|
|
| 5845 |
"resolved": "https://registry.npmjs.org/elysia/-/elysia-1.3.4.tgz",
|
| 5846 |
"integrity": "sha512-kAfM3Zwovy3z255IZgTKVxBw91HbgKhYl3TqrGRdZqqr+Fd+4eKOfvxgaKij22+MZLczPzIHtscAmvfpI3+q/A==",
|
| 5847 |
"license": "MIT",
|
|
|
|
| 5848 |
"dependencies": {
|
| 5849 |
"cookie": "^1.0.2",
|
| 5850 |
"exact-mirror": "0.1.2",
|
|
@@ -6045,6 +6116,7 @@
|
|
| 6045 |
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
| 6046 |
"dev": true,
|
| 6047 |
"license": "MIT",
|
|
|
|
| 6048 |
"dependencies": {
|
| 6049 |
"@eslint-community/eslint-utils": "^4.2.0",
|
| 6050 |
"@eslint-community/regexpp": "^4.6.1",
|
|
@@ -6682,6 +6754,7 @@
|
|
| 6682 |
"resolved": "https://registry.npmjs.org/file-type/-/file-type-21.0.0.tgz",
|
| 6683 |
"integrity": "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==",
|
| 6684 |
"license": "MIT",
|
|
|
|
| 6685 |
"dependencies": {
|
| 6686 |
"@tokenizer/inflate": "^0.2.7",
|
| 6687 |
"strtok3": "^10.2.2",
|
|
@@ -7213,6 +7286,25 @@
|
|
| 7213 |
"node": ">=12"
|
| 7214 |
}
|
| 7215 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7216 |
"node_modules/http-errors": {
|
| 7217 |
"version": "2.0.0",
|
| 7218 |
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
|
@@ -7822,8 +7914,7 @@
|
|
| 7822 |
"version": "4.0.0",
|
| 7823 |
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
| 7824 |
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
| 7825 |
-
"license": "MIT"
|
| 7826 |
-
"peer": true
|
| 7827 |
},
|
| 7828 |
"node_modules/js-yaml": {
|
| 7829 |
"version": "4.1.0",
|
|
@@ -9601,6 +9692,7 @@
|
|
| 9601 |
"integrity": "sha512-cJW4Xd/G3v5ovXtJJ52MAOclqeac9S/aGGgRzLabuF8TnIb6xHvMzKIa6JmrRzUkeXJgfL1MhukP0NK6l39h3A==",
|
| 9602 |
"devOptional": true,
|
| 9603 |
"license": "Apache-2.0",
|
|
|
|
| 9604 |
"dependencies": {
|
| 9605 |
"playwright-core": "1.55.1"
|
| 9606 |
},
|
|
@@ -9646,6 +9738,7 @@
|
|
| 9646 |
}
|
| 9647 |
],
|
| 9648 |
"license": "MIT",
|
|
|
|
| 9649 |
"dependencies": {
|
| 9650 |
"nanoid": "^3.3.11",
|
| 9651 |
"picocolors": "^1.1.1",
|
|
@@ -9877,6 +9970,7 @@
|
|
| 9877 |
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
| 9878 |
"dev": true,
|
| 9879 |
"license": "MIT",
|
|
|
|
| 9880 |
"bin": {
|
| 9881 |
"prettier": "bin/prettier.cjs"
|
| 9882 |
},
|
|
@@ -9893,6 +9987,7 @@
|
|
| 9893 |
"integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==",
|
| 9894 |
"dev": true,
|
| 9895 |
"license": "MIT",
|
|
|
|
| 9896 |
"peerDependencies": {
|
| 9897 |
"prettier": "^3.0.0",
|
| 9898 |
"svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0"
|
|
@@ -9982,7 +10077,6 @@
|
|
| 9982 |
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
|
| 9983 |
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
|
| 9984 |
"license": "MIT",
|
| 9985 |
-
"peer": true,
|
| 9986 |
"dependencies": {
|
| 9987 |
"ansi-regex": "^5.0.1",
|
| 9988 |
"ansi-styles": "^5.0.0",
|
|
@@ -9997,7 +10091,6 @@
|
|
| 9997 |
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
| 9998 |
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
| 9999 |
"license": "MIT",
|
| 10000 |
-
"peer": true,
|
| 10001 |
"engines": {
|
| 10002 |
"node": ">=10"
|
| 10003 |
},
|
|
@@ -10206,8 +10299,7 @@
|
|
| 10206 |
"version": "17.0.2",
|
| 10207 |
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
| 10208 |
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
| 10209 |
-
"license": "MIT"
|
| 10210 |
-
"peer": true
|
| 10211 |
},
|
| 10212 |
"node_modules/read-cache": {
|
| 10213 |
"version": "1.0.0",
|
|
@@ -10371,6 +10463,7 @@
|
|
| 10371 |
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.1.tgz",
|
| 10372 |
"integrity": "sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==",
|
| 10373 |
"license": "MIT",
|
|
|
|
| 10374 |
"dependencies": {
|
| 10375 |
"@types/estree": "1.0.7"
|
| 10376 |
},
|
|
@@ -11289,6 +11382,7 @@
|
|
| 11289 |
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.33.14.tgz",
|
| 11290 |
"integrity": "sha512-kRlbhIlMTijbFmVDQFDeKXPLlX1/ovXwV0I162wRqQhRcygaqDIcu1d/Ese3H2uI+yt3uT8E7ndgDthQv5v5BA==",
|
| 11291 |
"license": "MIT",
|
|
|
|
| 11292 |
"dependencies": {
|
| 11293 |
"@ampproject/remapping": "^2.3.0",
|
| 11294 |
"@jridgewell/sourcemap-codec": "^1.5.0",
|
|
@@ -11428,6 +11522,7 @@
|
|
| 11428 |
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
|
| 11429 |
"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
|
| 11430 |
"license": "MIT",
|
|
|
|
| 11431 |
"dependencies": {
|
| 11432 |
"@alloc/quick-lru": "^5.2.0",
|
| 11433 |
"arg": "^5.0.2",
|
|
@@ -11885,6 +11980,7 @@
|
|
| 11885 |
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
| 11886 |
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
| 11887 |
"license": "Apache-2.0",
|
|
|
|
| 11888 |
"bin": {
|
| 11889 |
"tsc": "bin/tsc",
|
| 11890 |
"tsserver": "bin/tsserver"
|
|
@@ -12120,6 +12216,7 @@
|
|
| 12120 |
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
|
| 12121 |
"integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
|
| 12122 |
"license": "MIT",
|
|
|
|
| 12123 |
"dependencies": {
|
| 12124 |
"esbuild": "^0.25.0",
|
| 12125 |
"fdir": "^6.4.4",
|
|
@@ -12255,6 +12352,7 @@
|
|
| 12255 |
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.2.tgz",
|
| 12256 |
"integrity": "sha512-fyNn/Rp016Bt5qvY0OQvIUCwW2vnaEBLxP42PmKbNIoasSYjML+8xyeADOPvBe+Xfl/ubIw4og7Lt9jflRsCNw==",
|
| 12257 |
"license": "MIT",
|
|
|
|
| 12258 |
"dependencies": {
|
| 12259 |
"@types/chai": "^5.2.2",
|
| 12260 |
"@vitest/expect": "3.2.2",
|
|
@@ -12577,6 +12675,7 @@
|
|
| 12577 |
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
|
| 12578 |
"integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
|
| 12579 |
"license": "MIT",
|
|
|
|
| 12580 |
"engines": {
|
| 12581 |
"node": ">=10.0.0"
|
| 12582 |
},
|
|
@@ -12699,6 +12798,7 @@
|
|
| 12699 |
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.55.tgz",
|
| 12700 |
"integrity": "sha512-219huNnkSLQnLsQ3uaRjXsxMrVm5C9W3OOpEVt2k5tvMKuA8nBSu38e0B//a+he9Iq2dvmk2VyYVlHqiHa4YBA==",
|
| 12701 |
"license": "MIT",
|
|
|
|
| 12702 |
"funding": {
|
| 12703 |
"url": "https://github.com/sponsors/colinhacks"
|
| 12704 |
}
|
|
|
|
| 24 |
"file-type": "^21.0.0",
|
| 25 |
"handlebars": "^4.7.8",
|
| 26 |
"highlight.js": "^11.7.0",
|
| 27 |
+
"htmlparser2": "^10.0.0",
|
| 28 |
"husky": "^9.0.11",
|
| 29 |
"ip-address": "^9.0.5",
|
| 30 |
"jsdom": "^22.0.0",
|
|
|
|
| 681 |
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.927.0.tgz",
|
| 682 |
"integrity": "sha512-CasoHKKE/K+6YcVqjE+v5dVyKqKBtfzZyvGi669HvJ1f4EPHbVRPPLIb0eAYd/aEmwHsB/nn9VnyN9Wq5OppUQ==",
|
| 683 |
"license": "Apache-2.0",
|
| 684 |
+
"peer": true,
|
| 685 |
"dependencies": {
|
| 686 |
"@aws-sdk/client-cognito-identity": "3.927.0",
|
| 687 |
"@aws-sdk/core": "3.927.0",
|
|
|
|
| 958 |
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
| 959 |
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
|
| 960 |
"license": "MIT",
|
|
|
|
| 961 |
"dependencies": {
|
| 962 |
"@babel/helper-validator-identifier": "^7.27.1",
|
| 963 |
"js-tokens": "^4.0.0",
|
|
|
|
| 972 |
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
| 973 |
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
|
| 974 |
"license": "MIT",
|
|
|
|
| 975 |
"engines": {
|
| 976 |
"node": ">=6.9.0"
|
| 977 |
}
|
|
|
|
| 1073 |
}
|
| 1074 |
],
|
| 1075 |
"license": "MIT",
|
| 1076 |
+
"peer": true,
|
| 1077 |
"engines": {
|
| 1078 |
"node": ">=18"
|
| 1079 |
},
|
|
|
|
| 1097 |
}
|
| 1098 |
],
|
| 1099 |
"license": "MIT",
|
| 1100 |
+
"peer": true,
|
| 1101 |
"engines": {
|
| 1102 |
"node": ">=18"
|
| 1103 |
}
|
|
|
|
| 3250 |
"version": "0.34.41",
|
| 3251 |
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz",
|
| 3252 |
"integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==",
|
| 3253 |
+
"license": "MIT",
|
| 3254 |
+
"peer": true
|
| 3255 |
},
|
| 3256 |
"node_modules/@smithy/abort-controller": {
|
| 3257 |
"version": "4.2.4",
|
|
|
|
| 3864 |
"integrity": "sha512-EMYTY4+rNa7TaRZYzCqhQslEkACEZzWc363jOYuc90oJrgvlWTcgqTxcGSIJim48hPaXwYlHyatRnnMmTFf5tA==",
|
| 3865 |
"devOptional": true,
|
| 3866 |
"license": "MIT",
|
| 3867 |
+
"peer": true,
|
| 3868 |
"dependencies": {
|
| 3869 |
"@sveltejs/acorn-typescript": "^1.0.5",
|
| 3870 |
"@types/cookie": "^0.6.0",
|
|
|
|
| 3897 |
"integrity": "sha512-wojIS/7GYnJDYIg1higWj2ROA6sSRWvcR1PO/bqEyFr/5UZah26c8Cz4u0NaqjPeVltzsVpt2Tm8d2io0V+4Tw==",
|
| 3898 |
"devOptional": true,
|
| 3899 |
"license": "MIT",
|
| 3900 |
+
"peer": true,
|
| 3901 |
"dependencies": {
|
| 3902 |
"@sveltejs/vite-plugin-svelte-inspector": "^4.0.1",
|
| 3903 |
"debug": "^4.4.1",
|
|
|
|
| 3937 |
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
|
| 3938 |
"integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
|
| 3939 |
"license": "Apache-2.0",
|
|
|
|
| 3940 |
"dependencies": {
|
| 3941 |
"tslib": "^2.8.0"
|
| 3942 |
}
|
|
|
|
| 3982 |
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
|
| 3983 |
"integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
|
| 3984 |
"license": "MIT",
|
|
|
|
| 3985 |
"engines": {
|
| 3986 |
"node": ">=12",
|
| 3987 |
"npm": ">=6"
|
|
|
|
| 4027 |
"version": "5.0.4",
|
| 4028 |
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
| 4029 |
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
|
| 4030 |
+
"license": "MIT"
|
|
|
|
| 4031 |
},
|
| 4032 |
"node_modules/@types/chai": {
|
| 4033 |
"version": "5.2.2",
|
|
|
|
| 4256 |
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
|
| 4257 |
"dev": true,
|
| 4258 |
"license": "BSD-2-Clause",
|
| 4259 |
+
"peer": true,
|
| 4260 |
"dependencies": {
|
| 4261 |
"@typescript-eslint/scope-manager": "6.21.0",
|
| 4262 |
"@typescript-eslint/types": "6.21.0",
|
|
|
|
| 4655 |
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
| 4656 |
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
| 4657 |
"license": "MIT",
|
| 4658 |
+
"peer": true,
|
| 4659 |
"bin": {
|
| 4660 |
"acorn": "bin/acorn"
|
| 4661 |
},
|
|
|
|
| 4839 |
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
| 4840 |
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
| 4841 |
"license": "Apache-2.0",
|
|
|
|
| 4842 |
"dependencies": {
|
| 4843 |
"dequal": "^2.0.3"
|
| 4844 |
}
|
|
|
|
| 5104 |
}
|
| 5105 |
],
|
| 5106 |
"license": "MIT",
|
| 5107 |
+
"peer": true,
|
| 5108 |
"dependencies": {
|
| 5109 |
"caniuse-lite": "^1.0.30001718",
|
| 5110 |
"electron-to-chromium": "^1.5.160",
|
|
|
|
| 5774 |
"version": "0.5.16",
|
| 5775 |
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
| 5776 |
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
| 5777 |
+
"license": "MIT"
|
| 5778 |
+
},
|
| 5779 |
+
"node_modules/dom-serializer": {
|
| 5780 |
+
"version": "2.0.0",
|
| 5781 |
+
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
| 5782 |
+
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
| 5783 |
"license": "MIT",
|
| 5784 |
+
"dependencies": {
|
| 5785 |
+
"domelementtype": "^2.3.0",
|
| 5786 |
+
"domhandler": "^5.0.2",
|
| 5787 |
+
"entities": "^4.2.0"
|
| 5788 |
+
},
|
| 5789 |
+
"funding": {
|
| 5790 |
+
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
| 5791 |
+
}
|
| 5792 |
+
},
|
| 5793 |
+
"node_modules/dom-serializer/node_modules/entities": {
|
| 5794 |
+
"version": "4.5.0",
|
| 5795 |
+
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
| 5796 |
+
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
| 5797 |
+
"license": "BSD-2-Clause",
|
| 5798 |
+
"engines": {
|
| 5799 |
+
"node": ">=0.12"
|
| 5800 |
+
},
|
| 5801 |
+
"funding": {
|
| 5802 |
+
"url": "https://github.com/fb55/entities?sponsor=1"
|
| 5803 |
+
}
|
| 5804 |
+
},
|
| 5805 |
+
"node_modules/domelementtype": {
|
| 5806 |
+
"version": "2.3.0",
|
| 5807 |
+
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
| 5808 |
+
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
|
| 5809 |
+
"funding": [
|
| 5810 |
+
{
|
| 5811 |
+
"type": "github",
|
| 5812 |
+
"url": "https://github.com/sponsors/fb55"
|
| 5813 |
+
}
|
| 5814 |
+
],
|
| 5815 |
+
"license": "BSD-2-Clause"
|
| 5816 |
},
|
| 5817 |
"node_modules/domexception": {
|
| 5818 |
"version": "4.0.0",
|
|
|
|
| 5827 |
"node": ">=12"
|
| 5828 |
}
|
| 5829 |
},
|
| 5830 |
+
"node_modules/domhandler": {
|
| 5831 |
+
"version": "5.0.3",
|
| 5832 |
+
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
| 5833 |
+
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
| 5834 |
+
"license": "BSD-2-Clause",
|
| 5835 |
+
"dependencies": {
|
| 5836 |
+
"domelementtype": "^2.3.0"
|
| 5837 |
+
},
|
| 5838 |
+
"engines": {
|
| 5839 |
+
"node": ">= 4"
|
| 5840 |
+
},
|
| 5841 |
+
"funding": {
|
| 5842 |
+
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
| 5843 |
+
}
|
| 5844 |
+
},
|
| 5845 |
"node_modules/dompurify": {
|
| 5846 |
"version": "3.3.0",
|
| 5847 |
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz",
|
|
|
|
| 5852 |
"@types/trusted-types": "^2.0.7"
|
| 5853 |
}
|
| 5854 |
},
|
| 5855 |
+
"node_modules/domutils": {
|
| 5856 |
+
"version": "3.2.2",
|
| 5857 |
+
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
|
| 5858 |
+
"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
|
| 5859 |
+
"license": "BSD-2-Clause",
|
| 5860 |
+
"dependencies": {
|
| 5861 |
+
"dom-serializer": "^2.0.0",
|
| 5862 |
+
"domelementtype": "^2.3.0",
|
| 5863 |
+
"domhandler": "^5.0.3"
|
| 5864 |
+
},
|
| 5865 |
+
"funding": {
|
| 5866 |
+
"url": "https://github.com/fb55/domutils?sponsor=1"
|
| 5867 |
+
}
|
| 5868 |
+
},
|
| 5869 |
"node_modules/dotenv": {
|
| 5870 |
"version": "16.5.0",
|
| 5871 |
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
|
|
|
|
| 5915 |
"resolved": "https://registry.npmjs.org/elysia/-/elysia-1.3.4.tgz",
|
| 5916 |
"integrity": "sha512-kAfM3Zwovy3z255IZgTKVxBw91HbgKhYl3TqrGRdZqqr+Fd+4eKOfvxgaKij22+MZLczPzIHtscAmvfpI3+q/A==",
|
| 5917 |
"license": "MIT",
|
| 5918 |
+
"peer": true,
|
| 5919 |
"dependencies": {
|
| 5920 |
"cookie": "^1.0.2",
|
| 5921 |
"exact-mirror": "0.1.2",
|
|
|
|
| 6116 |
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
| 6117 |
"dev": true,
|
| 6118 |
"license": "MIT",
|
| 6119 |
+
"peer": true,
|
| 6120 |
"dependencies": {
|
| 6121 |
"@eslint-community/eslint-utils": "^4.2.0",
|
| 6122 |
"@eslint-community/regexpp": "^4.6.1",
|
|
|
|
| 6754 |
"resolved": "https://registry.npmjs.org/file-type/-/file-type-21.0.0.tgz",
|
| 6755 |
"integrity": "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==",
|
| 6756 |
"license": "MIT",
|
| 6757 |
+
"peer": true,
|
| 6758 |
"dependencies": {
|
| 6759 |
"@tokenizer/inflate": "^0.2.7",
|
| 6760 |
"strtok3": "^10.2.2",
|
|
|
|
| 7286 |
"node": ">=12"
|
| 7287 |
}
|
| 7288 |
},
|
| 7289 |
+
"node_modules/htmlparser2": {
|
| 7290 |
+
"version": "10.0.0",
|
| 7291 |
+
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz",
|
| 7292 |
+
"integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==",
|
| 7293 |
+
"funding": [
|
| 7294 |
+
"https://github.com/fb55/htmlparser2?sponsor=1",
|
| 7295 |
+
{
|
| 7296 |
+
"type": "github",
|
| 7297 |
+
"url": "https://github.com/sponsors/fb55"
|
| 7298 |
+
}
|
| 7299 |
+
],
|
| 7300 |
+
"license": "MIT",
|
| 7301 |
+
"dependencies": {
|
| 7302 |
+
"domelementtype": "^2.3.0",
|
| 7303 |
+
"domhandler": "^5.0.3",
|
| 7304 |
+
"domutils": "^3.2.1",
|
| 7305 |
+
"entities": "^6.0.0"
|
| 7306 |
+
}
|
| 7307 |
+
},
|
| 7308 |
"node_modules/http-errors": {
|
| 7309 |
"version": "2.0.0",
|
| 7310 |
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
|
|
|
| 7914 |
"version": "4.0.0",
|
| 7915 |
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
| 7916 |
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
| 7917 |
+
"license": "MIT"
|
|
|
|
| 7918 |
},
|
| 7919 |
"node_modules/js-yaml": {
|
| 7920 |
"version": "4.1.0",
|
|
|
|
| 9692 |
"integrity": "sha512-cJW4Xd/G3v5ovXtJJ52MAOclqeac9S/aGGgRzLabuF8TnIb6xHvMzKIa6JmrRzUkeXJgfL1MhukP0NK6l39h3A==",
|
| 9693 |
"devOptional": true,
|
| 9694 |
"license": "Apache-2.0",
|
| 9695 |
+
"peer": true,
|
| 9696 |
"dependencies": {
|
| 9697 |
"playwright-core": "1.55.1"
|
| 9698 |
},
|
|
|
|
| 9738 |
}
|
| 9739 |
],
|
| 9740 |
"license": "MIT",
|
| 9741 |
+
"peer": true,
|
| 9742 |
"dependencies": {
|
| 9743 |
"nanoid": "^3.3.11",
|
| 9744 |
"picocolors": "^1.1.1",
|
|
|
|
| 9970 |
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
| 9971 |
"dev": true,
|
| 9972 |
"license": "MIT",
|
| 9973 |
+
"peer": true,
|
| 9974 |
"bin": {
|
| 9975 |
"prettier": "bin/prettier.cjs"
|
| 9976 |
},
|
|
|
|
| 9987 |
"integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==",
|
| 9988 |
"dev": true,
|
| 9989 |
"license": "MIT",
|
| 9990 |
+
"peer": true,
|
| 9991 |
"peerDependencies": {
|
| 9992 |
"prettier": "^3.0.0",
|
| 9993 |
"svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0"
|
|
|
|
| 10077 |
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
|
| 10078 |
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
|
| 10079 |
"license": "MIT",
|
|
|
|
| 10080 |
"dependencies": {
|
| 10081 |
"ansi-regex": "^5.0.1",
|
| 10082 |
"ansi-styles": "^5.0.0",
|
|
|
|
| 10091 |
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
| 10092 |
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
| 10093 |
"license": "MIT",
|
|
|
|
| 10094 |
"engines": {
|
| 10095 |
"node": ">=10"
|
| 10096 |
},
|
|
|
|
| 10299 |
"version": "17.0.2",
|
| 10300 |
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
| 10301 |
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
| 10302 |
+
"license": "MIT"
|
|
|
|
| 10303 |
},
|
| 10304 |
"node_modules/read-cache": {
|
| 10305 |
"version": "1.0.0",
|
|
|
|
| 10463 |
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.1.tgz",
|
| 10464 |
"integrity": "sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==",
|
| 10465 |
"license": "MIT",
|
| 10466 |
+
"peer": true,
|
| 10467 |
"dependencies": {
|
| 10468 |
"@types/estree": "1.0.7"
|
| 10469 |
},
|
|
|
|
| 11382 |
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.33.14.tgz",
|
| 11383 |
"integrity": "sha512-kRlbhIlMTijbFmVDQFDeKXPLlX1/ovXwV0I162wRqQhRcygaqDIcu1d/Ese3H2uI+yt3uT8E7ndgDthQv5v5BA==",
|
| 11384 |
"license": "MIT",
|
| 11385 |
+
"peer": true,
|
| 11386 |
"dependencies": {
|
| 11387 |
"@ampproject/remapping": "^2.3.0",
|
| 11388 |
"@jridgewell/sourcemap-codec": "^1.5.0",
|
|
|
|
| 11522 |
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
|
| 11523 |
"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
|
| 11524 |
"license": "MIT",
|
| 11525 |
+
"peer": true,
|
| 11526 |
"dependencies": {
|
| 11527 |
"@alloc/quick-lru": "^5.2.0",
|
| 11528 |
"arg": "^5.0.2",
|
|
|
|
| 11980 |
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
| 11981 |
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
| 11982 |
"license": "Apache-2.0",
|
| 11983 |
+
"peer": true,
|
| 11984 |
"bin": {
|
| 11985 |
"tsc": "bin/tsc",
|
| 11986 |
"tsserver": "bin/tsserver"
|
|
|
|
| 12216 |
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
|
| 12217 |
"integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
|
| 12218 |
"license": "MIT",
|
| 12219 |
+
"peer": true,
|
| 12220 |
"dependencies": {
|
| 12221 |
"esbuild": "^0.25.0",
|
| 12222 |
"fdir": "^6.4.4",
|
|
|
|
| 12352 |
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.2.tgz",
|
| 12353 |
"integrity": "sha512-fyNn/Rp016Bt5qvY0OQvIUCwW2vnaEBLxP42PmKbNIoasSYjML+8xyeADOPvBe+Xfl/ubIw4og7Lt9jflRsCNw==",
|
| 12354 |
"license": "MIT",
|
| 12355 |
+
"peer": true,
|
| 12356 |
"dependencies": {
|
| 12357 |
"@types/chai": "^5.2.2",
|
| 12358 |
"@vitest/expect": "3.2.2",
|
|
|
|
| 12675 |
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
|
| 12676 |
"integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
|
| 12677 |
"license": "MIT",
|
| 12678 |
+
"peer": true,
|
| 12679 |
"engines": {
|
| 12680 |
"node": ">=10.0.0"
|
| 12681 |
},
|
|
|
|
| 12798 |
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.55.tgz",
|
| 12799 |
"integrity": "sha512-219huNnkSLQnLsQ3uaRjXsxMrVm5C9W3OOpEVt2k5tvMKuA8nBSu38e0B//a+he9Iq2dvmk2VyYVlHqiHa4YBA==",
|
| 12800 |
"license": "MIT",
|
| 12801 |
+
"peer": true,
|
| 12802 |
"funding": {
|
| 12803 |
"url": "https://github.com/sponsors/colinhacks"
|
| 12804 |
}
|
package.json
CHANGED
|
@@ -83,6 +83,7 @@
|
|
| 83 |
"file-type": "^21.0.0",
|
| 84 |
"handlebars": "^4.7.8",
|
| 85 |
"highlight.js": "^11.7.0",
|
|
|
|
| 86 |
"husky": "^9.0.11",
|
| 87 |
"ip-address": "^9.0.5",
|
| 88 |
"jsdom": "^22.0.0",
|
|
|
|
| 83 |
"file-type": "^21.0.0",
|
| 84 |
"handlebars": "^4.7.8",
|
| 85 |
"highlight.js": "^11.7.0",
|
| 86 |
+
"htmlparser2": "^10.0.0",
|
| 87 |
"husky": "^9.0.11",
|
| 88 |
"ip-address": "^9.0.5",
|
| 89 |
"jsdom": "^22.0.0",
|
src/lib/components/chat/MarkdownRenderer.svelte.test.ts
CHANGED
|
@@ -32,8 +32,8 @@ describe("MarkdownRenderer", () => {
|
|
| 32 |
it("doesnt render raw html directly", () => {
|
| 33 |
render(MarkdownRenderer, { content: "<button>Click me</button>" });
|
| 34 |
expect(page.getByRole("button").elements).toHaveLength(0);
|
| 35 |
-
//
|
| 36 |
-
expect(page.getByRole("paragraph")).toHaveTextContent("Click me");
|
| 37 |
});
|
| 38 |
it("renders latex", () => {
|
| 39 |
const { baseElement } = render(MarkdownRenderer, { content: "$(oo)^2$" });
|
|
|
|
| 32 |
it("doesnt render raw html directly", () => {
|
| 33 |
render(MarkdownRenderer, { content: "<button>Click me</button>" });
|
| 34 |
expect(page.getByRole("button").elements).toHaveLength(0);
|
| 35 |
+
// htmlparser2 escapes disallowed tags
|
| 36 |
+
expect(page.getByRole("paragraph")).toHaveTextContent("<button>Click me</button>");
|
| 37 |
});
|
| 38 |
it("renders latex", () => {
|
| 39 |
const { baseElement } = render(MarkdownRenderer, { content: "$(oo)^2$" });
|
src/lib/utils/marked.spec.ts
CHANGED
|
@@ -79,9 +79,10 @@ describe("marked html video tag support", () => {
|
|
| 79 |
expect(html).not.toContain("javascript:");
|
| 80 |
});
|
| 81 |
|
| 82 |
-
test("
|
| 83 |
const html = renderHtml("<script>alert(1)</script>");
|
| 84 |
expect(html).not.toContain("<script>");
|
|
|
|
| 85 |
});
|
| 86 |
|
| 87 |
test("allows <audio> tags with controls", () => {
|
|
|
|
| 79 |
expect(html).not.toContain("javascript:");
|
| 80 |
});
|
| 81 |
|
| 82 |
+
test("escapes disallowed html tags", () => {
|
| 83 |
const html = renderHtml("<script>alert(1)</script>");
|
| 84 |
expect(html).not.toContain("<script>");
|
| 85 |
+
expect(html).toContain("<script>");
|
| 86 |
});
|
| 87 |
|
| 88 |
test("allows <audio> tags with controls", () => {
|
src/lib/utils/marked.ts
CHANGED
|
@@ -2,7 +2,7 @@ import katex from "katex";
|
|
| 2 |
import "katex/dist/contrib/mhchem.mjs";
|
| 3 |
import { Marked } from "marked";
|
| 4 |
import type { Tokens, TokenizerExtension, RendererExtension } from "marked";
|
| 5 |
-
import
|
| 6 |
// Simple type to replace removed WebSearchSource
|
| 7 |
type SimpleSource = {
|
| 8 |
title?: string;
|
|
@@ -57,24 +57,6 @@ const bundledLanguages: [string, LanguageFn][] = [
|
|
| 57 |
|
| 58 |
bundledLanguages.forEach(([name, language]) => hljs.registerLanguage(name, language));
|
| 59 |
|
| 60 |
-
// DOMPurify config for allowing video/audio tags in markdown
|
| 61 |
-
const DOMPURIFY_CONFIG = {
|
| 62 |
-
ALLOWED_TAGS: ["video", "audio", "source"],
|
| 63 |
-
ALLOWED_ATTR: [
|
| 64 |
-
"src",
|
| 65 |
-
"type",
|
| 66 |
-
"controls",
|
| 67 |
-
"autoplay",
|
| 68 |
-
"loop",
|
| 69 |
-
"muted",
|
| 70 |
-
"playsinline",
|
| 71 |
-
"poster",
|
| 72 |
-
"width",
|
| 73 |
-
"height",
|
| 74 |
-
"preload",
|
| 75 |
-
],
|
| 76 |
-
};
|
| 77 |
-
|
| 78 |
// Media URL detection
|
| 79 |
const VIDEO_EXTENSIONS = /\.(mp4|webm|ogg|mov|m4v)([?#]|$)/i;
|
| 80 |
const AUDIO_EXTENSIONS = /\.(mp3|wav|m4a|aac|flac)([?#]|$)/i;
|
|
@@ -87,6 +69,34 @@ function isAudioUrl(url: string): boolean {
|
|
| 87 |
return AUDIO_EXTENSIONS.test(url);
|
| 88 |
}
|
| 89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
interface katexBlockToken extends Tokens.Generic {
|
| 91 |
type: "katexBlock";
|
| 92 |
raw: string;
|
|
@@ -256,6 +266,82 @@ function highlightCode(text: string, lang?: string): string {
|
|
| 256 |
return hljs.highlightAuto(text).value;
|
| 257 |
}
|
| 258 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
function createMarkedInstance(sources: SimpleSource[]): Marked {
|
| 260 |
return new Marked({
|
| 261 |
hooks: {
|
|
@@ -285,7 +371,7 @@ function createMarkedInstance(sources: SimpleSource[]): Marked {
|
|
| 285 |
}
|
| 286 |
return `<img src="${safeSrc}" alt="${safeAlt}"${safeTitle} />`;
|
| 287 |
},
|
| 288 |
-
html: (html) =>
|
| 289 |
},
|
| 290 |
gfm: true,
|
| 291 |
breaks: true,
|
|
|
|
| 2 |
import "katex/dist/contrib/mhchem.mjs";
|
| 3 |
import { Marked } from "marked";
|
| 4 |
import type { Tokens, TokenizerExtension, RendererExtension } from "marked";
|
| 5 |
+
import { parseDocument } from "htmlparser2";
|
| 6 |
// Simple type to replace removed WebSearchSource
|
| 7 |
type SimpleSource = {
|
| 8 |
title?: string;
|
|
|
|
| 57 |
|
| 58 |
bundledLanguages.forEach(([name, language]) => hljs.registerLanguage(name, language));
|
| 59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
// Media URL detection
|
| 61 |
const VIDEO_EXTENSIONS = /\.(mp4|webm|ogg|mov|m4v)([?#]|$)/i;
|
| 62 |
const AUDIO_EXTENSIONS = /\.(mp3|wav|m4a|aac|flac)([?#]|$)/i;
|
|
|
|
| 69 |
return AUDIO_EXTENSIONS.test(url);
|
| 70 |
}
|
| 71 |
|
| 72 |
+
// Multimedia HTML sanitization (works in Web Workers - no DOM needed)
|
| 73 |
+
const MULTIMEDIA_TAGS = new Set(["video", "source", "audio"]);
|
| 74 |
+
const MULTIMEDIA_ALLOWED_ATTRS = new Set([
|
| 75 |
+
"src",
|
| 76 |
+
"type",
|
| 77 |
+
"controls",
|
| 78 |
+
"autoplay",
|
| 79 |
+
"loop",
|
| 80 |
+
"muted",
|
| 81 |
+
"playsinline",
|
| 82 |
+
"poster",
|
| 83 |
+
"width",
|
| 84 |
+
"height",
|
| 85 |
+
"preload",
|
| 86 |
+
]);
|
| 87 |
+
const MULTIMEDIA_BOOLEAN_ATTRS = new Set(["controls", "autoplay", "loop", "muted", "playsinline"]);
|
| 88 |
+
const MULTIMEDIA_URI_ATTRS = new Set(["src", "poster"]);
|
| 89 |
+
const MULTIMEDIA_ALLOWED_URI_PATTERN = /^(?!javascript:|data:text\/html)/i;
|
| 90 |
+
const MULTIMEDIA_HTML_REGEX = /<\/?(video|source|audio)\b/i;
|
| 91 |
+
|
| 92 |
+
type HtmlNode = {
|
| 93 |
+
type: string;
|
| 94 |
+
name?: string;
|
| 95 |
+
attribs?: Record<string, string>;
|
| 96 |
+
children?: HtmlNode[];
|
| 97 |
+
data?: string;
|
| 98 |
+
};
|
| 99 |
+
|
| 100 |
interface katexBlockToken extends Tokens.Generic {
|
| 101 |
type: "katexBlock";
|
| 102 |
raw: string;
|
|
|
|
| 266 |
return hljs.highlightAuto(text).value;
|
| 267 |
}
|
| 268 |
|
| 269 |
+
function sanitizeMediaUrl(value: string): string | undefined {
|
| 270 |
+
const trimmed = value.trim().replace(/>$/, "");
|
| 271 |
+
if (!MULTIMEDIA_ALLOWED_URI_PATTERN.test(trimmed)) return undefined;
|
| 272 |
+
return trimmed;
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
function serializeMediaAttributes(attribs?: Record<string, string>): string {
|
| 276 |
+
if (!attribs) return "";
|
| 277 |
+
const parts: string[] = [];
|
| 278 |
+
for (const [rawName, rawValue] of Object.entries(attribs)) {
|
| 279 |
+
const name = rawName.toLowerCase();
|
| 280 |
+
if (!MULTIMEDIA_ALLOWED_ATTRS.has(name)) continue;
|
| 281 |
+
if (MULTIMEDIA_BOOLEAN_ATTRS.has(name)) {
|
| 282 |
+
parts.push(name);
|
| 283 |
+
continue;
|
| 284 |
+
}
|
| 285 |
+
let value = rawValue ?? "";
|
| 286 |
+
if (MULTIMEDIA_URI_ATTRS.has(name)) {
|
| 287 |
+
const safeUrl = sanitizeMediaUrl(value);
|
| 288 |
+
if (!safeUrl) continue;
|
| 289 |
+
value = safeUrl;
|
| 290 |
+
}
|
| 291 |
+
parts.push(`${name}="${escapeHTML(value)}"`);
|
| 292 |
+
}
|
| 293 |
+
return parts.length ? ` ${parts.join(" ")}` : "";
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
function serializeMediaNode(node: HtmlNode, state: { hasDisallowedTag: boolean }): string {
|
| 297 |
+
if (node.type === "text") {
|
| 298 |
+
return escapeHTML(node.data ?? "");
|
| 299 |
+
}
|
| 300 |
+
if (node.type === "tag" || node.type === "script" || node.type === "style") {
|
| 301 |
+
const tagName = node.name?.toLowerCase() ?? "";
|
| 302 |
+
if (!MULTIMEDIA_TAGS.has(tagName)) {
|
| 303 |
+
state.hasDisallowedTag = true;
|
| 304 |
+
return "";
|
| 305 |
+
}
|
| 306 |
+
const attrs = serializeMediaAttributes(node.attribs);
|
| 307 |
+
if (tagName === "source") {
|
| 308 |
+
return `<source${attrs}>`;
|
| 309 |
+
}
|
| 310 |
+
const children = (node.children ?? [])
|
| 311 |
+
.map((child) => serializeMediaNode(child, state))
|
| 312 |
+
.join("");
|
| 313 |
+
return `<${tagName}${attrs}>${children}</${tagName}>`;
|
| 314 |
+
}
|
| 315 |
+
if (node.type === "comment") {
|
| 316 |
+
return "";
|
| 317 |
+
}
|
| 318 |
+
return "";
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
/**
|
| 322 |
+
* Sanitizes HTML to allow only video/audio/source tags with safe attributes.
|
| 323 |
+
* Uses htmlparser2 which works in Web Workers (no DOM needed).
|
| 324 |
+
* If any disallowed tags are found, escapes the entire input.
|
| 325 |
+
*/
|
| 326 |
+
function sanitizeHtmlForMultimedia(html: string): string {
|
| 327 |
+
if (!MULTIMEDIA_HTML_REGEX.test(html)) {
|
| 328 |
+
return escapeHTML(html);
|
| 329 |
+
}
|
| 330 |
+
const document = parseDocument(html, {
|
| 331 |
+
lowerCaseAttributeNames: true,
|
| 332 |
+
lowerCaseTags: true,
|
| 333 |
+
recognizeSelfClosing: true,
|
| 334 |
+
}) as unknown as { children: HtmlNode[] };
|
| 335 |
+
const state = { hasDisallowedTag: false };
|
| 336 |
+
const sanitized = (document.children ?? [])
|
| 337 |
+
.map((child) => serializeMediaNode(child, state))
|
| 338 |
+
.join("");
|
| 339 |
+
if (state.hasDisallowedTag) {
|
| 340 |
+
return escapeHTML(html);
|
| 341 |
+
}
|
| 342 |
+
return sanitized;
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
function createMarkedInstance(sources: SimpleSource[]): Marked {
|
| 346 |
return new Marked({
|
| 347 |
hooks: {
|
|
|
|
| 371 |
}
|
| 372 |
return `<img src="${safeSrc}" alt="${safeAlt}"${safeTitle} />`;
|
| 373 |
},
|
| 374 |
+
html: (html) => sanitizeHtmlForMultimedia(html),
|
| 375 |
},
|
| 376 |
gfm: true,
|
| 377 |
breaks: true,
|