@strapi/plugin-users-permissions 5.23.6 → 5.24.1

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.
Files changed (41) hide show
  1. package/dist/server/bootstrap/index.js +26 -7
  2. package/dist/server/bootstrap/index.js.map +1 -1
  3. package/dist/server/bootstrap/index.mjs +26 -7
  4. package/dist/server/bootstrap/index.mjs.map +1 -1
  5. package/dist/server/config.js +16 -0
  6. package/dist/server/config.js.map +1 -1
  7. package/dist/server/config.mjs +16 -0
  8. package/dist/server/config.mjs.map +1 -1
  9. package/dist/server/controllers/auth.js +198 -3
  10. package/dist/server/controllers/auth.js.map +1 -1
  11. package/dist/server/controllers/auth.mjs +198 -3
  12. package/dist/server/controllers/auth.mjs.map +1 -1
  13. package/dist/server/routes/content-api/auth.js +16 -0
  14. package/dist/server/routes/content-api/auth.js.map +1 -1
  15. package/dist/server/routes/content-api/auth.mjs +16 -0
  16. package/dist/server/routes/content-api/auth.mjs.map +1 -1
  17. package/dist/server/routes/content-api/validation.js +1 -0
  18. package/dist/server/routes/content-api/validation.js.map +1 -1
  19. package/dist/server/routes/content-api/validation.mjs +1 -0
  20. package/dist/server/routes/content-api/validation.mjs.map +1 -1
  21. package/dist/server/services/constants.js +19 -0
  22. package/dist/server/services/constants.js.map +1 -0
  23. package/dist/server/services/constants.mjs +17 -0
  24. package/dist/server/services/constants.mjs.map +1 -0
  25. package/dist/server/services/jwt.js +45 -2
  26. package/dist/server/services/jwt.js.map +1 -1
  27. package/dist/server/services/jwt.mjs +45 -2
  28. package/dist/server/services/jwt.mjs.map +1 -1
  29. package/dist/server/services/user.js +29 -20
  30. package/dist/server/services/user.js.map +1 -1
  31. package/dist/server/services/user.mjs +29 -20
  32. package/dist/server/services/user.mjs.map +1 -1
  33. package/package.json +3 -3
  34. package/server/bootstrap/index.js +29 -0
  35. package/server/config.js +22 -0
  36. package/server/controllers/auth.js +232 -8
  37. package/server/routes/content-api/auth.js +12 -0
  38. package/server/routes/content-api/validation.js +1 -0
  39. package/server/services/constants.js +9 -0
  40. package/server/services/jwt.js +50 -2
  41. package/server/services/user.js +11 -0
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.js","sources":["../../../server/services/jwt.js"],"sourcesContent":["'use strict';\n\n/**\n * Jwt.js service\n *\n * @description: A set of functions similar to controller's actions to avoid code duplication.\n */\n\nconst _ = require('lodash');\nconst jwt = require('jsonwebtoken');\n\nmodule.exports = ({ strapi }) => ({\n getToken(ctx) {\n let token;\n\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n token = parts[1];\n } else {\n return null;\n }\n\n return this.verify(token);\n },\n\n issue(payload, jwtOptions = {}) {\n _.defaults(jwtOptions, strapi.config.get('plugin::users-permissions.jwt'));\n return jwt.sign(\n _.clone(payload.toJSON ? payload.toJSON() : payload),\n strapi.config.get('plugin::users-permissions.jwtSecret'),\n jwtOptions\n );\n },\n\n verify(token) {\n return new Promise((resolve, reject) => {\n jwt.verify(\n token,\n strapi.config.get('plugin::users-permissions.jwtSecret'),\n {},\n (err, tokenPayload = {}) => {\n if (err) {\n return reject(new Error('Invalid token.'));\n }\n resolve(tokenPayload);\n }\n );\n });\n },\n});\n"],"names":["_","require$$0","jwt","require$$1","jwt_1","strapi","getToken","ctx","token","request","header","authorization","parts","split","toLowerCase","length","verify","issue","payload","jwtOptions","defaults","config","get","sign","clone","toJSON","Promise","resolve","reject","err","tokenPayload","Error"],"mappings":";;;;;;;;;;AAEA;;;;AAIA,KAEA,MAAMA,CAAIC,GAAAA,UAAAA;AACV,IAAA,MAAMC,GAAMC,GAAAA,UAAAA;AAEZC,IAAAA,KAAAA,GAAiB,CAAC,EAAEC,MAAM,EAAE,IAAM;AAChCC,YAAAA,QAAAA,CAAAA,CAASC,GAAG,EAAA;gBACV,IAAIC,KAAAA;AAEJ,gBAAA,IAAID,GAAIE,CAAAA,OAAO,IAAIF,GAAAA,CAAIE,OAAO,CAACC,MAAM,IAAIH,GAAAA,CAAIE,OAAO,CAACC,MAAM,CAACC,aAAa,EAAE;oBACzE,MAAMC,KAAAA,GAAQL,IAAIE,OAAO,CAACC,MAAM,CAACC,aAAa,CAACE,KAAK,CAAC,KAAA,CAAA;oBAErD,IAAID,KAAK,CAAC,CAAA,CAAE,CAACE,WAAW,OAAO,QAAYF,IAAAA,KAAAA,CAAMG,MAAM,KAAK,CAAG,EAAA;wBAC7D,OAAO,IAAA;AACR;oBAEDP,KAAQI,GAAAA,KAAK,CAAC,CAAE,CAAA;iBACX,MAAA;oBACL,OAAO,IAAA;AACR;gBAED,OAAO,IAAI,CAACI,MAAM,CAACR,KAAAA,CAAAA;AACpB,aAAA;AAEDS,YAAAA,KAAAA,CAAAA,CAAMC,OAAO,EAAEC,UAAa,GAAA,EAAE,EAAA;AAC5BnB,gBAAAA,CAAAA,CAAEoB,QAAQ,CAACD,UAAAA,EAAYd,OAAOgB,MAAM,CAACC,GAAG,CAAC,+BAAA,CAAA,CAAA;AACzC,gBAAA,OAAOpB,IAAIqB,IAAI,CACbvB,EAAEwB,KAAK,CAACN,QAAQO,MAAM,GAAGP,OAAQO,CAAAA,MAAM,KAAKP,OAC5Cb,CAAAA,EAAAA,MAAAA,CAAOgB,MAAM,CAACC,GAAG,CAAC,qCAClBH,CAAAA,EAAAA,UAAAA,CAAAA;AAEH,aAAA;AAEDH,YAAAA,MAAAA,CAAAA,CAAOR,KAAK,EAAA;gBACV,OAAO,IAAIkB,OAAQ,CAAA,CAACC,OAASC,EAAAA,MAAAA,GAAAA;AAC3B1B,oBAAAA,GAAAA,CAAIc,MAAM,CACRR,KACAH,EAAAA,MAAAA,CAAOgB,MAAM,CAACC,GAAG,CAAC,qCAAA,CAAA,EAClB,EACA,EAAA,CAACO,GAAKC,EAAAA,YAAAA,GAAe,EAAE,GAAA;AACrB,wBAAA,IAAID,GAAK,EAAA;4BACP,OAAOD,MAAAA,CAAO,IAAIG,KAAM,CAAA,gBAAA,CAAA,CAAA;AACzB;wBACDJ,OAAQG,CAAAA,YAAAA,CAAAA;AACT,qBAAA,CAAA;AAET,iBAAA,CAAA;AACG;SACH,CAAA;;;;;;"}
1
+ {"version":3,"file":"jwt.js","sources":["../../../server/services/jwt.js"],"sourcesContent":["'use strict';\n\n/**\n * Jwt.js service\n *\n * @description: A set of functions similar to controller's actions to avoid code duplication.\n */\n\nconst _ = require('lodash');\nconst jwt = require('jsonwebtoken');\n\nmodule.exports = ({ strapi }) => ({\n getToken(ctx) {\n let token;\n\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n token = parts[1];\n } else {\n return null;\n }\n\n return this.verify(token);\n },\n\n issue(payload, jwtOptions = {}) {\n const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');\n\n if (mode === 'refresh') {\n const userId = String(payload.id ?? payload.userId ?? '');\n if (!userId) {\n throw new Error('Cannot issue token: missing user id');\n }\n\n const issueRefreshToken = async () => {\n const refresh = await strapi\n .sessionManager('users-permissions')\n .generateRefreshToken(userId, undefined, { type: 'refresh' });\n\n const access = await strapi\n .sessionManager('users-permissions')\n .generateAccessToken(refresh.token);\n if ('error' in access) {\n throw new Error('Failed to generate access token');\n }\n\n return access.token;\n };\n\n return issueRefreshToken();\n }\n\n _.defaults(jwtOptions, strapi.config.get('plugin::users-permissions.jwt'));\n return jwt.sign(\n _.clone(payload.toJSON ? payload.toJSON() : payload),\n strapi.config.get('plugin::users-permissions.jwtSecret'),\n jwtOptions\n );\n },\n\n async verify(token) {\n const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');\n\n if (mode === 'refresh') {\n // Accept only access tokens minted by the SessionManager for UP\n const result = strapi.sessionManager('users-permissions').validateAccessToken(token);\n if (!result.isValid || result.payload.type !== 'access') {\n throw new Error('Invalid token.');\n }\n\n const user = await strapi.db\n .query('plugin::users-permissions.user')\n .findOne({ where: { id: Number(result.payload.userId) || result.payload.userId } });\n if (!user) {\n throw new Error('Invalid token.');\n }\n\n return { id: user.id };\n }\n\n return new Promise((resolve, reject) => {\n const jwtConfig = strapi.config.get('plugin::users-permissions.jwt', {});\n const algorithms = jwtConfig && jwtConfig.algorithm ? [jwtConfig.algorithm] : undefined;\n\n jwt.verify(\n token,\n strapi.config.get('plugin::users-permissions.jwtSecret'),\n algorithms ? { algorithms } : {},\n (err, tokenPayload = {}) => {\n if (err) {\n return reject(new Error('Invalid token.'));\n }\n resolve(tokenPayload);\n }\n );\n });\n },\n});\n"],"names":["_","require$$0","jwt","require$$1","jwt_1","strapi","getToken","ctx","token","request","header","authorization","parts","split","toLowerCase","length","verify","issue","payload","jwtOptions","mode","config","get","userId","String","id","Error","issueRefreshToken","refresh","sessionManager","generateRefreshToken","undefined","type","access","generateAccessToken","defaults","sign","clone","toJSON","result","validateAccessToken","isValid","user","db","query","findOne","where","Number","Promise","resolve","reject","jwtConfig","algorithms","algorithm","err","tokenPayload"],"mappings":"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"}
@@ -27,12 +27,55 @@ function requireJwt() {
27
27
  return this.verify(token);
28
28
  },
