@strapi/plugin-users-permissions 4.5.5 → 4.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/plugin-users-permissions",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.6",
|
|
4
4
|
"description": "Protect your API with a full-authentication process based on JWT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@strapi/helper-plugin": "4.5.
|
|
31
|
-
"@strapi/utils": "4.5.
|
|
30
|
+
"@strapi/helper-plugin": "4.5.6",
|
|
31
|
+
"@strapi/utils": "4.5.6",
|
|
32
32
|
"bcryptjs": "2.4.3",
|
|
33
33
|
"grant-koa": "5.4.8",
|
|
34
|
-
"jsonwebtoken": "
|
|
34
|
+
"jsonwebtoken": "9.0.0",
|
|
35
35
|
"koa": "^2.13.4",
|
|
36
36
|
"koa2-ratelimit": "^1.1.2",
|
|
37
37
|
"lodash": "4.17.21",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"required": true,
|
|
65
65
|
"kind": "plugin"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "d36609ff26fb4e00a41a7e2b657f16c7466203fe"
|
|
68
68
|
}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { trim } = require('lodash/fp');
|
|
4
|
+
const {
|
|
5
|
+
template: { createLooseInterpolationRegExp, createStrictInterpolationRegExp },
|
|
6
|
+
} = require('@strapi/utils');
|
|
7
|
+
|
|
8
|
+
const invalidPatternsRegexes = [
|
|
9
|
+
// Ignore "evaluation" patterns: <% ... %>
|
|
10
|
+
/<%[^=]([\s\S]*?)%>/m,
|
|
11
|
+
// Ignore basic string interpolations
|
|
12
|
+
/\${([^{}]*)}/m,
|
|
13
|
+
];
|
|
4
14
|
|
|
5
|
-
const invalidPatternsRegexes = [/<%[^=]([^<>%]*)%>/m, /\${([^{}]*)}/m];
|
|
6
15
|
const authorizedKeys = [
|
|
7
16
|
'URL',
|
|
8
17
|
'ADMIN_URL',
|
|
@@ -19,27 +28,42 @@ const matchAll = (pattern, src) => {
|
|
|
19
28
|
let match;
|
|
20
29
|
|
|
21
30
|
const regexPatternWithGlobal = RegExp(pattern, 'g');
|
|
31
|
+
|
|
22
32
|
// eslint-disable-next-line no-cond-assign
|
|
23
33
|
while ((match = regexPatternWithGlobal.exec(src))) {
|
|
24
34
|
const [, group] = match;
|
|
25
35
|
|
|
26
|
-
matches.push(
|
|
36
|
+
matches.push(trim(group));
|
|
27
37
|
}
|
|
38
|
+
|
|
28
39
|
return matches;
|
|
29
40
|
};
|
|
30
41
|
|
|
31
42
|
const isValidEmailTemplate = (template) => {
|
|
43
|
+
// Check for known invalid patterns
|
|
32
44
|
for (const reg of invalidPatternsRegexes) {
|
|
33
45
|
if (reg.test(template)) {
|
|
34
46
|
return false;
|
|
35
47
|
}
|
|
36
48
|
}
|
|
37
49
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
const interpolation = {
|
|
51
|
+
// Strict interpolation pattern to match only valid groups
|
|
52
|
+
strict: createStrictInterpolationRegExp(authorizedKeys),
|
|
53
|
+
// Weak interpolation pattern to match as many group as possible.
|
|
54
|
+
loose: createLooseInterpolationRegExp(),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Compute both strict & loose matches
|
|
58
|
+
const strictMatches = matchAll(interpolation.strict, template);
|
|
59
|
+
const looseMatches = matchAll(interpolation.loose, template);
|
|
60
|
+
|
|
61
|
+
// If we have more matches with the loose RegExp than with the strict one,
|
|
62
|
+
// then it means that at least one of the interpolation group is invalid
|
|
63
|
+
// Note: In the future, if we wanted to give more details for error formatting
|
|
64
|
+
// purposes, we could return the difference between the two arrays
|
|
65
|
+
if (looseMatches.length > strictMatches.length) {
|
|
66
|
+
return false;
|
|
43
67
|
}
|
|
44
68
|
|
|
45
69
|
return true;
|
package/server/services/user.js
CHANGED
|
@@ -109,17 +109,25 @@ module.exports = ({ strapi }) => ({
|
|
|
109
109
|
await this.edit(user.id, { confirmationToken });
|
|
110
110
|
|
|
111
111
|
const apiPrefix = strapi.config.get('api.rest.prefix');
|
|
112
|
-
settings.message = await userPermissionService.template(settings.message, {
|
|
113
|
-
URL: urlJoin(getAbsoluteServerUrl(strapi.config), apiPrefix, '/auth/email-confirmation'),
|
|
114
|
-
SERVER_URL: getAbsoluteServerUrl(strapi.config),
|
|
115
|
-
ADMIN_URL: getAbsoluteAdminUrl(strapi.config),
|
|
116
|
-
USER: sanitizedUserInfo,
|
|
117
|
-
CODE: confirmationToken,
|
|
118
|
-
});
|
|
119
112
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
113
|
+
try {
|
|
114
|
+
settings.message = await userPermissionService.template(settings.message, {
|
|
115
|
+
URL: urlJoin(getAbsoluteServerUrl(strapi.config), apiPrefix, '/auth/email-confirmation'),
|
|
116
|
+
SERVER_URL: getAbsoluteServerUrl(strapi.config),
|
|
117
|
+
ADMIN_URL: getAbsoluteAdminUrl(strapi.config),
|
|
118
|
+
USER: sanitizedUserInfo,
|
|
119
|
+
CODE: confirmationToken,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
settings.object = await userPermissionService.template(settings.object, {
|
|
123
|
+
USER: sanitizedUserInfo,
|
|
124
|
+
});
|
|
125
|
+
} catch {
|
|
126
|
+
strapi.log.error(
|
|
127
|
+
'[plugin::users-permissions.sendConfirmationEmail]: Failed to generate a template for "user confirmation email". Please make sure your email template is valid and does not contain invalid characters or patterns'
|
|
128
|
+
);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
123
131
|
|
|
124
132
|
// Send an email to the user.
|
|
125
133
|
await strapi
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
4
|
const { filter, map, pipe, prop } = require('lodash/fp');
|
|
5
5
|
const urlJoin = require('url-join');
|
|
6
|
+
const {
|
|
7
|
+
template: { createStrictInterpolationRegExp },
|
|
8
|
+
errors,
|
|
9
|
+
keysDeep,
|
|
10
|
+
} = require('@strapi/utils');
|
|
6
11
|
|
|
7
12
|
const { getService } = require('../utils');
|
|
8
13
|
|
|
@@ -230,7 +235,15 @@ module.exports = ({ strapi }) => ({
|
|
|
230
235
|
},
|
|
231
236
|
|
|
232
237
|
template(layout, data) {
|
|
233
|
-
const
|
|
234
|
-
|
|
238
|
+
const allowedTemplateVariables = keysDeep(data);
|
|
239
|
+
|
|
240
|
+
// Create a strict interpolation RegExp based on possible variable names
|
|
241
|
+
const interpolate = createStrictInterpolationRegExp(allowedTemplateVariables, 'g');
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
return _.template(layout, { interpolate, evaluate: false, escape: false })(data);
|
|
245
|
+
} catch (e) {
|
|
246
|
+
throw new errors.ApplicationError('Invalid email template');
|
|
247
|
+
}
|
|
235
248
|
},
|
|
236
249
|
});
|