Skip to content

Instantly share code, notes, and snippets.

@johnhunter
Created April 17, 2022 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnhunter/b3f0e9d5096a3f0422d06f0a4201339b to your computer and use it in GitHub Desktop.
Save johnhunter/b3f0e9d5096a3f0422d06f0a4201339b to your computer and use it in GitHub Desktop.
Eleventy-load obfuscate for use with eleventy-load-html plugin
/**
* Escape RegExp special characters
*
* Inlined from escape-string-regexp@5.0.0 as we don't use ESM here.
*
* @see https://github.com/sindresorhus/escape-string-regexp
*
* @param {string} string
* @returns {RegEx}
*/
const escapeStringRegexp = (string) => {
if (typeof string !== 'string') {
throw new TypeError('Expected a string');
}
// Escape characters with special meaning either inside or outside character sets.
// Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar.
return string.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d');
};
/**
* Default obfuscator function transforms to html entities
*
* @param {string} str
* @returns {string}
*/
const toEntities = (str) =>
Array.from(str)
.map((char) => `&#${char.charCodeAt(0)};`)
.join('');
/**
* Eleventy-loader plugin to obfuscate given values in html output.
*
* This plugin rule should follow the eleventy-load-html loader to avoid entities being unescaped.
*
* @param {string} content
* @param {{ enabled?: boolean, values?:string[], obfuscator?: (s:string) => string }} options
* @returns {string}
*/
module.exports = function (content, options = {}) {
const { enabled, values = [], obfuscator = toEntities } = options;
if (!enabled) {
return content;
}
return values.reduce((acc, value) => {
const re = new RegExp(escapeStringRegexp(value), 'g');
acc = acc.replace(re, (match) => obfuscator(match));
return acc;
}, content);
};
//...
// eleventy-load configuration
// eleventyObfuscate loader should follow eleventyLoadHtml
{
test: /\.(html|md|njk)$/,
loaders: [
{
loader: eleventyLoadHtml,
options: {
minimize: isProduction ? {} : false,
},
},
{
loader: eleventyObfuscate,
options: {
values: obsfuscateValues,
enabled: true,
},
},
],
},
// ...
@johnhunter
Copy link
Author

The obsfuscateValues should be an array of strings to match. This assumes those value are known at build time (e.g. contact email defined in the site data. If you need to obfuscate page content then a complex solution would be required.

@johnhunter
Copy link
Author

@johnhunter
Copy link
Author

johnhunter commented Apr 17, 2022

Can do away with the regex and use replaceAll if you are using Node >= 15.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment