@strapi/admin 5.50.1 → 5.51.0

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 (174) hide show
  1. package/dist/admin/admin/src/components/NpsSurvey.js.map +1 -1
  2. package/dist/admin/admin/src/components/NpsSurvey.mjs.map +1 -1
  3. package/dist/admin/admin/src/hooks/useMenu.js +1 -1
  4. package/dist/admin/admin/src/hooks/useMenu.js.map +1 -1
  5. package/dist/admin/admin/src/hooks/useMenu.mjs +1 -1
  6. package/dist/admin/admin/src/hooks/useMenu.mjs.map +1 -1
  7. package/dist/admin/admin/src/hooks/useRBAC.js +1 -1
  8. package/dist/admin/admin/src/hooks/useRBAC.js.map +1 -1
  9. package/dist/admin/admin/src/hooks/useRBAC.mjs +1 -1
  10. package/dist/admin/admin/src/hooks/useRBAC.mjs.map +1 -1
  11. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js +3 -9
  12. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
  13. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs +3 -9
  14. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
  15. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js +14 -6
  16. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js.map +1 -1
  17. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs +14 -6
  18. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs.map +1 -1
  19. package/dist/admin/admin/src/reducer.js +3 -3
  20. package/dist/admin/admin/src/reducer.js.map +1 -1
  21. package/dist/admin/admin/src/reducer.mjs +4 -4
  22. package/dist/admin/admin/src/reducer.mjs.map +1 -1
  23. package/dist/admin/admin/src/render.js +6 -2
  24. package/dist/admin/admin/src/render.js.map +1 -1
  25. package/dist/admin/admin/src/render.mjs +6 -2
  26. package/dist/admin/admin/src/render.mjs.map +1 -1
  27. package/dist/admin/admin/src/translations/en.json.js +1 -2
  28. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  29. package/dist/admin/admin/src/translations/en.json.mjs +1 -2
  30. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  31. package/dist/admin/admin/src/translations/ko.json.js +157 -1
  32. package/dist/admin/admin/src/translations/ko.json.js.map +1 -1
  33. package/dist/admin/admin/src/translations/ko.json.mjs +157 -1
  34. package/dist/admin/admin/src/translations/ko.json.mjs.map +1 -1
  35. package/dist/admin/admin/src/utils/cookies.js +84 -2
  36. package/dist/admin/admin/src/utils/cookies.js.map +1 -1
  37. package/dist/admin/admin/src/utils/cookies.mjs +82 -3
  38. package/dist/admin/admin/src/utils/cookies.mjs.map +1 -1
  39. package/dist/admin/admin/src/utils/getFetchClient.js +2 -2
  40. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  41. package/dist/admin/admin/src/utils/getFetchClient.mjs +3 -3
  42. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  43. package/dist/admin/admin/src/utils/getProjectType.js +22 -0
  44. package/dist/admin/admin/src/utils/getProjectType.js.map +1 -0
  45. package/dist/admin/admin/src/utils/getProjectType.mjs +20 -0
  46. package/dist/admin/admin/src/utils/getProjectType.mjs.map +1 -0
  47. package/dist/admin/ee/admin/src/pages/AuthResponse.js +1 -1
  48. package/dist/admin/ee/admin/src/pages/AuthResponse.js.map +1 -1
  49. package/dist/admin/ee/admin/src/pages/AuthResponse.mjs +2 -2
  50. package/dist/admin/ee/admin/src/pages/AuthResponse.mjs.map +1 -1
  51. package/dist/admin/shared/utils/auth-cookie-domain.js +41 -0
  52. package/dist/admin/shared/utils/auth-cookie-domain.js.map +1 -0
  53. package/dist/admin/shared/utils/auth-cookie-domain.mjs +38 -0
  54. package/dist/admin/shared/utils/auth-cookie-domain.mjs.map +1 -0
  55. package/dist/admin/shared/utils/auth-cookie-name.js +31 -0
  56. package/dist/admin/shared/utils/auth-cookie-name.js.map +1 -0
  57. package/dist/admin/shared/utils/auth-cookie-name.mjs +28 -0
  58. package/dist/admin/shared/utils/auth-cookie-name.mjs.map +1 -0
  59. package/dist/admin/shared/utils/auth-cookie-path.js +39 -0
  60. package/dist/admin/shared/utils/auth-cookie-path.js.map +1 -0
  61. package/dist/admin/shared/utils/auth-cookie-path.mjs +36 -0
  62. package/dist/admin/shared/utils/auth-cookie-path.mjs.map +1 -0
  63. package/dist/admin/src/pages/Settings/pages/Webhooks/hooks/useWebhooks.d.ts +3 -3
  64. package/dist/admin/src/services/apiTokens.d.ts +2 -2
  65. package/dist/admin/src/services/webhooks.d.ts +2 -2
  66. package/dist/admin/src/utils/cookies.d.ts +26 -0
  67. package/dist/admin/src/utils/getProjectType.d.ts +16 -0
  68. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useAuditLogsData.d.ts +1 -1
  69. package/dist/ee/admin/src/services/ai.d.ts +3 -3
  70. package/dist/ee/admin/src/services/auditLogs.d.ts +1 -1
  71. package/dist/ee/server/src/audit-logs/routes/audit-logs.d.ts +1 -1
  72. package/dist/ee/server/src/controllers/admin.d.ts +2 -0
  73. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  74. package/dist/ee/server/src/controllers/authentication-utils/middlewares.d.ts.map +1 -1
  75. package/dist/ee/server/src/controllers/index.d.ts +2 -0
  76. package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
  77. package/dist/ee/server/src/index.d.ts +2 -0
  78. package/dist/ee/server/src/index.d.ts.map +1 -1
  79. package/dist/ee/server/src/routes/index.d.ts +2 -2
  80. package/dist/ee/server/src/routes/sso.d.ts +2 -2
  81. package/dist/ee/server/src/services/auth.d.ts.map +1 -1
  82. package/dist/ee/server/src/services/index.d.ts +2 -2
  83. package/dist/ee/server/src/services/user.d.ts.map +1 -1
  84. package/dist/server/ee/server/src/controllers/admin.js +1 -0
  85. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  86. package/dist/server/ee/server/src/controllers/admin.mjs +1 -0
  87. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  88. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js +10 -4
  89. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js.map +1 -1
  90. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs +11 -5
  91. package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs.map +1 -1
  92. package/dist/server/ee/server/src/services/auth.js +5 -5
  93. package/dist/server/ee/server/src/services/auth.js.map +1 -1
  94. package/dist/server/ee/server/src/services/auth.mjs +5 -5
  95. package/dist/server/ee/server/src/services/auth.mjs.map +1 -1
  96. package/dist/server/ee/server/src/services/user.js +1 -0
  97. package/dist/server/ee/server/src/services/user.js.map +1 -1
  98. package/dist/server/ee/server/src/services/user.mjs +1 -0
  99. package/dist/server/ee/server/src/services/user.mjs.map +1 -1
  100. package/dist/server/server/src/content-types/User.js +6 -0
  101. package/dist/server/server/src/content-types/User.js.map +1 -1
  102. package/dist/server/server/src/content-types/User.mjs +6 -0
  103. package/dist/server/server/src/content-types/User.mjs.map +1 -1
  104. package/dist/server/server/src/controllers/authentication.js +12 -10
  105. package/dist/server/server/src/controllers/authentication.js.map +1 -1
  106. package/dist/server/server/src/controllers/authentication.mjs +10 -8
  107. package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
  108. package/dist/server/server/src/routes/serve-admin-panel.js +17 -4
  109. package/dist/server/server/src/routes/serve-admin-panel.js.map +1 -1
  110. package/dist/server/server/src/routes/serve-admin-panel.mjs +17 -4
  111. package/dist/server/server/src/routes/serve-admin-panel.mjs.map +1 -1
  112. package/dist/server/server/src/services/auth.js +51 -6
  113. package/dist/server/server/src/services/auth.js.map +1 -1
  114. package/dist/server/server/src/services/auth.mjs +46 -6
  115. package/dist/server/server/src/services/auth.mjs.map +1 -1
  116. package/dist/server/server/src/services/index.js +1 -1
  117. package/dist/server/server/src/services/index.js.map +1 -1
  118. package/dist/server/server/src/services/user.js +1 -0
  119. package/dist/server/server/src/services/user.js.map +1 -1
  120. package/dist/server/server/src/services/user.mjs +1 -0
  121. package/dist/server/server/src/services/user.mjs.map +1 -1
  122. package/dist/server/shared/utils/auth-cookie-domain.js +41 -0
  123. package/dist/server/shared/utils/auth-cookie-domain.js.map +1 -0
  124. package/dist/server/shared/utils/auth-cookie-domain.mjs +38 -0
  125. package/dist/server/shared/utils/auth-cookie-domain.mjs.map +1 -0
  126. package/dist/server/shared/utils/auth-cookie-name.js +31 -0
  127. package/dist/server/shared/utils/auth-cookie-name.js.map +1 -0
  128. package/dist/server/shared/utils/auth-cookie-name.mjs +28 -0
  129. package/dist/server/shared/utils/auth-cookie-name.mjs.map +1 -0
  130. package/dist/server/shared/utils/auth-cookie-path.js +39 -0
  131. package/dist/server/shared/utils/auth-cookie-path.js.map +1 -0
  132. package/dist/server/shared/utils/auth-cookie-path.mjs +36 -0
  133. package/dist/server/shared/utils/auth-cookie-path.mjs.map +1 -0
  134. package/dist/server/shared/utils/session-auth.js +59 -2
  135. package/dist/server/shared/utils/session-auth.js.map +1 -1
  136. package/dist/server/shared/utils/session-auth.mjs +55 -3
  137. package/dist/server/shared/utils/session-auth.mjs.map +1 -1
  138. package/dist/server/src/content-types/User.d.ts +6 -0
  139. package/dist/server/src/content-types/User.d.ts.map +1 -1
  140. package/dist/server/src/content-types/index.d.ts +6 -0
  141. package/dist/server/src/content-types/index.d.ts.map +1 -1
  142. package/dist/server/src/controllers/admin.d.ts +3 -3
  143. package/dist/server/src/controllers/authentication.d.ts.map +1 -1
  144. package/dist/server/src/controllers/index.d.ts +3 -3
  145. package/dist/server/src/domain/user.d.ts +2 -1
  146. package/dist/server/src/domain/user.d.ts.map +1 -1
  147. package/dist/server/src/index.d.ts +25 -19
  148. package/dist/server/src/index.d.ts.map +1 -1
  149. package/dist/server/src/middlewares/index.d.ts +1 -1
  150. package/dist/server/src/routes/serve-admin-panel.d.ts.map +1 -1
  151. package/dist/server/src/services/auth.d.ts +18 -0
  152. package/dist/server/src/services/auth.d.ts.map +1 -1
  153. package/dist/server/src/services/index.d.ts +13 -13
  154. package/dist/server/src/services/index.d.ts.map +1 -1
  155. package/dist/server/src/services/user.d.ts.map +1 -1
  156. package/dist/shared/contracts/shared.d.ts +2 -1
  157. package/dist/shared/contracts/shared.d.ts.map +1 -1
  158. package/dist/shared/utils/__tests__/auth-cookie-domain.test.d.ts +1 -0
  159. package/dist/shared/utils/__tests__/auth-cookie-domain.test.d.ts.map +1 -0
  160. package/dist/shared/utils/__tests__/auth-cookie-name.test.d.ts +1 -0
  161. package/dist/shared/utils/__tests__/auth-cookie-name.test.d.ts.map +1 -0
  162. package/dist/shared/utils/__tests__/auth-cookie-path.test.d.ts +1 -0
  163. package/dist/shared/utils/__tests__/auth-cookie-path.test.d.ts.map +1 -0
  164. package/dist/shared/utils/__tests__/session-auth.test.d.ts +1 -0
  165. package/dist/shared/utils/__tests__/session-auth.test.d.ts.map +1 -0
  166. package/dist/shared/utils/auth-cookie-domain.d.ts +21 -0
  167. package/dist/shared/utils/auth-cookie-domain.d.ts.map +1 -0
  168. package/dist/shared/utils/auth-cookie-name.d.ts +14 -0
  169. package/dist/shared/utils/auth-cookie-name.d.ts.map +1 -0
  170. package/dist/shared/utils/auth-cookie-path.d.ts +17 -0
  171. package/dist/shared/utils/auth-cookie-path.d.ts.map +1 -0
  172. package/dist/shared/utils/session-auth.d.ts +16 -0
  173. package/dist/shared/utils/session-auth.d.ts.map +1 -1
  174. package/package.json +20 -17
