@strapi/admin 5.53.0 → 5.55.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 (183) hide show
  1. package/dist/admin/admin/src/App.js +1 -1
  2. package/dist/admin/admin/src/App.js.map +1 -1
  3. package/dist/admin/admin/src/App.mjs +1 -1
  4. package/dist/admin/admin/src/App.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/DismissibleBanner.js +60 -0
  6. package/dist/admin/admin/src/components/DismissibleBanner.js.map +1 -0
  7. package/dist/admin/admin/src/components/DismissibleBanner.mjs +58 -0
  8. package/dist/admin/admin/src/components/DismissibleBanner.mjs.map +1 -0
  9. package/dist/admin/admin/src/components/Form.js +11 -2
  10. package/dist/admin/admin/src/components/Form.js.map +1 -1
  11. package/dist/admin/admin/src/components/Form.mjs +11 -2
  12. package/dist/admin/admin/src/components/Form.mjs.map +1 -1
  13. package/dist/admin/admin/src/components/FormInputs/DateTime.js +1 -1
  14. package/dist/admin/admin/src/components/FormInputs/DateTime.js.map +1 -1
  15. package/dist/admin/admin/src/components/FormInputs/DateTime.mjs +1 -1
  16. package/dist/admin/admin/src/components/FormInputs/DateTime.mjs.map +1 -1
  17. package/dist/admin/admin/src/components/FormInputs/Time.js +1 -1
  18. package/dist/admin/admin/src/components/FormInputs/Time.js.map +1 -1
  19. package/dist/admin/admin/src/components/FormInputs/Time.mjs +1 -1
  20. package/dist/admin/admin/src/components/FormInputs/Time.mjs.map +1 -1
  21. package/dist/admin/admin/src/components/LanguageProvider.js +35 -1
  22. package/dist/admin/admin/src/components/LanguageProvider.js.map +1 -1
  23. package/dist/admin/admin/src/components/LanguageProvider.mjs +17 -2
  24. package/dist/admin/admin/src/components/LanguageProvider.mjs.map +1 -1
  25. package/dist/admin/admin/src/components/MainNav/NavUser.js +1 -2
  26. package/dist/admin/admin/src/components/MainNav/NavUser.js.map +1 -1
  27. package/dist/admin/admin/src/components/MainNav/NavUser.mjs +1 -2
  28. package/dist/admin/admin/src/components/MainNav/NavUser.mjs.map +1 -1
  29. package/dist/admin/admin/src/components/MediaLibraryBanner.js +85 -0
  30. package/dist/admin/admin/src/components/MediaLibraryBanner.js.map +1 -0
  31. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs +83 -0
  32. package/dist/admin/admin/src/components/MediaLibraryBanner.mjs.map +1 -0
  33. package/dist/admin/admin/src/components/Providers.js +6 -6
  34. package/dist/admin/admin/src/components/Providers.js.map +1 -1
  35. package/dist/admin/admin/src/components/Providers.mjs +6 -6
  36. package/dist/admin/admin/src/components/Providers.mjs.map +1 -1
  37. package/dist/admin/admin/src/components/SubNav.js +113 -35
  38. package/dist/admin/admin/src/components/SubNav.js.map +1 -1
  39. package/dist/admin/admin/src/components/SubNav.mjs +115 -37
  40. package/dist/admin/admin/src/components/SubNav.mjs.map +1 -1
  41. package/dist/admin/admin/src/components/SubNavFolder.js +188 -0
  42. package/dist/admin/admin/src/components/SubNavFolder.js.map +1 -0
  43. package/dist/admin/admin/src/components/SubNavFolder.mjs +186 -0
  44. package/dist/admin/admin/src/components/SubNavFolder.mjs.map +1 -0
  45. package/dist/admin/admin/src/components/UpsellBanner.js +56 -86
  46. package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
  47. package/dist/admin/admin/src/components/UpsellBanner.mjs +58 -88
  48. package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
  49. package/dist/admin/admin/src/core/store/configure.js +14 -2
  50. package/dist/admin/admin/src/core/store/configure.js.map +1 -1
  51. package/dist/admin/admin/src/core/store/configure.mjs +14 -2
  52. package/dist/admin/admin/src/core/store/configure.mjs.map +1 -1
  53. package/dist/admin/admin/src/core/store/hooks.mjs +1 -1
  54. package/dist/admin/admin/src/features/Auth.js +162 -46
  55. package/dist/admin/admin/src/features/Auth.js.map +1 -1
  56. package/dist/admin/admin/src/features/Auth.mjs +164 -48
  57. package/dist/admin/admin/src/features/Auth.mjs.map +1 -1
  58. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  59. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  60. package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.js +19 -0
  61. package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.js.map +1 -0
  62. package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.mjs +17 -0
  63. package/dist/admin/admin/src/hooks/useRegisterUnsavedChanges.mjs.map +1 -0
  64. package/dist/admin/admin/src/hooks/{useIdleSessionLogout.js → useSessionKeepalive.js} +34 -27
  65. package/dist/admin/admin/src/hooks/useSessionKeepalive.js.map +1 -0
  66. package/dist/admin/admin/src/hooks/{useIdleSessionLogout.mjs → useSessionKeepalive.mjs} +34 -27
  67. package/dist/admin/admin/src/hooks/useSessionKeepalive.mjs.map +1 -0
  68. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +2 -0
  69. package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
  70. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +2 -0
  71. package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
  72. package/dist/admin/admin/src/pages/SessionsPage.js +2 -5
  73. package/dist/admin/admin/src/pages/SessionsPage.js.map +1 -1
  74. package/dist/admin/admin/src/pages/SessionsPage.mjs +2 -5
  75. package/dist/admin/admin/src/pages/SessionsPage.mjs.map +1 -1
  76. package/dist/admin/admin/src/render.js +6 -1
  77. package/dist/admin/admin/src/render.js.map +1 -1
  78. package/dist/admin/admin/src/render.mjs +6 -1
  79. package/dist/admin/admin/src/render.mjs.map +1 -1
  80. package/dist/admin/admin/src/translations/en.json.js +16 -0
  81. package/dist/admin/admin/src/translations/en.json.js.map +1 -1
  82. package/dist/admin/admin/src/translations/en.json.mjs +16 -0
  83. package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
  84. package/dist/admin/admin/src/utils/baseQuery.js +3 -13
  85. package/dist/admin/admin/src/utils/baseQuery.js.map +1 -1
  86. package/dist/admin/admin/src/utils/baseQuery.mjs +3 -13
  87. package/dist/admin/admin/src/utils/baseQuery.mjs.map +1 -1
  88. package/dist/admin/admin/src/utils/getFetchClient.js +34 -5
  89. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  90. package/dist/admin/admin/src/utils/getFetchClient.mjs +34 -6
  91. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  92. package/dist/admin/admin/src/utils/unsavedChangesRegistry.js +25 -0
  93. package/dist/admin/admin/src/utils/unsavedChangesRegistry.js.map +1 -0
  94. package/dist/admin/admin/src/utils/unsavedChangesRegistry.mjs +22 -0
  95. package/dist/admin/admin/src/utils/unsavedChangesRegistry.mjs.map +1 -0
  96. package/dist/admin/admin/tests/utils.js +14 -14
  97. package/dist/admin/admin/tests/utils.js.map +1 -1
  98. package/dist/admin/admin/tests/utils.mjs +14 -14
  99. package/dist/admin/admin/tests/utils.mjs.map +1 -1
  100. package/dist/admin/ee/admin/src/hooks/useAIAvailability.js +1 -6
  101. package/dist/admin/ee/admin/src/hooks/useAIAvailability.js.map +1 -1
  102. package/dist/admin/ee/admin/src/hooks/useAIAvailability.mjs +1 -6
  103. package/dist/admin/ee/admin/src/hooks/useAIAvailability.mjs.map +1 -1
  104. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js +7 -1
  105. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js.map +1 -1
  106. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs +7 -1
  107. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs.map +1 -1
  108. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +9 -1
  109. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
  110. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +9 -1
  111. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
  112. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.js +0 -4
  113. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.js.map +1 -1
  114. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.mjs +0 -4
  115. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.mjs.map +1 -1
  116. package/dist/admin/index.js +1 -0
  117. package/dist/admin/index.js.map +1 -1
  118. package/dist/admin/index.mjs +1 -1
  119. package/dist/admin/src/components/DismissibleBanner.d.ts +8 -0
  120. package/dist/admin/src/components/MediaLibraryBanner.d.ts +2 -0
  121. package/dist/admin/src/components/SubNav.d.ts +27 -8
  122. package/dist/admin/src/components/SubNavFolder.d.ts +15 -0
  123. package/dist/admin/src/features/Tracking.d.ts +2 -1
  124. package/dist/admin/src/hooks/useRegisterUnsavedChanges.d.ts +6 -0
  125. package/dist/admin/src/hooks/useSessionKeepalive.d.ts +88 -0
  126. package/dist/admin/src/services/admin.d.ts +1 -0
  127. package/dist/admin/src/utils/getFetchClient.d.ts +14 -6
  128. package/dist/admin/src/utils/unsavedChangesRegistry.d.ts +11 -0
  129. package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +8 -0
  130. package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
  131. package/dist/ee/server/src/index.d.ts.map +1 -1
  132. package/dist/server/ee/server/src/controllers/admin.js +1 -5
  133. package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
  134. package/dist/server/ee/server/src/controllers/admin.mjs +1 -5
  135. package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
  136. package/dist/server/ee/server/src/index.js +2 -0
  137. package/dist/server/ee/server/src/index.js.map +1 -1
  138. package/dist/server/ee/server/src/index.mjs +2 -0
  139. package/dist/server/ee/server/src/index.mjs.map +1 -1
  140. package/dist/server/server/src/ai/controllers/ai.js +3 -3
  141. package/dist/server/server/src/ai/controllers/ai.js.map +1 -1
  142. package/dist/server/server/src/ai/controllers/ai.mjs +3 -3
  143. package/dist/server/server/src/ai/controllers/ai.mjs.map +1 -1
  144. package/dist/server/server/src/ai/services/ai.js +37 -12
  145. package/dist/server/server/src/ai/services/ai.js.map +1 -1
  146. package/dist/server/server/src/ai/services/ai.mjs +37 -12
  147. package/dist/server/server/src/ai/services/ai.mjs.map +1 -1
  148. package/dist/server/server/src/audit-logs/tokens.js +106 -0
  149. package/dist/server/server/src/audit-logs/tokens.js.map +1 -0
  150. package/dist/server/server/src/audit-logs/tokens.mjs +99 -0
  151. package/dist/server/server/src/audit-logs/tokens.mjs.map +1 -0
  152. package/dist/server/server/src/controllers/admin.js +10 -1
  153. package/dist/server/server/src/controllers/admin.js.map +1 -1
  154. package/dist/server/server/src/controllers/admin.mjs +10 -1
  155. package/dist/server/server/src/controllers/admin.mjs.map +1 -1
  156. package/dist/server/server/src/services/api-token.js +106 -4
  157. package/dist/server/server/src/services/api-token.js.map +1 -1
  158. package/dist/server/server/src/services/api-token.mjs +107 -5
  159. package/dist/server/server/src/services/api-token.mjs.map +1 -1
  160. package/dist/server/server/src/services/transfer/token.js +56 -4
  161. package/dist/server/server/src/services/transfer/token.js.map +1 -1
  162. package/dist/server/server/src/services/transfer/token.mjs +57 -5
  163. package/dist/server/server/src/services/transfer/token.mjs.map +1 -1
  164. package/dist/server/src/ai/services/ai.d.ts +3 -1
  165. package/dist/server/src/ai/services/ai.d.ts.map +1 -1
  166. package/dist/server/src/audit-logs/tokens.d.ts +86 -0
  167. package/dist/server/src/audit-logs/tokens.d.ts.map +1 -0
  168. package/dist/server/src/controllers/admin.d.ts +1 -0
  169. package/dist/server/src/controllers/admin.d.ts.map +1 -1
  170. package/dist/server/src/controllers/index.d.ts +1 -0
  171. package/dist/server/src/controllers/index.d.ts.map +1 -1
  172. package/dist/server/src/index.d.ts +1 -0
  173. package/dist/server/src/index.d.ts.map +1 -1
  174. package/dist/server/src/services/api-token.d.ts.map +1 -1
  175. package/dist/server/src/services/transfer/token.d.ts.map +1 -1
  176. package/dist/shared/contracts/admin.d.ts +1 -0
  177. package/dist/shared/contracts/admin.d.ts.map +1 -1
  178. package/dist/shared/contracts/shared.d.ts +1 -0
  179. package/dist/shared/contracts/shared.d.ts.map +1 -1
  180. package/package.json +7 -7
  181. package/dist/admin/admin/src/hooks/useIdleSessionLogout.js.map +0 -1
  182. package/dist/admin/admin/src/hooks/useIdleSessionLogout.mjs.map +0 -1
  183. package/dist/admin/src/hooks/useIdleSessionLogout.d.ts +0 -87
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sources":["../../../../../server/src/controllers/admin.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport path from 'path';\n\nimport { map, values, sumBy, pipe, flatMap, propEq } from 'lodash/fp';\nimport _ from 'lodash';\nimport { exists } from 'fs-extra';\nimport { env } from '@strapi/utils';\nimport {\n validateUpdateProjectSettings,\n validateUpdateProjectSettingsFiles,\n validateUpdateProjectSettingsImagesDimensions,\n} from '../validation/project-settings';\nimport { getService } from '../utils';\n\nimport type {\n Init,\n GetProjectSettings,\n Information,\n Plugins,\n TelemetryProperties,\n UpdateProjectSettings,\n GetGuidedTourMeta,\n} from '../../../shared/contracts/admin';\n\n// Lazy: only resolved on first GET /admin/project-type request\ntype TsUtilsModule = typeof import('@strapi/typescript-utils');\nlet lazyTsUtils: TsUtilsModule | undefined;\nconst isUsingTypeScript: TsUtilsModule['isUsingTypeScript'] = (\n ...args: Parameters<TsUtilsModule['isUsingTypeScript']>\n) => {\n if (!lazyTsUtils) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n lazyTsUtils = require('@strapi/typescript-utils');\n }\n return (lazyTsUtils as TsUtilsModule).isUsingTypeScript(...args);\n};\n\n/**\n * A set of functions called \"actions\" for `Admin`\n */\nexport default {\n // TODO very temporary to check the switch ee/ce\n // When removing this we need to update the /admin/src/index.js file\n // whe,re we set the strapi.window.isEE value\n\n // NOTE: admin/ee/server overrides this controller, and adds the EE features\n // This returns an empty feature list for CE\n async getProjectType() {\n const flags = strapi.config.get('admin.flags', {});\n return { data: { isEE: false, features: [], flags, ai: { enabled: false } } };\n },\n\n async init() {\n let uuid = strapi.config.get('uuid', false);\n const hasAdmin = await getService('user').exists();\n const { menuLogo, authLogo } = await getService('project-settings').getProjectSettings();\n // set to null if telemetryDisabled flag not avaialble in package.json\n const telemetryDisabled: boolean | null = strapi.config.get(\n 'packageJsonStrapi.telemetryDisabled',\n null\n );\n\n if (telemetryDisabled !== null && telemetryDisabled === true) {\n uuid = false;\n }\n\n return {\n data: {\n uuid,\n hasAdmin,\n menuLogo: menuLogo ? menuLogo.url : null,\n authLogo: authLogo ? authLogo.url : null,\n },\n } satisfies Init.Response;\n },\n\n async getProjectSettings() {\n return getService(\n 'project-settings'\n ).getProjectSettings() satisfies Promise<GetProjectSettings.Response>;\n },\n\n async updateProjectSettings(ctx: Context) {\n const {\n request: { files, body },\n } = ctx as { request: UpdateProjectSettings.Request };\n\n const projectSettingsService = getService('project-settings');\n\n await validateUpdateProjectSettings(body);\n await validateUpdateProjectSettingsFiles(files);\n\n const formatedFiles = await projectSettingsService.parseFilesData(files);\n await validateUpdateProjectSettingsImagesDimensions(formatedFiles);\n\n return projectSettingsService.updateProjectSettings({\n ...body,\n ...formatedFiles,\n }) satisfies Promise<UpdateProjectSettings.Response>;\n },\n\n async telemetryProperties(ctx: Context) {\n // If the telemetry is disabled, ignore the request and return early\n if (strapi.telemetry.isDisabled) {\n ctx.status = 204;\n return;\n }\n\n const useTypescriptOnServer = await isUsingTypeScript(strapi.dirs.app.root);\n const useTypescriptOnAdmin = await isUsingTypeScript(\n path.join(strapi.dirs.app.root, 'src', 'admin')\n );\n const isHostedOnStrapiCloud = env('STRAPI_HOSTING', null) === 'strapi.cloud';\n\n const numberOfAllContentTypes = _.size(strapi.contentTypes);\n const numberOfComponents = _.size(strapi.components);\n\n const getNumberOfDynamicZones = () => {\n return pipe(\n map('attributes'),\n flatMap(values),\n // @ts-expect-error lodash types\n sumBy(propEq('type', 'dynamiczone'))\n )(strapi.contentTypes as any);\n };\n\n return {\n data: {\n useTypescriptOnServer,\n useTypescriptOnAdmin,\n isHostedOnStrapiCloud,\n numberOfAllContentTypes, // TODO: V5: This event should be renamed numberOfContentTypes in V5 as the name is already taken to describe the number of content types using i18n.\n numberOfComponents,\n numberOfDynamicZones: getNumberOfDynamicZones(),\n },\n } satisfies TelemetryProperties.Response;\n },\n\n async information() {\n const currentEnvironment: string = strapi.config.get('environment');\n const autoReload = strapi.config.get('autoReload', false);\n const strapiVersion = strapi.config.get('info.strapi', null);\n const dependencies = strapi.config.get('info.dependencies', {});\n const projectId = strapi.config.get('uuid', null);\n const nodeVersion = process.version;\n const communityEdition = !strapi.EE;\n const useYarn: boolean = await exists(path.join(process.cwd(), 'yarn.lock'));\n\n return {\n data: {\n currentEnvironment,\n autoReload,\n strapiVersion,\n dependencies,\n projectId,\n nodeVersion,\n communityEdition,\n useYarn,\n },\n } satisfies Information.Response;\n },\n\n async plugins(ctx: Context) {\n const enabledPlugins = strapi.config.get('enabledPlugins') as any;\n\n // List of core plugins that are always enabled,\n // and so it's not necessary to display them in the plugins list\n const CORE_PLUGINS = [\n 'content-manager',\n 'content-type-builder',\n 'email',\n 'upload',\n 'i18n',\n 'content-releases',\n 'review-workflows',\n ];\n\n const plugins = Object.entries(enabledPlugins)\n .filter(([key]: any) => !CORE_PLUGINS.includes(key))\n .map(([key, plugin]: any) => ({\n name: plugin.info.name || key,\n displayName: plugin.info.displayName || plugin.info.name || key,\n description: plugin.info.description || '',\n packageName: plugin.info.packageName,\n }));\n\n ctx.send({ plugins } satisfies Plugins.Response);\n },\n\n async licenseTrialTimeLeft() {\n const data = await strapi.ee.getTrialEndDate({\n strapi,\n });\n\n return data;\n },\n\n async getGuidedTourMeta(ctx: Context) {\n const isFirstSuperAdminUser = await getService('user').isFirstSuperAdminUser(ctx.state.user.id);\n\n return {\n data: {\n isFirstSuperAdminUser,\n schemas: strapi.contentTypes,\n },\n } satisfies GetGuidedTourMeta.Response;\n },\n};\n"],"names":["lazyTsUtils","isUsingTypeScript","args","require","getProjectType","flags","strapi","config","get","data","isEE","features","ai","enabled","init","uuid","hasAdmin","getService","exists","menuLogo","authLogo","getProjectSettings","telemetryDisabled","url","updateProjectSettings","ctx","request","files","body","projectSettingsService","validateUpdateProjectSettings","validateUpdateProjectSettingsFiles","formatedFiles","parseFilesData","validateUpdateProjectSettingsImagesDimensions","telemetryProperties","telemetry","isDisabled","status","useTypescriptOnServer","dirs","app","root","useTypescriptOnAdmin","path","join","isHostedOnStrapiCloud","env","numberOfAllContentTypes","_","size","contentTypes","numberOfComponents","components","getNumberOfDynamicZones","pipe","map","flatMap","values","sumBy","propEq","numberOfDynamicZones","information","currentEnvironment","autoReload","strapiVersion","dependencies","projectId","nodeVersion","process","version","communityEdition","EE","useYarn","cwd","plugins","enabledPlugins","CORE_PLUGINS","Object","entries","filter","key","includes","plugin","name","info","displayName","description","packageName","send","licenseTrialTimeLeft","ee","getTrialEndDate","getGuidedTourMeta","isFirstSuperAdminUser","state","user","id","schemas"],"mappings":"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"}
1
+ {"version":3,"file":"admin.js","sources":["../../../../../server/src/controllers/admin.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport path from 'path';\n\nimport { map, values, sumBy, pipe, flatMap, propEq } from 'lodash/fp';\nimport _ from 'lodash';\nimport { exists } from 'fs-extra';\nimport { env } from '@strapi/utils';\nimport {\n validateUpdateProjectSettings,\n validateUpdateProjectSettingsFiles,\n validateUpdateProjectSettingsImagesDimensions,\n} from '../validation/project-settings';\nimport { getService } from '../utils';\n\nimport type {\n Init,\n GetProjectSettings,\n Information,\n Plugins,\n TelemetryProperties,\n UpdateProjectSettings,\n GetGuidedTourMeta,\n} from '../../../shared/contracts/admin';\n\n// Lazy: only resolved on first GET /admin/project-type request\ntype TsUtilsModule = typeof import('@strapi/typescript-utils');\nlet lazyTsUtils: TsUtilsModule | undefined;\nconst isUsingTypeScript: TsUtilsModule['isUsingTypeScript'] = (\n ...args: Parameters<TsUtilsModule['isUsingTypeScript']>\n) => {\n if (!lazyTsUtils) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n lazyTsUtils = require('@strapi/typescript-utils');\n }\n return (lazyTsUtils as TsUtilsModule).isUsingTypeScript(...args);\n};\n\n/**\n * A set of functions called \"actions\" for `Admin`\n */\nexport default {\n // TODO very temporary to check the switch ee/ce\n // When removing this we need to update the /admin/src/index.js file\n // whe,re we set the strapi.window.isEE value\n\n // NOTE: admin/ee/server overrides this controller, and adds the EE features\n // This returns an empty feature list for CE\n async getProjectType() {\n const flags = strapi.config.get('admin.flags', {});\n return { data: { isEE: false, features: [], flags, ai: { enabled: false } } };\n },\n\n async init() {\n let uuid = strapi.config.get('uuid', false);\n const hasAdmin = await getService('user').exists();\n const { menuLogo, authLogo } = await getService('project-settings').getProjectSettings();\n // set to null if telemetryDisabled flag not avaialble in package.json\n const telemetryDisabled: boolean | null = strapi.config.get(\n 'packageJsonStrapi.telemetryDisabled',\n null\n );\n\n if (telemetryDisabled !== null && telemetryDisabled === true) {\n uuid = false;\n }\n\n return {\n data: {\n uuid,\n hasAdmin,\n menuLogo: menuLogo ? menuLogo.url : null,\n authLogo: authLogo ? authLogo.url : null,\n },\n } satisfies Init.Response;\n },\n\n async getProjectSettings() {\n return getService(\n 'project-settings'\n ).getProjectSettings() satisfies Promise<GetProjectSettings.Response>;\n },\n\n async updateProjectSettings(ctx: Context) {\n const {\n request: { files, body },\n } = ctx as { request: UpdateProjectSettings.Request };\n\n const projectSettingsService = getService('project-settings');\n\n await validateUpdateProjectSettings(body);\n await validateUpdateProjectSettingsFiles(files);\n\n const formatedFiles = await projectSettingsService.parseFilesData(files);\n await validateUpdateProjectSettingsImagesDimensions(formatedFiles);\n\n return projectSettingsService.updateProjectSettings({\n ...body,\n ...formatedFiles,\n }) satisfies Promise<UpdateProjectSettings.Response>;\n },\n\n async telemetryProperties(ctx: Context) {\n // If the telemetry is disabled, ignore the request and return early\n if (strapi.telemetry.isDisabled) {\n ctx.status = 204;\n return;\n }\n\n const useTypescriptOnServer = await isUsingTypeScript(strapi.dirs.app.root);\n const useTypescriptOnAdmin = await isUsingTypeScript(\n path.join(strapi.dirs.app.root, 'src', 'admin')\n );\n const isHostedOnStrapiCloud = env('STRAPI_HOSTING', null) === 'strapi.cloud';\n\n const numberOfAllContentTypes = _.size(strapi.contentTypes);\n const numberOfComponents = _.size(strapi.components);\n\n const getNumberOfDynamicZones = () => {\n return pipe(\n map('attributes'),\n flatMap(values),\n // @ts-expect-error lodash types\n sumBy(propEq('type', 'dynamiczone'))\n )(strapi.contentTypes as any);\n };\n\n const getNumberOfFolders = async (): Promise<number> => {\n try {\n const contentStructure = strapi.get('content-structure') as\n | { countGroups?: () => Promise<number> }\n | undefined;\n\n return (await contentStructure?.countGroups?.()) ?? 0;\n } catch {\n return 0;\n }\n };\n\n return {\n data: {\n useTypescriptOnServer,\n useTypescriptOnAdmin,\n isHostedOnStrapiCloud,\n numberOfAllContentTypes, // TODO: V5: This event should be renamed numberOfContentTypes in V5 as the name is already taken to describe the number of content types using i18n.\n numberOfComponents,\n numberOfDynamicZones: getNumberOfDynamicZones(),\n numberOfContentTypeFolders: await getNumberOfFolders(),\n },\n } satisfies TelemetryProperties.Response;\n },\n\n async information() {\n const currentEnvironment: string = strapi.config.get('environment');\n const autoReload = strapi.config.get('autoReload', false);\n const strapiVersion = strapi.config.get('info.strapi', null);\n const dependencies = strapi.config.get('info.dependencies', {});\n const projectId = strapi.config.get('uuid', null);\n const nodeVersion = process.version;\n const communityEdition = !strapi.EE;\n const useYarn: boolean = await exists(path.join(process.cwd(), 'yarn.lock'));\n\n return {\n data: {\n currentEnvironment,\n autoReload,\n strapiVersion,\n dependencies,\n projectId,\n nodeVersion,\n communityEdition,\n useYarn,\n },\n } satisfies Information.Response;\n },\n\n async plugins(ctx: Context) {\n const enabledPlugins = strapi.config.get('enabledPlugins') as any;\n\n // List of core plugins that are always enabled,\n // and so it's not necessary to display them in the plugins list\n const CORE_PLUGINS = [\n 'content-manager',\n 'content-type-builder',\n 'email',\n 'upload',\n 'i18n',\n 'content-releases',\n 'review-workflows',\n ];\n\n const plugins = Object.entries(enabledPlugins)\n .filter(([key]: any) => !CORE_PLUGINS.includes(key))\n .map(([key, plugin]: any) => ({\n name: plugin.info.name || key,\n displayName: plugin.info.displayName || plugin.info.name || key,\n description: plugin.info.description || '',\n packageName: plugin.info.packageName,\n }));\n\n ctx.send({ plugins } satisfies Plugins.Response);\n },\n\n async licenseTrialTimeLeft() {\n const data = await strapi.ee.getTrialEndDate({\n strapi,\n });\n\n return data;\n },\n\n async getGuidedTourMeta(ctx: Context) {\n const isFirstSuperAdminUser = await getService('user').isFirstSuperAdminUser(ctx.state.user.id);\n\n return {\n data: {\n isFirstSuperAdminUser,\n schemas: strapi.contentTypes,\n },\n } satisfies GetGuidedTourMeta.Response;\n },\n};\n"],"names":["lazyTsUtils","isUsingTypeScript","args","require","getProjectType","flags","strapi","config","get","data","isEE","features","ai","enabled","init","uuid","hasAdmin","getService","exists","menuLogo","authLogo","getProjectSettings","telemetryDisabled","url","updateProjectSettings","ctx","request","files","body","projectSettingsService","validateUpdateProjectSettings","validateUpdateProjectSettingsFiles","formatedFiles","parseFilesData","validateUpdateProjectSettingsImagesDimensions","telemetryProperties","telemetry","isDisabled","status","useTypescriptOnServer","dirs","app","root","useTypescriptOnAdmin","path","join","isHostedOnStrapiCloud","env","numberOfAllContentTypes","_","size","contentTypes","numberOfComponents","components","getNumberOfDynamicZones","pipe","map","flatMap","values","sumBy","propEq","getNumberOfFolders","contentStructure","countGroups","numberOfDynamicZones","numberOfContentTypeFolders","information","currentEnvironment","autoReload","strapiVersion","dependencies","projectId","nodeVersion","process","version","communityEdition","EE","useYarn","cwd","plugins","enabledPlugins","CORE_PLUGINS","Object","entries","filter","key","includes","plugin","name","info","displayName","description","packageName","send","licenseTrialTimeLeft","ee","getTrialEndDate","getGuidedTourMeta","isFirstSuperAdminUser","state","user","id","schemas"],"mappings":"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"}
@@ -83,6 +83,14 @@ const isUsingTypeScript = (...args)=>{
83
83
  return pipe(map('attributes'), flatMap(values), // @ts-expect-error lodash types
84
84
  sumBy(propEq('type', 'dynamiczone')))(strapi.contentTypes);
85
85
  };
