unvendor: Replace DOMPurify
| @@ -50,7 +50,6 @@ module.exports = { | ||
| 50 | 50 | }, |
| 51 | 51 | // These scripts are loaded in HTML; tell ESLint not to complain about them being undefined |
| 52 | 52 | globals: { |
| 53 | - DOMPurify: 'readonly', | |
| 54 | 53 | droll: 'readonly', |
| 55 | 54 | Handlebars: 'readonly', |
| 56 | 55 | hljs: 'readonly', |
| @@ -22,6 +22,7 @@ | ||
| 22 | 22 | "cookie-session": "^2.1.0", |
| 23 | 23 | "cors": "^2.8.5", |
| 24 | 24 | "csrf-csrf": "^2.2.3", |
| 25 | + "dompurify": "^3.1.7", | |
| 25 | 26 | "express": "^4.21.0", |
| 26 | 27 | "form-data": "^4.0.0", |
| 27 | 28 | "fuse.js": "^7.0.0", |
| @@ -68,7 +69,6 @@ | ||
| 68 | 69 | "@types/cookie-parser": "^1.4.7", |
| 69 | 70 | "@types/cookie-session": "^2.0.49", |
| 70 | 71 | "@types/cors": "^2.8.17", |
| 71 | - "@types/dompurify": "^3.0.5", | |
| 72 | 72 | "@types/express": "^4.17.21", |
| 73 | 73 | "@types/jquery": "^3.5.29", |
| 74 | 74 | "@types/lodash": "^4.17.10", |
| @@ -1174,16 +1174,6 @@ | ||
| 1174 | 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 | 1177 | "node_modules/@types/estree": { |
| 1188 | 1178 | "version": "1.0.6", |
| 1189 | 1179 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", |
| @@ -1427,13 +1417,6 @@ | ||
| 1427 | 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 | 1420 | "node_modules/@types/write-file-atomic": { |
| 1438 | 1421 | "version": "4.0.3", |
| 1439 | 1422 | "resolved": "https://registry.npmjs.org/@types/write-file-atomic/-/write-file-atomic-4.0.3.tgz", |
| @@ -3221,6 +3204,12 @@ | ||
| 3221 | 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 | 3213 | "node_modules/domutils": { |
| 3225 | 3214 | "version": "3.1.0", |
| 3226 | 3215 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", |
| @@ -12,6 +12,7 @@ | ||
| 12 | 12 | "cookie-session": "^2.1.0", |
| 13 | 13 | "cors": "^2.8.5", |
| 14 | 14 | "csrf-csrf": "^2.2.3", |
| 15 | + "dompurify": "^3.1.7", | |
| 15 | 16 | "express": "^4.21.0", |
| 16 | 17 | "form-data": "^4.0.0", |
| 17 | 18 | "fuse.js": "^7.0.0", |
| @@ -94,7 +95,6 @@ | ||
| 94 | 95 | "@types/cookie-parser": "^1.4.7", |
| 95 | 96 | "@types/cookie-session": "^2.0.49", |
| 96 | 97 | "@types/cors": "^2.8.17", |
| 97 | - "@types/dompurify": "^3.0.5", | |
| 98 | 98 | "@types/express": "^4.17.21", |
| 99 | 99 | "@types/jquery": "^3.5.29", |
| 100 | 100 | "@types/lodash": "^4.17.10", |
| @@ -16,6 +16,7 @@ declare var ai; | ||
| 16 | 16 | declare var SillyTavern: { |
| 17 | 17 | getContext(): any; |
| 18 | 18 | llm: any; |
| 19 | + libs: any; | |
| 19 | 20 | }; |
| 20 | 21 | |
| 21 | 22 | // Jquery plugins |
| @@ -3,7 +3,33 @@ | ||
| 3 | 3 | * They are bundled and exposed by Webpack in the /lib.js file. |
| 4 | 4 | */ |
| 5 | 5 | import Fuse from 'fuse.js'; |
| 6 | +import 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 | + */ | |
| 13 | +export 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 | + | |
| 27 | +export default { | |
| 28 | + Fuse, | |
| 29 | + DOMPurify, | |
| 30 | +}; | |
| 6 | 31 | |
| 7 | 32 | export { |
| 8 | 33 | Fuse, |
| 34 | + DOMPurify, | |
| 9 | 35 | }; |
| @@ -1,4 +1,4 @@ | ||
| 1 | 1 | import { Fuse, DOMPurify, initLibraryShims, default as libs } from './lib.js'; |
| 2 | 2 | |
| 3 | 3 | import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter, addSafariPatch } from './scripts/RossAscends-mods.js'; |
| 4 | 4 | import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js'; |
| @@ -410,6 +410,7 @@ DOMPurify.addHook('uponSanitizeElement', (node, _, config) => { | ||
| 410 | 410 | |
| 411 | 411 | // API OBJECT FOR EXTERNAL WIRING |
| 412 | 412 | window['SillyTavern'] = {}; |
| 413 | +window['SillyTavern'].libs = libs; | |
| 413 | 414 | |
| 414 | 415 | // Event source init |
| 415 | 416 | export const event_types = { |
| @@ -940,6 +941,7 @@ async function firstLoadInit() { | ||
| 940 | 941 | throw new Error('Initialization failed'); |
| 941 | 942 | } |
| 942 | 943 | |
| 944 | + initLibraryShims(); | |
| 943 | 945 | addSafariPatch(); |
| 944 | 946 | await getClientVersion(); |
| 945 | 947 | await readSecretState(); |
| @@ -2058,8 +2060,15 @@ export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, san | ||
| 2058 | 2060 | mes = mes.replace(new RegExp(`(^|\n)${escapeRegex(ch_name)}:`, 'g'), '$1'); |
| 2059 | 2061 | } |
| 2060 | 2062 | |
| 2061 | 2063 | /** @type {anyimport('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 | 2072 | mes = encodeStyleTags(mes); |
| 2064 | 2073 | mes = DOMPurify.sanitize(mes, config); |
| 2065 | 2074 | mes = decodeStyleTags(mes); |
| @@ -1,5 +1,7 @@ | ||
| 1 | 1 | 'use strict'; |
| 2 | 2 | |
| 3 | +import { DOMPurify } from '../lib.js'; | |
| 4 | + | |
| 3 | 5 | import { event_types, eventSource, is_send_press, main_api, substituteParams } from '../script.js'; |
| 4 | 6 | import { is_group_generating } from './group-chats.js'; |
| 5 | 7 | import { Message, TokenHandler } from './openai.js'; |
| @@ -1,3 +1,5 @@ | ||
| 1 | +import { DOMPurify } from '../lib.js'; | |
| 2 | + | |
| 1 | 3 | import { |
| 2 | 4 | characters, |
| 3 | 5 | online_status, |
| @@ -1,3 +1,5 @@ | ||
| 1 | +import { DOMPurify } from '../lib.js'; | |
| 2 | + | |
| 1 | 3 | import { eventSource, event_types, saveSettings, saveSettingsDebounced, getRequestHeaders, animation_duration } from '../script.js'; |
| 2 | 4 | import { showLoader } from './loader.js'; |
| 3 | 5 | import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js'; |
| @@ -3,6 +3,7 @@ TODO: | ||
| 3 | 3 | */ |
| 4 | 4 | //const DEBUG_TONY_SAMA_FORK_MODE = true |
| 5 | 5 | |
| 6 | +import { DOMPurify } from '../../../lib.js'; | |
| 6 | 7 | import { getRequestHeaders, processDroppedFiles, eventSource, event_types } from '../../../script.js'; |
| 7 | 8 | import { deleteExtension, extensionNames, getContext, installExtension, renderExtensionTemplateAsync } from '../../extensions.js'; |
| 8 | 9 | import { POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js'; |
| @@ -3,7 +3,7 @@ | ||
| 3 | 3 | * By CncAnon (@CncAnon1) |
| 4 | 4 | * https://github.com/CncAnon1/TavernAITurbo |
| 5 | 5 | */ |
| 6 | 6 | import { Fuse, DOMPurify } from '../lib.js'; |
| 7 | 7 | |
| 8 | 8 | import { |
| 9 | 9 | abortStatusCheck, |
| @@ -1,3 +1,4 @@ | ||
| 1 | +import { DOMPurify } from '../lib.js'; | |
| 1 | 2 | import { callPopup, getRequestHeaders } from '../script.js'; |
| 2 | 3 | |
| 3 | 4 | export const SECRET_KEYS = { |
| @@ -1,4 +1,4 @@ | ||
| 1 | 1 | import { Fuse, DOMPurify } from '../lib.js'; |
| 2 | 2 | |
| 3 | 3 | import { |
| 4 | 4 | Generate, |
| @@ -1,3 +1,4 @@ | ||
| 1 | +import { DOMPurify } from '../../lib.js'; | |
| 1 | 2 | import { sendSystemMessage, system_message_types } from '../../script.js'; |
| 2 | 3 | import { callGenericPopup, POPUP_TYPE } from '../popup.js'; |
| 3 | 4 | import { escapeHtml } from '../utils.js'; |
| @@ -1,3 +1,5 @@ | ||
| 1 | +import { DOMPurify } from '../lib.js'; | |
| 2 | + | |
| 1 | 3 | import { |
| 2 | 4 | characters, |
| 3 | 5 | saveSettingsDebounced, |
| @@ -1,3 +1,4 @@ | ||
| 1 | +import { DOMPurify } from '../lib.js'; | |
| 1 | 2 | import { applyLocale } from './i18n.js'; |
| 2 | 3 | |
| 3 | 4 | /** |
| @@ -1,3 +1,4 @@ | ||
| 1 | +import { DOMPurify } from '../lib.js'; | |
| 1 | 2 | import { isMobile } from './RossAscends-mods.js'; |
| 2 | 3 | import { amount_gen, callPopup, eventSource, event_types, getRequestHeaders, max_context, online_status, setGenerationParamsFromPreset } from '../script.js'; |
| 3 | 4 | import { textgenerationwebui_settings as textgen_settings, textgen_types } from './textgen-settings.js'; |
| @@ -1,3 +1,5 @@ | ||
| 1 | +import { DOMPurify } from '../lib.js'; | |
| 2 | + | |
| 1 | 3 | import { addOneMessage, chat, event_types, eventSource, main_api, saveChatConditional, system_avatar, systemUserName } from '../script.js'; |
| 2 | 4 | import { chat_completion_sources, oai_settings } from './openai.js'; |
| 3 | 5 | import { Popup } from './popup.js'; |
| @@ -1,3 +1,5 @@ | ||
| 1 | +import { DOMPurify } from '../lib.js'; | |
| 2 | + | |
| 1 | 3 | import { getContext } from './extensions.js'; |
| 2 | 4 | import { characters, getRequestHeaders, this_chid } from '../script.js'; |
| 3 | 5 | import { isMobile } from './RossAscends-mods.js'; |
| @@ -4,12 +4,7 @@ export const publicLibConfig = { | ||
| 4 | 4 | entry: './public/lib.js', |
| 5 | 5 | cache: true, |
| 6 | 6 | devtool: 'source-map', |
| 7 | 7 | module: {}, |
| 8 | - rules: [{ | |
| 9 | - test: /\.js$/, | |
| 10 | - exclude: /node_modules/, | |
| 11 | - }], | |
| 12 | - }, | |
| 13 | 8 | experiments: { |
| 14 | 9 | outputModule: true, |
| 15 | 10 | }, |