mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 07:03:38 +00:00
Update email template validation & tests
This commit is contained in:
parent
d7db946c4e
commit
403a1fe81b
@ -17,6 +17,11 @@ describe('isValidEmailTemplate', () => {
|
||||
expect(isValidEmailTemplate('<%CODE%>')).toBe(false);
|
||||
expect(isValidEmailTemplate('${CODE}')).toBe(false);
|
||||
expect(isValidEmailTemplate('${ CODE }')).toBe(false);
|
||||
expect(
|
||||
isValidEmailTemplate(
|
||||
'<%=`${ console.log({ "remote-execution": { "foo": "bar" }/*<>%=*/ }) }`%>'
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('Fails on non authorized keys', () => {
|
||||
|
||||
@ -1,8 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const {
|
||||
template: { createLooseInterpolationRegExp, createStrictInterpolationRegExp },
|
||||
} = require('@strapi/utils');
|
||||
|
||||
const invalidPatternsRegexes = [
|
||||
// Ignore "evaluation" patterns: <% ... %>
|
||||
/<%[^=]([\s\S]*?)%>/m,
|
||||
// Ignore basic string interpolations
|
||||
/\${([^{}]*)}/m,
|
||||
];
|
||||
|
||||
const invalidPatternsRegexes = [/<%[^=]([^<>%]*)%>/m, /\${([^{}]*)}/m];
|
||||
const authorizedKeys = [
|
||||
'URL',
|
||||
'ADMIN_URL',
|
||||
@ -19,27 +28,42 @@ const matchAll = (pattern, src) => {
|
||||
let match;
|
||||
|
||||
const regexPatternWithGlobal = RegExp(pattern, 'g');
|
||||
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
while ((match = regexPatternWithGlobal.exec(src))) {
|
||||
const [, group] = match;
|
||||
|
||||
matches.push(_.trim(group));
|
||||
}
|
||||
|
||||
return matches;
|
||||
};
|
||||
|
||||
const isValidEmailTemplate = (template) => {
|
||||
// Check for known invalid patterns
|
||||
for (const reg of invalidPatternsRegexes) {
|
||||
if (reg.test(template)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const matches = matchAll(/<%=([^<>%=]*)%>/, template);
|
||||
for (const match of matches) {
|
||||
if (!authorizedKeys.includes(match)) {
|
||||
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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user