29
29
  issue (payload, jwtOptions = {}) {
30
+ const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');
31
+ if (mode === 'refresh') {
32
+ const userId = String(payload.id ?? payload.userId ?? '');
33
+ if (!userId) {
34
+ throw new Error('Cannot issue token: missing user id');
35
+ }
36
+ const issueRefreshToken = async ()=>{
37
+ const refresh = await strapi.sessionManager('users-permissions').generateRefreshToken(userId, undefined, {
38
+ type: 'refresh'
39
+ });
40
+ const access = await strapi.sessionManager('users-permissions').generateAccessToken(refresh.token);
41
+ if ('error' in access) {
42
+ throw new Error('Failed to generate access token');
43
+ }
44
+ return access.token;
45
+ };
46
+ return issueRefreshToken();
47
+ }
30
48
  _.defaults(jwtOptions, strapi.config.get('plugin::users-permissions.jwt'));
31
49
  return jwt.sign(_.clone(payload.toJSON ? payload.toJSON() : payload), strapi.config.get('plugin::users-permissions.jwtSecret'), jwtOptions);
32
50
  },
33
- verify (token) {
51
+ async verify (token) {
52
+ const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');
53
+ if (mode === 'refresh') {
54
+ // Accept only access tokens minted by the SessionManager for UP
55
+ const result = strapi.sessionManager('users-permissions').validateAccessToken(token);
56
+ if (!result.isValid || result.payload.type !== 'access') {
57
+ throw new Error('Invalid token.');
58
+ }
59
+ const user = await strapi.db.query('plugin::users-permissions.user').findOne({
60
+ where: {
61
+ id: Number(result.payload.userId) || result.payload.userId
62
+ }
63
+ });
64
+ if (!user) {
65
+ throw new Error('Invalid token.');
66
+ }
67
+ return {
68
+ id: user.id
69
+ };
70
+ }
34
71
  return new Promise((resolve, reject)=>{
35
- jwt.verify(token, strapi.config.get('plugin::users-permissions.jwtSecret'), {}, (err, tokenPayload = {})=>{
72
+ const jwtConfig = strapi.config.get('plugin::users-permissions.jwt', {});
73
+ const algorithms = jwtConfig && jwtConfig.algorithm ? [
74
+ jwtConfig.algorithm
75
+ ] : undefined;
76
+ jwt.verify(token, strapi.config.get('plugin::users-permissions.jwtSecret'), algorithms ? {
77
+ algorithms
78
+ } : {}, (err, tokenPayload = {})=>{
36
79
  if (err) {
37
80
  return reject(new Error('Invalid token.'));
38
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.mjs","sources":["../../../server/services/jwt.js"],"sourcesContent":["'use strict';\n\n/**\n * Jwt.js service\n *\n * @description: A set of functions similar to controller's actions to avoid code duplication.\n */\n\nconst _ = require('lodash');\nconst jwt = require('jsonwebtoken');\n\nmodule.exports = ({ strapi }) => ({\n getToken(ctx) {\n let token;\n\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n token = parts[1];\n } else {\n return null;\n }\n\n return this.verify(token);\n },\n\n issue(payload, jwtOptions = {}) {\n _.defaults(jwtOptions, strapi.config.get('plugin::users-permissions.jwt'));\n return jwt.sign(\n _.clone(payload.toJSON ? payload.toJSON() : payload),\n strapi.config.get('plugin::users-permissions.jwtSecret'),\n jwtOptions\n );\n },\n\n verify(token) {\n return new Promise((resolve, reject) => {\n jwt.verify(\n token,\n strapi.config.get('plugin::users-permissions.jwtSecret'),\n {},\n (err, tokenPayload = {}) => {\n if (err) {\n return reject(new Error('Invalid token.'));\n }\n resolve(tokenPayload);\n }\n );\n });\n },\n});\n"],"names":["_","require$$0","jwt","require$$1","jwt_1","strapi","getToken","ctx","token","request","header","authorization","parts","split","toLowerCase","length","verify","issue","payload","jwtOptions","defaults","config","get","sign","clone","toJSON","Promise","resolve","reject","err","tokenPayload","Error"],"mappings":";;;;;;;;AAEA;;;;AAIA,KAEA,MAAMA,CAAIC,GAAAA,UAAAA;AACV,IAAA,MAAMC,GAAMC,GAAAA,UAAAA;AAEZC,IAAAA,KAAAA,GAAiB,CAAC,EAAEC,MAAM,EAAE,IAAM;AAChCC,YAAAA,QAAAA,CAAAA,CAASC,GAAG,EAAA;gBACV,IAAIC,KAAAA;AAEJ,gBAAA,IAAID,GAAIE,CAAAA,OAAO,IAAIF,GAAAA,CAAIE,OAAO,CAACC,MAAM,IAAIH,GAAAA,CAAIE,OAAO,CAACC,MAAM,CAACC,aAAa,EAAE;oBACzE,MAAMC,KAAAA,GAAQL,IAAIE,OAAO,CAACC,MAAM,CAACC,aAAa,CAACE,KAAK,CAAC,KAAA,CAAA;oBAErD,IAAID,KAAK,CAAC,CAAA,CAAE,CAACE,WAAW,OAAO,QAAYF,IAAAA,KAAAA,CAAMG,MAAM,KAAK,CAAG,EAAA;wBAC7D,OAAO,IAAA;AACR;oBAEDP,KAAQI,GAAAA,KAAK,CAAC,CAAE,CAAA;iBACX,MAAA;oBACL,OAAO,IAAA;AACR;gBAED,OAAO,IAAI,CAACI,MAAM,CAACR,KAAAA,CAAAA;AACpB,aAAA;AAEDS,YAAAA,KAAAA,CAAAA,CAAMC,OAAO,EAAEC,UAAa,GAAA,EAAE,EAAA;AAC5BnB,gBAAAA,CAAAA,CAAEoB,QAAQ,CAACD,UAAAA,EAAYd,OAAOgB,MAAM,CAACC,GAAG,CAAC,+BAAA,CAAA,CAAA;AACzC,gBAAA,OAAOpB,IAAIqB,IAAI,CACbvB,EAAEwB,KAAK,CAACN,QAAQO,MAAM,GAAGP,OAAQO,CAAAA,MAAM,KAAKP,OAC5Cb,CAAAA,EAAAA,MAAAA,CAAOgB,MAAM,CAACC,GAAG,CAAC,qCAClBH,CAAAA,EAAAA,UAAAA,CAAAA;AAEH,aAAA;AAEDH,YAAAA,MAAAA,CAAAA,CAAOR,KAAK,EAAA;gBACV,OAAO,IAAIkB,OAAQ,CAAA,CAACC,OAASC,EAAAA,MAAAA,GAAAA;AAC3B1B,oBAAAA,GAAAA,CAAIc,MAAM,CACRR,KACAH,EAAAA,MAAAA,CAAOgB,MAAM,CAACC,GAAG,CAAC,qCAAA,CAAA,EAClB,EACA,EAAA,CAACO,GAAKC,EAAAA,YAAAA,GAAe,EAAE,GAAA;AACrB,wBAAA,IAAID,GAAK,EAAA;4BACP,OAAOD,MAAAA,CAAO,IAAIG,KAAM,CAAA,gBAAA,CAAA,CAAA;AACzB;wBACDJ,OAAQG,CAAAA,YAAAA,CAAAA;AACT,qBAAA,CAAA;AAET,iBAAA,CAAA;AACG;SACH,CAAA;;;;;;"}
1
+ {"version":3,"file":"jwt.mjs","sources":["../../../server/services/jwt.js"],"sourcesContent":["'use strict';\n\n/**\n * Jwt.js service\n *\n * @description: A set of functions similar to controller's actions to avoid code duplication.\n */\n\nconst _ = require('lodash');\nconst jwt = require('jsonwebtoken');\n\nmodule.exports = ({ strapi }) => ({\n getToken(ctx) {\n let token;\n\n if (ctx.request && ctx.request.header && ctx.request.header.authorization) {\n const parts = ctx.request.header.authorization.split(/\\s+/);\n\n if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {\n return null;\n }\n\n token = parts[1];\n } else {\n return null;\n }\n\n return this.verify(token);\n },\n\n issue(payload, jwtOptions = {}) {\n const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');\n\n if (mode === 'refresh') {\n const userId = String(payload.id ?? payload.userId ?? '');\n if (!userId) {\n throw new Error('Cannot issue token: missing user id');\n }\n\n const issueRefreshToken = async () => {\n const refresh = await strapi\n .sessionManager('users-permissions')\n .generateRefreshToken(userId, undefined, { type: 'refresh' });\n\n const access = await strapi\n .sessionManager('users-permissions')\n .generateAccessToken(refresh.token);\n if ('error' in access) {\n throw new Error('Failed to generate access token');\n }\n\n return access.token;\n };\n\n return issueRefreshToken();\n }\n\n _.defaults(jwtOptions, strapi.config.get('plugin::users-permissions.jwt'));\n return jwt.sign(\n _.clone(payload.toJSON ? payload.toJSON() : payload),\n strapi.config.get('plugin::users-permissions.jwtSecret'),\n jwtOptions\n );\n },\n\n async verify(token) {\n const mode = strapi.config.get('plugin::users-permissions.jwtManagement', 'legacy-support');\n\n if (mode === 'refresh') {\n // Accept only access tokens minted by the SessionManager for UP\n const result = strapi.sessionManager('users-permissions').validateAccessToken(token);\n if (!result.isValid || result.payload.type !== 'access') {\n throw new Error('Invalid token.');\n }\n\n const user = await strapi.db\n .query('plugin::users-permissions.user')\n .findOne({ where: { id: Number(result.payload.userId) || result.payload.userId } });\n if (!user) {\n throw new Error('Invalid token.');\n }\n\n return { id: user.id };\n }\n\n return new Promise((resolve, reject) => {\n const jwtConfig = strapi.config.get('plugin::users-permissions.jwt', {});\n const algorithms = jwtConfig && jwtConfig.algorithm ? [jwtConfig.algorithm] : undefined;\n\n jwt.verify(\n token,\n strapi.config.get('plugin::users-permissions.jwtSecret'),\n algorithms ? { algorithms } : {},\n (err, tokenPayload = {}) => {\n if (err) {\n return reject(new Error('Invalid token.'));\n }\n resolve(tokenPayload);\n }\n );\n });\n },\n});\n"],"names":["_","require$$0","jwt","require$$1","jwt_1","strapi","getToken","ctx","token","request","header","authorization","parts","split","toLowerCase","length","verify","issue","payload","jwtOptions","mode","config","get","userId","String","id","Error","issueRefreshToken","refresh","sessionManager","generateRefreshToken","undefined","type","access","generateAccessToken","defaults","sign","clone","toJSON","result","validateAccessToken","isValid","user","db","query","findOne","where","Number","Promise","resolve","reject","jwtConfig","algorithms","algorithm","err","tokenPayload"],"mappings":"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"}
@@ -23,13 +23,17 @@ function requireUser() {
23
23
  const { toNumber, getOr } = require$$0$1;
24
24
  const { getService } = index.__require();
25
25
  const USER_MODEL_UID = 'plugin::users-permissions.user';
26
- user = ({ strapi })=>({
26
+ const getSessionManager = ()=>{
27
+ const manager = strapi.sessionManager;
28
+ return manager ?? null;
29
+ };
30
+ user = ({ strapi: strapi1 })=>({
27
31
  /**
28
32
  * Promise to count users
29
33
  *
30
34
  * @return {Promise}
31
35
  */ count (params) {
32
- return strapi.db.query(USER_MODEL_UID).count({
36
+ return strapi1.db.query(USER_MODEL_UID).count({
33
37
  where: params
34
38
  });
35
39
  },
@@ -41,7 +45,7 @@ function requireUser() {
41
45
  * @param {object} values - The object containing the fields to be hashed.
42
46
  * @return {object} The values object with hashed password fields if they were present.
43
47
  */ async ensureHashedPasswords (values) {
44
- const attributes = strapi.getModel(USER_MODEL_UID).attributes;
48
+ const attributes = strapi1.getModel(USER_MODEL_UID).attributes;
45
49
  for(const key in values){
46
50
  if (attributes[key] && attributes[key].type === 'password') {
47
51
  // Check if a custom encryption.rounds has been set on the password attribute
@@ -55,7 +59,7 @@ function requireUser() {
55
59
  * Promise to add a/an user.
56
60
  * @return {Promise}
57
61
  */ async add (values) {
58
- return strapi.db.query(USER_MODEL_UID).create({
62
+ return strapi1.db.query(USER_MODEL_UID).create({
59
63
  data: await this.ensureHashedPasswords(values),
60
64
  populate: [
61
65
  'role'
@@ -68,7 +72,7 @@ function requireUser() {
68
72
  * @param {object} params
69
73
  * @return {Promise}
70
74
  */ async edit (userId, params = {}) {
71
- return strapi.db.query(USER_MODEL_UID).update({
75
+ return strapi1.db.query(USER_MODEL_UID).update({
72
76
  where: {
73
77
  id: userId
74
78
  },
@@ -82,8 +86,8 @@ function requireUser() {
82
86
  * Promise to fetch a/an user.
83
87
  * @return {Promise}
84
88
  */ fetch (id, params) {
85
- const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});
86
- return strapi.db.query(USER_MODEL_UID).findOne({
89
+ const query = strapi1.get('query-params').transform(USER_MODEL_UID, params ?? {});
90
+ return strapi1.db.query(USER_MODEL_UID).findOne({
87
91
  ...query,
88
92
  where: {
89
93
  $and: [
@@ -99,7 +103,7 @@ function requireUser() {
99
103
  * Promise to fetch authenticated user.
100
104
  * @return {Promise}
101
105
  */ fetchAuthenticatedUser (id) {
102
- return strapi.db.query(USER_MODEL_UID).findOne({
106
+ return strapi1.db.query(USER_MODEL_UID).findOne({
103
107
  where: {
104
108
  id
105
109
  },
@@ -112,14 +116,19 @@ function requireUser() {
112
116
  * Promise to fetch all users.
113
117
  * @return {Promise}
114
118
  */ fetchAll (params) {
115
- const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});
116
- return strapi.db.query(USER_MODEL_UID).findMany(query);
119
+ const query = strapi1.get('query-params').transform(USER_MODEL_UID, params ?? {});
120
+ return strapi1.db.query(USER_MODEL_UID).findMany(query);
117
121
  },
118
122
  /**
119
123
  * Promise to remove a/an user.
120
124
  * @return {Promise}
121
125
  */ async remove (params) {
122
- return strapi.db.query(USER_MODEL_UID).delete({
126
+ // Invalidate sessions for all affected users
127
+ const sessionManager = getSessionManager();
128
+ if (sessionManager && sessionManager.hasOrigin('users-permissions') && params.id) {
129
+ await sessionManager('users-permissions').invalidateRefreshToken(String(params.id));
130
+ }
131
+ return strapi1.db.query(USER_MODEL_UID).delete({
123
132
  where: params
124
133
  });
125
134
  },
@@ -128,29 +137,29 @@ function requireUser() {
128
137
  },
129
138
  async sendConfirmationEmail (user) {
130
139
  const userPermissionService = getService('users-permissions');
131
- const pluginStore = await strapi.store({
140
+ const pluginStore = await strapi1.store({
132
141
  type: 'plugin',
133
142
  name: 'users-permissions'
134
143
  });
135
- const userSchema = strapi.getModel(USER_MODEL_UID);
144
+ const userSchema = strapi1.getModel(USER_MODEL_UID);
136
145
  const settings = await pluginStore.get({
137
146
  key: 'email'
138
147
  }).then((storeEmail)=>storeEmail.email_confirmation.options);
139
148
  // Sanitize the template's user information
140
149
  const sanitizedUserInfo = await sanitize.sanitizers.defaultSanitizeOutput({
141
150
  schema: userSchema,
142
- getModel: strapi.getModel.bind(strapi)
151
+ getModel: strapi1.getModel.bind(strapi1)
143
152
  }, user);
144
153
  const confirmationToken = crypto.randomBytes(20).toString('hex');
145
154
  await this.edit(user.id, {
146
155
  confirmationToken
147
156
  });
148
- const apiPrefix = strapi.config.get('api.rest.prefix');
157
+ const apiPrefix = strapi1.config.get('api.rest.prefix');
149
158
  try {
150
159
  settings.message = await userPermissionService.template(settings.message, {
151
- URL: urlJoin(strapi.config.get('server.absoluteUrl'), apiPrefix, '/auth/email-confirmation'),
152
- SERVER_URL: strapi.config.get('server.absoluteUrl'),
153
- ADMIN_URL: strapi.config.get('admin.absoluteUrl'),
160
+ URL: urlJoin(strapi1.config.get('server.absoluteUrl'), apiPrefix, '/auth/email-confirmation'),
161
+ SERVER_URL: strapi1.config.get('server.absoluteUrl'),
162
+ ADMIN_URL: strapi1.config.get('admin.absoluteUrl'),
154
163
  USER: sanitizedUserInfo,
155
164
  CODE: confirmationToken
156
165
  });
@@ -158,11 +167,11 @@ function requireUser() {
158
167
  USER: sanitizedUserInfo
159
168
  });
160
169
  } catch {
161
- strapi.log.error('[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');
170
+ strapi1.log.error('[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');
162
171
  return;
163
172
  }
164
173
  // Send an email to the user.
165
- await strapi.plugin('email').service('email').send({
174
+ await strapi1.plugin('email').service('email').send({
166
175
  to: user.email,
167
176
  from: settings.from.email && settings.from.name ? `${settings.from.name} <${settings.from.email}>` : undefined,
168
177
  replyTo: settings.response_email,
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","sources":["../../../server/services/user.js"],"sourcesContent":["'use strict';\n\n/**\n * User.js service\n *\n * @description: A set of functions similar to controller's actions to avoid code duplication.\n */\n\nconst crypto = require('crypto');\nconst bcrypt = require('bcryptjs');\nconst urlJoin = require('url-join');\n\nconst { sanitize } = require('@strapi/utils');\nconst { toNumber, getOr } = require('lodash/fp');\nconst { getService } = require('../utils');\n\nconst USER_MODEL_UID = 'plugin::users-permissions.user';\n\nmodule.exports = ({ strapi }) => ({\n /**\n * Promise to count users\n *\n * @return {Promise}\n */\n\n count(params) {\n return strapi.db.query(USER_MODEL_UID).count({ where: params });\n },\n\n /**\n * Hashes password fields in the provided values object if they are present.\n * It checks each key in the values object against the model's attributes and\n * hashes it if the attribute type is 'password',\n *\n * @param {object} values - The object containing the fields to be hashed.\n * @return {object} The values object with hashed password fields if they were present.\n */\n async ensureHashedPasswords(values) {\n const attributes = strapi.getModel(USER_MODEL_UID).attributes;\n\n for (const key in values) {\n if (attributes[key] && attributes[key].type === 'password') {\n // Check if a custom encryption.rounds has been set on the password attribute\n const rounds = toNumber(getOr(10, 'encryption.rounds', attributes[key]));\n values[key] = await bcrypt.hash(values[key], rounds);\n }\n }\n\n return values;\n },\n\n /**\n * Promise to add a/an user.\n * @return {Promise}\n */\n async add(values) {\n return strapi.db.query(USER_MODEL_UID).create({\n data: await this.ensureHashedPasswords(values),\n populate: ['role'],\n });\n },\n\n /**\n * Promise to edit a/an user.\n * @param {string} userId\n * @param {object} params\n * @return {Promise}\n */\n async edit(userId, params = {}) {\n return strapi.db.query(USER_MODEL_UID).update({\n where: { id: userId },\n data: await this.ensureHashedPasswords(params),\n populate: ['role'],\n });\n },\n\n /**\n * Promise to fetch a/an user.\n * @return {Promise}\n */\n fetch(id, params) {\n const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});\n\n return strapi.db.query(USER_MODEL_UID).findOne({\n ...query,\n where: {\n $and: [{ id }, query.where || {}],\n },\n });\n },\n\n /**\n * Promise to fetch authenticated user.\n * @return {Promise}\n */\n fetchAuthenticatedUser(id) {\n return strapi.db.query(USER_MODEL_UID).findOne({ where: { id }, populate: ['role'] });\n },\n\n /**\n * Promise to fetch all users.\n * @return {Promise}\n */\n fetchAll(params) {\n const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});\n\n return strapi.db.query(USER_MODEL_UID).findMany(query);\n },\n\n /**\n * Promise to remove a/an user.\n * @return {Promise}\n */\n async remove(params) {\n return strapi.db.query(USER_MODEL_UID).delete({ where: params });\n },\n\n validatePassword(password, hash) {\n return bcrypt.compare(password, hash);\n },\n\n async sendConfirmationEmail(user) {\n const userPermissionService = getService('users-permissions');\n const pluginStore = await strapi.store({ type: 'plugin', name: 'users-permissions' });\n const userSchema = strapi.getModel(USER_MODEL_UID);\n\n const settings = await pluginStore\n .get({ key: 'email' })\n .then((storeEmail) => storeEmail.email_confirmation.options);\n\n // Sanitize the template's user information\n const sanitizedUserInfo = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: userSchema,\n getModel: strapi.getModel.bind(strapi),\n },\n user\n );\n\n const confirmationToken = crypto.randomBytes(20).toString('hex');\n\n await this.edit(user.id, { confirmationToken });\n\n const apiPrefix = strapi.config.get('api.rest.prefix');\n\n try {\n settings.message = await userPermissionService.template(settings.message, {\n URL: urlJoin(\n strapi.config.get('server.absoluteUrl'),\n apiPrefix,\n '/auth/email-confirmation'\n ),\n SERVER_URL: strapi.config.get('server.absoluteUrl'),\n ADMIN_URL: strapi.config.get('admin.absoluteUrl'),\n USER: sanitizedUserInfo,\n CODE: confirmationToken,\n });\n\n settings.object = await userPermissionService.template(settings.object, {\n USER: sanitizedUserInfo,\n });\n } catch {\n strapi.log.error(\n '[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'\n );\n return;\n }\n\n // Send an email to the user.\n await strapi\n .plugin('email')\n .service('email')\n .send({\n to: user.email,\n from:\n settings.from.email && settings.from.name\n ? `${settings.from.name} <${settings.from.email}>`\n : undefined,\n replyTo: settings.response_email,\n subject: settings.object,\n text: settings.message,\n html: settings.message,\n });\n },\n});\n"],"names":["crypto","require$$0","bcrypt","require$$1","urlJoin","require$$2","sanitize","require$$3","toNumber","getOr","require$$4","getService","require$$5","USER_MODEL_UID","user","strapi","count","params","db","query","where","ensureHashedPasswords","values","attributes","getModel","key","type","rounds","hash","add","create","data","populate","edit","userId","update","id","fetch","get","transform","findOne","$and","fetchAuthenticatedUser","fetchAll","findMany","remove","delete","validatePassword","password","compare","sendConfirmationEmail","userPermissionService","pluginStore","store","name","userSchema","settings","then","storeEmail","email_confirmation","options","sanitizedUserInfo","sanitizers","defaultSanitizeOutput","schema","bind","confirmationToken","randomBytes","toString","apiPrefix","config","message","template","URL","SERVER_URL","ADMIN_URL","USER","CODE","object","log","error","plugin","service","send","to","email","from","undefined","replyTo","response_email","subject","text","html"],"mappings":"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"}
1
+ {"version":3,"file":"user.js","sources":["../../../server/services/user.js"],"sourcesContent":["'use strict';\n\n/**\n * User.js service\n *\n * @description: A set of functions similar to controller's actions to avoid code duplication.\n */\n\nconst crypto = require('crypto');\nconst bcrypt = require('bcryptjs');\nconst urlJoin = require('url-join');\n\nconst { sanitize } = require('@strapi/utils');\nconst { toNumber, getOr } = require('lodash/fp');\nconst { getService } = require('../utils');\n\nconst USER_MODEL_UID = 'plugin::users-permissions.user';\n\nconst getSessionManager = () => {\n const manager = strapi.sessionManager;\n return manager ?? null;\n};\n\nmodule.exports = ({ strapi }) => ({\n /**\n * Promise to count users\n *\n * @return {Promise}\n */\n\n count(params) {\n return strapi.db.query(USER_MODEL_UID).count({ where: params });\n },\n\n /**\n * Hashes password fields in the provided values object if they are present.\n * It checks each key in the values object against the model's attributes and\n * hashes it if the attribute type is 'password',\n *\n * @param {object} values - The object containing the fields to be hashed.\n * @return {object} The values object with hashed password fields if they were present.\n */\n async ensureHashedPasswords(values) {\n const attributes = strapi.getModel(USER_MODEL_UID).attributes;\n\n for (const key in values) {\n if (attributes[key] && attributes[key].type === 'password') {\n // Check if a custom encryption.rounds has been set on the password attribute\n const rounds = toNumber(getOr(10, 'encryption.rounds', attributes[key]));\n values[key] = await bcrypt.hash(values[key], rounds);\n }\n }\n\n return values;\n },\n\n /**\n * Promise to add a/an user.\n * @return {Promise}\n */\n async add(values) {\n return strapi.db.query(USER_MODEL_UID).create({\n data: await this.ensureHashedPasswords(values),\n populate: ['role'],\n });\n },\n\n /**\n * Promise to edit a/an user.\n * @param {string} userId\n * @param {object} params\n * @return {Promise}\n */\n async edit(userId, params = {}) {\n return strapi.db.query(USER_MODEL_UID).update({\n where: { id: userId },\n data: await this.ensureHashedPasswords(params),\n populate: ['role'],\n });\n },\n\n /**\n * Promise to fetch a/an user.\n * @return {Promise}\n */\n fetch(id, params) {\n const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});\n\n return strapi.db.query(USER_MODEL_UID).findOne({\n ...query,\n where: {\n $and: [{ id }, query.where || {}],\n },\n });\n },\n\n /**\n * Promise to fetch authenticated user.\n * @return {Promise}\n */\n fetchAuthenticatedUser(id) {\n return strapi.db.query(USER_MODEL_UID).findOne({ where: { id }, populate: ['role'] });\n },\n\n /**\n * Promise to fetch all users.\n * @return {Promise}\n */\n fetchAll(params) {\n const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});\n\n return strapi.db.query(USER_MODEL_UID).findMany(query);\n },\n\n /**\n * Promise to remove a/an user.\n * @return {Promise}\n */\n async remove(params) {\n // Invalidate sessions for all affected users\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('users-permissions') && params.id) {\n await sessionManager('users-permissions').invalidateRefreshToken(String(params.id));\n }\n\n return strapi.db.query(USER_MODEL_UID).delete({ where: params });\n },\n\n validatePassword(password, hash) {\n return bcrypt.compare(password, hash);\n },\n\n async sendConfirmationEmail(user) {\n const userPermissionService = getService('users-permissions');\n const pluginStore = await strapi.store({ type: 'plugin', name: 'users-permissions' });\n const userSchema = strapi.getModel(USER_MODEL_UID);\n\n const settings = await pluginStore\n .get({ key: 'email' })\n .then((storeEmail) => storeEmail.email_confirmation.options);\n\n // Sanitize the template's user information\n const sanitizedUserInfo = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: userSchema,\n getModel: strapi.getModel.bind(strapi),\n },\n user\n );\n\n const confirmationToken = crypto.randomBytes(20).toString('hex');\n\n await this.edit(user.id, { confirmationToken });\n\n const apiPrefix = strapi.config.get('api.rest.prefix');\n\n try {\n settings.message = await userPermissionService.template(settings.message, {\n URL: urlJoin(\n strapi.config.get('server.absoluteUrl'),\n apiPrefix,\n '/auth/email-confirmation'\n ),\n SERVER_URL: strapi.config.get('server.absoluteUrl'),\n ADMIN_URL: strapi.config.get('admin.absoluteUrl'),\n USER: sanitizedUserInfo,\n CODE: confirmationToken,\n });\n\n settings.object = await userPermissionService.template(settings.object, {\n USER: sanitizedUserInfo,\n });\n } catch {\n strapi.log.error(\n '[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'\n );\n return;\n }\n\n // Send an email to the user.\n await strapi\n .plugin('email')\n .service('email')\n .send({\n to: user.email,\n from:\n settings.from.email && settings.from.name\n ? `${settings.from.name} <${settings.from.email}>`\n : undefined,\n replyTo: settings.response_email,\n subject: settings.object,\n text: settings.message,\n html: settings.message,\n });\n },\n});\n"],"names":["crypto","require$$0","bcrypt","require$$1","urlJoin","require$$2","sanitize","require$$3","toNumber","getOr","require$$4","getService","require$$5","USER_MODEL_UID","getSessionManager","manager","strapi","sessionManager","user","count","params","db","query","where","ensureHashedPasswords","values","attributes","getModel","key","type","rounds","hash","add","create","data","populate","edit","userId","update","id","fetch","get","transform","findOne","$and","fetchAuthenticatedUser","fetchAll","findMany","remove","hasOrigin","invalidateRefreshToken","String","delete","validatePassword","password","compare","sendConfirmationEmail","userPermissionService","pluginStore","store","name","userSchema","settings","then","storeEmail","email_confirmation","options","sanitizedUserInfo","sanitizers","defaultSanitizeOutput","schema","bind","confirmationToken","randomBytes","toString","apiPrefix","config","message","template","URL","SERVER_URL","ADMIN_URL","USER","CODE","object","log","error","plugin","service","send","to","email","from","undefined","replyTo","response_email","subject","text","html"],"mappings":"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"}
@@ -21,13 +21,17 @@ function requireUser() {
21
21
  const { toNumber, getOr } = require$$0$1;
22
22
  const { getService } = requireUtils();
23
23
  const USER_MODEL_UID = 'plugin::users-permissions.user';
24
- user = ({ strapi })=>({
24
+ const getSessionManager = ()=>{
25
+ const manager = strapi.sessionManager;
26
+ return manager ?? null;
27
+ };
28
+ user = ({ strapi: strapi1 })=>({
25
29
  /**
26
30
  * Promise to count users
27
31
  *
28
32
  * @return {Promise}
29
33
  */ count (params) {
30
- return strapi.db.query(USER_MODEL_UID).count({
34
+ return strapi1.db.query(USER_MODEL_UID).count({
31
35
  where: params
32
36
  });
33
37
  },
@@ -39,7 +43,7 @@ function requireUser() {
39
43
  * @param {object} values - The object containing the fields to be hashed.
40
44
  * @return {object} The values object with hashed password fields if they were present.
41
45
  */ async ensureHashedPasswords (values) {
42
- const attributes = strapi.getModel(USER_MODEL_UID).attributes;
46
+ const attributes = strapi1.getModel(USER_MODEL_UID).attributes;
43
47
  for(const key in values){
44
48
  if (attributes[key] && attributes[key].type === 'password') {
45
49
  // Check if a custom encryption.rounds has been set on the password attribute
@@ -53,7 +57,7 @@ function requireUser() {
53
57
  * Promise to add a/an user.
54
58
  * @return {Promise}
55
59
  */ async add (values) {
56
- return strapi.db.query(USER_MODEL_UID).create({
60
+ return strapi1.db.query(USER_MODEL_UID).create({
57
61
  data: await this.ensureHashedPasswords(values),
58
62
  populate: [
59
63
  'role'
@@ -66,7 +70,7 @@ function requireUser() {
66
70
  * @param {object} params
67
71
  * @return {Promise}
68
72
  */ async edit (userId, params = {}) {
69
- return strapi.db.query(USER_MODEL_UID).update({
73
+ return strapi1.db.query(USER_MODEL_UID).update({
70
74
  where: {
71
75
  id: userId
72
76
  },
@@ -80,8 +84,8 @@ function requireUser() {
80
84
  * Promise to fetch a/an user.
81
85
  * @return {Promise}
82
86
  */ fetch (id, params) {
83
- const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});
84
- return strapi.db.query(USER_MODEL_UID).findOne({
87
+ const query = strapi1.get('query-params').transform(USER_MODEL_UID, params ?? {});
88
+ return strapi1.db.query(USER_MODEL_UID).findOne({
85
89
  ...query,
86
90
  where: {
87
91
  $and: [
@@ -97,7 +101,7 @@ function requireUser() {
97
101
  * Promise to fetch authenticated user.
98
102
  * @return {Promise}
99
103
  */ fetchAuthenticatedUser (id) {
100
- return strapi.db.query(USER_MODEL_UID).findOne({
104
+ return strapi1.db.query(USER_MODEL_UID).findOne({
101
105
  where: {
102
106
  id
103
107
  },
@@ -110,14 +114,19 @@ function requireUser() {
110
114
  * Promise to fetch all users.
111
115
  * @return {Promise}
112
116
  */ fetchAll (params) {
113
- const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});
114
- return strapi.db.query(USER_MODEL_UID).findMany(query);
117
+ const query = strapi1.get('query-params').transform(USER_MODEL_UID, params ?? {});
118
+ return strapi1.db.query(USER_MODEL_UID).findMany(query);
115
119
  },
116
120
  /**
117
121
  * Promise to remove a/an user.
118
122
  * @return {Promise}
119
123
  */ async remove (params) {
120
- return strapi.db.query(USER_MODEL_UID).delete({
124
+ // Invalidate sessions for all affected users
125
+ const sessionManager = getSessionManager();
126
+ if (sessionManager && sessionManager.hasOrigin('users-permissions') && params.id) {
127
+ await sessionManager('users-permissions').invalidateRefreshToken(String(params.id));
128
+ }
129
+ return strapi1.db.query(USER_MODEL_UID).delete({
121
130
  where: params
122
131
  });
123
132
  },
@@ -126,29 +135,29 @@ function requireUser() {
126
135
  },
127
136
  async sendConfirmationEmail (user) {
128
137
  const userPermissionService = getService('users-permissions');
129
- const pluginStore = await strapi.store({
138
+ const pluginStore = await strapi1.store({
130
139
  type: 'plugin',
131
140
  name: 'users-permissions'
132
141
  });
133
- const userSchema = strapi.getModel(USER_MODEL_UID);
142
+ const userSchema = strapi1.getModel(USER_MODEL_UID);
134
143
  const settings = await pluginStore.get({
135
144
  key: 'email'
136
145
  }).then((storeEmail)=>storeEmail.email_confirmation.options);
137
146
  // Sanitize the template's user information
138
147
  const sanitizedUserInfo = await sanitize.sanitizers.defaultSanitizeOutput({
139
148
  schema: userSchema,
140
- getModel: strapi.getModel.bind(strapi)
149
+ getModel: strapi1.getModel.bind(strapi1)
141
150
  }, user);
142
151
  const confirmationToken = crypto.randomBytes(20).toString('hex');
143
152
  await this.edit(user.id, {
144
153
  confirmationToken
145
154
  });
146
- const apiPrefix = strapi.config.get('api.rest.prefix');
155
+ const apiPrefix = strapi1.config.get('api.rest.prefix');
147
156
  try {
148
157
  settings.message = await userPermissionService.template(settings.message, {
149
- URL: urlJoin(strapi.config.get('server.absoluteUrl'), apiPrefix, '/auth/email-confirmation'),
150
- SERVER_URL: strapi.config.get('server.absoluteUrl'),
151
- ADMIN_URL: strapi.config.get('admin.absoluteUrl'),
158
+ URL: urlJoin(strapi1.config.get('server.absoluteUrl'), apiPrefix, '/auth/email-confirmation'),
159
+ SERVER_URL: strapi1.config.get('server.absoluteUrl'),
160
+ ADMIN_URL: strapi1.config.get('admin.absoluteUrl'),
152
161
  USER: sanitizedUserInfo,
153
162
  CODE: confirmationToken
154
163
  });
@@ -156,11 +165,11 @@ function requireUser() {
156
165
  USER: sanitizedUserInfo
157
166
  });
158
167
  } catch {
159
- strapi.log.error('[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');
168
+ strapi1.log.error('[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');
160
169
  return;
161
170
  }
162
171
  // Send an email to the user.
163
- await strapi.plugin('email').service('email').send({
172
+ await strapi1.plugin('email').service('email').send({
164
173
  to: user.email,
165
174
  from: settings.from.email && settings.from.name ? `${settings.from.name} <${settings.from.email}>` : undefined,
166
175
  replyTo: settings.response_email,
@@ -1 +1 @@
1
- {"version":3,"file":"user.mjs","sources":["../../../server/services/user.js"],"sourcesContent":["'use strict';\n\n/**\n * User.js service\n *\n * @description: A set of functions similar to controller's actions to avoid code duplication.\n */\n\nconst crypto = require('crypto');\nconst bcrypt = require('bcryptjs');\nconst urlJoin = require('url-join');\n\nconst { sanitize } = require('@strapi/utils');\nconst { toNumber, getOr } = require('lodash/fp');\nconst { getService } = require('../utils');\n\nconst USER_MODEL_UID = 'plugin::users-permissions.user';\n\nmodule.exports = ({ strapi }) => ({\n /**\n * Promise to count users\n *\n * @return {Promise}\n */\n\n count(params) {\n return strapi.db.query(USER_MODEL_UID).count({ where: params });\n },\n\n /**\n * Hashes password fields in the provided values object if they are present.\n * It checks each key in the values object against the model's attributes and\n * hashes it if the attribute type is 'password',\n *\n * @param {object} values - The object containing the fields to be hashed.\n * @return {object} The values object with hashed password fields if they were present.\n */\n async ensureHashedPasswords(values) {\n const attributes = strapi.getModel(USER_MODEL_UID).attributes;\n\n for (const key in values) {\n if (attributes[key] && attributes[key].type === 'password') {\n // Check if a custom encryption.rounds has been set on the password attribute\n const rounds = toNumber(getOr(10, 'encryption.rounds', attributes[key]));\n values[key] = await bcrypt.hash(values[key], rounds);\n }\n }\n\n return values;\n },\n\n /**\n * Promise to add a/an user.\n * @return {Promise}\n */\n async add(values) {\n return strapi.db.query(USER_MODEL_UID).create({\n data: await this.ensureHashedPasswords(values),\n populate: ['role'],\n });\n },\n\n /**\n * Promise to edit a/an user.\n * @param {string} userId\n * @param {object} params\n * @return {Promise}\n */\n async edit(userId, params = {}) {\n return strapi.db.query(USER_MODEL_UID).update({\n where: { id: userId },\n data: await this.ensureHashedPasswords(params),\n populate: ['role'],\n });\n },\n\n /**\n * Promise to fetch a/an user.\n * @return {Promise}\n */\n fetch(id, params) {\n const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});\n\n return strapi.db.query(USER_MODEL_UID).findOne({\n ...query,\n where: {\n $and: [{ id }, query.where || {}],\n },\n });\n },\n\n /**\n * Promise to fetch authenticated user.\n * @return {Promise}\n */\n fetchAuthenticatedUser(id) {\n return strapi.db.query(USER_MODEL_UID).findOne({ where: { id }, populate: ['role'] });\n },\n\n /**\n * Promise to fetch all users.\n * @return {Promise}\n */\n fetchAll(params) {\n const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});\n\n return strapi.db.query(USER_MODEL_UID).findMany(query);\n },\n\n /**\n * Promise to remove a/an user.\n * @return {Promise}\n */\n async remove(params) {\n return strapi.db.query(USER_MODEL_UID).delete({ where: params });\n },\n\n validatePassword(password, hash) {\n return bcrypt.compare(password, hash);\n },\n\n async sendConfirmationEmail(user) {\n const userPermissionService = getService('users-permissions');\n const pluginStore = await strapi.store({ type: 'plugin', name: 'users-permissions' });\n const userSchema = strapi.getModel(USER_MODEL_UID);\n\n const settings = await pluginStore\n .get({ key: 'email' })\n .then((storeEmail) => storeEmail.email_confirmation.options);\n\n // Sanitize the template's user information\n const sanitizedUserInfo = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: userSchema,\n getModel: strapi.getModel.bind(strapi),\n },\n user\n );\n\n const confirmationToken = crypto.randomBytes(20).toString('hex');\n\n await this.edit(user.id, { confirmationToken });\n\n const apiPrefix = strapi.config.get('api.rest.prefix');\n\n try {\n settings.message = await userPermissionService.template(settings.message, {\n URL: urlJoin(\n strapi.config.get('server.absoluteUrl'),\n apiPrefix,\n '/auth/email-confirmation'\n ),\n SERVER_URL: strapi.config.get('server.absoluteUrl'),\n ADMIN_URL: strapi.config.get('admin.absoluteUrl'),\n USER: sanitizedUserInfo,\n CODE: confirmationToken,\n });\n\n settings.object = await userPermissionService.template(settings.object, {\n USER: sanitizedUserInfo,\n });\n } catch {\n strapi.log.error(\n '[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'\n );\n return;\n }\n\n // Send an email to the user.\n await strapi\n .plugin('email')\n .service('email')\n .send({\n to: user.email,\n from:\n settings.from.email && settings.from.name\n ? `${settings.from.name} <${settings.from.email}>`\n : undefined,\n replyTo: settings.response_email,\n subject: settings.object,\n text: settings.message,\n html: settings.message,\n });\n },\n});\n"],"names":["crypto","require$$0","bcrypt","require$$1","urlJoin","require$$2","sanitize","require$$3","toNumber","getOr","require$$4","getService","require$$5","USER_MODEL_UID","user","strapi","count","params","db","query","where","ensureHashedPasswords","values","attributes","getModel","key","type","rounds","hash","add","create","data","populate","edit","userId","update","id","fetch","get","transform","findOne","$and","fetchAuthenticatedUser","fetchAll","findMany","remove","delete","validatePassword","password","compare","sendConfirmationEmail","userPermissionService","pluginStore","store","name","userSchema","settings","then","storeEmail","email_confirmation","options","sanitizedUserInfo","sanitizers","defaultSanitizeOutput","schema","bind","confirmationToken","randomBytes","toString","apiPrefix","config","message","template","URL","SERVER_URL","ADMIN_URL","USER","CODE","object","log","error","plugin","service","send","to","email","from","undefined","replyTo","response_email","subject","text","html"],"mappings":"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"}
1
+ {"version":3,"file":"user.mjs","sources":["../../../server/services/user.js"],"sourcesContent":["'use strict';\n\n/**\n * User.js service\n *\n * @description: A set of functions similar to controller's actions to avoid code duplication.\n */\n\nconst crypto = require('crypto');\nconst bcrypt = require('bcryptjs');\nconst urlJoin = require('url-join');\n\nconst { sanitize } = require('@strapi/utils');\nconst { toNumber, getOr } = require('lodash/fp');\nconst { getService } = require('../utils');\n\nconst USER_MODEL_UID = 'plugin::users-permissions.user';\n\nconst getSessionManager = () => {\n const manager = strapi.sessionManager;\n return manager ?? null;\n};\n\nmodule.exports = ({ strapi }) => ({\n /**\n * Promise to count users\n *\n * @return {Promise}\n */\n\n count(params) {\n return strapi.db.query(USER_MODEL_UID).count({ where: params });\n },\n\n /**\n * Hashes password fields in the provided values object if they are present.\n * It checks each key in the values object against the model's attributes and\n * hashes it if the attribute type is 'password',\n *\n * @param {object} values - The object containing the fields to be hashed.\n * @return {object} The values object with hashed password fields if they were present.\n */\n async ensureHashedPasswords(values) {\n const attributes = strapi.getModel(USER_MODEL_UID).attributes;\n\n for (const key in values) {\n if (attributes[key] && attributes[key].type === 'password') {\n // Check if a custom encryption.rounds has been set on the password attribute\n const rounds = toNumber(getOr(10, 'encryption.rounds', attributes[key]));\n values[key] = await bcrypt.hash(values[key], rounds);\n }\n }\n\n return values;\n },\n\n /**\n * Promise to add a/an user.\n * @return {Promise}\n */\n async add(values) {\n return strapi.db.query(USER_MODEL_UID).create({\n data: await this.ensureHashedPasswords(values),\n populate: ['role'],\n });\n },\n\n /**\n * Promise to edit a/an user.\n * @param {string} userId\n * @param {object} params\n * @return {Promise}\n */\n async edit(userId, params = {}) {\n return strapi.db.query(USER_MODEL_UID).update({\n where: { id: userId },\n data: await this.ensureHashedPasswords(params),\n populate: ['role'],\n });\n },\n\n /**\n * Promise to fetch a/an user.\n * @return {Promise}\n */\n fetch(id, params) {\n const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});\n\n return strapi.db.query(USER_MODEL_UID).findOne({\n ...query,\n where: {\n $and: [{ id }, query.where || {}],\n },\n });\n },\n\n /**\n * Promise to fetch authenticated user.\n * @return {Promise}\n */\n fetchAuthenticatedUser(id) {\n return strapi.db.query(USER_MODEL_UID).findOne({ where: { id }, populate: ['role'] });\n },\n\n /**\n * Promise to fetch all users.\n * @return {Promise}\n */\n fetchAll(params) {\n const query = strapi.get('query-params').transform(USER_MODEL_UID, params ?? {});\n\n return strapi.db.query(USER_MODEL_UID).findMany(query);\n },\n\n /**\n * Promise to remove a/an user.\n * @return {Promise}\n */\n async remove(params) {\n // Invalidate sessions for all affected users\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('users-permissions') && params.id) {\n await sessionManager('users-permissions').invalidateRefreshToken(String(params.id));\n }\n\n return strapi.db.query(USER_MODEL_UID).delete({ where: params });\n },\n\n validatePassword(password, hash) {\n return bcrypt.compare(password, hash);\n },\n\n async sendConfirmationEmail(user) {\n const userPermissionService = getService('users-permissions');\n const pluginStore = await strapi.store({ type: 'plugin', name: 'users-permissions' });\n const userSchema = strapi.getModel(USER_MODEL_UID);\n\n const settings = await pluginStore\n .get({ key: 'email' })\n .then((storeEmail) => storeEmail.email_confirmation.options);\n\n // Sanitize the template's user information\n const sanitizedUserInfo = await sanitize.sanitizers.defaultSanitizeOutput(\n {\n schema: userSchema,\n getModel: strapi.getModel.bind(strapi),\n },\n user\n );\n\n const confirmationToken = crypto.randomBytes(20).toString('hex');\n\n await this.edit(user.id, { confirmationToken });\n\n const apiPrefix = strapi.config.get('api.rest.prefix');\n\n try {\n settings.message = await userPermissionService.template(settings.message, {\n URL: urlJoin(\n strapi.config.get('server.absoluteUrl'),\n apiPrefix,\n '/auth/email-confirmation'\n ),\n SERVER_URL: strapi.config.get('server.absoluteUrl'),\n ADMIN_URL: strapi.config.get('admin.absoluteUrl'),\n USER: sanitizedUserInfo,\n CODE: confirmationToken,\n });\n\n settings.object = await userPermissionService.template(settings.object, {\n USER: sanitizedUserInfo,\n });\n } catch {\n strapi.log.error(\n '[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'\n );\n return;\n }\n\n // Send an email to the user.\n await strapi\n .plugin('email')\n .service('email')\n .send({\n to: user.email,\n from:\n settings.from.email && settings.from.name\n ? `${settings.from.name} <${settings.from.email}>`\n : undefined,\n replyTo: settings.response_email,\n subject: settings.object,\n text: settings.message,\n html: settings.message,\n });\n },\n});\n"],"names":["crypto","require$$0","bcrypt","require$$1","urlJoin","require$$2","sanitize","require$$3","toNumber","getOr","require$$4","getService","require$$5","USER_MODEL_UID","getSessionManager","manager","strapi","sessionManager","user","count","params","db","query","where","ensureHashedPasswords","values","attributes","getModel","key","type","rounds","hash","add","create","data","populate","edit","userId","update","id","fetch","get","transform","findOne","$and","fetchAuthenticatedUser","fetchAll","findMany","remove","hasOrigin","invalidateRefreshToken","String","delete","validatePassword","password","compare","sendConfirmationEmail","userPermissionService","pluginStore","store","name","userSchema","settings","then","storeEmail","email_confirmation","options","sanitizedUserInfo","sanitizers","defaultSanitizeOutput","schema","bind","confirmationToken","randomBytes","toString","apiPrefix","config","message","template","URL","SERVER_URL","ADMIN_URL","USER","CODE","object","log","error","plugin","service","send","to","email","from","undefined","replyTo","response_email","subject","text","html"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/plugin-users-permissions",
3
- "version": "5.23.6",
3
+ "version": "5.24.1",
4
4
  "description": "Protect your API with a full-authentication process based on JWT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -50,7 +50,7 @@
50
50
  "dependencies": {
51
51
  "@strapi/design-system": "2.0.0-rc.29",
52
52
  "@strapi/icons": "2.0.0-rc.29",
53
- "@strapi/utils": "5.23.6",
53
+ "@strapi/utils": "5.24.1",
54
54
  "bcryptjs": "2.4.3",
55
55
  "formik": "2.4.5",
56
56
  "grant": "^5.4.8",
@@ -70,7 +70,7 @@
70
70
  "zod": "3.25.67"
71
71
  },
72
72
  "devDependencies": {
73
- "@strapi/strapi": "5.23.6",
73
+ "@strapi/strapi": "5.24.1",
74
74
  "@testing-library/dom": "10.1.0",
75
75
  "@testing-library/react": "15.0.7",
76
76
  "@testing-library/user-event": "14.5.2",
@@ -11,6 +11,18 @@ const crypto = require('crypto');
11
11
  const _ = require('lodash');
12
12
  const { getService } = require('../utils');
13
13
  const usersPermissionsActions = require('./users-permissions-actions');
14
+ const {
15
+ DEFAULT_ACCESS_TOKEN_LIFESPAN,
16
+ DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN,
17
+ DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN,
18
+ DEFAULT_MAX_SESSION_LIFESPAN,
19
+ DEFAULT_IDLE_SESSION_LIFESPAN,
20
+ } = require('../services/constants');
21
+
22
+ const getSessionManager = () => {
23
+ const manager = strapi.sessionManager;
24
+ return manager ?? null;
25
+ };
14
26
 
15
27
  const initGrant = async (pluginStore) => {
16
28
  const allProviders = getService('providers-registry').getAll();
@@ -113,6 +125,23 @@ module.exports = async ({ strapi }) => {
113
125
 
114
126
  await getService('users-permissions').initialize();
115
127
 
128
+ // Define users-permissions origin configuration for sessionManager
129
+ const upConfig = strapi.config.get('plugin::users-permissions');
130
+ const sessionManager = getSessionManager();
131
+
132
+ if (sessionManager) {
133
+ sessionManager.defineOrigin('users-permissions', {
134
+ jwtSecret: upConfig.jwtSecret || strapi.config.get('admin.auth.secret'),
135
+ accessTokenLifespan: upConfig.sessions?.accessTokenLifespan || DEFAULT_ACCESS_TOKEN_LIFESPAN,
136
+ maxRefreshTokenLifespan:
137
+ upConfig.sessions?.maxRefreshTokenLifespan || DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN,
138
+ idleRefreshTokenLifespan:
139
+ upConfig.sessions?.idleRefreshTokenLifespan || DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN,
140
+ maxSessionLifespan: upConfig.sessions?.maxSessionLifespan || DEFAULT_MAX_SESSION_LIFESPAN,
141
+ idleSessionLifespan: upConfig.sessions?.idleSessionLifespan || DEFAULT_IDLE_SESSION_LIFESPAN,
142
+ });
143
+ }
144
+
116
145
  if (!strapi.config.get('plugin::users-permissions.jwtSecret')) {
117
146
  if (process.env.NODE_ENV !== 'development') {
118
147
  throw new Error(
package/server/config.js CHANGED
@@ -1,11 +1,33 @@
1
1
  'use strict';
2
2
 
3
+ const {
4
+ DEFAULT_ACCESS_TOKEN_LIFESPAN,
5
+ DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN,
6
+ DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN,
7
+ DEFAULT_MAX_SESSION_LIFESPAN,
8
+ DEFAULT_IDLE_SESSION_LIFESPAN,
9
+ } = require('./services/constants');
10
+
3
11
  module.exports = {
4
12
  default: ({ env }) => ({
5
13
  jwtSecret: env('JWT_SECRET'),
6
14
  jwt: {
7
15
  expiresIn: '30d',
8
16
  },
17
+ /**
18
+ * JWT management mode for the Content API authentication
19
+ * - "legacy-support": use plugin JWTs (backward compatible)
20
+ * - "refresh": use SessionManager (access/refresh tokens)
21
+ */
22
+ jwtManagement: 'legacy-support',
23
+ sessions: {
24
+ accessTokenLifespan: DEFAULT_ACCESS_TOKEN_LIFESPAN,
25
+ maxRefreshTokenLifespan: DEFAULT_MAX_REFRESH_TOKEN_LIFESPAN,
26
+ idleRefreshTokenLifespan: DEFAULT_IDLE_REFRESH_TOKEN_LIFESPAN,
27
+ maxSessionLifespan: DEFAULT_MAX_SESSION_LIFESPAN,
28
+ idleSessionLifespan: DEFAULT_IDLE_SESSION_LIFESPAN,
29
+ httpOnly: false,
30
+ },
9
31
  ratelimit: {
10
32
  interval: 60000,
11
33
  max: 10,