mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 16:38:19 +01:00
72 lines
1.9 KiB
TypeScript
72 lines
1.9 KiB
TypeScript
import { stringifyEntitiesLight } from "stringify-entities";
|
|
import xss, { type IFilterXSSOptions } from "xss";
|
|
|
|
export const sanitizedHtmlStrip = (html: string) => {
|
|
return sanitizeHtml(html, {
|
|
whiteList: {},
|
|
});
|
|
};
|
|
|
|
export const sanitizeHtml = async (
|
|
html: string,
|
|
extraConfig?: IFilterXSSOptions,
|
|
) => {
|
|
const sanitizedHtml = xss(html, {
|
|
whiteList: {
|
|
a: ["href", "title", "target", "rel", "class"],
|
|
p: ["class"],
|
|
br: ["class"],
|
|
b: ["class"],
|
|
i: ["class"],
|
|
em: ["class"],
|
|
strong: ["class"],
|
|
del: ["class"],
|
|
code: ["class"],
|
|
u: ["class"],
|
|
pre: ["class"],
|
|
ul: ["class"],
|
|
ol: ["class"],
|
|
li: ["class"],
|
|
blockquote: ["class"],
|
|
},
|
|
stripIgnoreTag: false,
|
|
escapeHtml: (unsafeHtml) =>
|
|
stringifyEntitiesLight(unsafeHtml, {
|
|
escapeOnly: true,
|
|
}),
|
|
...extraConfig,
|
|
});
|
|
|
|
// Check text to only allow h-*, p-*, u-*, dt-*, e-*, mention, hashtag, ellipsis, invisible classes
|
|
const allowedClasses = [
|
|
"h-",
|
|
"p-",
|
|
"u-",
|
|
"dt-",
|
|
"e-",
|
|
"mention",
|
|
"hashtag",
|
|
"ellipsis",
|
|
"invisible",
|
|
];
|
|
|
|
return await new HTMLRewriter()
|
|
.on("*[class]", {
|
|
element(element) {
|
|
const classes = element.getAttribute("class")?.split(" ") ?? [];
|
|
|
|
for (const className of classes) {
|
|
if (
|
|
!allowedClasses.some((allowedClass) =>
|
|
className.startsWith(allowedClass),
|
|
)
|
|
) {
|
|
element.removeAttribute("class");
|
|
}
|
|
}
|
|
},
|
|
})
|
|
.transform(new Response(sanitizedHtml))
|
|
.text();
|
|
};
|