86
+ const getNumberOfFolders = async ()=>{
87
+ try {
88
+ const contentStructure = strapi.get('content-structure');
89
+ return await contentStructure?.countGroups?.() ?? 0;
90
+ } catch {
91
+ return 0;
92
+ }
93
+ };
86
94
  return {
87
95
  data: {
88
96
  useTypescriptOnServer,
@@ -90,7 +98,8 @@ const isUsingTypeScript = (...args)=>{
90
98
  isHostedOnStrapiCloud,
91
99
  numberOfAllContentTypes,
92
100
  numberOfComponents,
93
- numberOfDynamicZones: getNumberOfDynamicZones()
101
+ numberOfDynamicZones: getNumberOfDynamicZones(),
102
+ numberOfContentTypeFolders: await getNumberOfFolders()
94
103
  }
95
104
  };
96
105
  },
@@ -1 +1 @@
1
- {"version":3,"file":"admin.mjs","sources":["../../../../../server/src/controllers/admin.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport path from 'path';\n\nimport { map, values, sumBy, pipe, flatMap, propEq } from 'lodash/fp';\nimport _ from 'lodash';\nimport { exists } from 'fs-extra';\nimport { env } from '@strapi/utils';\nimport {\n validateUpdateProjectSettings,\n validateUpdateProjectSettingsFiles,\n validateUpdateProjectSettingsImagesDimensions,\n} from '../validation/project-settings';\nimport { getService } from '../utils';\n\nimport type {\n Init,\n GetProjectSettings,\n Information,\n Plugins,\n TelemetryProperties,\n UpdateProjectSettings,\n GetGuidedTourMeta,\n} from '../../../shared/contracts/admin';\n\n// Lazy: only resolved on first GET /admin/project-type request\ntype TsUtilsModule = typeof import('@strapi/typescript-utils');\nlet lazyTsUtils: TsUtilsModule | undefined;\nconst isUsingTypeScript: TsUtilsModule['isUsingTypeScript'] = (\n ...args: Parameters<TsUtilsModule['isUsingTypeScript']>\n) => {\n if (!lazyTsUtils) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n lazyTsUtils = require('@strapi/typescript-utils');\n }\n return (lazyTsUtils as TsUtilsModule).isUsingTypeScript(...args);\n};\n\n/**\n * A set of functions called \"actions\" for `Admin`\n */\nexport default {\n // TODO very temporary to check the switch ee/ce\n // When removing this we need to update the /admin/src/index.js file\n // whe,re we set the strapi.window.isEE value\n\n // NOTE: admin/ee/server overrides this controller, and adds the EE features\n // This returns an empty feature list for CE\n async getProjectType() {\n const flags = strapi.config.get('admin.flags', {});\n return { data: { isEE: false, features: [], flags, ai: { enabled: false } } };\n },\n\n async init() {\n let uuid = strapi.config.get('uuid', false);\n const hasAdmin = await getService('user').exists();\n const { menuLogo, authLogo } = await getService('project-settings').getProjectSettings();\n // set to null if telemetryDisabled flag not avaialble in package.json\n const telemetryDisabled: boolean | null = strapi.config.get(\n 'packageJsonStrapi.telemetryDisabled',\n null\n );\n\n if (telemetryDisabled !== null && telemetryDisabled === true) {\n uuid = false;\n }\n\n return {\n data: {\n uuid,\n hasAdmin,\n menuLogo: menuLogo ? menuLogo.url : null,\n authLogo: authLogo ? authLogo.url : null,\n },\n } satisfies Init.Response;\n },\n\n async getProjectSettings() {\n return getService(\n 'project-settings'\n ).getProjectSettings() satisfies Promise<GetProjectSettings.Response>;\n },\n\n async updateProjectSettings(ctx: Context) {\n const {\n request: { files, body },\n } = ctx as { request: UpdateProjectSettings.Request };\n\n const projectSettingsService = getService('project-settings');\n\n await validateUpdateProjectSettings(body);\n await validateUpdateProjectSettingsFiles(files);\n\n const formatedFiles = await projectSettingsService.parseFilesData(files);\n await validateUpdateProjectSettingsImagesDimensions(formatedFiles);\n\n return projectSettingsService.updateProjectSettings({\n ...body,\n ...formatedFiles,\n }) satisfies Promise<UpdateProjectSettings.Response>;\n },\n\n async telemetryProperties(ctx: Context) {\n // If the telemetry is disabled, ignore the request and return early\n if (strapi.telemetry.isDisabled) {\n ctx.status = 204;\n return;\n }\n\n const useTypescriptOnServer = await isUsingTypeScript(strapi.dirs.app.root);\n const useTypescriptOnAdmin = await isUsingTypeScript(\n path.join(strapi.dirs.app.root, 'src', 'admin')\n );\n const isHostedOnStrapiCloud = env('STRAPI_HOSTING', null) === 'strapi.cloud';\n\n const numberOfAllContentTypes = _.size(strapi.contentTypes);\n const numberOfComponents = _.size(strapi.components);\n\n const getNumberOfDynamicZones = () => {\n return pipe(\n map('attributes'),\n flatMap(values),\n // @ts-expect-error lodash types\n sumBy(propEq('type', 'dynamiczone'))\n )(strapi.contentTypes as any);\n };\n\n return {\n data: {\n useTypescriptOnServer,\n useTypescriptOnAdmin,\n isHostedOnStrapiCloud,\n numberOfAllContentTypes, // TODO: V5: This event should be renamed numberOfContentTypes in V5 as the name is already taken to describe the number of content types using i18n.\n numberOfComponents,\n numberOfDynamicZones: getNumberOfDynamicZones(),\n },\n } satisfies TelemetryProperties.Response;\n },\n\n async information() {\n const currentEnvironment: string = strapi.config.get('environment');\n const autoReload = strapi.config.get('autoReload', false);\n const strapiVersion = strapi.config.get('info.strapi', null);\n const dependencies = strapi.config.get('info.dependencies', {});\n const projectId = strapi.config.get('uuid', null);\n const nodeVersion = process.version;\n const communityEdition = !strapi.EE;\n const useYarn: boolean = await exists(path.join(process.cwd(), 'yarn.lock'));\n\n return {\n data: {\n currentEnvironment,\n autoReload,\n strapiVersion,\n dependencies,\n projectId,\n nodeVersion,\n communityEdition,\n useYarn,\n },\n } satisfies Information.Response;\n },\n\n async plugins(ctx: Context) {\n const enabledPlugins = strapi.config.get('enabledPlugins') as any;\n\n // List of core plugins that are always enabled,\n // and so it's not necessary to display them in the plugins list\n const CORE_PLUGINS = [\n 'content-manager',\n 'content-type-builder',\n 'email',\n 'upload',\n 'i18n',\n 'content-releases',\n 'review-workflows',\n ];\n\n const plugins = Object.entries(enabledPlugins)\n .filter(([key]: any) => !CORE_PLUGINS.includes(key))\n .map(([key, plugin]: any) => ({\n name: plugin.info.name || key,\n displayName: plugin.info.displayName || plugin.info.name || key,\n description: plugin.info.description || '',\n packageName: plugin.info.packageName,\n }));\n\n ctx.send({ plugins } satisfies Plugins.Response);\n },\n\n async licenseTrialTimeLeft() {\n const data = await strapi.ee.getTrialEndDate({\n strapi,\n });\n\n return data;\n },\n\n async getGuidedTourMeta(ctx: Context) {\n const isFirstSuperAdminUser = await getService('user').isFirstSuperAdminUser(ctx.state.user.id);\n\n return {\n data: {\n isFirstSuperAdminUser,\n schemas: strapi.contentTypes,\n },\n } satisfies GetGuidedTourMeta.Response;\n },\n};\n"],"names":["lazyTsUtils","isUsingTypeScript","args","require","getProjectType","flags","strapi","config","get","data","isEE","features","ai","enabled","init","uuid","hasAdmin","getService","exists","menuLogo","authLogo","getProjectSettings","telemetryDisabled","url","updateProjectSettings","ctx","request","files","body","projectSettingsService","validateUpdateProjectSettings","validateUpdateProjectSettingsFiles","formatedFiles","parseFilesData","validateUpdateProjectSettingsImagesDimensions","telemetryProperties","telemetry","isDisabled","status","useTypescriptOnServer","dirs","app","root","useTypescriptOnAdmin","path","join","isHostedOnStrapiCloud","env","numberOfAllContentTypes","_","size","contentTypes","numberOfComponents","components","getNumberOfDynamicZones","pipe","map","flatMap","values","sumBy","propEq","numberOfDynamicZones","information","currentEnvironment","autoReload","strapiVersion","dependencies","projectId","nodeVersion","process","version","communityEdition","EE","useYarn","cwd","plugins","enabledPlugins","CORE_PLUGINS","Object","entries","filter","key","includes","plugin","name","info","displayName","description","packageName","send","licenseTrialTimeLeft","ee","getTrialEndDate","getGuidedTourMeta","isFirstSuperAdminUser","state","user","id","schemas"],"mappings":"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"}
1
+ {"version":3,"file":"admin.mjs","sources":["../../../../../server/src/controllers/admin.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport path from 'path';\n\nimport { map, values, sumBy, pipe, flatMap, propEq } from 'lodash/fp';\nimport _ from 'lodash';\nimport { exists } from 'fs-extra';\nimport { env } from '@strapi/utils';\nimport {\n validateUpdateProjectSettings,\n validateUpdateProjectSettingsFiles,\n validateUpdateProjectSettingsImagesDimensions,\n} from '../validation/project-settings';\nimport { getService } from '../utils';\n\nimport type {\n Init,\n GetProjectSettings,\n Information,\n Plugins,\n TelemetryProperties,\n UpdateProjectSettings,\n GetGuidedTourMeta,\n} from '../../../shared/contracts/admin';\n\n// Lazy: only resolved on first GET /admin/project-type request\ntype TsUtilsModule = typeof import('@strapi/typescript-utils');\nlet lazyTsUtils: TsUtilsModule | undefined;\nconst isUsingTypeScript: TsUtilsModule['isUsingTypeScript'] = (\n ...args: Parameters<TsUtilsModule['isUsingTypeScript']>\n) => {\n if (!lazyTsUtils) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n lazyTsUtils = require('@strapi/typescript-utils');\n }\n return (lazyTsUtils as TsUtilsModule).isUsingTypeScript(...args);\n};\n\n/**\n * A set of functions called \"actions\" for `Admin`\n */\nexport default {\n // TODO very temporary to check the switch ee/ce\n // When removing this we need to update the /admin/src/index.js file\n // whe,re we set the strapi.window.isEE value\n\n // NOTE: admin/ee/server overrides this controller, and adds the EE features\n // This returns an empty feature list for CE\n async getProjectType() {\n const flags = strapi.config.get('admin.flags', {});\n return { data: { isEE: false, features: [], flags, ai: { enabled: false } } };\n },\n\n async init() {\n let uuid = strapi.config.get('uuid', false);\n const hasAdmin = await getService('user').exists();\n const { menuLogo, authLogo } = await getService('project-settings').getProjectSettings();\n // set to null if telemetryDisabled flag not avaialble in package.json\n const telemetryDisabled: boolean | null = strapi.config.get(\n 'packageJsonStrapi.telemetryDisabled',\n null\n );\n\n if (telemetryDisabled !== null && telemetryDisabled === true) {\n uuid = false;\n }\n\n return {\n data: {\n uuid,\n hasAdmin,\n menuLogo: menuLogo ? menuLogo.url : null,\n authLogo: authLogo ? authLogo.url : null,\n },\n } satisfies Init.Response;\n },\n\n async getProjectSettings() {\n return getService(\n 'project-settings'\n ).getProjectSettings() satisfies Promise<GetProjectSettings.Response>;\n },\n\n async updateProjectSettings(ctx: Context) {\n const {\n request: { files, body },\n } = ctx as { request: UpdateProjectSettings.Request };\n\n const projectSettingsService = getService('project-settings');\n\n await validateUpdateProjectSettings(body);\n await validateUpdateProjectSettingsFiles(files);\n\n const formatedFiles = await projectSettingsService.parseFilesData(files);\n await validateUpdateProjectSettingsImagesDimensions(formatedFiles);\n\n return projectSettingsService.updateProjectSettings({\n ...body,\n ...formatedFiles,\n }) satisfies Promise<UpdateProjectSettings.Response>;\n },\n\n async telemetryProperties(ctx: Context) {\n // If the telemetry is disabled, ignore the request and return early\n if (strapi.telemetry.isDisabled) {\n ctx.status = 204;\n return;\n }\n\n const useTypescriptOnServer = await isUsingTypeScript(strapi.dirs.app.root);\n const useTypescriptOnAdmin = await isUsingTypeScript(\n path.join(strapi.dirs.app.root, 'src', 'admin')\n );\n const isHostedOnStrapiCloud = env('STRAPI_HOSTING', null) === 'strapi.cloud';\n\n const numberOfAllContentTypes = _.size(strapi.contentTypes);\n const numberOfComponents = _.size(strapi.components);\n\n const getNumberOfDynamicZones = () => {\n return pipe(\n map('attributes'),\n flatMap(values),\n // @ts-expect-error lodash types\n sumBy(propEq('type', 'dynamiczone'))\n )(strapi.contentTypes as any);\n };\n\n const getNumberOfFolders = async (): Promise<number> => {\n try {\n const contentStructure = strapi.get('content-structure') as\n | { countGroups?: () => Promise<number> }\n | undefined;\n\n return (await contentStructure?.countGroups?.()) ?? 0;\n } catch {\n return 0;\n }\n };\n\n return {\n data: {\n useTypescriptOnServer,\n useTypescriptOnAdmin,\n isHostedOnStrapiCloud,\n numberOfAllContentTypes, // TODO: V5: This event should be renamed numberOfContentTypes in V5 as the name is already taken to describe the number of content types using i18n.\n numberOfComponents,\n numberOfDynamicZones: getNumberOfDynamicZones(),\n numberOfContentTypeFolders: await getNumberOfFolders(),\n },\n } satisfies TelemetryProperties.Response;\n },\n\n async information() {\n const currentEnvironment: string = strapi.config.get('environment');\n const autoReload = strapi.config.get('autoReload', false);\n const strapiVersion = strapi.config.get('info.strapi', null);\n const dependencies = strapi.config.get('info.dependencies', {});\n const projectId = strapi.config.get('uuid', null);\n const nodeVersion = process.version;\n const communityEdition = !strapi.EE;\n const useYarn: boolean = await exists(path.join(process.cwd(), 'yarn.lock'));\n\n return {\n data: {\n currentEnvironment,\n autoReload,\n strapiVersion,\n dependencies,\n projectId,\n nodeVersion,\n communityEdition,\n useYarn,\n },\n } satisfies Information.Response;\n },\n\n async plugins(ctx: Context) {\n const enabledPlugins = strapi.config.get('enabledPlugins') as any;\n\n // List of core plugins that are always enabled,\n // and so it's not necessary to display them in the plugins list\n const CORE_PLUGINS = [\n 'content-manager',\n 'content-type-builder',\n 'email',\n 'upload',\n 'i18n',\n 'content-releases',\n 'review-workflows',\n ];\n\n const plugins = Object.entries(enabledPlugins)\n .filter(([key]: any) => !CORE_PLUGINS.includes(key))\n .map(([key, plugin]: any) => ({\n name: plugin.info.name || key,\n displayName: plugin.info.displayName || plugin.info.name || key,\n description: plugin.info.description || '',\n packageName: plugin.info.packageName,\n }));\n\n ctx.send({ plugins } satisfies Plugins.Response);\n },\n\n async licenseTrialTimeLeft() {\n const data = await strapi.ee.getTrialEndDate({\n strapi,\n });\n\n return data;\n },\n\n async getGuidedTourMeta(ctx: Context) {\n const isFirstSuperAdminUser = await getService('user').isFirstSuperAdminUser(ctx.state.user.id);\n\n return {\n data: {\n isFirstSuperAdminUser,\n schemas: strapi.contentTypes,\n },\n } satisfies GetGuidedTourMeta.Response;\n },\n};\n"],"names":["lazyTsUtils","isUsingTypeScript","args","require","getProjectType","flags","strapi","config","get","data","isEE","features","ai","enabled","init","uuid","hasAdmin","getService","exists","menuLogo","authLogo","getProjectSettings","telemetryDisabled","url","updateProjectSettings","ctx","request","files","body","projectSettingsService","validateUpdateProjectSettings","validateUpdateProjectSettingsFiles","formatedFiles","parseFilesData","validateUpdateProjectSettingsImagesDimensions","telemetryProperties","telemetry","isDisabled","status","useTypescriptOnServer","dirs","app","root","useTypescriptOnAdmin","path","join","isHostedOnStrapiCloud","env","numberOfAllContentTypes","_","size","contentTypes","numberOfComponents","components","getNumberOfDynamicZones","pipe","map","flatMap","values","sumBy","propEq","getNumberOfFolders","contentStructure","countGroups","numberOfDynamicZones","numberOfContentTypeFolders","information","currentEnvironment","autoReload","strapiVersion","dependencies","projectId","nodeVersion","process","version","communityEdition","EE","useYarn","cwd","plugins","enabledPlugins","CORE_PLUGINS","Object","entries","filter","key","includes","plugin","name","info","displayName","description","packageName","send","licenseTrialTimeLeft","ee","getTrialEndDate","getGuidedTourMeta","isFirstSuperAdminUser","state","user","id","schemas"],"mappings":"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"}
@@ -8,6 +8,7 @@ var index = require('../utils/index.js');
8
8
  var index$1 = require('../domain/permission/index.js');
