Files
klz-cables.com/.pnpm-store/v10/files/a1/a99705816a3b11608da2b728cdaff0f730160ee31cda0eaa22d19381249ba033f00d75121a9882e12ecf91902070bac5000ef5c0e28c60549818c0a00f62ba
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

57 lines
2.6 KiB
Plaintext

/**
* Sanitizes user data for emails to prevent injection of HTML, executable code, or other malicious content.
* This function ensures the content is safe by:
* - Removing HTML tags
* - Removing control characters
* - Normalizing whitespace
* - Escaping special HTML characters
* - Allowing only letters, numbers, spaces, and basic punctuation
* - Limiting length (default 100 characters)
*
* @param data - data to sanitize
* @param maxLength - maximum allowed length (default is 100)
* @returns a sanitized string safe to include in email content
*/ export function sanitizeUserDataForEmail(data, maxLength = 100) {
if (typeof data !== 'string') {
return '';
}
// Decode HTML numeric entities like < or <
const decodedEntities = data.replace(/&#x([0-9a-fA-F]+);/g, (_, hex)=>String.fromCharCode(parseInt(hex, 16))).replace(/&#(\d+);/g, (_, dec)=>String.fromCharCode(parseInt(dec, 10)));
// Remove HTML tags
const noTags = decodedEntities.replace(/<[^>]+>/g, '');
const noInvisible = noTags.replace(/[\u200B-\u200F\u2028-\u202F\u2060-\u206F\uFEFF]/g, '');
// Remove control characters except common whitespace
const noControls = [
...noInvisible
].filter((char)=>{
const code = char.charCodeAt(0);
return code >= 32 || // printable and above
code === 9 || // tab
code === 10 || // new line
code === 13 // return
;
}).join('');
// Remove '(?' and backticks `
let noInjectionSyntax = noControls.replace(/\(\?/g, '').replace(/`/g, '');
// {{...}} remove braces but keep inner content
noInjectionSyntax = noInjectionSyntax.replace(/\{\{(.*?)\}\}/g, '$1');
// Escape special HTML characters
const escaped = noInjectionSyntax.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
// Normalize whitespace to single space
const normalizedWhitespace = escaped.replace(/\s+/g, ' ');
// Allow:
// - Unicode letters (\p{L})
// - Unicode numbers (\p{N})
// - Unicode marks (\p{M}, e.g. accents)
// - Unicode spaces (\p{Zs})
// - Punctuation: common ascii + inverted ! and ?
const allowedPunctuation = " .,!?'" + '"¡¿、!()〆-';
// Escape regex special characters
const escapedPunct = allowedPunctuation.replace(/[[\]\\^$*+?.()|{}]/g, '\\$&');
const pattern = `[^\\p{L}\\p{N}\\p{M}\\p{Zs}${escapedPunct}]`;
const cleaned = normalizedWhitespace.replace(new RegExp(pattern, 'gu'), '');
// Trim and limit length, trim again to remove trailing spaces
return cleaned.slice(0, maxLength).trim();
}
//# sourceMappingURL=sanitizeUserDataForEmail.js.map