@@ -1 +1 @@
1
- {"version":3,"file":"serve-admin-panel.js","sources":["../../../../../server/src/routes/serve-admin-panel.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport { resolve, join, extname, basename } from 'path';\nimport fse from 'fs-extra';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\nconst registerAdminPanelRoute = ({ strapi }: { strapi: Core.Strapi }) => {\n let buildDir = resolve(strapi.dirs.dist.root, 'build');\n\n if (!fse.pathExistsSync(buildDir)) {\n buildDir = resolve(__dirname, '../../build');\n }\n\n const serveAdminMiddleware = async (ctx: Context, next: Next) => {\n await next();\n\n if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {\n return;\n }\n\n if (ctx.body != null || ctx.status !== 404) {\n return;\n }\n\n ctx.type = 'html';\n ctx.body = fse.createReadStream(join(buildDir, 'index.html'));\n };\n\n strapi.server.routes([\n {\n method: 'GET',\n path: `${strapi.config.admin.path}/:path*`,\n handler: [\n serveAdminMiddleware,\n serveStatic(buildDir, {\n maxage: 31536000,\n defer: false,\n index: 'index.html',\n setHeaders(res: any, path: any) {\n const ext = extname(path);\n // publicly cache static files to avoid unnecessary network & disk access\n if (ext !== '.html') {\n res.setHeader('cache-control', 'public, max-age=31536000, immutable');\n }\n },\n }),\n ],\n config: { auth: false },\n },\n ]);\n};\n\n// serveStatic is not supposed to be used to serve a folder that have sub-folders\nexport const serveStatic = (filesDir: any, koaStaticOptions = {}) => {\n const serve = koaStatic(filesDir, koaStaticOptions);\n\n return async (ctx: Context, next: Next) => {\n if (!extname(ctx.path)) {\n await next();\n return;\n }\n\n const prev = ctx.path;\n const newPath = `/${basename(ctx.path)}`;\n\n ctx.path = newPath;\n await serve(ctx, async () => {\n ctx.path = prev;\n await next();\n ctx.path = newPath;\n });\n ctx.path = prev;\n };\n};\n\nexport default registerAdminPanelRoute;\n"],"names":["registerAdminPanelRoute","strapi","buildDir","resolve","dirs","dist","root","fse","pathExistsSync","__dirname","serveAdminMiddleware","ctx","next","method","body","status","type","createReadStream","join","server","routes","path","config","admin","handler","serveStatic","maxage","defer","index","setHeaders","res","ext","extname","setHeader","auth","filesDir","koaStaticOptions","serve","koaStatic","prev","newPath","basename"],"mappings":";;;;;;;;;;;;;AAMA,MAAMA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAClE,IAAIC,QAAAA,GAAWC,aAAQF,MAAAA,CAAOG,IAAI,CAACC,IAAI,CAACC,IAAI,EAAE,OAAA,CAAA;AAE9C,IAAA,IAAI,CAACC,oBAAAA,CAAIC,cAAc,CAACN,QAAAA,CAAAA,EAAW;AACjCA,QAAAA,QAAAA,GAAWC,aAAQM,SAAAA,EAAW,aAAA,CAAA;AAChC,IAAA;IAEA,MAAMC,oBAAAA,GAAuB,OAAOC,GAAAA,EAAcC,IAAAA,GAAAA;QAChD,MAAMA,IAAAA,EAAAA;AAEN,QAAA,IAAID,IAAIE,MAAM,KAAK,UAAUF,GAAAA,CAAIE,MAAM,KAAK,KAAA,EAAO;AACjD,YAAA;AACF,QAAA;AAEA,QAAA,IAAIF,IAAIG,IAAI,IAAI,QAAQH,GAAAA,CAAII,MAAM,KAAK,GAAA,EAAK;AAC1C,YAAA;AACF,QAAA;AAEAJ,QAAAA,GAAAA,CAAIK,IAAI,GAAG,MAAA;AACXL,QAAAA,GAAAA,CAAIG,IAAI,GAAGP,oBAAAA,CAAIU,gBAAgB,CAACC,UAAKhB,QAAAA,EAAU,YAAA,CAAA,CAAA;AACjD,IAAA,CAAA;IAEAD,MAAAA,CAAOkB,MAAM,CAACC,MAAM,CAAC;AACnB,QAAA;YACEP,MAAAA,EAAQ,KAAA;YACRQ,IAAAA,EAAM,CAAA,EAAGpB,OAAOqB,MAAM,CAACC,KAAK,CAACF,IAAI,CAAC,OAAO,CAAC;YAC1CG,OAAAA,EAAS;AACPd,gBAAAA,oBAAAA;AACAe,gBAAAA,WAAAA,CAAYvB,QAAAA,EAAU;oBACpBwB,MAAAA,EAAQ,QAAA;oBACRC,KAAAA,EAAO,KAAA;oBACPC,KAAAA,EAAO,YAAA;oBACPC,UAAAA,CAAAA,CAAWC,GAAQ,EAAET,MAAS,EAAA;AAC5B,wBAAA,MAAMU,MAAMC,YAAAA,CAAQX,MAAAA,CAAAA;;AAEpB,wBAAA,IAAIU,QAAQ,OAAA,EAAS;4BACnBD,GAAAA,CAAIG,SAAS,CAAC,eAAA,EAAiB,qCAAA,CAAA;AACjC,wBAAA;AACF,oBAAA;AACF,iBAAA;AACD,aAAA;YACDX,MAAAA,EAAQ;gBAAEY,IAAAA,EAAM;AAAM;AACxB;AACD,KAAA,CAAA;AACH;AAEA;MACaT,WAAAA,GAAc,CAACU,QAAAA,EAAeC,gBAAAA,GAAmB,EAAE,GAAA;IAC9D,MAAMC,KAAAA,GAAQC,2BAAUH,QAAAA,EAAUC,gBAAAA,CAAAA;AAElC,IAAA,OAAO,OAAOzB,GAAAA,EAAcC,IAAAA,GAAAA;AAC1B,QAAA,IAAI,CAACoB,YAAAA,CAAQrB,GAAAA,CAAIU,IAAI,CAAA,EAAG;YACtB,MAAMT,IAAAA,EAAAA;AACN,YAAA;AACF,QAAA;QAEA,MAAM2B,IAAAA,GAAO5B,IAAIU,IAAI;AACrB,QAAA,MAAMmB,UAAU,CAAC,CAAC,EAAEC,aAAAA,CAAS9B,GAAAA,CAAIU,IAAI,CAAA,CAAA,CAAG;AAExCV,QAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACX,QAAA,MAAMH,MAAM1B,GAAAA,EAAK,UAAA;AACfA,YAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;YACX,MAAM3B,IAAAA,EAAAA;AACND,YAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACb,QAAA,CAAA,CAAA;AACA7B,QAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;AACb,IAAA,CAAA;AACF;;;;;"}
1
+ {"version":3,"file":"serve-admin-panel.js","sources":["../../../../../server/src/routes/serve-admin-panel.ts"],"sourcesContent":["import type { ServerResponse } from 'http';\nimport type { Context, Next } from 'koa';\nimport { resolve, join, extname, basename } from 'path';\nimport fse from 'fs-extra';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\nconst ADMIN_SHELL_CACHE_CONTROL = 'no-cache';\nconst ADMIN_SHELL_SURROGATE_CONTROL = 'no-store';\nconst HASHED_ASSET_CACHE_CONTROL = 'public, max-age=31536000, immutable';\n\nconst applyAdminShellCacheHeaders = (setHeader: (name: string, value: string) => void) => {\n setHeader('Cache-Control', ADMIN_SHELL_CACHE_CONTROL);\n setHeader('Surrogate-Control', ADMIN_SHELL_SURROGATE_CONTROL);\n};\n\nconst registerAdminPanelRoute = ({ strapi }: { strapi: Core.Strapi }) => {\n let buildDir = resolve(strapi.dirs.dist.root, 'build');\n\n if (!fse.pathExistsSync(buildDir)) {\n buildDir = resolve(__dirname, '../../build');\n }\n\n const serveAdminMiddleware = async (ctx: Context, next: Next) => {\n await next();\n\n if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {\n return;\n }\n\n if (ctx.body != null || ctx.status !== 404) {\n return;\n }\n\n applyAdminShellCacheHeaders((name, value) => {\n ctx.set(name, value);\n });\n ctx.type = 'html';\n ctx.body = fse.createReadStream(join(buildDir, 'index.html'));\n };\n\n strapi.server.routes([\n {\n method: 'GET',\n path: `${strapi.config.admin.path}/:path*`,\n handler: [\n serveAdminMiddleware,\n serveStatic(buildDir, {\n maxage: 0,\n defer: false,\n index: 'index.html',\n setHeaders(res: ServerResponse, path: string) {\n const ext = extname(path);\n if (ext === '.html') {\n applyAdminShellCacheHeaders((name, value) => {\n res.setHeader(name, value);\n });\n return;\n }\n\n res.setHeader('Cache-Control', HASHED_ASSET_CACHE_CONTROL);\n },\n }),\n ],\n config: { auth: false },\n },\n ]);\n};\n\n// serveStatic is not supposed to be used to serve a folder that have sub-folders\nexport const serveStatic = (filesDir: any, koaStaticOptions = {}) => {\n const serve = koaStatic(filesDir, koaStaticOptions);\n\n return async (ctx: Context, next: Next) => {\n if (!extname(ctx.path)) {\n await next();\n return;\n }\n\n const prev = ctx.path;\n const newPath = `/${basename(ctx.path)}`;\n\n ctx.path = newPath;\n await serve(ctx, async () => {\n ctx.path = prev;\n await next();\n ctx.path = newPath;\n });\n ctx.path = prev;\n };\n};\n\nexport default registerAdminPanelRoute;\n"],"names":["ADMIN_SHELL_CACHE_CONTROL","ADMIN_SHELL_SURROGATE_CONTROL","HASHED_ASSET_CACHE_CONTROL","applyAdminShellCacheHeaders","setHeader","registerAdminPanelRoute","strapi","buildDir","resolve","dirs","dist","root","fse","pathExistsSync","__dirname","serveAdminMiddleware","ctx","next","method","body","status","name","value","set","type","createReadStream","join","server","routes","path","config","admin","handler","serveStatic","maxage","defer","index","setHeaders","res","ext","extname","auth","filesDir","koaStaticOptions","serve","koaStatic","prev","newPath","basename"],"mappings":";;;;;;;;;;;;;AAOA,MAAMA,yBAAAA,GAA4B,UAAA;AAClC,MAAMC,6BAAAA,GAAgC,UAAA;AACtC,MAAMC,0BAAAA,GAA6B,qCAAA;AAEnC,MAAMC,8BAA8B,CAACC,SAAAA,GAAAA;AACnCA,IAAAA,SAAAA,CAAU,eAAA,EAAiBJ,yBAAAA,CAAAA;AAC3BI,IAAAA,SAAAA,CAAU,mBAAA,EAAqBH,6BAAAA,CAAAA;AACjC,CAAA;AAEA,MAAMI,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAClE,IAAIC,QAAAA,GAAWC,aAAQF,MAAAA,CAAOG,IAAI,CAACC,IAAI,CAACC,IAAI,EAAE,OAAA,CAAA;AAE9C,IAAA,IAAI,CAACC,oBAAAA,CAAIC,cAAc,CAACN,QAAAA,CAAAA,EAAW;AACjCA,QAAAA,QAAAA,GAAWC,aAAQM,SAAAA,EAAW,aAAA,CAAA;AAChC,IAAA;IAEA,MAAMC,oBAAAA,GAAuB,OAAOC,GAAAA,EAAcC,IAAAA,GAAAA;QAChD,MAAMA,IAAAA,EAAAA;AAEN,QAAA,IAAID,IAAIE,MAAM,KAAK,UAAUF,GAAAA,CAAIE,MAAM,KAAK,KAAA,EAAO;AACjD,YAAA;AACF,QAAA;AAEA,QAAA,IAAIF,IAAIG,IAAI,IAAI,QAAQH,GAAAA,CAAII,MAAM,KAAK,GAAA,EAAK;AAC1C,YAAA;AACF,QAAA;AAEAjB,QAAAA,2BAAAA,CAA4B,CAACkB,IAAAA,EAAMC,KAAAA,GAAAA;YACjCN,GAAAA,CAAIO,GAAG,CAACF,IAAAA,EAAMC,KAAAA,CAAAA;AAChB,QAAA,CAAA,CAAA;AACAN,QAAAA,GAAAA,CAAIQ,IAAI,GAAG,MAAA;AACXR,QAAAA,GAAAA,CAAIG,IAAI,GAAGP,oBAAAA,CAAIa,gBAAgB,CAACC,UAAKnB,QAAAA,EAAU,YAAA,CAAA,CAAA;AACjD,IAAA,CAAA;IAEAD,MAAAA,CAAOqB,MAAM,CAACC,MAAM,CAAC;AACnB,QAAA;YACEV,MAAAA,EAAQ,KAAA;YACRW,IAAAA,EAAM,CAAA,EAAGvB,OAAOwB,MAAM,CAACC,KAAK,CAACF,IAAI,CAAC,OAAO,CAAC;YAC1CG,OAAAA,EAAS;AACPjB,gBAAAA,oBAAAA;AACAkB,gBAAAA,WAAAA,CAAY1B,QAAAA,EAAU;oBACpB2B,MAAAA,EAAQ,CAAA;oBACRC,KAAAA,EAAO,KAAA;oBACPC,KAAAA,EAAO,YAAA;oBACPC,UAAAA,CAAAA,CAAWC,GAAmB,EAAET,MAAY,EAAA;AAC1C,wBAAA,MAAMU,MAAMC,YAAAA,CAAQX,MAAAA,CAAAA;AACpB,wBAAA,IAAIU,QAAQ,OAAA,EAAS;AACnBpC,4BAAAA,2BAAAA,CAA4B,CAACkB,IAAAA,EAAMC,KAAAA,GAAAA;gCACjCgB,GAAAA,CAAIlC,SAAS,CAACiB,IAAAA,EAAMC,KAAAA,CAAAA;AACtB,4BAAA,CAAA,CAAA;AACA,4BAAA;AACF,wBAAA;wBAEAgB,GAAAA,CAAIlC,SAAS,CAAC,eAAA,EAAiBF,0BAAAA,CAAAA;AACjC,oBAAA;AACF,iBAAA;AACD,aAAA;YACD4B,MAAAA,EAAQ;gBAAEW,IAAAA,EAAM;AAAM;AACxB;AACD,KAAA,CAAA;AACH;AAEA;MACaR,WAAAA,GAAc,CAACS,QAAAA,EAAeC,gBAAAA,GAAmB,EAAE,GAAA;IAC9D,MAAMC,KAAAA,GAAQC,2BAAUH,QAAAA,EAAUC,gBAAAA,CAAAA;AAElC,IAAA,OAAO,OAAO3B,GAAAA,EAAcC,IAAAA,GAAAA;AAC1B,QAAA,IAAI,CAACuB,YAAAA,CAAQxB,GAAAA,CAAIa,IAAI,CAAA,EAAG;YACtB,MAAMZ,IAAAA,EAAAA;AACN,YAAA;AACF,QAAA;QAEA,MAAM6B,IAAAA,GAAO9B,IAAIa,IAAI;AACrB,QAAA,MAAMkB,UAAU,CAAC,CAAC,EAAEC,aAAAA,CAAShC,GAAAA,CAAIa,IAAI,CAAA,CAAA,CAAG;AAExCb,QAAAA,GAAAA,CAAIa,IAAI,GAAGkB,OAAAA;AACX,QAAA,MAAMH,MAAM5B,GAAAA,EAAK,UAAA;AACfA,YAAAA,GAAAA,CAAIa,IAAI,GAAGiB,IAAAA;YACX,MAAM7B,IAAAA,EAAAA;AACND,YAAAA,GAAAA,CAAIa,IAAI,GAAGkB,OAAAA;AACb,QAAA,CAAA,CAAA;AACA/B,QAAAA,GAAAA,CAAIa,IAAI,GAAGiB,IAAAA;AACb,IAAA,CAAA;AACF;;;;;"}
@@ -2,6 +2,13 @@ import { resolve, join, extname, basename } from 'path';
2
2
  import fse from 'fs-extra';
3
3
  import koaStatic from 'koa-static';
4
4
 