9
9
  var permission = require('../validation/permission.js');
10
10
  var apiTokenUtils = require('../strategies/api-token-utils.js');
11
+ var tokens = require('../audit-logs/tokens.js');
11
12
 
12
13
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
14
 
@@ -634,6 +635,20 @@ const getExpirationFields = (lifespan)=>{
634
635
  });
635
636
  }
636
637
  }
638
+ await utils.emitAudit({
639
+ strapi
640
+ }, tokens.AUDITED_EVENTS.TOKEN_CREATE, {
641
+ tokenId: apiToken.id,
642
+ name: apiToken.name,
643
+ kind: 'content-api',
644
+ description: apiToken.description ?? null,
645
+ lifespan: apiToken.lifespan,
646
+ expiresAt: apiToken.expiresAt,
647
+ type: apiToken.type,
648
+ ...apiToken.type === constants.API_TOKEN_TYPE.CUSTOM && {
649
+ permissions: result.permissions ?? []
650
+ }
651
+ });
637
652
  // Casted to any to avoid complex type duplication
638
653
  return fp.omit([
639
654
  'adminPermissions',
@@ -686,6 +701,18 @@ const getExpirationFields = (lifespan)=>{
686
701
  });
687
702
  }
688
703
  }
704
+ await utils.emitAudit({
705
+ strapi
706
+ }, tokens.AUDITED_EVENTS.TOKEN_CREATE, {
707
+ tokenId: apiToken.id,
708
+ name: apiToken.name,
709
+ kind: 'admin',
710
+ adminUserOwner: ownerId,
711
+ description: apiToken.description ?? null,
712
+ lifespan: apiToken.lifespan,
713
+ expiresAt: apiToken.expiresAt,
714
+ permissions: tokens.toAdminPermissionRefs(result.adminPermissions)
715
+ });
689
716
  // Casted to any to avoid complex type duplication
