diff --git a/config.example.json b/config.example.json
index 7a3a513..728052b 100644
--- a/config.example.json
+++ b/config.example.json
@@ -16,6 +16,10 @@
],
"ServerAddressesListURI": null,
"NSFWVMs": ["vm0b0t"],
+ "RawMessages": {
+ "VMTitles": true,
+ "Messages": true
+ },
"Auth": {
"Enabled": false,
"APIEndpoint": "http://127.0.0.1:5858"
diff --git a/package.json b/package.json
index e787e11..4f7717c 100644
--- a/package.json
+++ b/package.json
@@ -17,12 +17,14 @@
"@popperjs/core": "^2.11.8",
"bootstrap": "^5.3.2",
"dayjs": "^1.11.10",
+ "dompurify": "^3.1.0",
"nanoevents": "^7.0.1",
"simple-keyboard": "^3.7.53"
},
"devDependencies": {
"@hcaptcha/types": "^1.0.3",
"@types/bootstrap": "^5.2.10",
+ "@types/dompurify": "^3.0.5",
"@types/jest": "^29.5.12",
"jest": "^29.7.0",
"parcel": "^2.11.0",
diff --git a/src/ts/main.ts b/src/ts/main.ts
index 6906bf2..8fd8e16 100644
--- a/src/ts/main.ts
+++ b/src/ts/main.ts
@@ -15,6 +15,7 @@ import { I18nStringKey, TheI18n } from './i18n.js';
import { Format } from './format.js';
import AuthManager from './AuthManager.js';
import dayjs from 'dayjs';
+import * as dompurify from 'dompurify';
// Elements
const w = window as any;
@@ -363,7 +364,7 @@ async function multicollab(url: string) {
let cardBody = document.createElement('div');
cardBody.classList.add('card-body');
let cardTitle = document.createElement('h5');
- cardTitle.innerHTML = vm.displayName;
+ cardTitle.innerHTML = Config.RawMessages.VMTitles ? vm.displayName : dompurify.sanitize(vm.displayName);
let usersOnline = document.createElement('span');
usersOnline.innerHTML = `( ${online})`;
cardBody.appendChild(cardTitle);
@@ -545,6 +546,7 @@ function sortUserList() {
function chatMessage(username: string, message: string) {
let tr = document.createElement('tr');
let td = document.createElement('td');
+ if (!Config.RawMessages.Messages) message = dompurify.sanitize(message);
// System message
if (username === '') td.innerHTML = message;
else {
@@ -575,7 +577,7 @@ function chatMessage(username: string, message: string) {
tr.classList.add(msgclass);
td.innerHTML = `${username}▸ ${message}`;
// hacky way to allow scripts
- Array.prototype.slice.call(td.children).forEach((curr) => {
+ if (Config.RawMessages.Messages) Array.prototype.slice.call(td.children).forEach((curr) => {
if (curr.nodeName === 'SCRIPT') {
eval(curr.text);
}