unvendor: Replace DOMPurify
| @@ -50,7 +50,6 @@ module.exports = { | |||
| 50 | }, | 50 | }, |
| 51 | // These scripts are loaded in HTML; tell ESLint not to complain about them being undefined | 51 | // 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', |
| @@ -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", |
| @@ -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", |
| @@ -16,6 +16,7 @@ declare var ai; | |||
| 16 | declare var SillyTavern: { | 16 | declare var SillyTavern: { |
| 17 | getContext(): any; | 17 | getContext(): any; |
| 18 | llm: any; | 18 | llm: any; |
| 19 | libs: any; | ||
| 19 | }; | 20 | }; |
| 20 | 21 | ||
| 21 | // Jquery plugins | 22 | // Jquery plugins |
| @@ -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 | */ |
| 5 | import Fuse from 'fuse.js'; | 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 | export { | 32 | export { |
| 8 | Fuse, | 33 | Fuse, |
| 34 | DOMPurify, | ||
| 9 | }; | 35 | }; |
| @@ -1,4 +1,4 @@ | |||
| 1 | import { Fuse } from './lib.js'; | 1 | import { Fuse, DOMPurify, initLibraryShims, default as libs } from './lib.js'; |
| 2 | 2 | ||
| 3 | import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter, addSafariPatch } from './scripts/RossAscends-mods.js'; | 3 | import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter, addSafariPatch } from './scripts/RossAscends-mods.js'; |
| 4 | import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js'; | 4 | import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js'; |
| @@ -410,6 +410,7 @@ DOMPurify.addHook('uponSanitizeElement', (node, _, config) => { | |||
| 410 | 410 | ||
| 411 | // API OBJECT FOR EXTERNAL WIRING | 411 | // API OBJECT FOR EXTERNAL WIRING |
| 412 | window['SillyTavern'] = {}; | 412 | window['SillyTavern'] = {}; |
| 413 | window['SillyTavern'].libs = libs; | ||
| 413 | 414 | ||
| 414 | // Event source init | 415 | // Event source init |
| 415 | export const event_types = { | 416 | export const event_types = { |
| @@ -940,6 +941,7 @@ async function firstLoadInit() { | |||
| 940 | throw new Error('Initialization failed'); | 941 | throw new Error('Initialization failed'); |
| 941 | } | 942 | } |
| 942 | 943 | ||
| 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 | } |
| 2060 | 2062 | ||
| 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); |
| @@ -1,5 +1,7 @@ | |||
| 1 | 'use strict'; | 1 | 'use strict'; |
| 2 | 2 | ||
| 3 | import { DOMPurify } from '../lib.js'; | ||
| 4 | |||
| 3 | import { event_types, eventSource, is_send_press, main_api, substituteParams } from '../script.js'; | 5 | import { event_types, eventSource, is_send_press, main_api, substituteParams } from '../script.js'; |
| 4 | import { is_group_generating } from './group-chats.js'; | 6 | import { is_group_generating } from './group-chats.js'; |
| 5 | import { Message, TokenHandler } from './openai.js'; | 7 | import { Message, TokenHandler } from './openai.js'; |
| @@ -1,3 +1,5 @@ | |||
| 1 | import { DOMPurify } from '../lib.js'; | ||
| 2 | |||
| 1 | import { | 3 | import { |
| 2 | characters, | 4 | characters, |
| 3 | online_status, | 5 | online_status, |
| @@ -1,3 +1,5 @@ | |||
| 1 | import { DOMPurify } from '../lib.js'; | ||
| 2 | |||
| 1 | import { eventSource, event_types, saveSettings, saveSettingsDebounced, getRequestHeaders, animation_duration } from '../script.js'; | 3 | import { eventSource, event_types, saveSettings, saveSettingsDebounced, getRequestHeaders, animation_duration } from '../script.js'; |
| 2 | import { showLoader } from './loader.js'; | 4 | import { showLoader } from './loader.js'; |
| 3 | import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js'; | 5 | import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js'; |
| @@ -3,6 +3,7 @@ TODO: | |||
| 3 | */ | 3 | */ |
| 4 | //const DEBUG_TONY_SAMA_FORK_MODE = true | 4 | //const DEBUG_TONY_SAMA_FORK_MODE = true |
| 5 | 5 | ||
| 6 | import { DOMPurify } from '../../../lib.js'; | ||
| 6 | import { getRequestHeaders, processDroppedFiles, eventSource, event_types } from '../../../script.js'; | 7 | import { getRequestHeaders, processDroppedFiles, eventSource, event_types } from '../../../script.js'; |
| 7 | import { deleteExtension, extensionNames, getContext, installExtension, renderExtensionTemplateAsync } from '../../extensions.js'; | 8 | import { deleteExtension, extensionNames, getContext, installExtension, renderExtensionTemplateAsync } from '../../extensions.js'; |
| 8 | import { POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js'; | 9 | import { POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js'; |
| @@ -3,7 +3,7 @@ | |||
| 3 | * By CncAnon (@CncAnon1) | 3 | * By CncAnon (@CncAnon1) |
| 4 | * https://github.com/CncAnon1/TavernAITurbo | 4 | * https://github.com/CncAnon1/TavernAITurbo |
| 5 | */ | 5 | */ |
| 6 | import { Fuse } from '../lib.js'; | 6 | import { Fuse, DOMPurify } from '../lib.js'; |
| 7 | 7 | ||
| 8 | import { | 8 | import { |
| 9 | abortStatusCheck, | 9 | abortStatusCheck, |
| @@ -1,3 +1,4 @@ | |||
| 1 | import { DOMPurify } from '../lib.js'; | ||
| 1 | import { callPopup, getRequestHeaders } from '../script.js'; | 2 | import { callPopup, getRequestHeaders } from '../script.js'; |
| 2 | 3 | ||
| 3 | export const SECRET_KEYS = { | 4 | export const SECRET_KEYS = { |
| @@ -1,4 +1,4 @@ | |||
| 1 | import { Fuse } from '../lib.js'; | 1 | import { Fuse, DOMPurify } from '../lib.js'; |
| 2 | 2 | ||
| 3 | import { | 3 | import { |
| 4 | Generate, | 4 | Generate, |
| @@ -1,3 +1,4 @@ | |||
| 1 | import { DOMPurify } from '../../lib.js'; | ||
| 1 | import { sendSystemMessage, system_message_types } from '../../script.js'; | 2 | import { sendSystemMessage, system_message_types } from '../../script.js'; |
| 2 | import { callGenericPopup, POPUP_TYPE } from '../popup.js'; | 3 | import { callGenericPopup, POPUP_TYPE } from '../popup.js'; |
| 3 | import { escapeHtml } from '../utils.js'; | 4 | import { escapeHtml } from '../utils.js'; |
| @@ -1,3 +1,5 @@ | |||
| 1 | import { DOMPurify } from '../lib.js'; | ||
| 2 | |||
| 1 | import { | 3 | import { |
| 2 | characters, | 4 | characters, |
| 3 | saveSettingsDebounced, | 5 | saveSettingsDebounced, |
| @@ -1,3 +1,4 @@ | |||
| 1 | import { DOMPurify } from '../lib.js'; | ||
| 1 | import { applyLocale } from './i18n.js'; | 2 | import { applyLocale } from './i18n.js'; |
| 2 | 3 | ||
| 3 | /** | 4 | /** |
| @@ -1,3 +1,4 @@ | |||
| 1 | import { DOMPurify } from '../lib.js'; | ||
| 1 | import { isMobile } from './RossAscends-mods.js'; | 2 | import { isMobile } from './RossAscends-mods.js'; |
| 2 | import { amount_gen, callPopup, eventSource, event_types, getRequestHeaders, max_context, online_status, setGenerationParamsFromPreset } from '../script.js'; | 3 | import { amount_gen, callPopup, eventSource, event_types, getRequestHeaders, max_context, online_status, setGenerationParamsFromPreset } from '../script.js'; |
| 3 | import { textgenerationwebui_settings as textgen_settings, textgen_types } from './textgen-settings.js'; | 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 | import { addOneMessage, chat, event_types, eventSource, main_api, saveChatConditional, system_avatar, systemUserName } from '../script.js'; | 3 | import { addOneMessage, chat, event_types, eventSource, main_api, saveChatConditional, system_avatar, systemUserName } from '../script.js'; |
| 2 | import { chat_completion_sources, oai_settings } from './openai.js'; | 4 | import { chat_completion_sources, oai_settings } from './openai.js'; |
| 3 | import { Popup } from './popup.js'; | 5 | import { Popup } from './popup.js'; |
| @@ -1,3 +1,5 @@ | |||
| 1 | import { DOMPurify } from '../lib.js'; | ||
| 2 | |||
| 1 | import { getContext } from './extensions.js'; | 3 | import { getContext } from './extensions.js'; |
| 2 | import { characters, getRequestHeaders, this_chid } from '../script.js'; | 4 | import { characters, getRequestHeaders, this_chid } from '../script.js'; |
| 3 | import { isMobile } from './RossAscends-mods.js'; | 5 | import { isMobile } from './RossAscends-mods.js'; |
| @@ -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 | }, |