unvendor: Replace DOMPurify

3387fe4bd6a3f9ddb7227f69453317e0096a2607

Cohee <18619528+Cohee1207@users.noreply.github.com>

20 files changed, +67 -31Showing whitespace changes
.eslintrc.cjs+0 -1
@@ -50,7 +50,6 @@ module.exports = {
50 },50 },
51 // These scripts are loaded in HTML; tell ESLint not to complain about them being undefined51 // These scripts are loaded in HTML; tell ESLint not to complain about them being undefined
52 globals: {52 globals: {
53 DOMPurify: 'readonly',
54 droll: 'readonly',53 droll: 'readonly',
55 Handlebars: 'readonly',54 Handlebars: 'readonly',
56 hljs: 'readonly',55 hljs: 'readonly',
package-lock.json+7 -18
@@ -22,6 +22,7 @@
22 "cookie-session": "^2.1.0",22 "cookie-session": "^2.1.0",
23 "cors": "^2.8.5",23 "cors": "^2.8.5",
24 "csrf-csrf": "^2.2.3",24 "csrf-csrf": "^2.2.3",
25 "dompurify": "^3.1.7",
25 "express": "^4.21.0",26 "express": "^4.21.0",
26 "form-data": "^4.0.0",27 "form-data": "^4.0.0",
27 "fuse.js": "^7.0.0",28 "fuse.js": "^7.0.0",
@@ -68,7 +69,6 @@
68 "@types/cookie-parser": "^1.4.7",69 "@types/cookie-parser": "^1.4.7",
69 "@types/cookie-session": "^2.0.49",70 "@types/cookie-session": "^2.0.49",
70 "@types/cors": "^2.8.17",71 "@types/cors": "^2.8.17",
71 "@types/dompurify": "^3.0.5",
72 "@types/express": "^4.17.21",72 "@types/express": "^4.17.21",
73 "@types/jquery": "^3.5.29",73 "@types/jquery": "^3.5.29",
74 "@types/lodash": "^4.17.10",74 "@types/lodash": "^4.17.10",
@@ -1174,16 +1174,6 @@
1174 "@types/node": "*"1174 "@types/node": "*"
1175 }1175 }
1176 },1176 },
1177 "node_modules/@types/dompurify": {
1178 "version": "3.0.5",
1179 "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz",
1180 "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==",
1181 "dev": true,
1182 "license": "MIT",
1183 "dependencies": {
1184 "@types/trusted-types": "*"
1185 }
1186 },
1187 "node_modules/@types/estree": {1177 "node_modules/@types/estree": {
1188 "version": "1.0.6",1178 "version": "1.0.6",
1189 "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",1179 "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
@@ -1427,13 +1417,6 @@
1427 "@types/jquery": "*"1417 "@types/jquery": "*"
1428 }1418 }
1429 },1419 },
1430 "node_modules/@types/trusted-types": {
1431 "version": "2.0.7",
1432 "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
1433 "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
1434 "dev": true,
1435 "license": "MIT"
1436 },
1437 "node_modules/@types/write-file-atomic": {1420 "node_modules/@types/write-file-atomic": {
1438 "version": "4.0.3",1421 "version": "4.0.3",
1439 "resolved": "https://registry.npmjs.org/@types/write-file-atomic/-/write-file-atomic-4.0.3.tgz",1422 "resolved": "https://registry.npmjs.org/@types/write-file-atomic/-/write-file-atomic-4.0.3.tgz",
@@ -3221,6 +3204,12 @@
3221 "url": "https://github.com/fb55/domhandler?sponsor=1"3204 "url": "https://github.com/fb55/domhandler?sponsor=1"
3222 }3205 }
3223 },3206 },
3207 "node_modules/dompurify": {
3208 "version": "3.1.7",
3209 "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz",
3210 "integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==",
3211 "license": "(MPL-2.0 OR Apache-2.0)"
3212 },
3224 "node_modules/domutils": {3213 "node_modules/domutils": {
3225 "version": "3.1.0",3214 "version": "3.1.0",
3226 "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",3215 "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
package.json+1 -1
@@ -12,6 +12,7 @@
12 "cookie-session": "^2.1.0",12 "cookie-session": "^2.1.0",
13 "cors": "^2.8.5",13 "cors": "^2.8.5",
14 "csrf-csrf": "^2.2.3",14 "csrf-csrf": "^2.2.3",
15 "dompurify": "^3.1.7",
15 "express": "^4.21.0",16 "express": "^4.21.0",
16 "form-data": "^4.0.0",17 "form-data": "^4.0.0",
17 "fuse.js": "^7.0.0",18 "fuse.js": "^7.0.0",
@@ -94,7 +95,6 @@
94 "@types/cookie-parser": "^1.4.7",95 "@types/cookie-parser": "^1.4.7",
95 "@types/cookie-session": "^2.0.49",96 "@types/cookie-session": "^2.0.49",
96 "@types/cors": "^2.8.17",97 "@types/cors": "^2.8.17",
97 "@types/dompurify": "^3.0.5",
98 "@types/express": "^4.17.21",98 "@types/express": "^4.17.21",
99 "@types/jquery": "^3.5.29",99 "@types/jquery": "^3.5.29",
100 "@types/lodash": "^4.17.10",100 "@types/lodash": "^4.17.10",
public/global.d.ts+1 -0
@@ -16,6 +16,7 @@ declare var ai;
16declare var SillyTavern: {16declare var SillyTavern: {
17 getContext(): any;17 getContext(): any;
18 llm: any;18 llm: any;
19 libs: any;
19};20};
2021
21// Jquery plugins22// Jquery plugins
public/lib.js+26 -0
@@ -3,7 +3,33 @@
3 * They are bundled and exposed by Webpack in the /lib.js file.3 * They are bundled and exposed by Webpack in the /lib.js file.
4 */4 */
5import Fuse from 'fuse.js';5import Fuse from 'fuse.js';
6import DOMPurify from 'dompurify';
7
8/**
9 * Expose the libraries to the 'window' object.
10 * Needed for compatibility with old extensions.
11 * Note: New extensions are encouraged to import the libraries directly from lib.js.
12 */
13export function initLibraryShims() {
14 if (!window) {
15 return;
16 }
17 if (!('Fuse' in window)) {
18 // @ts-ignore
19 window.Fuse = Fuse;
20 }
21 if (!('DOMPurify' in window)) {
22 // @ts-ignore
23 window.DOMPurify = DOMPurify;
24 }
25}
26
27export default {
28 Fuse,
29 DOMPurify,
30};
631
7export {32export {
8 Fuse,33 Fuse,
34 DOMPurify,
9};35};
public/script.js+12 -3
@@ -1,4 +1,4 @@
1import { Fuse } from './lib.js';1import { Fuse, DOMPurify, initLibraryShims, default as libs } from './lib.js';
22
3import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter, addSafariPatch } from './scripts/RossAscends-mods.js';3import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter, addSafariPatch } from './scripts/RossAscends-mods.js';
4import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js';4import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js';
@@ -410,6 +410,7 @@ DOMPurify.addHook('uponSanitizeElement', (node, _, config) => {
410410
411// API OBJECT FOR EXTERNAL WIRING411// API OBJECT FOR EXTERNAL WIRING
412window['SillyTavern'] = {};412window['SillyTavern'] = {};
413window['SillyTavern'].libs = libs;
413414
414// Event source init415// Event source init
415export const event_types = {416export const event_types = {
@@ -940,6 +941,7 @@ async function firstLoadInit() {
940 throw new Error('Initialization failed');941 throw new Error('Initialization failed');
941 }942 }
942943
944 initLibraryShims();
943 addSafariPatch();945 addSafariPatch();
944 await getClientVersion();946 await getClientVersion();
945 await readSecretState();947 await readSecretState();
@@ -2058,8 +2060,15 @@ export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, san
2058 mes = mes.replace(new RegExp(`(^|\n)${escapeRegex(ch_name)}:`, 'g'), '$1');2060 mes = mes.replace(new RegExp(`(^|\n)${escapeRegex(ch_name)}:`, 'g'), '$1');
2059 }2061 }
20602062
2061 /** @type {any} */2063 /** @type {import('dompurify').Config & { RETURN_DOM_FRAGMENT: false; RETURN_DOM: false }} */
2062 const config = { MESSAGE_SANITIZE: true, ADD_TAGS: ['custom-style'], ...sanitizerOverrides };2064 const config = {
2065 RETURN_DOM: false,
2066 RETURN_DOM_FRAGMENT: false,
2067 RETURN_TRUSTED_TYPE: false,
2068 MESSAGE_SANITIZE: true,
2069 ADD_TAGS: ['custom-style'],
2070 ...sanitizerOverrides,
2071 };
2063 mes = encodeStyleTags(mes);2072 mes = encodeStyleTags(mes);
2064 mes = DOMPurify.sanitize(mes, config);2073 mes = DOMPurify.sanitize(mes, config);
2065 mes = decodeStyleTags(mes);2074 mes = decodeStyleTags(mes);
public/scripts/PromptManager.js+2 -0
@@ -1,5 +1,7 @@
1'use strict';1'use strict';
22
3import { DOMPurify } from '../lib.js';
4
3import { event_types, eventSource, is_send_press, main_api, substituteParams } from '../script.js';5import { event_types, eventSource, is_send_press, main_api, substituteParams } from '../script.js';
4import { is_group_generating } from './group-chats.js';6import { is_group_generating } from './group-chats.js';
5import { Message, TokenHandler } from './openai.js';7import { Message, TokenHandler } from './openai.js';
public/scripts/RossAscends-mods.js+2 -0
@@ -1,3 +1,5 @@
1import { DOMPurify } from '../lib.js';
2
1import {3import {
2 characters,4 characters,
3 online_status,5 online_status,
public/scripts/extensions.js+2 -0
@@ -1,3 +1,5 @@
1import { DOMPurify } from '../lib.js';
2
1import { eventSource, event_types, saveSettings, saveSettingsDebounced, getRequestHeaders, animation_duration } from '../script.js';3import { eventSource, event_types, saveSettings, saveSettingsDebounced, getRequestHeaders, animation_duration } from '../script.js';
2import { showLoader } from './loader.js';4import { showLoader } from './loader.js';
3import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';5import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
public/scripts/extensions/assets/index.js+1 -0
@@ -3,6 +3,7 @@ TODO:
3*/3*/
4//const DEBUG_TONY_SAMA_FORK_MODE = true4//const DEBUG_TONY_SAMA_FORK_MODE = true
55
6import { DOMPurify } from '../../../lib.js';
6import { getRequestHeaders, processDroppedFiles, eventSource, event_types } from '../../../script.js';7import { getRequestHeaders, processDroppedFiles, eventSource, event_types } from '../../../script.js';
7import { deleteExtension, extensionNames, getContext, installExtension, renderExtensionTemplateAsync } from '../../extensions.js';8import { deleteExtension, extensionNames, getContext, installExtension, renderExtensionTemplateAsync } from '../../extensions.js';
8import { POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js';9import { POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js';
public/scripts/openai.js+1 -1
@@ -3,7 +3,7 @@
3* By CncAnon (@CncAnon1)3* By CncAnon (@CncAnon1)
4* https://github.com/CncAnon1/TavernAITurbo4* https://github.com/CncAnon1/TavernAITurbo
5*/5*/
6import { Fuse } from '../lib.js';6import { Fuse, DOMPurify } from '../lib.js';
77
8import {8import {
9 abortStatusCheck,9 abortStatusCheck,
public/scripts/secrets.js+1 -0
@@ -1,3 +1,4 @@
1import { DOMPurify } from '../lib.js';
1import { callPopup, getRequestHeaders } from '../script.js';2import { callPopup, getRequestHeaders } from '../script.js';
23
3export const SECRET_KEYS = {4export const SECRET_KEYS = {
public/scripts/slash-commands.js+1 -1
@@ -1,4 +1,4 @@
1import { Fuse } from '../lib.js';1import { Fuse, DOMPurify } from '../lib.js';
22
3import {3import {
4 Generate,4 Generate,
public/scripts/slash-commands/SlashCommandReturnHelper.js+1 -0
@@ -1,3 +1,4 @@
1import { DOMPurify } from '../../lib.js';
1import { sendSystemMessage, system_message_types } from '../../script.js';2import { sendSystemMessage, system_message_types } from '../../script.js';
2import { callGenericPopup, POPUP_TYPE } from '../popup.js';3import { callGenericPopup, POPUP_TYPE } from '../popup.js';
3import { escapeHtml } from '../utils.js';4import { escapeHtml } from '../utils.js';
public/scripts/tags.js+2 -0
@@ -1,3 +1,5 @@
1import { DOMPurify } from '../lib.js';
2
1import {3import {
2 characters,4 characters,
3 saveSettingsDebounced,5 saveSettingsDebounced,
public/scripts/templates.js+1 -0
@@ -1,3 +1,4 @@
1import { DOMPurify } from '../lib.js';
1import { applyLocale } from './i18n.js';2import { applyLocale } from './i18n.js';
23
3/**4/**
public/scripts/textgen-models.js+1 -0
@@ -1,3 +1,4 @@
1import { DOMPurify } from '../lib.js';
1import { isMobile } from './RossAscends-mods.js';2import { isMobile } from './RossAscends-mods.js';
2import { amount_gen, callPopup, eventSource, event_types, getRequestHeaders, max_context, online_status, setGenerationParamsFromPreset } from '../script.js';3import { amount_gen, callPopup, eventSource, event_types, getRequestHeaders, max_context, online_status, setGenerationParamsFromPreset } from '../script.js';
3import { textgenerationwebui_settings as textgen_settings, textgen_types } from './textgen-settings.js';4import { textgenerationwebui_settings as textgen_settings, textgen_types } from './textgen-settings.js';
public/scripts/tool-calling.js+2 -0
@@ -1,3 +1,5 @@
1import { DOMPurify } from '../lib.js';
2
1import { addOneMessage, chat, event_types, eventSource, main_api, saveChatConditional, system_avatar, systemUserName } from '../script.js';3import { addOneMessage, chat, event_types, eventSource, main_api, saveChatConditional, system_avatar, systemUserName } from '../script.js';
2import { chat_completion_sources, oai_settings } from './openai.js';4import { chat_completion_sources, oai_settings } from './openai.js';
3import { Popup } from './popup.js';5import { Popup } from './popup.js';
public/scripts/utils.js+2 -0
@@ -1,3 +1,5 @@
1import { DOMPurify } from '../lib.js';
2
1import { getContext } from './extensions.js';3import { getContext } from './extensions.js';
2import { characters, getRequestHeaders, this_chid } from '../script.js';4import { characters, getRequestHeaders, this_chid } from '../script.js';
3import { isMobile } from './RossAscends-mods.js';5import { isMobile } from './RossAscends-mods.js';
webpack.config.js+1 -6
@@ -4,12 +4,7 @@ export const publicLibConfig = {
4 entry: './public/lib.js',4 entry: './public/lib.js',
5 cache: true,5 cache: true,
6 devtool: 'source-map',6 devtool: 'source-map',
7 module: {7 module: {},
8 rules: [{
9 test: /\.js$/,
10 exclude: /node_modules/,
11 }],
12 },
13 experiments: {8 experiments: {
14 outputModule: true,9 outputModule: true,
15 },10 },