phx-node
Version:
PHX NODE
75 lines • 3.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PHXEmailRenderToHTML = exports.PHXAllowTags = void 0;
const liquidjs_1 = require("liquidjs");
/**
* Sử dụng để validate html không sử dụng style, class, event
* @param html
*/
const PHXAllowTags = (html) => {
const allowedTags = ["p", "b", "i", "a", "br", "img"];
const tagRegex = /<\/?([a-zA-Z0-9]+)(\s[^>]*)?>/g;
let match;
while ((match = tagRegex.exec(html)) !== null) {
const [fullMatch, tagName, attrs = ""] = match;
const lowerTag = tagName.toLowerCase();
if (fullMatch.startsWith("</"))
continue;
if (!allowedTags.includes(lowerTag)) {
throw new Error(`Tag <${lowerTag}> is not allowed`);
}
const cleanedAttrs = attrs.trim();
// chặn class cho TẤT CẢ (bao gồm img)
if (/class\s*=/i.test(cleanedAttrs)) {
throw new Error(`Tag <${lowerTag}> cannot have class attribute`);
}
// chặn event cho tất cả
if (/on[a-z]+\s*=/i.test(cleanedAttrs)) {
throw new Error(`Tag <${lowerTag}> contains forbidden event attribute`);
}
// chặn style với tất cả trừ img
if (lowerTag !== "img" && /\bstyle\s*=/i.test(cleanedAttrs)) {
throw new Error(`Tag <${lowerTag}> cannot have style attribute`);
}
if (lowerTag === "a") {
const hrefMatch = cleanedAttrs === null || cleanedAttrs === void 0 ? void 0 : cleanedAttrs.match(/\bhref\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i);
if (!hrefMatch) {
throw new Error(`<a> tag must have valid href`);
}
}
if (lowerTag === "img") {
const cleanedAttrs = attrs === null || attrs === void 0 ? void 0 : attrs.trim();
const srcMatch = cleanedAttrs === null || cleanedAttrs === void 0 ? void 0 : cleanedAttrs.match(/\bsrc\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i);
if (!srcMatch) {
throw new Error(`<img> tag must have valid src`);
}
}
if (attrs && lowerTag !== "a" && lowerTag !== "img") {
const cleanedAttrs = attrs.trim();
if (cleanedAttrs) {
throw new Error(`Tag <${lowerTag}> should not have attributes`);
}
}
}
return html;
};
exports.PHXAllowTags = PHXAllowTags;
/**
* Sử dụng để validate html và thay thế các giá trị trong html ví dụ <p>{{name}}</p>
* @param html | html cần thay thế
* @param obj | object cần thay thế vào html
*/
const PHXEmailRenderToHTML = (html, obj) => {
const htmlSanitize = (0, exports.PHXAllowTags)(html);
const validatedValue = {};
for (const [key, value] of Object.entries(obj)) {
validatedValue[key] = (0, exports.PHXAllowTags)(value);
}
const liquid = new liquidjs_1.Liquid({
strictVariables: true,
strictFilters: true,
});
return liquid.parseAndRenderSync(htmlSanitize, validatedValue);
};
exports.PHXEmailRenderToHTML = PHXEmailRenderToHTML;
//# sourceMappingURL=email-render-to-HTML.js.map