75 lines
1.8 KiB
JavaScript
Raw Permalink Normal View History

'use strict';
2023-01-10 10:34:49 +01:00
const { trim } = require('lodash/fp');
const {
template: { createLooseInterpolationRegExp, createStrictInterpolationRegExp },
} = require('@strapi/utils');
const invalidPatternsRegexes = [
// Ignore "evaluation" patterns: <% ... %>
/<%[^=]([\s\S]*?)%>/m,
// Ignore basic string interpolations
/\${([^{}]*)}/m,
];
const authorizedKeys = [
'URL',
2022-03-21 11:04:54 +01:00
'ADMIN_URL',
'SERVER_URL',
'CODE',
'USER',
'USER.email',
'USER.username',
'TOKEN',
];
const matchAll = (pattern, src) => {
const matches = [];
let match;
const regexPatternWithGlobal = RegExp(pattern, 'g');
2022-08-08 23:33:39 +02:00
// eslint-disable-next-line no-cond-assign
while ((match = regexPatternWithGlobal.exec(src))) {
const [, group] = match;
2023-01-10 10:34:49 +01:00
matches.push(trim(group));
}
return matches;
};
2022-08-08 23:33:39 +02:00
const isValidEmailTemplate = (template) => {
// Check for known invalid patterns
2022-08-08 15:50:34 +02:00
for (const reg of invalidPatternsRegexes) {
if (reg.test(template)) {
return false;
}
}
const interpolation = {
// Strict interpolation pattern to match only valid groups
strict: createStrictInterpolationRegExp(authorizedKeys),
// Weak interpolation pattern to match as many group as possible.
loose: createLooseInterpolationRegExp(),
};
// Compute both strict & loose matches
const strictMatches = matchAll(interpolation.strict, template);
const looseMatches = matchAll(interpolation.loose, template);
// If we have more matches with the loose RegExp than with the strict one,
// then it means that at least one of the interpolation group is invalid
// Note: In the future, if we wanted to give more details for error formatting
// purposes, we could return the difference between the two arrays
if (looseMatches.length > strictMatches.length) {
return false;
}
return true;
};
module.exports = {
isValidEmailTemplate,
};