690
717
  return {
691
718
  ...fp.omit([
@@ -701,9 +728,18 @@ const regenerate = async (id)=>{
701
728
  const apiToken = await strapi.db.query('admin::api-token').update({
702
729
  select: [
703
730
  'id',
731
+ 'name',
704
732
  'accessKey',
705
733
  'kind'
706
734
  ],
735
+ // The owner id only, for the audit row; it is stripped from the response below
736
+ populate: {
737
+ adminUserOwner: {
738
+ select: [
739
+ 'id'
740
+ ]
741
+ }
742
+ },
707
743
  where: {
708
744
  id
709
745
  },
@@ -715,8 +751,21 @@ const regenerate = async (id)=>{
715
751
  if (!apiToken) {
716
752
  throw new NotFoundError('The provided token id does not exist');
717
753
  }
754
+ const ownerId = apiToken.kind === 'admin' ? resolveAdminTokenOwnerId(apiToken) : null;
755
+ await utils.emitAudit({
756
+ strapi
757
+ }, tokens.AUDITED_EVENTS.TOKEN_REGENERATE, {
758
+ tokenId: apiToken.id,
759
+ name: apiToken.name,
760
+ kind: apiToken.kind ?? 'content-api',
761
+ ...ownerId != null && {
762
+ adminUserOwner: ownerId
763
+ }
764
+ });
718
765
  return {
719
- ...apiToken,
766
+ ...fp.omit([
767
+ 'adminUserOwner'
768
+ ], apiToken),
720
769
  kind: apiToken.kind ?? 'content-api',
721
770
  accessKey
722
771
  };
@@ -831,6 +880,17 @@ For security reasons, prefer storing the secret in an environment variable and r
831
880
  if (deletedToken === null || deletedToken === undefined) {
832
881
  return deletedToken;
833
882
  }
883
+ const ownerId = deletedToken.kind === 'admin' ? resolveAdminTokenOwnerId(deletedToken) : null;
884
+ await utils.emitAudit({
885
+ strapi
886
+ }, tokens.AUDITED_EVENTS.TOKEN_DELETE, {
887
+ tokenId: deletedToken.id,
888
+ name: deletedToken.name,
889
+ kind: deletedToken.kind ?? 'content-api',
890
+ ...ownerId != null && {
891
+ adminUserOwner: ownerId
892
+ }
893
+ });
834
894
  if (deletedToken.kind === 'admin') {
835
895
  return {
836
896
  ...deletedToken,
@@ -853,7 +913,9 @@ For security reasons, prefer storing the secret in an environment variable and r
853
913
  const originalToken = await strapi.db.query('admin::api-token').findOne({
854
914
  select: SELECT_FIELDS,
855
915
  populate: [
856
- 'adminUserOwner'
916
+ 'adminUserOwner',
917
+ 'permissions',
918
+ 'adminPermissions'
857
919
  ],
858
920
  where: {
859
921
  id
@@ -862,6 +924,34 @@ For security reasons, prefer storing the secret in an environment variable and r
862
924
  if (!originalToken) {
863
925
  throw new NotFoundError('Token not found');
864
926
  }
927
+ // Populated with its permissions: the audit row for this update lists what changed,
928
+ // so the state before the write is needed. `type` is a content-api concept: admin
929
+ // tokens only carry the column default.
930
+ const previousSnapshot = {
931
+ name: originalToken.name,
932
+ description: originalToken.description,
933
+ ...originalToken.kind !== 'admin' && {
934
+ type: originalToken.type
935
+ },
936
+ permissions: originalToken.kind === 'admin' ? tokens.toAdminPermissionRefs(originalToken.adminPermissions) : tokens.toActionRefs(originalToken.permissions)
937
+ };
938
+ const emitUpdate = async (kind, next, adminUserOwner)=>{
939
+ const changes = tokens.getTokenChanges(previousSnapshot, next);
940
+ if (Object.keys(changes).length === 0) {
941
+ return;
942
+ }
943
+ await utils.emitAudit({
944
+ strapi
945
+ }, tokens.AUDITED_EVENTS.TOKEN_UPDATE, {
946
+ tokenId: originalToken.id,
947
+ name: next.name,
948
+ kind,
949
+ changes,
950
+ ...adminUserOwner != null && {
951
+ adminUserOwner
952
+ }
953
+ });
954
+ };
865
955
  const raw = attributes;
866
956
  // kind is immutable after creation.
867
957
  // Null-kind rows are legacy content-api tokens — treat null and 'content-api' as the same
@@ -880,7 +970,7 @@ For security reasons, prefer storing the secret in an environment variable and r
880
970
  const changingTypeToCustom = incomingType === constants.API_TOKEN_TYPE.CUSTOM && originalToken.type !== constants.API_TOKEN_TYPE.CUSTOM;
881
971
  // Only re-validate if permissions or type are being changed
882
972
  if (incomingPermissions !== undefined || changingTypeToCustom) {
883
- assertCustomTokenPermissionsValidity(resolvedType, incomingPermissions ?? originalToken.permissions);
973
+ assertCustomTokenPermissionsValidity(resolvedType, incomingPermissions);
884
974
  }
885
975
  } else if (originalToken.kind === 'admin') {
886
976
  assertAdminKindFields(attributes);
@@ -951,9 +1041,16 @@ For security reasons, prefer storing the secret in an environment variable and r
951
1041
  });
952
1042
  }
953
1043
  const permissionsFromDb = await strapi.db.query('admin::api-token').load(updatedToken, 'permissions');
1044
+ const permissions = permissionsFromDb ? tokens.toActionRefs(permissionsFromDb) : undefined;
1045
+ await emitUpdate('content-api', {
1046
+ name: updatedToken.name,
1047
+ description: updatedToken.description ?? null,
1048
+ type: updatedToken.type,
1049
+ permissions: permissions ?? []
1050
+ });
954
1051
  return {
955
1052
  ...updatedToken,
956
- permissions: permissionsFromDb ? permissionsFromDb.map((p)=>p.action) : undefined
1053
+ permissions
957
1054
  };
958
1055
  }
959
1056
  // kind === 'admin'
@@ -965,6 +1062,11 @@ For security reasons, prefer storing the secret in an environment variable and r
965
1062
  }
966
1063
  const adminPermissionsFromDb = await strapi.db.query('admin::api-token').load(updatedToken, 'adminPermissions');
967
1064
  const adminUserOwnerFromDb = await strapi.db.query('admin::api-token').load(updatedToken, 'adminUserOwner');
1065
+ await emitUpdate('admin', {
1066
+ name: updatedToken.name,
1067
+ description: updatedToken.description ?? null,
1068
+ permissions: tokens.toAdminPermissionRefs(adminPermissionsFromDb || [])
1069
+ }, resolveAdminTokenOwnerId(originalToken));
968
1070
  return {
969
1071
  ...updatedToken,
970
1072
  adminPermissions: adminPermissionsFromDb || [],