55 lines
1.9 KiB
JavaScript
55 lines
1.9 KiB
JavaScript
import sanitizeHtml from "sanitize-html";
|
|
import { readLiveSchema } from "../functions/live-schema";
|
|
import getSanitizeHtmlOptions from "./sanitize-html-options";
|
|
function grabTableFields(tableName) {
|
|
const dbSchema = global.DB_SCHEMA || readLiveSchema();
|
|
const tableSchema = dbSchema?.tables?.find((t) => t.tableName === tableName);
|
|
return tableSchema?.fields || [];
|
|
}
|
|
/**
|
|
* Only fields with an explicit `html: true` flag are sanitized.
|
|
* Missing / falsy / non-true values are never sanitized.
|
|
*/
|
|
function isExplicitHtmlField(field) {
|
|
return field?.html === true;
|
|
}
|
|
function sanitizeValue(value, config) {
|
|
if (typeof value !== "string") {
|
|
return value;
|
|
}
|
|
return sanitizeHtml(value, getSanitizeHtmlOptions(config));
|
|
}
|
|
/**
|
|
* Sanitize string values ONLY for schema fields with explicit `html: true`.
|
|
* Other fields (including plain text that happens to contain HTML) are left untouched.
|
|
*/
|
|
export default function sanitizeHtmlFields({ table, data, config, }) {
|
|
const fields = grabTableFields(table);
|
|
if (fields.length === 0) {
|
|
return data;
|
|
}
|
|
const htmlFieldNames = new Set(fields
|
|
.filter(isExplicitHtmlField)
|
|
.map((f) => f.fieldName)
|
|
.filter((name) => Boolean(name)));
|
|
// No explicitly marked html fields on this table — skip entirely
|
|
if (htmlFieldNames.size === 0) {
|
|
return data;
|
|
}
|
|
const sanitized = { ...data };
|
|
const resolvedConfig = config || global.CONFIG;
|
|
for (const key of Object.keys(sanitized)) {
|
|
// Only sanitize keys that map to fields with html: true
|
|
if (!htmlFieldNames.has(key))
|
|
continue;
|
|
sanitized[key] = sanitizeValue(sanitized[key], resolvedConfig);
|
|
}
|
|
return sanitized;
|
|
}
|
|
/**
|
|
* Sanitize an array of row objects for insert.
|
|
*/
|
|
export function sanitizeHtmlFieldsBatch({ table, data, config, }) {
|
|
return data.map((row) => sanitizeHtmlFields({ table, data: row, config }));
|
|
}
|