unvendor: Replace DOMPurify

This commit is contained in:
Cohee
2024-10-16 23:11:13 +03:00
parent e6d8f0a33e
commit 3387fe4bd6
20 changed files with 67 additions and 31 deletions

View File

@ -50,7 +50,6 @@ module.exports = {
}, },
// These scripts are loaded in HTML; tell ESLint not to complain about them being undefined // These scripts are loaded in HTML; tell ESLint not to complain about them being undefined
globals: { globals: {
DOMPurify: 'readonly',
droll: 'readonly', droll: 'readonly',
Handlebars: 'readonly', Handlebars: 'readonly',
hljs: 'readonly', hljs: 'readonly',

25
package-lock.json generated
View File

@ -22,6 +22,7 @@
"cookie-session": "^2.1.0", "cookie-session": "^2.1.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"csrf-csrf": "^2.2.3", "csrf-csrf": "^2.2.3",
"dompurify": "^3.1.7",
"express": "^4.21.0", "express": "^4.21.0",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"fuse.js": "^7.0.0", "fuse.js": "^7.0.0",
@ -68,7 +69,6 @@
"@types/cookie-parser": "^1.4.7", "@types/cookie-parser": "^1.4.7",
"@types/cookie-session": "^2.0.49", "@types/cookie-session": "^2.0.49",
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
"@types/dompurify": "^3.0.5",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/jquery": "^3.5.29", "@types/jquery": "^3.5.29",
"@types/lodash": "^4.17.10", "@types/lodash": "^4.17.10",
@ -1174,16 +1174,6 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/dompurify": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz",
"integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/trusted-types": "*"
}
},
"node_modules/@types/estree": { "node_modules/@types/estree": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
@ -1427,13 +1417,6 @@
"@types/jquery": "*" "@types/jquery": "*"
} }
}, },
"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==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/write-file-atomic": { "node_modules/@types/write-file-atomic": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/@types/write-file-atomic/-/write-file-atomic-4.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/write-file-atomic/-/write-file-atomic-4.0.3.tgz",
@ -3221,6 +3204,12 @@
"url": "https://github.com/fb55/domhandler?sponsor=1" "url": "https://github.com/fb55/domhandler?sponsor=1"
} }
}, },
"node_modules/dompurify": {
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz",
"integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==",
"license": "(MPL-2.0 OR Apache-2.0)"
},
"node_modules/domutils": { "node_modules/domutils": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",

View File

@ -12,6 +12,7 @@
"cookie-session": "^2.1.0", "cookie-session": "^2.1.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"csrf-csrf": "^2.2.3", "csrf-csrf": "^2.2.3",
"dompurify": "^3.1.7",
"express": "^4.21.0", "express": "^4.21.0",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"fuse.js": "^7.0.0", "fuse.js": "^7.0.0",
@ -94,7 +95,6 @@
"@types/cookie-parser": "^1.4.7", "@types/cookie-parser": "^1.4.7",
"@types/cookie-session": "^2.0.49", "@types/cookie-session": "^2.0.49",
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
"@types/dompurify": "^3.0.5",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/jquery": "^3.5.29", "@types/jquery": "^3.5.29",
"@types/lodash": "^4.17.10", "@types/lodash": "^4.17.10",

1
public/global.d.ts vendored
View File

@ -16,6 +16,7 @@ declare var ai;
declare var SillyTavern: { declare var SillyTavern: {
getContext(): any; getContext(): any;
llm: any; llm: any;
libs: any;
}; };
// Jquery plugins // Jquery plugins

View File

@ -3,7 +3,33 @@
* They are bundled and exposed by Webpack in the /lib.js file. * They are bundled and exposed by Webpack in the /lib.js file.
*/ */
import Fuse from 'fuse.js'; import Fuse from 'fuse.js';
import DOMPurify from 'dompurify';
/**
* Expose the libraries to the 'window' object.
* Needed for compatibility with old extensions.
* Note: New extensions are encouraged to import the libraries directly from lib.js.
*/
export function initLibraryShims() {
if (!window) {
return;
}
if (!('Fuse' in window)) {
// @ts-ignore
window.Fuse = Fuse;
}
if (!('DOMPurify' in window)) {
// @ts-ignore
window.DOMPurify = DOMPurify;
}
}
export default {
Fuse,
DOMPurify,
};
export { export {
Fuse, Fuse,
DOMPurify,
}; };

View File

@ -1,4 +1,4 @@
import { Fuse } from './lib.js'; import { Fuse, DOMPurify, initLibraryShims, default as libs } from './lib.js';
import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter, addSafariPatch } from './scripts/RossAscends-mods.js'; import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter, addSafariPatch } from './scripts/RossAscends-mods.js';
import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js'; import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js';
@ -410,6 +410,7 @@ DOMPurify.addHook('uponSanitizeElement', (node, _, config) => {
// API OBJECT FOR EXTERNAL WIRING // API OBJECT FOR EXTERNAL WIRING
window['SillyTavern'] = {}; window['SillyTavern'] = {};
window['SillyTavern'].libs = libs;
// Event source init // Event source init
export const event_types = { export const event_types = {
@ -940,6 +941,7 @@ async function firstLoadInit() {
throw new Error('Initialization failed'); throw new Error('Initialization failed');
} }
initLibraryShims();
addSafariPatch(); addSafariPatch();
await getClientVersion(); await getClientVersion();
await readSecretState(); await readSecretState();
@ -2058,8 +2060,15 @@ export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, san
mes = mes.replace(new RegExp(`(^|\n)${escapeRegex(ch_name)}:`, 'g'), '$1'); mes = mes.replace(new RegExp(`(^|\n)${escapeRegex(ch_name)}:`, 'g'), '$1');
} }
/** @type {any} */ /** @type {import('dompurify').Config & { RETURN_DOM_FRAGMENT: false; RETURN_DOM: false }} */
const config = { MESSAGE_SANITIZE: true, ADD_TAGS: ['custom-style'], ...sanitizerOverrides }; const config = {
RETURN_DOM: false,
RETURN_DOM_FRAGMENT: false,
RETURN_TRUSTED_TYPE: false,
MESSAGE_SANITIZE: true,
ADD_TAGS: ['custom-style'],
...sanitizerOverrides,
};
mes = encodeStyleTags(mes); mes = encodeStyleTags(mes);
mes = DOMPurify.sanitize(mes, config); mes = DOMPurify.sanitize(mes, config);
mes = decodeStyleTags(mes); mes = decodeStyleTags(mes);

View File

@ -1,5 +1,7 @@
'use strict'; 'use strict';
import { DOMPurify } from '../lib.js';
import { event_types, eventSource, is_send_press, main_api, substituteParams } from '../script.js'; import { event_types, eventSource, is_send_press, main_api, substituteParams } from '../script.js';
import { is_group_generating } from './group-chats.js'; import { is_group_generating } from './group-chats.js';
import { Message, TokenHandler } from './openai.js'; import { Message, TokenHandler } from './openai.js';

View File

@ -1,3 +1,5 @@
import { DOMPurify } from '../lib.js';
import { import {
characters, characters,
online_status, online_status,

View File

@ -1,3 +1,5 @@
import { DOMPurify } from '../lib.js';
import { eventSource, event_types, saveSettings, saveSettingsDebounced, getRequestHeaders, animation_duration } from '../script.js'; import { eventSource, event_types, saveSettings, saveSettingsDebounced, getRequestHeaders, animation_duration } from '../script.js';
import { showLoader } from './loader.js'; import { showLoader } from './loader.js';
import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js'; import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';

View File

@ -3,6 +3,7 @@ TODO:
*/ */
//const DEBUG_TONY_SAMA_FORK_MODE = true //const DEBUG_TONY_SAMA_FORK_MODE = true
import { DOMPurify } from '../../../lib.js';
import { getRequestHeaders, processDroppedFiles, eventSource, event_types } from '../../../script.js'; import { getRequestHeaders, processDroppedFiles, eventSource, event_types } from '../../../script.js';
import { deleteExtension, extensionNames, getContext, installExtension, renderExtensionTemplateAsync } from '../../extensions.js'; import { deleteExtension, extensionNames, getContext, installExtension, renderExtensionTemplateAsync } from '../../extensions.js';
import { POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js'; import { POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js';

View File

@ -3,7 +3,7 @@
* By CncAnon (@CncAnon1) * By CncAnon (@CncAnon1)
* https://github.com/CncAnon1/TavernAITurbo * https://github.com/CncAnon1/TavernAITurbo
*/ */
import { Fuse } from '../lib.js'; import { Fuse, DOMPurify } from '../lib.js';
import { import {
abortStatusCheck, abortStatusCheck,

View File

@ -1,3 +1,4 @@
import { DOMPurify } from '../lib.js';
import { callPopup, getRequestHeaders } from '../script.js'; import { callPopup, getRequestHeaders } from '../script.js';
export const SECRET_KEYS = { export const SECRET_KEYS = {

View File

@ -1,4 +1,4 @@
import { Fuse } from '../lib.js'; import { Fuse, DOMPurify } from '../lib.js';
import { import {
Generate, Generate,

View File

@ -1,3 +1,4 @@
import { DOMPurify } from '../../lib.js';
import { sendSystemMessage, system_message_types } from '../../script.js'; import { sendSystemMessage, system_message_types } from '../../script.js';
import { callGenericPopup, POPUP_TYPE } from '../popup.js'; import { callGenericPopup, POPUP_TYPE } from '../popup.js';
import { escapeHtml } from '../utils.js'; import { escapeHtml } from '../utils.js';

View File

@ -1,3 +1,5 @@
import { DOMPurify } from '../lib.js';
import { import {
characters, characters,
saveSettingsDebounced, saveSettingsDebounced,

View File

@ -1,3 +1,4 @@
import { DOMPurify } from '../lib.js';
import { applyLocale } from './i18n.js'; import { applyLocale } from './i18n.js';
/** /**

View File

@ -1,3 +1,4 @@
import { DOMPurify } from '../lib.js';
import { isMobile } from './RossAscends-mods.js'; import { isMobile } from './RossAscends-mods.js';
import { amount_gen, callPopup, eventSource, event_types, getRequestHeaders, max_context, online_status, setGenerationParamsFromPreset } from '../script.js'; import { amount_gen, callPopup, eventSource, event_types, getRequestHeaders, max_context, online_status, setGenerationParamsFromPreset } from '../script.js';
import { textgenerationwebui_settings as textgen_settings, textgen_types } from './textgen-settings.js'; import { textgenerationwebui_settings as textgen_settings, textgen_types } from './textgen-settings.js';

View File

@ -1,3 +1,5 @@
import { DOMPurify } from '../lib.js';
import { addOneMessage, chat, event_types, eventSource, main_api, saveChatConditional, system_avatar, systemUserName } from '../script.js'; import { addOneMessage, chat, event_types, eventSource, main_api, saveChatConditional, system_avatar, systemUserName } from '../script.js';
import { chat_completion_sources, oai_settings } from './openai.js'; import { chat_completion_sources, oai_settings } from './openai.js';
import { Popup } from './popup.js'; import { Popup } from './popup.js';

View File

@ -1,3 +1,5 @@
import { DOMPurify } from '../lib.js';
import { getContext } from './extensions.js'; import { getContext } from './extensions.js';
import { characters, getRequestHeaders, this_chid } from '../script.js'; import { characters, getRequestHeaders, this_chid } from '../script.js';
import { isMobile } from './RossAscends-mods.js'; import { isMobile } from './RossAscends-mods.js';

View File

@ -4,12 +4,7 @@ export const publicLibConfig = {
entry: './public/lib.js', entry: './public/lib.js',
cache: true, cache: true,
devtool: 'source-map', devtool: 'source-map',
module: { module: {},
rules: [{
test: /\.js$/,
exclude: /node_modules/,
}],
},
experiments: { experiments: {
outputModule: true, outputModule: true,
}, },