Files
klz-cables.com/.pnpm-store/v10/files/b3/52bb9711a822da4d9b1f8b12c8d80b67b3ed68102ebeaff8cf2f040768dfa304482f381be5d1ac528e9e3ccfe020b6b604397ebd198895d85afa63d431972f
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

1 line
4.3 KiB
Plaintext

{"version":3,"sources":["../../src/utilities/sanitizeUserDataForEmail.ts"],"sourcesContent":["/**\n * Sanitizes user data for emails to prevent injection of HTML, executable code, or other malicious content.\n * This function ensures the content is safe by:\n * - Removing HTML tags\n * - Removing control characters\n * - Normalizing whitespace\n * - Escaping special HTML characters\n * - Allowing only letters, numbers, spaces, and basic punctuation\n * - Limiting length (default 100 characters)\n *\n * @param data - data to sanitize\n * @param maxLength - maximum allowed length (default is 100)\n * @returns a sanitized string safe to include in email content\n */\nexport function sanitizeUserDataForEmail(data: unknown, maxLength = 100): string {\n if (typeof data !== 'string') {\n return ''\n }\n\n // Decode HTML numeric entities like &#x3C; or &#60;\n const decodedEntities = data\n .replace(/&#x([0-9a-fA-F]+);/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/&#(\\d+);/g, (_, dec) => String.fromCharCode(parseInt(dec, 10)))\n\n // Remove HTML tags\n const noTags = decodedEntities.replace(/<[^>]+>/g, '')\n\n const noInvisible = noTags.replace(/[\\u200B-\\u200F\\u2028-\\u202F\\u2060-\\u206F\\uFEFF]/g, '')\n\n // Remove control characters except common whitespace\n const noControls = [...noInvisible]\n .filter((char) => {\n const code = char.charCodeAt(0)\n return (\n code >= 32 || // printable and above\n code === 9 || // tab\n code === 10 || // new line\n code === 13 // return\n )\n })\n .join('')\n\n // Remove '(?' and backticks `\n let noInjectionSyntax = noControls.replace(/\\(\\?/g, '').replace(/`/g, '')\n\n // {{...}} remove braces but keep inner content\n noInjectionSyntax = noInjectionSyntax.replace(/\\{\\{(.*?)\\}\\}/g, '$1')\n\n // Escape special HTML characters\n const escaped = noInjectionSyntax\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n\n // Normalize whitespace to single space\n const normalizedWhitespace = escaped.replace(/\\s+/g, ' ')\n\n // Allow:\n // - Unicode letters (\\p{L})\n // - Unicode numbers (\\p{N})\n // - Unicode marks (\\p{M}, e.g. accents)\n // - Unicode spaces (\\p{Zs})\n // - Punctuation: common ascii + inverted ! and ?\n const allowedPunctuation = \" .,!?'\" + '\"¡¿、!()〆-'\n\n // Escape regex special characters\n const escapedPunct = allowedPunctuation.replace(/[[\\]\\\\^$*+?.()|{}]/g, '\\\\$&')\n\n const pattern = `[^\\\\p{L}\\\\p{N}\\\\p{M}\\\\p{Zs}${escapedPunct}]`\n\n const cleaned = normalizedWhitespace.replace(new RegExp(pattern, 'gu'), '')\n\n // Trim and limit length, trim again to remove trailing spaces\n return cleaned.slice(0, maxLength).trim()\n}\n"],"names":["sanitizeUserDataForEmail","data","maxLength","decodedEntities","replace","_","hex","String","fromCharCode","parseInt","dec","noTags","noInvisible","noControls","filter","char","code","charCodeAt","join","noInjectionSyntax","escaped","normalizedWhitespace","allowedPunctuation","escapedPunct","pattern","cleaned","RegExp","slice","trim"],"mappings":"AAAA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASA,yBAAyBC,IAAa,EAAEC,YAAY,GAAG;IACrE,IAAI,OAAOD,SAAS,UAAU;QAC5B,OAAO;IACT;IAEA,oDAAoD;IACpD,MAAME,kBAAkBF,KACrBG,OAAO,CAAC,uBAAuB,CAACC,GAAGC,MAAQC,OAAOC,YAAY,CAACC,SAASH,KAAK,MAC7EF,OAAO,CAAC,aAAa,CAACC,GAAGK,MAAQH,OAAOC,YAAY,CAACC,SAASC,KAAK;IAEtE,mBAAmB;IACnB,MAAMC,SAASR,gBAAgBC,OAAO,CAAC,YAAY;IAEnD,MAAMQ,cAAcD,OAAOP,OAAO,CAAC,oDAAoD;IAEvF,qDAAqD;IACrD,MAAMS,aAAa;WAAID;KAAY,CAChCE,MAAM,CAAC,CAACC;QACP,MAAMC,OAAOD,KAAKE,UAAU,CAAC;QAC7B,OACED,QAAQ,MAAM,sBAAsB;QACpCA,SAAS,KAAK,MAAM;QACpBA,SAAS,MAAM,WAAW;QAC1BA,SAAS,GAAG,SAAS;;IAEzB,GACCE,IAAI,CAAC;IAER,8BAA8B;IAC9B,IAAIC,oBAAoBN,WAAWT,OAAO,CAAC,SAAS,IAAIA,OAAO,CAAC,MAAM;IAEtE,+CAA+C;IAC/Ce,oBAAoBA,kBAAkBf,OAAO,CAAC,kBAAkB;IAEhE,iCAAiC;IACjC,MAAMgB,UAAUD,kBACbf,OAAO,CAAC,MAAM,SACdA,OAAO,CAAC,MAAM,QACdA,OAAO,CAAC,MAAM;IAEjB,uCAAuC;IACvC,MAAMiB,uBAAuBD,QAAQhB,OAAO,CAAC,QAAQ;IAErD,SAAS;IACT,4BAA4B;IAC5B,4BAA4B;IAC5B,wCAAwC;IACxC,4BAA4B;IAC5B,iDAAiD;IACjD,MAAMkB,qBAAqB,WAAW;IAEtC,kCAAkC;IAClC,MAAMC,eAAeD,mBAAmBlB,OAAO,CAAC,uBAAuB;IAEvE,MAAMoB,UAAU,CAAC,2BAA2B,EAAED,aAAa,CAAC,CAAC;IAE7D,MAAME,UAAUJ,qBAAqBjB,OAAO,CAAC,IAAIsB,OAAOF,SAAS,OAAO;IAExE,8DAA8D;IAC9D,OAAOC,QAAQE,KAAK,CAAC,GAAGzB,WAAW0B,IAAI;AACzC"}