5
+ const ADMIN_SHELL_CACHE_CONTROL = 'no-cache';
6
+ const ADMIN_SHELL_SURROGATE_CONTROL = 'no-store';
7
+ const HASHED_ASSET_CACHE_CONTROL = 'public, max-age=31536000, immutable';
8
+ const applyAdminShellCacheHeaders = (setHeader)=>{
9
+ setHeader('Cache-Control', ADMIN_SHELL_CACHE_CONTROL);
10
+ setHeader('Surrogate-Control', ADMIN_SHELL_SURROGATE_CONTROL);
11
+ };
5
12
  const registerAdminPanelRoute = ({ strapi })=>{
6
13
  let buildDir = resolve(strapi.dirs.dist.root, 'build');
7
14
  if (!fse.pathExistsSync(buildDir)) {
@@ -15,6 +22,9 @@ const registerAdminPanelRoute = ({ strapi })=>{
15
22
  if (ctx.body != null || ctx.status !== 404) {
16
23
  return;
17
24
  }
25
+ applyAdminShellCacheHeaders((name, value)=>{
26
+ ctx.set(name, value);
27
+ });
18
28
  ctx.type = 'html';
19
29
  ctx.body = fse.createReadStream(join(buildDir, 'index.html'));
20
30
  };
@@ -25,15 +35,18 @@ const registerAdminPanelRoute = ({ strapi })=>{
25
35
  handler: [
26
36
  serveAdminMiddleware,
27
37
  serveStatic(buildDir, {
28
- maxage: 31536000,
38
+ maxage: 0,
29
39
  defer: false,
30
40
  index: 'index.html',
31
41
  setHeaders (res, path) {
32
42
  const ext = extname(path);
33
- // publicly cache static files to avoid unnecessary network & disk access
34
- if (ext !== '.html') {
35
- res.setHeader('cache-control', 'public, max-age=31536000, immutable');
43
+ if (ext === '.html') {
44
+ applyAdminShellCacheHeaders((name, value)=>{
45
+ res.setHeader(name, value);
46
+ });
47
+ return;
36
48
  }
49
+ res.setHeader('Cache-Control', HASHED_ASSET_CACHE_CONTROL);
37
50
  }
38
51
  })
39
52
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"serve-admin-panel.mjs","sources":["../../../../../server/src/routes/serve-admin-panel.ts"],"sourcesContent":["import type { Context, Next } from 'koa';\nimport { resolve, join, extname, basename } from 'path';\nimport fse from 'fs-extra';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\nconst registerAdminPanelRoute = ({ strapi }: { strapi: Core.Strapi }) => {\n let buildDir = resolve(strapi.dirs.dist.root, 'build');\n\n if (!fse.pathExistsSync(buildDir)) {\n buildDir = resolve(__dirname, '../../build');\n }\n\n const serveAdminMiddleware = async (ctx: Context, next: Next) => {\n await next();\n\n if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {\n return;\n }\n\n if (ctx.body != null || ctx.status !== 404) {\n return;\n }\n\n ctx.type = 'html';\n ctx.body = fse.createReadStream(join(buildDir, 'index.html'));\n };\n\n strapi.server.routes([\n {\n method: 'GET',\n path: `${strapi.config.admin.path}/:path*`,\n handler: [\n serveAdminMiddleware,\n serveStatic(buildDir, {\n maxage: 31536000,\n defer: false,\n index: 'index.html',\n setHeaders(res: any, path: any) {\n const ext = extname(path);\n // publicly cache static files to avoid unnecessary network & disk access\n if (ext !== '.html') {\n res.setHeader('cache-control', 'public, max-age=31536000, immutable');\n }\n },\n }),\n ],\n config: { auth: false },\n },\n ]);\n};\n\n// serveStatic is not supposed to be used to serve a folder that have sub-folders\nexport const serveStatic = (filesDir: any, koaStaticOptions = {}) => {\n const serve = koaStatic(filesDir, koaStaticOptions);\n\n return async (ctx: Context, next: Next) => {\n if (!extname(ctx.path)) {\n await next();\n return;\n }\n\n const prev = ctx.path;\n const newPath = `/${basename(ctx.path)}`;\n\n ctx.path = newPath;\n await serve(ctx, async () => {\n ctx.path = prev;\n await next();\n ctx.path = newPath;\n });\n ctx.path = prev;\n };\n};\n\nexport default registerAdminPanelRoute;\n"],"names":["registerAdminPanelRoute","strapi","buildDir","resolve","dirs","dist","root","fse","pathExistsSync","__dirname","serveAdminMiddleware","ctx","next","method","body","status","type","createReadStream","join","server","routes","path","config","admin","handler","serveStatic","maxage","defer","index","setHeaders","res","ext","extname","setHeader","auth","filesDir","koaStaticOptions","serve","koaStatic","prev","newPath","basename"],"mappings":";;;;AAMA,MAAMA,uBAAAA,GAA0B,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAClE,IAAIC,QAAAA,GAAWC,QAAQF,MAAAA,CAAOG,IAAI,CAACC,IAAI,CAACC,IAAI,EAAE,OAAA,CAAA;AAE9C,IAAA,IAAI,CAACC,GAAAA,CAAIC,cAAc,CAACN,QAAAA,CAAAA,EAAW;AACjCA,QAAAA,QAAAA,GAAWC,QAAQM,SAAAA,EAAW,aAAA,CAAA;AAChC,IAAA;IAEA,MAAMC,oBAAAA,GAAuB,OAAOC,GAAAA,EAAcC,IAAAA,GAAAA;QAChD,MAAMA,IAAAA,EAAAA;AAEN,QAAA,IAAID,IAAIE,MAAM,KAAK,UAAUF,GAAAA,CAAIE,MAAM,KAAK,KAAA,EAAO;AACjD,YAAA;AACF,QAAA;AAEA,QAAA,IAAIF,IAAIG,IAAI,IAAI,QAAQH,GAAAA,CAAII,MAAM,KAAK,GAAA,EAAK;AAC1C,YAAA;AACF,QAAA;AAEAJ,QAAAA,GAAAA,CAAIK,IAAI,GAAG,MAAA;AACXL,QAAAA,GAAAA,CAAIG,IAAI,GAAGP,GAAAA,CAAIU,gBAAgB,CAACC,KAAKhB,QAAAA,EAAU,YAAA,CAAA,CAAA;AACjD,IAAA,CAAA;IAEAD,MAAAA,CAAOkB,MAAM,CAACC,MAAM,CAAC;AACnB,QAAA;YACEP,MAAAA,EAAQ,KAAA;YACRQ,IAAAA,EAAM,CAAA,EAAGpB,OAAOqB,MAAM,CAACC,KAAK,CAACF,IAAI,CAAC,OAAO,CAAC;YAC1CG,OAAAA,EAAS;AACPd,gBAAAA,oBAAAA;AACAe,gBAAAA,WAAAA,CAAYvB,QAAAA,EAAU;oBACpBwB,MAAAA,EAAQ,QAAA;oBACRC,KAAAA,EAAO,KAAA;oBACPC,KAAAA,EAAO,YAAA;oBACPC,UAAAA,CAAAA,CAAWC,GAAQ,EAAET,IAAS,EAAA;AAC5B,wBAAA,MAAMU,MAAMC,OAAAA,CAAQX,IAAAA,CAAAA;;AAEpB,wBAAA,IAAIU,QAAQ,OAAA,EAAS;4BACnBD,GAAAA,CAAIG,SAAS,CAAC,eAAA,EAAiB,qCAAA,CAAA;AACjC,wBAAA;AACF,oBAAA;AACF,iBAAA;AACD,aAAA;YACDX,MAAAA,EAAQ;gBAAEY,IAAAA,EAAM;AAAM;AACxB;AACD,KAAA,CAAA;AACH;AAEA;MACaT,WAAAA,GAAc,CAACU,QAAAA,EAAeC,gBAAAA,GAAmB,EAAE,GAAA;IAC9D,MAAMC,KAAAA,GAAQC,UAAUH,QAAAA,EAAUC,gBAAAA,CAAAA;AAElC,IAAA,OAAO,OAAOzB,GAAAA,EAAcC,IAAAA,GAAAA;AAC1B,QAAA,IAAI,CAACoB,OAAAA,CAAQrB,GAAAA,CAAIU,IAAI,CAAA,EAAG;YACtB,MAAMT,IAAAA,EAAAA;AACN,YAAA;AACF,QAAA;QAEA,MAAM2B,IAAAA,GAAO5B,IAAIU,IAAI;AACrB,QAAA,MAAMmB,UAAU,CAAC,CAAC,EAAEC,QAAAA,CAAS9B,GAAAA,CAAIU,IAAI,CAAA,CAAA,CAAG;AAExCV,QAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACX,QAAA,MAAMH,MAAM1B,GAAAA,EAAK,UAAA;AACfA,YAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;YACX,MAAM3B,IAAAA,EAAAA;AACND,YAAAA,GAAAA,CAAIU,IAAI,GAAGmB,OAAAA;AACb,QAAA,CAAA,CAAA;AACA7B,QAAAA,GAAAA,CAAIU,IAAI,GAAGkB,IAAAA;AACb,IAAA,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"serve-admin-panel.mjs","sources":["../../../../../server/src/routes/serve-admin-panel.ts"],"sourcesContent":["import type { ServerResponse } from 'http';\nimport type { Context, Next } from 'koa';\nimport { resolve, join, extname, basename } from 'path';\nimport fse from 'fs-extra';\nimport koaStatic from 'koa-static';\nimport type { Core } from '@strapi/types';\n\nconst ADMIN_SHELL_CACHE_CONTROL = 'no-cache';\nconst ADMIN_SHELL_SURROGATE_CONTROL = 'no-store';\nconst HASHED_ASSET_CACHE_CONTROL = 'public, max-age=31536000, immutable';\n\nconst applyAdminShellCacheHeaders = (setHeader: (name: string, value: string) => void) => {\n setHeader('Cache-Control', ADMIN_SHELL_CACHE_CONTROL);\n setHeader('Surrogate-Control', ADMIN_SHELL_SURROGATE_CONTROL);\n};\n\nconst registerAdminPanelRoute = ({ strapi }: { strapi: Core.Strapi }) => {\n let buildDir = resolve(strapi.dirs.dist.root, 'build');\n\n if (!fse.pathExistsSync(buildDir)) {\n buildDir = resolve(__dirname, '../../build');\n }\n\n const serveAdminMiddleware = async (ctx: Context, next: Next) => {\n await next();\n\n if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {\n return;\n }\n\n if (ctx.body != null || ctx.status !== 404) {\n return;\n }\n\n applyAdminShellCacheHeaders((name, value) => {\n ctx.set(name, value);\n });\n ctx.type = 'html';\n ctx.body = fse.createReadStream(join(buildDir, 'index.html'));\n };\n\n strapi.server.routes([\n {\n method: 'GET',\n path: `${strapi.config.admin.path}/:path*`,\n handler: [\n serveAdminMiddleware,\n serveStatic(buildDir, {\n maxage: 0,\n defer: false,\n index: 'index.html',\n setHeaders(res: ServerResponse, path: string) {\n const ext = extname(path);\n if (ext === '.html') {\n applyAdminShellCacheHeaders((name, value) => {\n res.setHeader(name, value);\n });\n return;\n }\n\n res.setHeader('Cache-Control', HASHED_ASSET_CACHE_CONTROL);\n },\n }),\n ],\n config: { auth: false },\n },\n ]);\n};\n\n// serveStatic is not supposed to be used to serve a folder that have sub-folders\nexport const serveStatic = (filesDir: any, koaStaticOptions = {}) => {\n const serve = koaStatic(filesDir, koaStaticOptions);\n\n return async (ctx: Context, next: Next) => {\n if (!extname(ctx.path)) {\n await next();\n return;\n }\n\n const prev = ctx.path;\n const newPath = `/${basename(ctx.path)}`;\n\n ctx.path = newPath;\n await serve(ctx, async () => {\n ctx.path = prev;\n await next();\n ctx.path = newPath;\n });\n ctx.path = prev;\n };\n};\n\nexport default registerAdminPanelRoute;\n"],"names":["ADMIN_SHELL_CACHE_CONTROL","ADMIN_SHELL_SURROGATE_CONTROL","HASHED_ASSET_CACHE_CONTROL","applyAdminShellCacheHeaders","setHeader","registerAdminPanelRoute","strapi","buildDir","resolve","dirs","dist","root","fse","pathExistsSync","__dirname","serveAdminMiddleware","ctx","next","method","body","status","name","value","set","type","createReadStream","join","server","routes","path","config","admin","handler","serveStatic","maxage","defer","index","setHeaders","res","ext","extname","auth","filesDir","koaStaticOptions","serve","koaStatic","prev","newPath","basename"],"mappings":"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"}
@@ -1,9 +1,12 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
3
5
  var bcrypt = require('bcryptjs');
4
6
  var _ = require('lodash');
5
7
  var utils = require('@strapi/utils');
6
8
  var index = require('../utils/index.js');
9
+ var token = require('./token.js');
7
10
  require('@strapi/types');
8
11
 
9
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -12,6 +15,46 @@ var bcrypt__default = /*#__PURE__*/_interopDefault(bcrypt);
12
15
  var ___default = /*#__PURE__*/_interopDefault(_);
13
16
 
14
17
  const { ApplicationError } = utils.errors;
18
+ // Default lifetime of an admin reset-password token. Overridable via
19
+ // `admin.forgotPassword.expiresIn` (number of seconds or a shorthand like '15m', '1h').
20
+ const DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';
21
+ /**
22
+ * Resolve the reset-password token lifetime, in milliseconds, from config.
23
+ * Falls back to {@link DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN} for unset/invalid values.
24
+ */ const getResetPasswordTokenTTL = ()=>{
25
+ const configured = strapi.config.get('admin.forgotPassword.expiresIn', DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN);
26
+ const seconds = token.expiresInToSeconds(configured) ?? token.expiresInToSeconds(DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN);
27
+ return seconds * 1000;
28
+ };
29
+ /**
30
+ * Create a reset-password token with an expiry and persist it on the user.
31
+ * Shared by the CE and EE auth services so the expiry behaviour can't drift.
32
+ * @returns the generated reset-password token
33
+ */ const assignResetPasswordToken = async (userId)=>{
34
+ const resetPasswordToken = index.getService('token').createToken();
35
+ const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());
36
+ await index.getService('user').updateById(userId, {
37
+ resetPasswordToken,
38
+ resetPasswordTokenExpiresAt
39
+ });
40
+ return resetPasswordToken;
41
+ };
42
+ /**
43
+ * Reject a reset-password token that has expired — or that has no expiry at all
44
+ * (tokens issued before this was introduced) — clearing the stale token so it
45
+ * cannot be retried. Shared by the CE and EE auth services. (GH#25711)
46
+ */ const assertResetPasswordTokenIsValid = async (user)=>{
47
+ const { resetPasswordTokenExpiresAt } = user;
48
+ const isExpired = !resetPasswordTokenExpiresAt || new Date(resetPasswordTokenExpiresAt).getTime() <= Date.now();
49
+ if (isExpired) {
50
+ // Clear the stale token so it can no longer be retried.
51
+ await index.getService('user').updateById(user.id, {
52
+ resetPasswordToken: null,
53
+ resetPasswordTokenExpiresAt: null
54
+ });
55
+ throw new ApplicationError('This reset password token has expired');
56
+ }
57
+ };
15
58
  /**
16
59
  * hashes a password
17
60
  * @param password - password to hash
@@ -79,10 +122,7 @@ const { ApplicationError } = utils.errors;
79
122
  if (!user) {
80
123
  return;
81
124
  }
82
- const resetPasswordToken = index.getService('token').createToken();
83
- await index.getService('user').updateById(user.id, {
84
- resetPasswordToken
85
- });
125
+ const resetPasswordToken = await assignResetPasswordToken(user.id);
86
126
  // Send an email to the admin.
87
127
  const url = `${strapi.config.get('admin.absoluteUrl')}/auth/reset-password?code=${resetPasswordToken}`;
88
128
  return strapi.plugin('email').service('email').sendTemplatedEmail({
@@ -116,9 +156,11 @@ const { ApplicationError } = utils.errors;
116
156
  if (!matchingUser) {
117
157
  throw new ApplicationError();
118
158
  }
159
+ await assertResetPasswordTokenIsValid(matchingUser);
119
160
  return index.getService('user').updateById(matchingUser.id, {
120
161
  password,
121
- resetPasswordToken: null
162
+ resetPasswordToken: null,
163
+ resetPasswordTokenExpiresAt: null
122
164
  });
123
165
  };
124
166
  var auth = {
@@ -129,5 +171,8 @@ var auth = {
129
171
  resetPassword
130
172
  };
131
173
 
132
- module.exports = auth;
174
+ exports.assertResetPasswordTokenIsValid = assertResetPasswordTokenIsValid;
175
+ exports.assignResetPasswordToken = assignResetPasswordToken;
176
+ exports.default = auth;
177
+ exports.getResetPasswordTokenTTL = getResetPasswordTokenTTL;
133
178
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\n\n/**\n * hashes a password\n * @param password - password to hash\n * @returns hashed password\n */\nconst hashPassword = (password: string) => bcrypt.hash(password, 10);\n\n/**\n * Validate a password\n * @param password\n * @param hash\n * @returns {Promise<boolean>} is the password valid\n */\nconst validatePassword = (password: string, hash: string) => bcrypt.compare(password, hash);\n\n/**\n * Check login credentials\n * @param email the users email address\n * @param password the users password\n */\nconst checkCredentials = async ({ email, password }: { email: string; password: string }) => {\n const user: AdminUser = await strapi.db.query('admin::user').findOne({ where: { email } });\n\n if (!user || !user.password) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n const isValid = await validatePassword(password, user.password);\n\n if (!isValid) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n if (!(user.isActive === true)) {\n return [null, false, { message: 'User not active' }];\n }\n\n return [null, user];\n};\n\n/**\n * Send an email to the user if it exists or do nothing\n * @param email user email for which to reset the password\n */\nconst forgotPassword = async ({ email } = {} as { email: string }) => {\n const user: AdminUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { email, isActive: true } });\n if (!user) {\n return;\n }\n\n const resetPasswordToken = getService('token').createToken();\n await getService('user').updateById(user.id, { resetPasswordToken });\n\n // Send an email to the admin.\n const url = `${strapi.config.get(\n 'admin.absoluteUrl'\n )}/auth/reset-password?code=${resetPasswordToken}`;\n\n return strapi\n .plugin('email')\n .service('email')\n .sendTemplatedEmail(\n {\n to: user.email,\n from: strapi.config.get('admin.forgotPassword.from'),\n replyTo: strapi.config.get('admin.forgotPassword.replyTo'),\n },\n strapi.config.get('admin.forgotPassword.emailTemplate'),\n {\n url,\n user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),\n }\n )\n .catch((err: unknown) => {\n // log error server side but do not disclose it to the user to avoid leaking informations\n strapi.log.error(err);\n });\n};\n\n/**\n * Reset a user password\n * @param resetPasswordToken token generated to request a password reset\n * @param password new user password\n */\nconst resetPassword = async (\n { resetPasswordToken, password } = {} as { resetPasswordToken: string; password: string }\n) => {\n const matchingUser: AdminUser | undefined = await strapi.db\n .query('admin::user')\n .findOne({ where: { resetPasswordToken, isActive: true } });\n\n if (!matchingUser) {\n throw new ApplicationError();\n }\n\n return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\n"],"names":["ApplicationError","errors","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","user","strapi","db","query","findOne","where","message","isValid","isActive","forgotPassword","resetPasswordToken","getService","createToken","updateById","id","url","config","get","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { expiresInToSeconds } from './token';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\n\n// Default lifetime of an admin reset-password token. Overridable via\n// `admin.forgotPassword.expiresIn` (number of seconds or a shorthand like '15m', '1h').\nconst DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';\n\n/**\n * Resolve the reset-password token lifetime, in milliseconds, from config.\n * Falls back to {@link DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN} for unset/invalid values.\n */\nconst getResetPasswordTokenTTL = (): number => {\n const configured = strapi.config.get(\n 'admin.forgotPassword.expiresIn',\n DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN\n );\n const seconds =\n expiresInToSeconds(configured) ??\n (expiresInToSeconds(DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN) as number);\n return seconds * 1000;\n};\n\n/**\n * Create a reset-password token with an expiry and persist it on the user.\n * Shared by the CE and EE auth services so the expiry behaviour can't drift.\n * @returns the generated reset-password token\n */\nconst assignResetPasswordToken = async (userId: AdminUser['id']): Promise<string> => {\n const resetPasswordToken = getService('token').createToken();\n const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());\n\n await getService('user').updateById(userId, {\n resetPasswordToken,\n resetPasswordTokenExpiresAt,\n });\n\n return resetPasswordToken;\n};\n\n/**\n * Reject a reset-password token that has expired — or that has no expiry at all\n * (tokens issued before this was introduced) — clearing the stale token so it\n * cannot be retried. Shared by the CE and EE auth services. (GH#25711)\n */\nconst assertResetPasswordTokenIsValid = async (user: AdminUser): Promise<void> => {\n const { resetPasswordTokenExpiresAt } = user;\n const isExpired =\n !resetPasswordTokenExpiresAt || new Date(resetPasswordTokenExpiresAt).getTime() <= Date.now();\n\n if (isExpired) {\n // Clear the stale token so it can no longer be retried.\n await getService('user').updateById(user.id, {\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n throw new ApplicationError('This reset password token has expired');\n }\n};\n\n/**\n * hashes a password\n * @param password - password to hash\n * @returns hashed password\n */\nconst hashPassword = (password: string) => bcrypt.hash(password, 10);\n\n/**\n * Validate a password\n * @param password\n * @param hash\n * @returns {Promise<boolean>} is the password valid\n */\nconst validatePassword = (password: string, hash: string) => bcrypt.compare(password, hash);\n\n/**\n * Check login credentials\n * @param email the users email address\n * @param password the users password\n */\nconst checkCredentials = async ({ email, password }: { email: string; password: string }) => {\n const user: AdminUser = await strapi.db.query('admin::user').findOne({ where: { email } });\n\n if (!user || !user.password) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n const isValid = await validatePassword(password, user.password);\n\n if (!isValid) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n if (!(user.isActive === true)) {\n return [null, false, { message: 'User not active' }];\n }\n\n return [null, user];\n};\n\n/**\n * Send an email to the user if it exists or do nothing\n * @param email user email for which to reset the password\n */\nconst forgotPassword = async ({ email } = {} as { email: string }) => {\n const user: AdminUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { email, isActive: true } });\n if (!user) {\n return;\n }\n\n const resetPasswordToken = await assignResetPasswordToken(user.id);\n\n // Send an email to the admin.\n const url = `${strapi.config.get(\n 'admin.absoluteUrl'\n )}/auth/reset-password?code=${resetPasswordToken}`;\n\n return strapi\n .plugin('email')\n .service('email')\n .sendTemplatedEmail(\n {\n to: user.email,\n from: strapi.config.get('admin.forgotPassword.from'),\n replyTo: strapi.config.get('admin.forgotPassword.replyTo'),\n },\n strapi.config.get('admin.forgotPassword.emailTemplate'),\n {\n url,\n user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),\n }\n )\n .catch((err: unknown) => {\n // log error server side but do not disclose it to the user to avoid leaking informations\n strapi.log.error(err);\n });\n};\n\n/**\n * Reset a user password\n * @param resetPasswordToken token generated to request a password reset\n * @param password new user password\n */\nconst resetPassword = async (\n { resetPasswordToken, password } = {} as { resetPasswordToken: string; password: string }\n) => {\n const matchingUser: AdminUser | undefined = await strapi.db\n .query('admin::user')\n .findOne({ where: { resetPasswordToken, isActive: true } });\n\n if (!matchingUser) {\n throw new ApplicationError();\n }\n\n await assertResetPasswordTokenIsValid(matchingUser);\n\n return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\nexport { getResetPasswordTokenTTL, assignResetPasswordToken, assertResetPasswordTokenIsValid };\n"],"names":["ApplicationError","errors","DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN","getResetPasswordTokenTTL","configured","strapi","config","get","seconds","expiresInToSeconds","assignResetPasswordToken","userId","resetPasswordToken","getService","createToken","resetPasswordTokenExpiresAt","Date","now","updateById","assertResetPasswordTokenIsValid","user","isExpired","getTime","id","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","db","query","findOne","where","message","isValid","isActive","forgotPassword","url","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":"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"}
@@ -2,9 +2,50 @@ import bcrypt from 'bcryptjs';
2
2
  import ___default from 'lodash';
3
3
  import { errors } from '@strapi/utils';
4
4
  import { getService } from '../utils/index.mjs';
5
+ import { expiresInToSeconds } from './token.mjs';
5
6
  import '@strapi/types';
6
7
 
7
8
  const { ApplicationError } = errors;
9
+ // Default lifetime of an admin reset-password token. Overridable via
10
+ // `admin.forgotPassword.expiresIn` (number of seconds or a shorthand like '15m', '1h').
11
+ const DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';
12
+ /**
13
+ * Resolve the reset-password token lifetime, in milliseconds, from config.
14
+ * Falls back to {@link DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN} for unset/invalid values.
15
+ */ const getResetPasswordTokenTTL = ()=>{
16
+ const configured = strapi.config.get('admin.forgotPassword.expiresIn', DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN);
17
+ const seconds = expiresInToSeconds(configured) ?? expiresInToSeconds(DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN);
18
+ return seconds * 1000;
19
+ };
20
+ /**
21
+ * Create a reset-password token with an expiry and persist it on the user.
22
+ * Shared by the CE and EE auth services so the expiry behaviour can't drift.
23
+ * @returns the generated reset-password token
24
+ */ const assignResetPasswordToken = async (userId)=>{
25
+ const resetPasswordToken = getService('token').createToken();
26
+ const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());
27
+ await getService('user').updateById(userId, {
28
+ resetPasswordToken,
29
+ resetPasswordTokenExpiresAt
30
+ });
31
+ return resetPasswordToken;
32
+ };
33
+ /**
34
+ * Reject a reset-password token that has expired — or that has no expiry at all
35
+ * (tokens issued before this was introduced) — clearing the stale token so it
36
+ * cannot be retried. Shared by the CE and EE auth services. (GH#25711)
37
+ */ const assertResetPasswordTokenIsValid = async (user)=>{
38
+ const { resetPasswordTokenExpiresAt } = user;
39
+ const isExpired = !resetPasswordTokenExpiresAt || new Date(resetPasswordTokenExpiresAt).getTime() <= Date.now();
40
+ if (isExpired) {
41
+ // Clear the stale token so it can no longer be retried.
42
+ await getService('user').updateById(user.id, {
43
+ resetPasswordToken: null,
44
+ resetPasswordTokenExpiresAt: null
45
+ });
46
+ throw new ApplicationError('This reset password token has expired');
47
+ }
48
+ };
8
49
  /**
9
50
  * hashes a password
10
51
  * @param password - password to hash
@@ -72,10 +113,7 @@ const { ApplicationError } = errors;
72
113
  if (!user) {
73
114
  return;
74
115
  }
75
- const resetPasswordToken = getService('token').createToken();
76
- await getService('user').updateById(user.id, {
77
- resetPasswordToken
78
- });
116
+ const resetPasswordToken = await assignResetPasswordToken(user.id);
79
117
  // Send an email to the admin.
80
118
  const url = `${strapi.config.get('admin.absoluteUrl')}/auth/reset-password?code=${resetPasswordToken}`;
81
119
  return strapi.plugin('email').service('email').sendTemplatedEmail({
@@ -109,9 +147,11 @@ const { ApplicationError } = errors;
109
147
  if (!matchingUser) {
110
148
  throw new ApplicationError();
111
149
  }
150
+ await assertResetPasswordTokenIsValid(matchingUser);
112
151
  return getService('user').updateById(matchingUser.id, {
113
152
  password,
114
- resetPasswordToken: null
153
+ resetPasswordToken: null,
154
+ resetPasswordTokenExpiresAt: null
115
155
  });
116
156
  };
117
157
  var auth = {
@@ -122,5 +162,5 @@ var auth = {
122
162
  resetPassword
123
163
  };
124
164
 
125
- export { auth as default };
165
+ export { assertResetPasswordTokenIsValid, assignResetPasswordToken, auth as default, getResetPasswordTokenTTL };
126
166
  //# sourceMappingURL=auth.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.mjs","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\n\n/**\n * hashes a password\n * @param password - password to hash\n * @returns hashed password\n */\nconst hashPassword = (password: string) => bcrypt.hash(password, 10);\n\n/**\n * Validate a password\n * @param password\n * @param hash\n * @returns {Promise<boolean>} is the password valid\n */\nconst validatePassword = (password: string, hash: string) => bcrypt.compare(password, hash);\n\n/**\n * Check login credentials\n * @param email the users email address\n * @param password the users password\n */\nconst checkCredentials = async ({ email, password }: { email: string; password: string }) => {\n const user: AdminUser = await strapi.db.query('admin::user').findOne({ where: { email } });\n\n if (!user || !user.password) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n const isValid = await validatePassword(password, user.password);\n\n if (!isValid) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n if (!(user.isActive === true)) {\n return [null, false, { message: 'User not active' }];\n }\n\n return [null, user];\n};\n\n/**\n * Send an email to the user if it exists or do nothing\n * @param email user email for which to reset the password\n */\nconst forgotPassword = async ({ email } = {} as { email: string }) => {\n const user: AdminUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { email, isActive: true } });\n if (!user) {\n return;\n }\n\n const resetPasswordToken = getService('token').createToken();\n await getService('user').updateById(user.id, { resetPasswordToken });\n\n // Send an email to the admin.\n const url = `${strapi.config.get(\n 'admin.absoluteUrl'\n )}/auth/reset-password?code=${resetPasswordToken}`;\n\n return strapi\n .plugin('email')\n .service('email')\n .sendTemplatedEmail(\n {\n to: user.email,\n from: strapi.config.get('admin.forgotPassword.from'),\n replyTo: strapi.config.get('admin.forgotPassword.replyTo'),\n },\n strapi.config.get('admin.forgotPassword.emailTemplate'),\n {\n url,\n user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),\n }\n )\n .catch((err: unknown) => {\n // log error server side but do not disclose it to the user to avoid leaking informations\n strapi.log.error(err);\n });\n};\n\n/**\n * Reset a user password\n * @param resetPasswordToken token generated to request a password reset\n * @param password new user password\n */\nconst resetPassword = async (\n { resetPasswordToken, password } = {} as { resetPasswordToken: string; password: string }\n) => {\n const matchingUser: AdminUser | undefined = await strapi.db\n .query('admin::user')\n .findOne({ where: { resetPasswordToken, isActive: true } });\n\n if (!matchingUser) {\n throw new ApplicationError();\n }\n\n return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\n"],"names":["ApplicationError","errors","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","user","strapi","db","query","findOne","where","message","isValid","isActive","forgotPassword","resetPasswordToken","getService","createToken","updateById","id","url","config","get","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":";;;;;;AAOA,MAAM,EAAEA,gBAAgB,EAAE,GAAGC,MAAAA;AAE7B;;;;AAIC,IACD,MAAMC,YAAAA,GAAe,CAACC,WAAqBC,MAAAA,CAAOC,IAAI,CAACF,QAAAA,EAAU,EAAA,CAAA;AAEjE;;;;;IAMA,MAAMG,mBAAmB,CAACH,QAAAA,EAAkBE,OAAiBD,MAAAA,CAAOG,OAAO,CAACJ,QAAAA,EAAUE,IAAAA,CAAAA;AAEtF;;;;AAIC,IACD,MAAMG,gBAAAA,GAAmB,OAAO,EAAEC,KAAK,EAAEN,QAAQ,EAAuC,GAAA;IACtF,MAAMO,IAAAA,GAAkB,MAAMC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeC,OAAO,CAAC;QAAEC,KAAAA,EAAO;AAAEN,YAAAA;AAAM;AAAE,KAAA,CAAA;AAExF,IAAA,IAAI,CAACC,IAAAA,IAAQ,CAACA,IAAAA,CAAKP,QAAQ,EAAE;QAC3B,OAAO;AAAC,YAAA,IAAA;AAAM,YAAA,KAAA;AAAO,YAAA;gBAAEa,OAAAA,EAAS;AAAsB;AAAE,SAAA;AAC1D,IAAA;AAEA,IAAA,MAAMC,OAAAA,GAAU,MAAMX,gBAAAA,CAAiBH,QAAAA,EAAUO,KAAKP,QAAQ,CAAA;AAE9D,IAAA,IAAI,CAACc,OAAAA,EAAS;QACZ,OAAO;AAAC,YAAA,IAAA;AAAM,YAAA,KAAA;AAAO,YAAA;gBAAED,OAAAA,EAAS;AAAsB;AAAE,SAAA;AAC1D,IAAA;AAEA,IAAA,IAAI,EAAEN,IAAAA,CAAKQ,QAAQ,KAAK,IAAG,CAAA,EAAI;QAC7B,OAAO;AAAC,YAAA,IAAA;AAAM,YAAA,KAAA;AAAO,YAAA;gBAAEF,OAAAA,EAAS;AAAkB;AAAE,SAAA;AACtD,IAAA;IAEA,OAAO;AAAC,QAAA,IAAA;AAAMN,QAAAA;AAAK,KAAA;AACrB,CAAA;AAEA;;;IAIA,MAAMS,iBAAiB,OAAO,EAAEV,KAAK,EAAE,GAAG,EAAuB,GAAA;IAC/D,MAAMC,IAAAA,GAAkB,MAAMC,MAAAA,CAAOC,EAAE,CACpCC,KAAK,CAAC,aAAA,CAAA,CACNC,OAAO,CAAC;QAAEC,KAAAA,EAAO;AAAEN,YAAAA,KAAAA;YAAOS,QAAAA,EAAU;AAAK;AAAE,KAAA,CAAA;AAC9C,IAAA,IAAI,CAACR,IAAAA,EAAM;AACT,QAAA;AACF,IAAA;IAEA,MAAMU,kBAAAA,GAAqBC,UAAAA,CAAW,OAAA,CAAA,CAASC,WAAW,EAAA;AAC1D,IAAA,MAAMD,WAAW,MAAA,CAAA,CAAQE,UAAU,CAACb,IAAAA,CAAKc,EAAE,EAAE;AAAEJ,QAAAA;AAAmB,KAAA,CAAA;;IAGlE,MAAMK,GAAAA,GAAM,CAAA,EAAGd,MAAAA,CAAOe,MAAM,CAACC,GAAG,CAC9B,mBAAA,CAAA,CACA,0BAA0B,EAAEP,kBAAAA,CAAAA,CAAoB;IAElD,OAAOT,MAAAA,CACJiB,MAAM,CAAC,OAAA,CAAA,CACPC,OAAO,CAAC,OAAA,CAAA,CACRC,kBAAkB,CACjB;AACEC,QAAAA,EAAAA,EAAIrB,KAAKD,KAAK;AACduB,QAAAA,IAAAA,EAAMrB,MAAAA,CAAOe,MAAM,CAACC,GAAG,CAAC,2BAAA,CAAA;AACxBM,QAAAA,OAAAA,EAAStB,MAAAA,CAAOe,MAAM,CAACC,GAAG,CAAC,8BAAA;AAC7B,KAAA,EACAhB,MAAAA,CAAOe,MAAM,CAACC,GAAG,CAAC,oCAAA,CAAA,EAClB;AACEF,QAAAA,GAAAA;QACAf,IAAAA,EAAMwB,UAAAA,CAAEC,IAAI,CAACzB,IAAAA,EAAM;AAAC,YAAA,OAAA;AAAS,YAAA,WAAA;AAAa,YAAA,UAAA;AAAY,YAAA;AAAW,SAAA;KACnE,CAAA,CAED0B,KAAK,CAAC,CAACC,GAAAA,GAAAA;;QAEN1B,MAAAA,CAAO2B,GAAG,CAACC,KAAK,CAACF,GAAAA,CAAAA;AACnB,IAAA,CAAA,CAAA;AACJ,CAAA;AAEA;;;;IAKA,MAAMG,aAAAA,GAAgB,OACpB,EAAEpB,kBAAkB,EAAEjB,QAAQ,EAAE,GAAG,EAAsD,GAAA;IAEzF,MAAMsC,YAAAA,GAAsC,MAAM9B,MAAAA,CAAOC,EAAE,CACxDC,KAAK,CAAC,aAAA,CAAA,CACNC,OAAO,CAAC;QAAEC,KAAAA,EAAO;AAAEK,YAAAA,kBAAAA;YAAoBF,QAAAA,EAAU;AAAK;AAAE,KAAA,CAAA;AAE3D,IAAA,IAAI,CAACuB,YAAAA,EAAc;AACjB,QAAA,MAAM,IAAIzC,gBAAAA,EAAAA;AACZ,IAAA;AAEA,IAAA,OAAOqB,WAAW,MAAA,CAAA,CAAQE,UAAU,CAACkB,YAAAA,CAAajB,EAAE,EAAE;AACpDrB,QAAAA,QAAAA;QACAiB,kBAAAA,EAAoB;AACtB,KAAA,CAAA;AACF,CAAA;AAEA,WAAe;AAAEZ,IAAAA,gBAAAA;AAAkBF,IAAAA,gBAAAA;AAAkBJ,IAAAA,YAAAA;AAAciB,IAAAA,cAAAA;AAAgBqB,IAAAA;AAAc,CAAA;;;;"}
1
+ {"version":3,"file":"auth.mjs","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { expiresInToSeconds } from './token';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\n\n// Default lifetime of an admin reset-password token. Overridable via\n// `admin.forgotPassword.expiresIn` (number of seconds or a shorthand like '15m', '1h').\nconst DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';\n\n/**\n * Resolve the reset-password token lifetime, in milliseconds, from config.\n * Falls back to {@link DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN} for unset/invalid values.\n */\nconst getResetPasswordTokenTTL = (): number => {\n const configured = strapi.config.get(\n 'admin.forgotPassword.expiresIn',\n DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN\n );\n const seconds =\n expiresInToSeconds(configured) ??\n (expiresInToSeconds(DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN) as number);\n return seconds * 1000;\n};\n\n/**\n * Create a reset-password token with an expiry and persist it on the user.\n * Shared by the CE and EE auth services so the expiry behaviour can't drift.\n * @returns the generated reset-password token\n */\nconst assignResetPasswordToken = async (userId: AdminUser['id']): Promise<string> => {\n const resetPasswordToken = getService('token').createToken();\n const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());\n\n await getService('user').updateById(userId, {\n resetPasswordToken,\n resetPasswordTokenExpiresAt,\n });\n\n return resetPasswordToken;\n};\n\n/**\n * Reject a reset-password token that has expired — or that has no expiry at all\n * (tokens issued before this was introduced) — clearing the stale token so it\n * cannot be retried. Shared by the CE and EE auth services. (GH#25711)\n */\nconst assertResetPasswordTokenIsValid = async (user: AdminUser): Promise<void> => {\n const { resetPasswordTokenExpiresAt } = user;\n const isExpired =\n !resetPasswordTokenExpiresAt || new Date(resetPasswordTokenExpiresAt).getTime() <= Date.now();\n\n if (isExpired) {\n // Clear the stale token so it can no longer be retried.\n await getService('user').updateById(user.id, {\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n throw new ApplicationError('This reset password token has expired');\n }\n};\n\n/**\n * hashes a password\n * @param password - password to hash\n * @returns hashed password\n */\nconst hashPassword = (password: string) => bcrypt.hash(password, 10);\n\n/**\n * Validate a password\n * @param password\n * @param hash\n * @returns {Promise<boolean>} is the password valid\n */\nconst validatePassword = (password: string, hash: string) => bcrypt.compare(password, hash);\n\n/**\n * Check login credentials\n * @param email the users email address\n * @param password the users password\n */\nconst checkCredentials = async ({ email, password }: { email: string; password: string }) => {\n const user: AdminUser = await strapi.db.query('admin::user').findOne({ where: { email } });\n\n if (!user || !user.password) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n const isValid = await validatePassword(password, user.password);\n\n if (!isValid) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n if (!(user.isActive === true)) {\n return [null, false, { message: 'User not active' }];\n }\n\n return [null, user];\n};\n\n/**\n * Send an email to the user if it exists or do nothing\n * @param email user email for which to reset the password\n */\nconst forgotPassword = async ({ email } = {} as { email: string }) => {\n const user: AdminUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { email, isActive: true } });\n if (!user) {\n return;\n }\n\n const resetPasswordToken = await assignResetPasswordToken(user.id);\n\n // Send an email to the admin.\n const url = `${strapi.config.get(\n 'admin.absoluteUrl'\n )}/auth/reset-password?code=${resetPasswordToken}`;\n\n return strapi\n .plugin('email')\n .service('email')\n .sendTemplatedEmail(\n {\n to: user.email,\n from: strapi.config.get('admin.forgotPassword.from'),\n replyTo: strapi.config.get('admin.forgotPassword.replyTo'),\n },\n strapi.config.get('admin.forgotPassword.emailTemplate'),\n {\n url,\n user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),\n }\n )\n .catch((err: unknown) => {\n // log error server side but do not disclose it to the user to avoid leaking informations\n strapi.log.error(err);\n });\n};\n\n/**\n * Reset a user password\n * @param resetPasswordToken token generated to request a password reset\n * @param password new user password\n */\nconst resetPassword = async (\n { resetPasswordToken, password } = {} as { resetPasswordToken: string; password: string }\n) => {\n const matchingUser: AdminUser | undefined = await strapi.db\n .query('admin::user')\n .findOne({ where: { resetPasswordToken, isActive: true } });\n\n if (!matchingUser) {\n throw new ApplicationError();\n }\n\n await assertResetPasswordTokenIsValid(matchingUser);\n\n return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\nexport { getResetPasswordTokenTTL, assignResetPasswordToken, assertResetPasswordTokenIsValid };\n"],"names":["ApplicationError","errors","DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN","getResetPasswordTokenTTL","configured","strapi","config","get","seconds","expiresInToSeconds","assignResetPasswordToken","userId","resetPasswordToken","getService","createToken","resetPasswordTokenExpiresAt","Date","now","updateById","assertResetPasswordTokenIsValid","user","isExpired","getTime","id","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","db","query","findOne","where","message","isValid","isActive","forgotPassword","url","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":"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"}
@@ -26,7 +26,7 @@ const contentApiTokenService = apiToken.createTokenService('content-api');
26
26
  const adminTokenService = apiToken.createTokenService('admin');
27
27
  // TODO: TS - Export services one by one as this export is cjs
28
28
  var services = {
29
- auth,
29
+ auth: auth.default,
30
30
  user,
31
31
  role,
32
32
  passport,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../server/src/services/index.ts"],"sourcesContent":["// NOTE: Make sure to use default export for services overwritten in EE\nimport auth from './auth';\nimport user from './user';\nimport role from './role';\nimport passport from './passport';\nimport metrics from './metrics';\nimport encryption from './encryption';\nimport * as token from './token';\nimport * as permission from './permission';\nimport * as contentType from './content-type';\nimport * as constants from './constants';\nimport * as condition from './condition';\nimport * as action from './action';\nimport { createTokenService } from './api-token';\nimport * as transfer from './transfer';\nimport * as projectSettings from './project-settings';\nimport { homepageService } from './homepage';\n\nconst contentApiTokenService = createTokenService('content-api');\nconst adminTokenService = createTokenService('admin');\n\n// TODO: TS - Export services one by one as this export is cjs\nexport default {\n auth,\n user,\n role,\n passport,\n token,\n permission,\n metrics,\n 'content-type': contentType,\n constants,\n condition,\n action,\n /** @deprecated Use 'api-token-content-api' instead */\n 'api-token': contentApiTokenService,\n 'api-token-content-api': contentApiTokenService,\n 'api-token-admin': adminTokenService,\n transfer,\n 'project-settings': projectSettings,\n encryption,\n homepage: homepageService,\n};\n"],"names":["contentApiTokenService","createTokenService","adminTokenService","auth","user","role","passport","token","permission","metrics","contentType","constants","condition","action","transfer","projectSettings","encryption","homepage","homepageService"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAkBA,MAAMA,yBAAyBC,2BAAAA,CAAmB,aAAA,CAAA;AAClD,MAAMC,oBAAoBD,2BAAAA,CAAmB,OAAA,CAAA;AAE7C;AACA,eAAe;AACbE,IAAAA,IAAAA;AACAC,IAAAA,IAAAA;AACAC,IAAAA,IAAAA;AACAC,IAAAA,QAAAA;AACAC,IAAAA,KAAAA;AACAC,IAAAA,UAAAA;AACAC,IAAAA,OAAAA;IACA,cAAA,EAAgBC,WAAAA;AAChBC,eAAAA,oBAAAA;AACAC,IAAAA,SAAAA;AACAC,IAAAA,MAAAA;AACA,2DACA,WAAA,EAAab,sBAAAA;IACb,uBAAA,EAAyBA,sBAAAA;IACzB,iBAAA,EAAmBE,iBAAAA;AACnBY,cAAAA,KAAAA;IACA,kBAAA,EAAoBC,eAAAA;AACpBC,IAAAA,UAAAA;IACAC,QAAAA,EAAUC;AACZ,CAAA;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../server/src/services/index.ts"],"sourcesContent":["// NOTE: Make sure to use default export for services overwritten in EE\nimport auth from './auth';\nimport user from './user';\nimport role from './role';\nimport passport from './passport';\nimport metrics from './metrics';\nimport encryption from './encryption';\nimport * as token from './token';\nimport * as permission from './permission';\nimport * as contentType from './content-type';\nimport * as constants from './constants';\nimport * as condition from './condition';\nimport * as action from './action';\nimport { createTokenService } from './api-token';\nimport * as transfer from './transfer';\nimport * as projectSettings from './project-settings';\nimport { homepageService } from './homepage';\n\nconst contentApiTokenService = createTokenService('content-api');\nconst adminTokenService = createTokenService('admin');\n\n// TODO: TS - Export services one by one as this export is cjs\nexport default {\n auth,\n user,\n role,\n passport,\n token,\n permission,\n metrics,\n 'content-type': contentType,\n constants,\n condition,\n action,\n /** @deprecated Use 'api-token-content-api' instead */\n 'api-token': contentApiTokenService,\n 'api-token-content-api': contentApiTokenService,\n 'api-token-admin': adminTokenService,\n transfer,\n 'project-settings': projectSettings,\n encryption,\n homepage: homepageService,\n};\n"],"names":["contentApiTokenService","createTokenService","adminTokenService","auth","user","role","passport","token","permission","metrics","contentType","constants","condition","action","transfer","projectSettings","encryption","homepage","homepageService"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAkBA,MAAMA,yBAAyBC,2BAAAA,CAAmB,aAAA,CAAA;AAClD,MAAMC,oBAAoBD,2BAAAA,CAAmB,OAAA,CAAA;AAE7C;AACA,eAAe;AACbE,UAAAA,YAAAA;AACAC,IAAAA,IAAAA;AACAC,IAAAA,IAAAA;AACAC,IAAAA,QAAAA;AACAC,IAAAA,KAAAA;AACAC,IAAAA,UAAAA;AACAC,IAAAA,OAAAA;IACA,cAAA,EAAgBC,WAAAA;AAChBC,eAAAA,oBAAAA;AACAC,IAAAA,SAAAA;AACAC,IAAAA,MAAAA;AACA,2DACA,WAAA,EAAab,sBAAAA;IACb,uBAAA,EAAyBA,sBAAAA;IACzB,iBAAA,EAAmBE,iBAAAA;AACnBY,cAAAA,KAAAA;IACA,kBAAA,EAAoBC,eAAAA;AACpBC,IAAAA,UAAAA;IACAC,QAAAA,EAAUC;AACZ,CAAA;;;;"}
@@ -32,6 +32,7 @@ const getSessionManager = ()=>{
32
32
  ...___default.default.omit(user, [
33
33
  'password',
34
34
  'resetPasswordToken',
35
+ 'resetPasswordTokenExpiresAt',
35
36
  'registrationToken',
36
37
  'roles'
37
38
  ]),
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","sources":["../../../../../server/src/services/user.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport _ from 'lodash';\nimport { defaults } from 'lodash/fp';\nimport { arrays, errors } from '@strapi/utils';\nimport type { Data } from '@strapi/types';\nimport { createUser, hasSuperAdminRole } from '../domain/user';\nimport type {\n AdminUser,\n AdminRole,\n AdminUserCreationPayload,\n SanitizedAdminUser,\n SanitizedAdminRole,\n AdminUserUpdatePayload,\n // eslint-disable-next-line node/no-unpublished-import\n} from '../../../shared/contracts/shared';\nimport { password as passwordValidator } from '../validation/common-validators';\nimport { getService } from '../utils';\nimport constants from './constants';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\nconst { ApplicationError, ValidationError } = errors;\nconst sanitizeUserRoles = (role: AdminRole): SanitizedAdminRole =>\n _.pick(role, ['id', 'name', 'description', 'code']);\n\nconst getSessionManager = () => {\n const manager = strapi.sessionManager;\n return manager ?? null;\n};\n\n/**\n * Remove private user fields\n * @param user - user to sanitize\n */\nconst sanitizeUser = (user: AdminUser): SanitizedAdminUser => {\n return {\n ..._.omit(user, ['password', 'resetPasswordToken', 'registrationToken', 'roles']),\n roles: user.roles && user.roles.map(sanitizeUserRoles),\n };\n};\n\n/**\n * Create and save a user in database\n * @param attributes A partial user object\n */\nconst createUserInDatabase = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const userInfo = {\n registrationToken: getService('token').createToken(),\n ...attributes,\n };\n\n if (_.has(attributes, 'password')) {\n userInfo.password = await getService('auth').hashPassword(attributes.password!);\n }\n\n const user = createUser(userInfo);\n\n const createdUser = await strapi.db\n .query('admin::user')\n .create({ data: user, populate: ['roles'] });\n\n return createdUser;\n};\n\nconst emitUserCreated = (user: AdminUser) => {\n getService('metrics').sendDidInviteUser();\n\n strapi.eventHub.emit('user.create', { user: sanitizeUser(user) });\n};\n\nconst create = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const createdUser = await createUserInDatabase(attributes);\n\n emitUserCreated(createdUser);\n\n return createdUser;\n};\n\nconst createFirstAdmin = async (\n attributes: Omit<Partial<AdminUserCreationPayload>, 'registrationToken' | 'isActive' | 'roles'>\n): Promise<AdminUser> => {\n const createdUser = await strapi.db.transaction(async ({ trx }) => {\n // Serialize first-admin creation across processes by locking a stable role row.\n // SQLite ignores FOR UPDATE, but falls back to its single-writer transaction behavior.\n const superAdminRole = await strapi.db\n .queryBuilder('admin::role')\n .select(['id'])\n .where({ code: SUPER_ADMIN_CODE })\n .first()\n .transacting(trx)\n .forUpdate()\n .execute<AdminRole | undefined>();\n\n if (!superAdminRole) {\n throw new ApplicationError(\n \"Cannot register the first admin because the super admin role doesn't exist.\"\n );\n }\n\n const hasAdmin = await exists();\n\n if (hasAdmin) {\n throw new ApplicationError('You cannot register a new super admin');\n }\n\n return createUserInDatabase({\n ...attributes,\n registrationToken: null,\n isActive: true,\n roles: [superAdminRole.id],\n });\n });\n\n emitUserCreated(createdUser);\n\n return createdUser;\n};\n\n/**\n * Update a user in database\n * @param id query params to find the user to update\n * @param attributes A partial user object\n */\nconst updateById = async (\n id: Data.ID,\n attributes: Partial<AdminUserUpdatePayload>\n): Promise<AdminUser> => {\n // Check at least one super admin remains\n if (_.has(attributes, 'roles')) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const willRemoveSuperAdminRole = !arrays.includesString(attributes.roles!, superAdminRole.id);\n\n if (lastAdminUser && willRemoveSuperAdminRole) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // cannot disable last super admin\n if (attributes.isActive === false) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n if (lastAdminUser) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // hash password if a new one is sent\n if (_.has(attributes, 'password')) {\n const hashedPassword = await getService('auth').hashPassword(attributes.password!);\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: {\n ...attributes,\n password: hashedPassword,\n },\n populate: ['roles'],\n });\n\n strapi.eventHub.emit('user.update', { user: sanitizeUser(updatedUser) });\n\n return updatedUser;\n }\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: attributes,\n populate: ['roles'],\n });\n\n if (updatedUser) {\n strapi.eventHub.emit('user.update', { user: sanitizeUser(updatedUser) });\n }\n\n return updatedUser;\n};\n\n/**\n * Reset a user password by email. (Used in admin:reset CLI)\n * @param email - user email\n * @param password - new password\n */\nconst resetPasswordByEmail = async (email: string, password: string) => {\n const user = await strapi.db\n .query('admin::user')\n .findOne({ where: { email }, populate: ['roles'] });\n\n if (!user) {\n throw new Error(`User not found for email: ${email}`);\n }\n\n try {\n await passwordValidator.validate(password);\n } catch (error) {\n throw new ValidationError(\n 'Invalid password. Expected a minimum of 8 characters with at least one number and one uppercase letter'\n );\n }\n\n await updateById(user.id, { password });\n};\n\n/**\n * Check if a user is the last super admin\n * @param userId user's id to look for\n */\nconst isLastSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const user = (await findOne(userId)) as AdminUser | null;\n if (!user) return false;\n\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n\n return superAdminRole.usersCount === 1 && hasSuperAdminRole(user);\n};\n\n/**\n * Check if a user is the first super admin\n * @param userId user's id to look for\n */\nconst isFirstSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const currentUser = (await findOne(userId)) as AdminUser | null;\n\n if (!currentUser || !hasSuperAdminRole(currentUser)) return false;\n\n const [oldestUser] = await strapi.db.query('admin::user').findMany({\n populate: {\n roles: {\n where: {\n code: { $eq: SUPER_ADMIN_CODE },\n },\n },\n },\n orderBy: { createdAt: 'asc' },\n limit: 1,\n select: ['id'],\n });\n\n return oldestUser.id === currentUser.id;\n};\n\n/**\n * Check if a user with specific attributes exists in the database\n * @param attributes A partial user object\n */\nconst exists = async (attributes = {} as unknown): Promise<boolean> => {\n return (await strapi.db.query('admin::user').count({ where: attributes })) > 0;\n};\n\n/**\n * Returns a user registration info\n * @param registrationToken - a user registration token\n * @returns - Returns user email, firstname and lastname\n */\nconst findRegistrationInfo = async (\n registrationToken: string\n): Promise<Pick<AdminUser, 'email' | 'firstname' | 'lastname'> | undefined> => {\n const user = await strapi.db.query('admin::user').findOne({ where: { registrationToken } });\n\n if (!user) {\n return undefined;\n }\n\n return _.pick(user, ['email', 'firstname', 'lastname']);\n};\n\n/**\n * Registers a user based on a registrationToken and some informations to update\n * @param params\n * @param params.registrationToken registration token\n * @param params.userInfo user info\n */\nconst register = async ({\n registrationToken,\n userInfo,\n}: {\n registrationToken: string;\n userInfo: Partial<AdminUser>;\n}) => {\n const matchingUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { registrationToken } });\n\n if (!matchingUser) {\n throw new ValidationError('Invalid registration info');\n }\n\n return getService('user').updateById(matchingUser.id, {\n password: userInfo.password,\n firstname: userInfo.firstname,\n lastname: userInfo.lastname,\n registrationToken: null,\n isActive: true,\n });\n};\n\n/**\n * Find one user\n */\nconst findOne = async (id: Data.ID, populate = ['roles']) => {\n return strapi.db.query('admin::user').findOne({ where: { id }, populate });\n};\n\n/**\n * Find one user by its email\n * @param email\n * @param populate\n * @returns\n */\nconst findOneByEmail = async (email: string, populate = []) => {\n return strapi.db.query('admin::user').findOne({\n where: { email: { $eqi: email } },\n populate,\n });\n};\n\n/** Find many users (paginated)\n * @param params\n */\nconst findPage = async (params = {}): Promise<unknown> => {\n const query = strapi\n .get('query-params')\n .transform('admin::user', defaults({ populate: ['roles'] }, params));\n\n return strapi.db.query('admin::user').findPage(query);\n};\n\n/** Delete a user\n * @param id id of the user to delete\n */\nconst deleteById = async (id: Data.ID): Promise<AdminUser | null> => {\n // Check at least one super admin remains\n const userToDelete: AdminUser | null = await strapi.db.query('admin::user').findOne({\n where: { id },\n populate: ['roles'],\n });\n\n if (!userToDelete) {\n return null;\n }\n\n if (userToDelete) {\n if (userToDelete.roles.some((r) => r.code === SUPER_ADMIN_CODE)) {\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n if (superAdminRole.usersCount === 1) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n }\n\n const deletedUser = await strapi.db\n .query('admin::user')\n .delete({ where: { id }, populate: ['roles'] });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n strapi.eventHub.emit('user.delete', { user: sanitizeUser(deletedUser) });\n\n return deletedUser;\n};\n\n/** Delete a user\n * @param ids ids of the users to delete\n */\nconst deleteByIds = async (ids: (string | number)[]): Promise<AdminUser[]> => {\n // Check at least one super admin remains\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const nbOfSuperAdminToDelete = await strapi.db.query('admin::user').count({\n where: {\n id: ids,\n roles: { id: superAdminRole.id },\n },\n });\n\n if (superAdminRole.usersCount === nbOfSuperAdminToDelete) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n\n const deletedUsers = [] as AdminUser[];\n for (const id of ids) {\n const deletedUser = await strapi.db.query('admin::user').delete({\n where: { id },\n populate: ['roles'],\n });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n deletedUsers.push(deletedUser);\n }\n\n strapi.eventHub.emit('user.delete', {\n users: deletedUsers.map((deletedUser) => sanitizeUser(deletedUser)),\n });\n\n return deletedUsers;\n};\n\n/** Count the users that don't have any associated roles\n */\nconst countUsersWithoutRole = async (): Promise<number> => {\n return strapi.db.query('admin::user').count({\n where: {\n roles: {\n id: { $null: true },\n },\n },\n });\n};\n\n/**\n * Count the number of users based on search params\n * @param params params used for the query\n */\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::user').count({ where });\n};\n\n/**\n * Assign some roles to several users\n */\nconst assignARoleToAll = async (roleId: Data.ID): Promise<void> => {\n const users = await strapi.db.query('admin::user').findMany({\n select: ['id'],\n where: {\n roles: { id: { $null: true } },\n },\n });\n\n await Promise.all(\n users.map((user) => {\n return strapi.db.query('admin::user').update({\n where: { id: user.id },\n data: { roles: [roleId] },\n });\n })\n );\n};\n\n/** Display a warning if some users don't have at least one role\n */\nconst displayWarningIfUsersDontHaveRole = async (): Promise<void> => {\n const count = await countUsersWithoutRole();\n\n if (count > 0) {\n strapi.log.warn(`Some users (${count}) don't have any role.`);\n }\n};\n\n/** Returns an array of interface languages currently used by users\n */\nconst getLanguagesInUse = async (): Promise<string[]> => {\n const users = await strapi.db.query('admin::user').findMany({ select: ['preferedLanguage'] });\n\n return users.map((user) => user.preferedLanguage || 'en');\n};\nexport default {\n create,\n createFirstAdmin,\n updateById,\n exists,\n findRegistrationInfo,\n register,\n sanitizeUser,\n findOne,\n findOneByEmail,\n findPage,\n deleteById,\n deleteByIds,\n countUsersWithoutRole,\n count,\n assignARoleToAll,\n displayWarningIfUsersDontHaveRole,\n resetPasswordByEmail,\n getLanguagesInUse,\n isFirstSuperAdminUser,\n};\n"],"names":["SUPER_ADMIN_CODE","constants","ApplicationError","ValidationError","errors","sanitizeUserRoles","role","_","pick","getSessionManager","manager","strapi","sessionManager","sanitizeUser","user","omit","roles","map","createUserInDatabase","attributes","userInfo","registrationToken","getService","createToken","has","password","hashPassword","createUser","createdUser","db","query","create","data","populate","emitUserCreated","sendDidInviteUser","eventHub","emit","createFirstAdmin","transaction","trx","superAdminRole","queryBuilder","select","where","code","first","transacting","forUpdate","execute","hasAdmin","exists","isActive","id","updateById","lastAdminUser","isLastSuperAdminUser","getSuperAdminWithUsersCount","willRemoveSuperAdminRole","arrays","includesString","hashedPassword","updatedUser","update","resetPasswordByEmail","email","findOne","Error","passwordValidator","validate","error","userId","usersCount","hasSuperAdminRole","isFirstSuperAdminUser","currentUser","oldestUser","findMany","$eq","orderBy","createdAt","limit","count","findRegistrationInfo","undefined","register","matchingUser","firstname","lastname","findOneByEmail","$eqi","findPage","params","get","transform","defaults","deleteById","userToDelete","some","r","deletedUser","delete","hasOrigin","invalidateRefreshToken","String","deleteByIds","ids","nbOfSuperAdminToDelete","deletedUsers","push","users","countUsersWithoutRole","$null","assignARoleToAll","roleId","Promise","all","displayWarningIfUsersDontHaveRole","log","warn","getLanguagesInUse","preferedLanguage"],"mappings":";;;;;;;;;;;;;;AAmBA,MAAM,EAAEA,gBAAgB,EAAE,GAAGC,SAAAA;AAE7B,MAAM,EAAEC,gBAAgB,EAAEC,eAAe,EAAE,GAAGC,YAAAA;AAC9C,MAAMC,oBAAoB,CAACC,IAAAA,GACzBC,kBAAAA,CAAEC,IAAI,CAACF,IAAAA,EAAM;AAAC,QAAA,IAAA;AAAM,QAAA,MAAA;AAAQ,QAAA,aAAA;AAAe,QAAA;AAAO,KAAA,CAAA;AAEpD,MAAMG,iBAAAA,GAAoB,IAAA;IACxB,MAAMC,OAAAA,GAAUC,OAAOC,cAAc;AACrC,IAAA,OAAOF,OAAAA,IAAW,IAAA;AACpB,CAAA;AAEA;;;IAIA,MAAMG,eAAe,CAACC,IAAAA,GAAAA;IACpB,OAAO;QACL,GAAGP,kBAAAA,CAAEQ,IAAI,CAACD,IAAAA,EAAM;AAAC,YAAA,UAAA;AAAY,YAAA,oBAAA;AAAsB,YAAA,mBAAA;AAAqB,YAAA;SAAQ,CAAC;AACjFE,QAAAA,KAAAA,EAAOF,KAAKE,KAAK,IAAIF,KAAKE,KAAK,CAACC,GAAG,CAACZ,iBAAAA;AACtC,KAAA;AACF,CAAA;AAEA;;;IAIA,MAAMa,oBAAAA,GAAuB;AAE3BC,UAAAA,GAAAA;AAEA,IAAA,MAAMC,QAAAA,GAAW;QACfC,iBAAAA,EAAmBC,gBAAAA,CAAW,SAASC,WAAW,EAAA;AAClD,QAAA,GAAGJ;AACL,KAAA;AAEA,IAAA,IAAIZ,kBAAAA,CAAEiB,GAAG,CAACL,UAAAA,EAAY,UAAA,CAAA,EAAa;QACjCC,QAAAA,CAASK,QAAQ,GAAG,MAAMH,gBAAAA,CAAW,QAAQI,YAAY,CAACP,WAAWM,QAAQ,CAAA;AAC/E,IAAA;AAEA,IAAA,MAAMX,OAAOa,iBAAAA,CAAWP,QAAAA,CAAAA;IAExB,MAAMQ,WAAAA,GAAc,MAAMjB,MAAAA,CAAOkB,EAAE,CAChCC,KAAK,CAAC,aAAA,CAAA,CACNC,MAAM,CAAC;QAAEC,IAAAA,EAAMlB,IAAAA;QAAMmB,QAAAA,EAAU;AAAC,YAAA;AAAQ;AAAC,KAAA,CAAA;IAE5C,OAAOL,WAAAA;AACT,CAAA;AAEA,MAAMM,kBAAkB,CAACpB,IAAAA,GAAAA;AACvBQ,IAAAA,gBAAAA,CAAW,WAAWa,iBAAiB,EAAA;AAEvCxB,IAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;AAAEvB,QAAAA,IAAAA,EAAMD,YAAAA,CAAaC,IAAAA;AAAM,KAAA,CAAA;AACjE,CAAA;AAEA,MAAMiB,MAAAA,GAAS;AAEbZ,UAAAA,GAAAA;IAEA,MAAMS,WAAAA,GAAc,MAAMV,oBAAAA,CAAqBC,UAAAA,CAAAA;IAE/Ce,eAAAA,CAAgBN,WAAAA,CAAAA;IAEhB,OAAOA,WAAAA;AACT,CAAA;AAEA,MAAMU,mBAAmB,OACvBnB,UAAAA,GAAAA;IAEA,MAAMS,WAAAA,GAAc,MAAMjB,MAAAA,CAAOkB,EAAE,CAACU,WAAW,CAAC,OAAO,EAAEC,GAAG,EAAE,GAAA;;;QAG5D,MAAMC,cAAAA,GAAiB,MAAM9B,MAAAA,CAAOkB,EAAE,CACnCa,YAAY,CAAC,aAAA,CAAA,CACbC,MAAM,CAAC;AAAC,YAAA;AAAK,SAAA,CAAA,CACbC,KAAK,CAAC;YAAEC,IAAAA,EAAM7C;AAAiB,SAAA,CAAA,CAC/B8C,KAAK,EAAA,CACLC,WAAW,CAACP,GAAAA,CAAAA,CACZQ,SAAS,GACTC,OAAO,EAAA;AAEV,QAAA,IAAI,CAACR,cAAAA,EAAgB;AACnB,YAAA,MAAM,IAAIvC,gBAAAA,CACR,6EAAA,CAAA;AAEJ,QAAA;AAEA,QAAA,MAAMgD,WAAW,MAAMC,MAAAA,EAAAA;AAEvB,QAAA,IAAID,QAAAA,EAAU;AACZ,YAAA,MAAM,IAAIhD,gBAAAA,CAAiB,uCAAA,CAAA;AAC7B,QAAA;AAEA,QAAA,OAAOgB,oBAAAA,CAAqB;AAC1B,YAAA,GAAGC,UAAU;YACbE,iBAAAA,EAAmB,IAAA;YACnB+B,QAAAA,EAAU,IAAA;YACVpC,KAAAA,EAAO;AAACyB,gBAAAA,cAAAA,CAAeY;AAAG;AAC5B,SAAA,CAAA;AACF,IAAA,CAAA,CAAA;IAEAnB,eAAAA,CAAgBN,WAAAA,CAAAA;IAEhB,OAAOA,WAAAA;AACT,CAAA;AAEA;;;;IAKA,MAAM0B,UAAAA,GAAa,OACjBD,EAAAA,EACAlC,UAAAA,GAAAA;;AAGA,IAAA,IAAIZ,kBAAAA,CAAEiB,GAAG,CAACL,UAAAA,EAAY,OAAA,CAAA,EAAU;QAC9B,MAAMoC,aAAAA,GAAgB,MAAMC,oBAAAA,CAAqBH,EAAAA,CAAAA;AACjD,QAAA,MAAMZ,cAAAA,GAAiB,MAAMnB,gBAAAA,CAAW,MAAA,CAAA,CAAQmC,2BAA2B,EAAA;QAC3E,MAAMC,wBAAAA,GAA2B,CAACC,YAAAA,CAAOC,cAAc,CAACzC,UAAAA,CAAWH,KAAK,EAAGyB,cAAAA,CAAeY,EAAE,CAAA;AAE5F,QAAA,IAAIE,iBAAiBG,wBAAAA,EAA0B;AAC7C,YAAA,MAAM,IAAIvD,eAAAA,CAAgB,wDAAA,CAAA;AAC5B,QAAA;AACF,IAAA;;IAGA,IAAIgB,UAAAA,CAAWiC,QAAQ,KAAK,KAAA,EAAO;QACjC,MAAMG,aAAAA,GAAgB,MAAMC,oBAAAA,CAAqBH,EAAAA,CAAAA;AACjD,QAAA,IAAIE,aAAAA,EAAe;AACjB,YAAA,MAAM,IAAIpD,eAAAA,CAAgB,wDAAA,CAAA;AAC5B,QAAA;AACF,IAAA;;AAGA,IAAA,IAAII,kBAAAA,CAAEiB,GAAG,CAACL,UAAAA,EAAY,UAAA,CAAA,EAAa;AACjC,QAAA,MAAM0C,iBAAiB,MAAMvC,gBAAAA,CAAW,QAAQI,YAAY,CAACP,WAAWM,QAAQ,CAAA;QAEhF,MAAMqC,WAAAA,GAAc,MAAMnD,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeiC,MAAM,CAAC;YAC9DnB,KAAAA,EAAO;AAAES,gBAAAA;AAAG,aAAA;YACZrB,IAAAA,EAAM;AACJ,gBAAA,GAAGb,UAAU;gBACbM,QAAAA,EAAUoC;AACZ,aAAA;YACA5B,QAAAA,EAAU;AAAC,gBAAA;AAAQ;AACrB,SAAA,CAAA;AAEAtB,QAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;AAAEvB,YAAAA,IAAAA,EAAMD,YAAAA,CAAaiD,WAAAA;AAAa,SAAA,CAAA;QAEtE,OAAOA,WAAAA;AACT,IAAA;IAEA,MAAMA,WAAAA,GAAc,MAAMnD,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeiC,MAAM,CAAC;QAC9DnB,KAAAA,EAAO;AAAES,YAAAA;AAAG,SAAA;QACZrB,IAAAA,EAAMb,UAAAA;QACNc,QAAAA,EAAU;AAAC,YAAA;AAAQ;AACrB,KAAA,CAAA;AAEA,IAAA,IAAI6B,WAAAA,EAAa;AACfnD,QAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;AAAEvB,YAAAA,IAAAA,EAAMD,YAAAA,CAAaiD,WAAAA;AAAa,SAAA,CAAA;AACxE,IAAA;IAEA,OAAOA,WAAAA;AACT,CAAA;AAEA;;;;IAKA,MAAME,oBAAAA,GAAuB,OAAOC,KAAAA,EAAexC,QAAAA,GAAAA;IACjD,MAAMX,IAAAA,GAAO,MAAMH,MAAAA,CAAOkB,EAAE,CACzBC,KAAK,CAAC,aAAA,CAAA,CACNoC,OAAO,CAAC;QAAEtB,KAAAA,EAAO;AAAEqB,YAAAA;AAAM,SAAA;QAAGhC,QAAAA,EAAU;AAAC,YAAA;AAAQ;AAAC,KAAA,CAAA;AAEnD,IAAA,IAAI,CAACnB,IAAAA,EAAM;AACT,QAAA,MAAM,IAAIqD,KAAAA,CAAM,CAAC,0BAA0B,EAAEF,KAAAA,CAAAA,CAAO,CAAA;AACtD,IAAA;IAEA,IAAI;QACF,MAAMG,yBAAAA,CAAkBC,QAAQ,CAAC5C,QAAAA,CAAAA;AACnC,IAAA,CAAA,CAAE,OAAO6C,KAAAA,EAAO;AACd,QAAA,MAAM,IAAInE,eAAAA,CACR,wGAAA,CAAA;AAEJ,IAAA;IAEA,MAAMmD,UAAAA,CAAWxC,IAAAA,CAAKuC,EAAE,EAAE;AAAE5B,QAAAA;AAAS,KAAA,CAAA;AACvC,CAAA;AAEA;;;IAIA,MAAM+B,uBAAuB,OAAOe,MAAAA,GAAAA;IAClC,MAAMzD,IAAAA,GAAQ,MAAMoD,OAAAA,CAAQK,MAAAA,CAAAA;IAC5B,IAAI,CAACzD,MAAM,OAAO,KAAA;AAElB,IAAA,MAAM2B,cAAAA,GAAiB,MAAMnB,gBAAAA,CAAW,MAAA,CAAA,CAAQmC,2BAA2B,EAAA;AAE3E,IAAA,OAAOhB,cAAAA,CAAe+B,UAAU,KAAK,CAAA,IAAKC,wBAAAA,CAAkB3D,IAAAA,CAAAA;AAC9D,CAAA;AAEA;;;IAIA,MAAM4D,wBAAwB,OAAOH,MAAAA,GAAAA;IACnC,MAAMI,WAAAA,GAAe,MAAMT,OAAAA,CAAQK,MAAAA,CAAAA;AAEnC,IAAA,IAAI,CAACI,WAAAA,IAAe,CAACF,wBAAAA,CAAkBE,cAAc,OAAO,KAAA;IAE5D,MAAM,CAACC,UAAAA,CAAW,GAAG,MAAMjE,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAe+C,QAAQ,CAAC;QACjE5C,QAAAA,EAAU;YACRjB,KAAAA,EAAO;gBACL4B,KAAAA,EAAO;oBACLC,IAAAA,EAAM;wBAAEiC,GAAAA,EAAK9E;AAAiB;AAChC;AACF;AACF,SAAA;QACA+E,OAAAA,EAAS;YAAEC,SAAAA,EAAW;AAAM,SAAA;QAC5BC,KAAAA,EAAO,CAAA;QACPtC,MAAAA,EAAQ;AAAC,YAAA;AAAK;AAChB,KAAA,CAAA;AAEA,IAAA,OAAOiC,UAAAA,CAAWvB,EAAE,KAAKsB,WAAAA,CAAYtB,EAAE;AACzC,CAAA;AAEA;;;AAGC,IACD,MAAMF,MAAAA,GAAS,OAAOhC,UAAAA,GAAa,EAAa,GAAA;IAC9C,OAAQ,MAAMR,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoD,KAAK,CAAC;QAAEtC,KAAAA,EAAOzB;KAAW,CAAA,GAAM,CAAA;AAC/E,CAAA;AAEA;;;;IAKA,MAAMgE,uBAAuB,OAC3B9D,iBAAAA,GAAAA;IAEA,MAAMP,IAAAA,GAAO,MAAMH,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoC,OAAO,CAAC;QAAEtB,KAAAA,EAAO;AAAEvB,YAAAA;AAAkB;AAAE,KAAA,CAAA;AAEzF,IAAA,IAAI,CAACP,IAAAA,EAAM;QACT,OAAOsE,SAAAA;AACT,IAAA;IAEA,OAAO7E,kBAAAA,CAAEC,IAAI,CAACM,IAAAA,EAAM;AAAC,QAAA,OAAA;AAAS,QAAA,WAAA;AAAa,QAAA;AAAW,KAAA,CAAA;AACxD,CAAA;AAEA;;;;;AAKC,IACD,MAAMuE,QAAAA,GAAW,OAAO,EACtBhE,iBAAiB,EACjBD,QAAQ,EAIT,GAAA;IACC,MAAMkE,YAAAA,GAAe,MAAM3E,MAAAA,CAAOkB,EAAE,CACjCC,KAAK,CAAC,aAAA,CAAA,CACNoC,OAAO,CAAC;QAAEtB,KAAAA,EAAO;AAAEvB,YAAAA;AAAkB;AAAE,KAAA,CAAA;AAE1C,IAAA,IAAI,CAACiE,YAAAA,EAAc;AACjB,QAAA,MAAM,IAAInF,eAAAA,CAAgB,2BAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,OAAOmB,iBAAW,MAAA,CAAA,CAAQgC,UAAU,CAACgC,YAAAA,CAAajC,EAAE,EAAE;AACpD5B,QAAAA,QAAAA,EAAUL,SAASK,QAAQ;AAC3B8D,QAAAA,SAAAA,EAAWnE,SAASmE,SAAS;AAC7BC,QAAAA,QAAAA,EAAUpE,SAASoE,QAAQ;QAC3BnE,iBAAAA,EAAmB,IAAA;QACnB+B,QAAAA,EAAU;AACZ,KAAA,CAAA;AACF,CAAA;AAEA;;AAEC,IACD,MAAMc,OAAAA,GAAU,OAAOb,EAAAA,EAAapB,QAAAA,GAAW;AAAC,IAAA;AAAQ,CAAA,GAAA;AACtD,IAAA,OAAOtB,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoC,OAAO,CAAC;QAAEtB,KAAAA,EAAO;AAAES,YAAAA;AAAG,SAAA;AAAGpB,QAAAA;AAAS,KAAA,CAAA;AAC1E,CAAA;AAEA;;;;;AAKC,IACD,MAAMwD,cAAAA,GAAiB,OAAOxB,KAAAA,EAAehC,WAAW,EAAE,GAAA;AACxD,IAAA,OAAOtB,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoC,OAAO,CAAC;QAC5CtB,KAAAA,EAAO;YAAEqB,KAAAA,EAAO;gBAAEyB,IAAAA,EAAMzB;AAAM;AAAE,SAAA;AAChChC,QAAAA;AACF,KAAA,CAAA;AACF,CAAA;AAEA;;AAEC,IACD,MAAM0D,QAAAA,GAAW,OAAOC,MAAAA,GAAS,EAAE,GAAA;IACjC,MAAM9D,KAAAA,GAAQnB,OACXkF,GAAG,CAAC,gBACJC,SAAS,CAAC,eAAeC,WAAAA,CAAS;QAAE9D,QAAAA,EAAU;AAAC,YAAA;AAAQ;KAAC,EAAG2D,MAAAA,CAAAA,CAAAA;AAE9D,IAAA,OAAOjF,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAe6D,QAAQ,CAAC7D,KAAAA,CAAAA;AACjD,CAAA;AAEA;;IAGA,MAAMkE,aAAa,OAAO3C,EAAAA,GAAAA;;IAExB,MAAM4C,YAAAA,GAAiC,MAAMtF,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoC,OAAO,CAAC;QAClFtB,KAAAA,EAAO;AAAES,YAAAA;AAAG,SAAA;QACZpB,QAAAA,EAAU;AAAC,YAAA;AAAQ;AACrB,KAAA,CAAA;AAEA,IAAA,IAAI,CAACgE,YAAAA,EAAc;QACjB,OAAO,IAAA;AACT,IAAA;AAEA,IAAA,IAAIA,YAAAA,EAAc;QAChB,IAAIA,YAAAA,CAAajF,KAAK,CAACkF,IAAI,CAAC,CAACC,CAAAA,GAAMA,CAAAA,CAAEtD,IAAI,KAAK7C,gBAAAA,CAAAA,EAAmB;AAC/D,YAAA,MAAMyC,cAAAA,GAAiB,MAAMnB,gBAAAA,CAAW,MAAA,CAAA,CAAQmC,2BAA2B,EAAA;YAC3E,IAAIhB,cAAAA,CAAe+B,UAAU,KAAK,CAAA,EAAG;AACnC,gBAAA,MAAM,IAAIrE,eAAAA,CAAgB,wDAAA,CAAA;AAC5B,YAAA;AACF,QAAA;AACF,IAAA;IAEA,MAAMiG,WAAAA,GAAc,MAAMzF,MAAAA,CAAOkB,EAAE,CAChCC,KAAK,CAAC,aAAA,CAAA,CACNuE,MAAM,CAAC;QAAEzD,KAAAA,EAAO;AAAES,YAAAA;AAAG,SAAA;QAAGpB,QAAAA,EAAU;AAAC,YAAA;AAAQ;AAAC,KAAA,CAAA;;AAG/C,IAAA,MAAMrB,cAAAA,GAAiBH,iBAAAA,EAAAA;AACvB,IAAA,IAAIG,cAAAA,IAAkBA,cAAAA,CAAe0F,SAAS,CAAC,OAAA,CAAA,EAAU;AACvD,QAAA,MAAM1F,cAAAA,CAAe,OAAA,CAAA,CAAS2F,sBAAsB,CAACC,MAAAA,CAAOnD,EAAAA,CAAAA,CAAAA;AAC9D,IAAA;AAEA1C,IAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;AAAEvB,QAAAA,IAAAA,EAAMD,YAAAA,CAAauF,WAAAA;AAAa,KAAA,CAAA;IAEtE,OAAOA,WAAAA;AACT,CAAA;AAEA;;IAGA,MAAMK,cAAc,OAAOC,GAAAA,GAAAA;;AAEzB,IAAA,MAAMjE,cAAAA,GAAiB,MAAMnB,gBAAAA,CAAW,MAAA,CAAA,CAAQmC,2BAA2B,EAAA;IAC3E,MAAMkD,sBAAAA,GAAyB,MAAMhG,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoD,KAAK,CAAC;QACxEtC,KAAAA,EAAO;YACLS,EAAAA,EAAIqD,GAAAA;YACJ1F,KAAAA,EAAO;AAAEqC,gBAAAA,EAAAA,EAAIZ,eAAeY;AAAG;AACjC;AACF,KAAA,CAAA;IAEA,IAAIZ,cAAAA,CAAe+B,UAAU,KAAKmC,sBAAAA,EAAwB;AACxD,QAAA,MAAM,IAAIxG,eAAAA,CAAgB,wDAAA,CAAA;AAC5B,IAAA;AAEA,IAAA,MAAMyG,eAAe,EAAE;IACvB,KAAK,MAAMvD,MAAMqD,GAAAA,CAAK;QACpB,MAAMN,WAAAA,GAAc,MAAMzF,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeuE,MAAM,CAAC;YAC9DzD,KAAAA,EAAO;AAAES,gBAAAA;AAAG,aAAA;YACZpB,QAAAA,EAAU;AAAC,gBAAA;AAAQ;AACrB,SAAA,CAAA;;AAGA,QAAA,MAAMrB,cAAAA,GAAiBH,iBAAAA,EAAAA;AACvB,QAAA,IAAIG,cAAAA,IAAkBA,cAAAA,CAAe0F,SAAS,CAAC,OAAA,CAAA,EAAU;AACvD,YAAA,MAAM1F,cAAAA,CAAe,OAAA,CAAA,CAAS2F,sBAAsB,CAACC,MAAAA,CAAOnD,EAAAA,CAAAA,CAAAA;AAC9D,QAAA;AAEAuD,QAAAA,YAAAA,CAAaC,IAAI,CAACT,WAAAA,CAAAA;AACpB,IAAA;AAEAzF,IAAAA,MAAAA,CAAOyB,QAAQ,CAACC,IAAI,CAAC,aAAA,EAAe;AAClCyE,QAAAA,KAAAA,EAAOF,YAAAA,CAAa3F,GAAG,CAAC,CAACmF,cAAgBvF,YAAAA,CAAauF,WAAAA,CAAAA;AACxD,KAAA,CAAA;IAEA,OAAOQ,YAAAA;AACT,CAAA;AAEA;AACC,IACD,MAAMG,qBAAAA,GAAwB,UAAA;AAC5B,IAAA,OAAOpG,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoD,KAAK,CAAC;QAC1CtC,KAAAA,EAAO;YACL5B,KAAAA,EAAO;gBACLqC,EAAAA,EAAI;oBAAE2D,KAAAA,EAAO;AAAK;AACpB;AACF;AACF,KAAA,CAAA;AACF,CAAA;AAEA;;;AAGC,IACD,MAAM9B,KAAAA,GAAQ,OAAOtC,KAAAA,GAAQ,EAAE,GAAA;AAC7B,IAAA,OAAOjC,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeoD,KAAK,CAAC;AAAEtC,QAAAA;AAAM,KAAA,CAAA;AACtD,CAAA;AAEA;;IAGA,MAAMqE,mBAAmB,OAAOC,MAAAA,GAAAA;IAC9B,MAAMJ,KAAAA,GAAQ,MAAMnG,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAe+C,QAAQ,CAAC;QAC1DlC,MAAAA,EAAQ;AAAC,YAAA;AAAK,SAAA;QACdC,KAAAA,EAAO;YACL5B,KAAAA,EAAO;gBAAEqC,EAAAA,EAAI;oBAAE2D,KAAAA,EAAO;AAAK;AAAE;AAC/B;AACF,KAAA,CAAA;AAEA,IAAA,MAAMG,QAAQC,GAAG,CACfN,KAAAA,CAAM7F,GAAG,CAAC,CAACH,IAAAA,GAAAA;AACT,QAAA,OAAOH,OAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeiC,MAAM,CAAC;YAC3CnB,KAAAA,EAAO;AAAES,gBAAAA,EAAAA,EAAIvC,KAAKuC;AAAG,aAAA;YACrBrB,IAAAA,EAAM;gBAAEhB,KAAAA,EAAO;AAACkG,oBAAAA;AAAO;AAAC;AAC1B,SAAA,CAAA;AACF,IAAA,CAAA,CAAA,CAAA;AAEJ,CAAA;AAEA;AACC,IACD,MAAMG,iCAAAA,GAAoC,UAAA;AACxC,IAAA,MAAMnC,QAAQ,MAAM6B,qBAAAA,EAAAA;AAEpB,IAAA,IAAI7B,QAAQ,CAAA,EAAG;QACbvE,MAAAA,CAAO2G,GAAG,CAACC,IAAI,CAAC,CAAC,YAAY,EAAErC,KAAAA,CAAM,sBAAsB,CAAC,CAAA;AAC9D,IAAA;AACF,CAAA;AAEA;AACC,IACD,MAAMsC,iBAAAA,GAAoB,UAAA;IACxB,MAAMV,KAAAA,GAAQ,MAAMnG,MAAAA,CAAOkB,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAe+C,QAAQ,CAAC;QAAElC,MAAAA,EAAQ;AAAC,YAAA;AAAmB;AAAC,KAAA,CAAA;AAE3F,IAAA,OAAOmE,MAAM7F,GAAG,CAAC,CAACH,IAAAA,GAASA,IAAAA,CAAK2G,gBAAgB,IAAI,IAAA,CAAA;AACtD,CAAA;AACA,WAAe;AACb1F,IAAAA,MAAAA;AACAO,IAAAA,gBAAAA;AACAgB,IAAAA,UAAAA;AACAH,IAAAA,MAAAA;AACAgC,IAAAA,oBAAAA;AACAE,IAAAA,QAAAA;AACAxE,IAAAA,YAAAA;AACAqD,IAAAA,OAAAA;AACAuB,IAAAA,cAAAA;AACAE,IAAAA,QAAAA;AACAK,IAAAA,UAAAA;AACAS,IAAAA,WAAAA;AACAM,IAAAA,qBAAAA;AACA7B,IAAAA,KAAAA;AACA+B,IAAAA,gBAAAA;AACAI,IAAAA,iCAAAA;AACArD,IAAAA,oBAAAA;AACAwD,IAAAA,iBAAAA;AACA9C,IAAAA;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"user.js","sources":["../../../../../server/src/services/user.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport _ from 'lodash';\nimport { defaults } from 'lodash/fp';\nimport { arrays, errors } from '@strapi/utils';\nimport type { Data } from '@strapi/types';\nimport { createUser, hasSuperAdminRole } from '../domain/user';\nimport type {\n AdminUser,\n AdminRole,\n AdminUserCreationPayload,\n SanitizedAdminUser,\n SanitizedAdminRole,\n AdminUserUpdatePayload,\n // eslint-disable-next-line node/no-unpublished-import\n} from '../../../shared/contracts/shared';\nimport { password as passwordValidator } from '../validation/common-validators';\nimport { getService } from '../utils';\nimport constants from './constants';\n\nconst { SUPER_ADMIN_CODE } = constants;\n\nconst { ApplicationError, ValidationError } = errors;\nconst sanitizeUserRoles = (role: AdminRole): SanitizedAdminRole =>\n _.pick(role, ['id', 'name', 'description', 'code']);\n\nconst getSessionManager = () => {\n const manager = strapi.sessionManager;\n return manager ?? null;\n};\n\n/**\n * Remove private user fields\n * @param user - user to sanitize\n */\nconst sanitizeUser = (user: AdminUser): SanitizedAdminUser => {\n return {\n ..._.omit(user, [\n 'password',\n 'resetPasswordToken',\n 'resetPasswordTokenExpiresAt',\n 'registrationToken',\n 'roles',\n ]),\n roles: user.roles && user.roles.map(sanitizeUserRoles),\n };\n};\n\n/**\n * Create and save a user in database\n * @param attributes A partial user object\n */\nconst createUserInDatabase = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const userInfo = {\n registrationToken: getService('token').createToken(),\n ...attributes,\n };\n\n if (_.has(attributes, 'password')) {\n userInfo.password = await getService('auth').hashPassword(attributes.password!);\n }\n\n const user = createUser(userInfo);\n\n const createdUser = await strapi.db\n .query('admin::user')\n .create({ data: user, populate: ['roles'] });\n\n return createdUser;\n};\n\nconst emitUserCreated = (user: AdminUser) => {\n getService('metrics').sendDidInviteUser();\n\n strapi.eventHub.emit('user.create', { user: sanitizeUser(user) });\n};\n\nconst create = async (\n // isActive is added in the controller, it's not sent by the API.\n attributes: Partial<AdminUserCreationPayload> & { isActive?: true }\n): Promise<AdminUser> => {\n const createdUser = await createUserInDatabase(attributes);\n\n emitUserCreated(createdUser);\n\n return createdUser;\n};\n\nconst createFirstAdmin = async (\n attributes: Omit<Partial<AdminUserCreationPayload>, 'registrationToken' | 'isActive' | 'roles'>\n): Promise<AdminUser> => {\n const createdUser = await strapi.db.transaction(async ({ trx }) => {\n // Serialize first-admin creation across processes by locking a stable role row.\n // SQLite ignores FOR UPDATE, but falls back to its single-writer transaction behavior.\n const superAdminRole = await strapi.db\n .queryBuilder('admin::role')\n .select(['id'])\n .where({ code: SUPER_ADMIN_CODE })\n .first()\n .transacting(trx)\n .forUpdate()\n .execute<AdminRole | undefined>();\n\n if (!superAdminRole) {\n throw new ApplicationError(\n \"Cannot register the first admin because the super admin role doesn't exist.\"\n );\n }\n\n const hasAdmin = await exists();\n\n if (hasAdmin) {\n throw new ApplicationError('You cannot register a new super admin');\n }\n\n return createUserInDatabase({\n ...attributes,\n registrationToken: null,\n isActive: true,\n roles: [superAdminRole.id],\n });\n });\n\n emitUserCreated(createdUser);\n\n return createdUser;\n};\n\n/**\n * Update a user in database\n * @param id query params to find the user to update\n * @param attributes A partial user object\n */\nconst updateById = async (\n id: Data.ID,\n attributes: Partial<AdminUserUpdatePayload>\n): Promise<AdminUser> => {\n // Check at least one super admin remains\n if (_.has(attributes, 'roles')) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const willRemoveSuperAdminRole = !arrays.includesString(attributes.roles!, superAdminRole.id);\n\n if (lastAdminUser && willRemoveSuperAdminRole) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // cannot disable last super admin\n if (attributes.isActive === false) {\n const lastAdminUser = await isLastSuperAdminUser(id);\n if (lastAdminUser) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n\n // hash password if a new one is sent\n if (_.has(attributes, 'password')) {\n const hashedPassword = await getService('auth').hashPassword(attributes.password!);\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: {\n ...attributes,\n password: hashedPassword,\n },\n populate: ['roles'],\n });\n\n strapi.eventHub.emit('user.update', { user: sanitizeUser(updatedUser) });\n\n return updatedUser;\n }\n\n const updatedUser = await strapi.db.query('admin::user').update({\n where: { id },\n data: attributes,\n populate: ['roles'],\n });\n\n if (updatedUser) {\n strapi.eventHub.emit('user.update', { user: sanitizeUser(updatedUser) });\n }\n\n return updatedUser;\n};\n\n/**\n * Reset a user password by email. (Used in admin:reset CLI)\n * @param email - user email\n * @param password - new password\n */\nconst resetPasswordByEmail = async (email: string, password: string) => {\n const user = await strapi.db\n .query('admin::user')\n .findOne({ where: { email }, populate: ['roles'] });\n\n if (!user) {\n throw new Error(`User not found for email: ${email}`);\n }\n\n try {\n await passwordValidator.validate(password);\n } catch (error) {\n throw new ValidationError(\n 'Invalid password. Expected a minimum of 8 characters with at least one number and one uppercase letter'\n );\n }\n\n await updateById(user.id, { password });\n};\n\n/**\n * Check if a user is the last super admin\n * @param userId user's id to look for\n */\nconst isLastSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const user = (await findOne(userId)) as AdminUser | null;\n if (!user) return false;\n\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n\n return superAdminRole.usersCount === 1 && hasSuperAdminRole(user);\n};\n\n/**\n * Check if a user is the first super admin\n * @param userId user's id to look for\n */\nconst isFirstSuperAdminUser = async (userId: Data.ID): Promise<boolean> => {\n const currentUser = (await findOne(userId)) as AdminUser | null;\n\n if (!currentUser || !hasSuperAdminRole(currentUser)) return false;\n\n const [oldestUser] = await strapi.db.query('admin::user').findMany({\n populate: {\n roles: {\n where: {\n code: { $eq: SUPER_ADMIN_CODE },\n },\n },\n },\n orderBy: { createdAt: 'asc' },\n limit: 1,\n select: ['id'],\n });\n\n return oldestUser.id === currentUser.id;\n};\n\n/**\n * Check if a user with specific attributes exists in the database\n * @param attributes A partial user object\n */\nconst exists = async (attributes = {} as unknown): Promise<boolean> => {\n return (await strapi.db.query('admin::user').count({ where: attributes })) > 0;\n};\n\n/**\n * Returns a user registration info\n * @param registrationToken - a user registration token\n * @returns - Returns user email, firstname and lastname\n */\nconst findRegistrationInfo = async (\n registrationToken: string\n): Promise<Pick<AdminUser, 'email' | 'firstname' | 'lastname'> | undefined> => {\n const user = await strapi.db.query('admin::user').findOne({ where: { registrationToken } });\n\n if (!user) {\n return undefined;\n }\n\n return _.pick(user, ['email', 'firstname', 'lastname']);\n};\n\n/**\n * Registers a user based on a registrationToken and some informations to update\n * @param params\n * @param params.registrationToken registration token\n * @param params.userInfo user info\n */\nconst register = async ({\n registrationToken,\n userInfo,\n}: {\n registrationToken: string;\n userInfo: Partial<AdminUser>;\n}) => {\n const matchingUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { registrationToken } });\n\n if (!matchingUser) {\n throw new ValidationError('Invalid registration info');\n }\n\n return getService('user').updateById(matchingUser.id, {\n password: userInfo.password,\n firstname: userInfo.firstname,\n lastname: userInfo.lastname,\n registrationToken: null,\n isActive: true,\n });\n};\n\n/**\n * Find one user\n */\nconst findOne = async (id: Data.ID, populate = ['roles']) => {\n return strapi.db.query('admin::user').findOne({ where: { id }, populate });\n};\n\n/**\n * Find one user by its email\n * @param email\n * @param populate\n * @returns\n */\nconst findOneByEmail = async (email: string, populate = []) => {\n return strapi.db.query('admin::user').findOne({\n where: { email: { $eqi: email } },\n populate,\n });\n};\n\n/** Find many users (paginated)\n * @param params\n */\nconst findPage = async (params = {}): Promise<unknown> => {\n const query = strapi\n .get('query-params')\n .transform('admin::user', defaults({ populate: ['roles'] }, params));\n\n return strapi.db.query('admin::user').findPage(query);\n};\n\n/** Delete a user\n * @param id id of the user to delete\n */\nconst deleteById = async (id: Data.ID): Promise<AdminUser | null> => {\n // Check at least one super admin remains\n const userToDelete: AdminUser | null = await strapi.db.query('admin::user').findOne({\n where: { id },\n populate: ['roles'],\n });\n\n if (!userToDelete) {\n return null;\n }\n\n if (userToDelete) {\n if (userToDelete.roles.some((r) => r.code === SUPER_ADMIN_CODE)) {\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n if (superAdminRole.usersCount === 1) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n }\n }\n\n const deletedUser = await strapi.db\n .query('admin::user')\n .delete({ where: { id }, populate: ['roles'] });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n strapi.eventHub.emit('user.delete', { user: sanitizeUser(deletedUser) });\n\n return deletedUser;\n};\n\n/** Delete a user\n * @param ids ids of the users to delete\n */\nconst deleteByIds = async (ids: (string | number)[]): Promise<AdminUser[]> => {\n // Check at least one super admin remains\n const superAdminRole = await getService('role').getSuperAdminWithUsersCount();\n const nbOfSuperAdminToDelete = await strapi.db.query('admin::user').count({\n where: {\n id: ids,\n roles: { id: superAdminRole.id },\n },\n });\n\n if (superAdminRole.usersCount === nbOfSuperAdminToDelete) {\n throw new ValidationError('You must have at least one user with super admin role.');\n }\n\n const deletedUsers = [] as AdminUser[];\n for (const id of ids) {\n const deletedUser = await strapi.db.query('admin::user').delete({\n where: { id },\n populate: ['roles'],\n });\n\n // Invalidate all sessions for the deleted user\n const sessionManager = getSessionManager();\n if (sessionManager && sessionManager.hasOrigin('admin')) {\n await sessionManager('admin').invalidateRefreshToken(String(id));\n }\n\n deletedUsers.push(deletedUser);\n }\n\n strapi.eventHub.emit('user.delete', {\n users: deletedUsers.map((deletedUser) => sanitizeUser(deletedUser)),\n });\n\n return deletedUsers;\n};\n\n/** Count the users that don't have any associated roles\n */\nconst countUsersWithoutRole = async (): Promise<number> => {\n return strapi.db.query('admin::user').count({\n where: {\n roles: {\n id: { $null: true },\n },\n },\n });\n};\n\n/**\n * Count the number of users based on search params\n * @param params params used for the query\n */\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::user').count({ where });\n};\n\n/**\n * Assign some roles to several users\n */\nconst assignARoleToAll = async (roleId: Data.ID): Promise<void> => {\n const users = await strapi.db.query('admin::user').findMany({\n select: ['id'],\n where: {\n roles: { id: { $null: true } },\n },\n });\n\n await Promise.all(\n users.map((user) => {\n return strapi.db.query('admin::user').update({\n where: { id: user.id },\n data: { roles: [roleId] },\n });\n })\n );\n};\n\n/** Display a warning if some users don't have at least one role\n */\nconst displayWarningIfUsersDontHaveRole = async (): Promise<void> => {\n const count = await countUsersWithoutRole();\n\n if (count > 0) {\n strapi.log.warn(`Some users (${count}) don't have any role.`);\n }\n};\n\n/** Returns an array of interface languages currently used by users\n */\nconst getLanguagesInUse = async (): Promise<string[]> => {\n const users = await strapi.db.query('admin::user').findMany({ select: ['preferedLanguage'] });\n\n return users.map((user) => user.preferedLanguage || 'en');\n};\nexport default {\n create,\n createFirstAdmin,\n updateById,\n exists,\n findRegistrationInfo,\n register,\n sanitizeUser,\n findOne,\n findOneByEmail,\n findPage,\n deleteById,\n deleteByIds,\n countUsersWithoutRole,\n count,\n assignARoleToAll,\n displayWarningIfUsersDontHaveRole,\n resetPasswordByEmail,\n getLanguagesInUse,\n isFirstSuperAdminUser,\n};\n"],"names":["SUPER_ADMIN_CODE","constants","ApplicationError","ValidationError","errors","sanitizeUserRoles","role","_","pick","getSessionManager","manager","strapi","sessionManager","sanitizeUser","user","omit","roles","map","createUserInDatabase","attributes","userInfo","registrationToken","getService","createToken","has","password","hashPassword","createUser","createdUser","db","query","create","data","populate","emitUserCreated","sendDidInviteUser","eventHub","emit","createFirstAdmin","transaction","trx","superAdminRole","queryBuilder","select","where","code","first","transacting","forUpdate","execute","hasAdmin","exists","isActive","id","updateById","lastAdminUser","isLastSuperAdminUser","getSuperAdminWithUsersCount","willRemoveSuperAdminRole","arrays","includesString","hashedPassword","updatedUser","update","resetPasswordByEmail","email","findOne","Error","passwordValidator","validate","error","userId","usersCount","hasSuperAdminRole","isFirstSuperAdminUser","currentUser","oldestUser","findMany","$eq","orderBy","createdAt","limit","count","findRegistrationInfo","undefined","register","matchingUser","firstname","lastname","findOneByEmail","$eqi","findPage","params","get","transform","defaults","deleteById","userToDelete","some","r","deletedUser","delete","hasOrigin","invalidateRefreshToken","String","deleteByIds","ids","nbOfSuperAdminToDelete","deletedUsers","push","users","countUsersWithoutRole","$null","assignARoleToAll","roleId","Promise","all","displayWarningIfUsersDontHaveRole","log","warn","getLanguagesInUse","preferedLanguage"],"mappings":"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"}
@@ -26,6 +26,7 @@ const getSessionManager = ()=>{
26
26
  ...___default.omit(user, [
27
27
  'password',
28
28
  'resetPasswordToken',
29
+ 'resetPasswordTokenExpiresAt',
29
30
  'registrationToken',
30
31
  'roles'
31
32
  ]),