@strapi/admin 5.44.0 → 5.45.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.
- package/dist/admin/admin/src/components/Table.js.map +1 -1
- package/dist/admin/admin/src/components/Table.mjs.map +1 -1
- package/dist/admin/admin/src/constants.js +49 -0
- package/dist/admin/admin/src/constants.js.map +1 -1
- package/dist/admin/admin/src/constants.mjs +49 -0
- package/dist/admin/admin/src/constants.mjs.map +1 -1
- package/dist/admin/admin/src/core/apis/router.js +4 -4
- package/dist/admin/admin/src/core/apis/router.js.map +1 -1
- package/dist/admin/admin/src/core/apis/router.mjs +4 -4
- package/dist/admin/admin/src/core/apis/router.mjs.map +1 -1
- package/dist/admin/admin/src/features/Tracking.js.map +1 -1
- package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/{pages/ApiTokens/EditView/components → components/Tokens}/FormApiTokenContainer.js +48 -11
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/{pages/ApiTokens/EditView/components → components/Tokens}/FormApiTokenContainer.mjs +49 -12
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/LifeSpanInput.js +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/LifeSpanInput.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/LifeSpanInput.mjs +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/LifeSpanInput.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js +21 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.mjs +21 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.js +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.mjs +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/constants.js +33 -0
- package/dist/admin/admin/src/pages/Settings/components/Tokens/constants.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/constants.mjs +14 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/constants.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/{pages/ApiTokens/EditView → components/Tokens}/utils/getDateOfExpiration.js +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/utils/getDateOfExpiration.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/{pages/ApiTokens/EditView → components/Tokens}/utils/getDateOfExpiration.mjs +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/utils/getDateOfExpiration.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/constants.js +182 -151
- package/dist/admin/admin/src/pages/Settings/constants.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/constants.mjs +182 -151
- package/dist/admin/admin/src/pages/Settings/constants.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/CreateView.js +17 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/CreateView.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/CreateView.mjs +15 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/CreateView.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/EditView/EditViewPage.js +314 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/EditView/EditViewPage.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/EditView/EditViewPage.mjs +292 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/EditView/EditViewPage.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/EditView/components/AdminPermissions.js +70 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/EditView/components/AdminPermissions.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/EditView/components/AdminPermissions.mjs +49 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/EditView/components/AdminPermissions.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/ListView.js +254 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/ListView.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/ListView.mjs +231 -0
- package/dist/admin/admin/src/pages/Settings/pages/AdminTokens/ListView.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.js +42 -33
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.mjs +43 -34
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js +3 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs +3 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js +23 -12
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs +23 -12
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.js +124 -35
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.mjs +126 -37
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js +24 -9
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.mjs +24 -9
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.js +5 -3
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.mjs +5 -3
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js +171 -36
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs +172 -37
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js +5 -3
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs +5 -3
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/hooks/usePermissionsDataManager.js +59 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/hooks/usePermissionsDataManager.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/hooks/usePermissionsDataManager.mjs +40 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/hooks/usePermissionsDataManager.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/createPermissionChecker.js +89 -0
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/createPermissionChecker.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/createPermissionChecker.mjs +86 -0
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/createPermissionChecker.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/updateValues.js +35 -9
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/updateValues.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/updateValues.mjs +35 -10
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/updateValues.mjs.map +1 -1
- package/dist/admin/admin/src/render.js +6 -3
- package/dist/admin/admin/src/render.js.map +1 -1
- package/dist/admin/admin/src/render.mjs +6 -3
- package/dist/admin/admin/src/render.mjs.map +1 -1
- package/dist/admin/admin/src/router.js +4 -4
- package/dist/admin/admin/src/router.js.map +1 -1
- package/dist/admin/admin/src/router.mjs +1 -1
- package/dist/admin/admin/src/router.mjs.map +1 -1
- package/dist/admin/admin/src/services/apiTokens.js +85 -2
- package/dist/admin/admin/src/services/apiTokens.js.map +1 -1
- package/dist/admin/admin/src/services/apiTokens.mjs +80 -3
- package/dist/admin/admin/src/services/apiTokens.mjs.map +1 -1
- package/dist/admin/admin/src/translations/en.json.js +16 -1
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +16 -1
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js +4 -1
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs +4 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
- package/dist/admin/admin/tests/server.js +99 -21
- package/dist/admin/admin/tests/server.js.map +1 -1
- package/dist/admin/admin/tests/server.mjs +99 -21
- package/dist/admin/admin/tests/server.mjs.map +1 -1
- package/dist/admin/src/constants.d.ts +26 -0
- package/dist/admin/src/core/apis/router.d.ts +1 -1
- package/dist/admin/src/features/Tracking.d.ts +2 -1
- package/dist/admin/src/pages/Settings/components/Tokens/FormApiTokenContainer.d.ts +24 -0
- package/dist/admin/src/pages/Settings/components/Tokens/Table.d.ts +2 -1
- package/dist/admin/src/pages/Settings/components/Tokens/constants.d.ts +17 -0
- package/dist/admin/src/pages/Settings/constants.d.ts +1 -1
- package/dist/admin/src/pages/Settings/pages/AdminTokens/CreateView.d.ts +1 -0
- package/dist/admin/src/pages/Settings/pages/AdminTokens/EditView/EditViewPage.d.ts +2 -0
- package/dist/admin/src/pages/Settings/pages/AdminTokens/EditView/components/AdminPermissions.d.ts +13 -0
- package/dist/admin/src/pages/Settings/pages/AdminTokens/ListView.d.ts +2 -0
- package/dist/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.d.ts +4 -3
- package/dist/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.d.ts +3 -1
- package/dist/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.d.ts +1 -0
- package/dist/admin/src/pages/Settings/pages/Roles/components/Permissions.d.ts +5 -0
- package/dist/admin/src/pages/Settings/pages/Roles/hooks/usePermissionsDataManager.d.ts +8 -7
- package/dist/admin/src/pages/Settings/pages/Roles/utils/createPermissionChecker.d.ts +27 -0
- package/dist/admin/src/pages/Settings/pages/Roles/utils/updateValues.d.ts +8 -2
- package/dist/admin/src/services/apiTokens.d.ts +5 -2
- package/dist/admin/src/types/permissions.d.ts +1 -1
- package/dist/server/server/src/bootstrap.js +37 -5
- package/dist/server/server/src/bootstrap.js.map +1 -1
- package/dist/server/server/src/bootstrap.mjs +37 -5
- package/dist/server/server/src/bootstrap.mjs.map +1 -1
- package/dist/server/server/src/config/admin-actions.js +48 -0
- package/dist/server/server/src/config/admin-actions.js.map +1 -1
- package/dist/server/server/src/config/admin-actions.mjs +48 -0
- package/dist/server/server/src/config/admin-actions.mjs.map +1 -1
- package/dist/server/server/src/content-types/Permission.js +10 -1
- package/dist/server/server/src/content-types/Permission.js.map +1 -1
- package/dist/server/server/src/content-types/Permission.mjs +10 -1
- package/dist/server/server/src/content-types/Permission.mjs.map +1 -1
- package/dist/server/server/src/content-types/User.js +8 -0
- package/dist/server/server/src/content-types/User.js.map +1 -1
- package/dist/server/server/src/content-types/User.mjs +8 -0
- package/dist/server/server/src/content-types/User.mjs.map +1 -1
- package/dist/server/server/src/content-types/api-token.js +27 -1
- package/dist/server/server/src/content-types/api-token.js.map +1 -1
- package/dist/server/server/src/content-types/api-token.mjs +27 -1
- package/dist/server/server/src/content-types/api-token.mjs.map +1 -1
- package/dist/server/server/src/controllers/admin-token.js +194 -0
- package/dist/server/server/src/controllers/admin-token.js.map +1 -0
- package/dist/server/server/src/controllers/admin-token.mjs +192 -0
- package/dist/server/server/src/controllers/admin-token.mjs.map +1 -0
- package/dist/server/server/src/controllers/api-token.js +48 -47
- package/dist/server/server/src/controllers/api-token.js.map +1 -1
- package/dist/server/server/src/controllers/api-token.mjs +48 -47
- package/dist/server/server/src/controllers/api-token.mjs.map +1 -1
- package/dist/server/server/src/controllers/index.js +2 -0
- package/dist/server/server/src/controllers/index.js.map +1 -1
- package/dist/server/server/src/controllers/index.mjs +2 -0
- package/dist/server/server/src/controllers/index.mjs.map +1 -1
- package/dist/server/server/src/domain/permission/index.js +2 -1
- package/dist/server/server/src/domain/permission/index.js.map +1 -1
- package/dist/server/server/src/domain/permission/index.mjs +2 -1
- package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
- package/dist/server/server/src/policies/index.js +2 -0
- package/dist/server/server/src/policies/index.js.map +1 -1
- package/dist/server/server/src/policies/index.mjs +2 -0
- package/dist/server/server/src/policies/index.mjs.map +1 -1
- package/dist/server/server/src/policies/isAdminTokensEnabled.js +16 -0
- package/dist/server/server/src/policies/isAdminTokensEnabled.js.map +1 -0
- package/dist/server/server/src/policies/isAdminTokensEnabled.mjs +14 -0
- package/dist/server/server/src/policies/isAdminTokensEnabled.mjs.map +1 -0
- package/dist/server/server/src/register.js +4 -2
- package/dist/server/server/src/register.js.map +1 -1
- package/dist/server/server/src/register.mjs +4 -2
- package/dist/server/server/src/register.mjs.map +1 -1
- package/dist/server/server/src/routes/admin-tokens.js +140 -0
- package/dist/server/server/src/routes/admin-tokens.js.map +1 -0
- package/dist/server/server/src/routes/admin-tokens.mjs +138 -0
- package/dist/server/server/src/routes/admin-tokens.mjs.map +1 -0
- package/dist/server/server/src/routes/index.js +2 -0
- package/dist/server/server/src/routes/index.js.map +1 -1
- package/dist/server/server/src/routes/index.mjs +2 -0
- package/dist/server/server/src/routes/index.mjs.map +1 -1
- package/dist/server/server/src/services/api-token.js +805 -101
- package/dist/server/server/src/services/api-token.js.map +1 -1
- package/dist/server/server/src/services/api-token.mjs +800 -101
- package/dist/server/server/src/services/api-token.mjs.map +1 -1
- package/dist/server/server/src/services/constants.js +2 -0
- package/dist/server/server/src/services/constants.js.map +1 -1
- package/dist/server/server/src/services/constants.mjs +2 -0
- package/dist/server/server/src/services/constants.mjs.map +1 -1
- package/dist/server/server/src/services/homepage.js +1 -1
- package/dist/server/server/src/services/homepage.js.map +1 -1
- package/dist/server/server/src/services/homepage.mjs +1 -1
- package/dist/server/server/src/services/homepage.mjs.map +1 -1
- package/dist/server/server/src/services/index.js +2 -1
- package/dist/server/server/src/services/index.js.map +1 -1
- package/dist/server/server/src/services/index.mjs +3 -2
- package/dist/server/server/src/services/index.mjs.map +1 -1
- package/dist/server/server/src/services/permission/engine.js +6 -0
- package/dist/server/server/src/services/permission/engine.js.map +1 -1
- package/dist/server/server/src/services/permission/engine.mjs +6 -0
- package/dist/server/server/src/services/permission/engine.mjs.map +1 -1
- package/dist/server/server/src/services/permission/queries.js +11 -2
- package/dist/server/server/src/services/permission/queries.js.map +1 -1
- package/dist/server/server/src/services/permission/queries.mjs +12 -3
- package/dist/server/server/src/services/permission/queries.mjs.map +1 -1
- package/dist/server/server/src/services/role.js +3 -0
- package/dist/server/server/src/services/role.js.map +1 -1
- package/dist/server/server/src/services/role.mjs +3 -0
- package/dist/server/server/src/services/role.mjs.map +1 -1
- package/dist/server/server/src/strategies/admin-token.js +110 -0
- package/dist/server/server/src/strategies/admin-token.js.map +1 -0
- package/dist/server/server/src/strategies/admin-token.mjs +104 -0
- package/dist/server/server/src/strategies/admin-token.mjs.map +1 -0
- package/dist/server/server/src/strategies/api-token-utils.js +56 -0
- package/dist/server/server/src/strategies/api-token-utils.js.map +1 -0
- package/dist/server/server/src/strategies/api-token-utils.mjs +52 -0
- package/dist/server/server/src/strategies/api-token-utils.mjs.map +1 -0
- package/dist/server/server/src/strategies/content-api-token.js +104 -0
- package/dist/server/server/src/strategies/content-api-token.js.map +1 -0
- package/dist/server/server/src/strategies/content-api-token.mjs +98 -0
- package/dist/server/server/src/strategies/content-api-token.mjs.map +1 -0
- package/dist/server/server/src/validation/admin-tokens.js +28 -0
- package/dist/server/server/src/validation/admin-tokens.js.map +1 -0
- package/dist/server/server/src/validation/admin-tokens.mjs +25 -0
- package/dist/server/server/src/validation/admin-tokens.mjs.map +1 -0
- package/dist/server/server/src/validation/api-tokens.js +5 -2
- package/dist/server/server/src/validation/api-tokens.js.map +1 -1
- package/dist/server/server/src/validation/api-tokens.mjs +5 -2
- package/dist/server/server/src/validation/api-tokens.mjs.map +1 -1
- package/dist/server/server/src/validation/project-settings.js +15 -16
- package/dist/server/server/src/validation/project-settings.js.map +1 -1
- package/dist/server/server/src/validation/project-settings.mjs +4 -5
- package/dist/server/server/src/validation/project-settings.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/config/admin-actions.d.ts.map +1 -1
- package/dist/server/src/content-types/Permission.d.ts +9 -0
- package/dist/server/src/content-types/Permission.d.ts.map +1 -1
- package/dist/server/src/content-types/User.d.ts +8 -0
- package/dist/server/src/content-types/User.d.ts.map +1 -1
- package/dist/server/src/content-types/api-token.d.ts +23 -0
- package/dist/server/src/content-types/api-token.d.ts.map +1 -1
- package/dist/server/src/content-types/index.d.ts +40 -0
- package/dist/server/src/content-types/index.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-token.d.ts +12 -0
- package/dist/server/src/controllers/admin-token.d.ts.map +1 -0
- package/dist/server/src/controllers/api-token.d.ts +0 -1
- package/dist/server/src/controllers/api-token.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +9 -1
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/domain/permission/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +56 -2
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/policies/index.d.ts +5 -0
- package/dist/server/src/policies/index.d.ts.map +1 -1
- package/dist/server/src/policies/isAdminTokensEnabled.d.ts +7 -0
- package/dist/server/src/policies/isAdminTokensEnabled.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/admin-tokens.d.ts +15 -0
- package/dist/server/src/routes/admin-tokens.d.ts.map +1 -0
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/services/api-token.d.ts +136 -12
- package/dist/server/src/services/api-token.d.ts.map +1 -1
- package/dist/server/src/services/constants.d.ts +13 -11
- package/dist/server/src/services/constants.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +2 -2
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/permission/engine.d.ts +5 -0
- package/dist/server/src/services/permission/engine.d.ts.map +1 -1
- package/dist/server/src/services/permission/queries.d.ts.map +1 -1
- package/dist/server/src/services/permission.d.ts +1 -0
- package/dist/server/src/services/permission.d.ts.map +1 -1
- package/dist/server/src/services/role.d.ts.map +1 -1
- package/dist/server/src/strategies/admin-token.d.ts +51 -0
- package/dist/server/src/strategies/admin-token.d.ts.map +1 -0
- package/dist/server/src/strategies/api-token-utils.d.ts +13 -0
- package/dist/server/src/strategies/api-token-utils.d.ts.map +1 -0
- package/dist/server/src/strategies/{api-token.d.ts → content-api-token.d.ts} +10 -11
- package/dist/server/src/strategies/content-api-token.d.ts.map +1 -0
- package/dist/server/src/strategies/index.d.ts +2 -1
- package/dist/server/src/strategies/index.d.ts.map +1 -1
- package/dist/server/src/validation/admin-tokens.d.ts +75 -0
- package/dist/server/src/validation/admin-tokens.d.ts.map +1 -0
- package/dist/server/src/validation/api-tokens.d.ts +4 -2
- package/dist/server/src/validation/api-tokens.d.ts.map +1 -1
- package/dist/server/src/validation/project-settings.d.ts +10 -10
- package/dist/server/src/validation/project-settings.d.ts.map +1 -1
- package/dist/shared/contracts/admin-token.d.ts +122 -0
- package/dist/shared/contracts/admin-token.d.ts.map +1 -0
- package/dist/shared/contracts/api-token.d.ts +6 -95
- package/dist/shared/contracts/api-token.d.ts.map +1 -1
- package/dist/shared/contracts/content-api-token.d.ts +97 -0
- package/dist/shared/contracts/content-api-token.d.ts.map +1 -0
- package/dist/shared/contracts/shared.d.ts +1 -0
- package/dist/shared/contracts/shared.d.ts.map +1 -1
- package/package.json +7 -7
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/FormApiTokenContainer.js.map +0 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/FormApiTokenContainer.mjs.map +0 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/constants.js +0 -37
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/constants.js.map +0 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/constants.mjs +0 -16
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/constants.mjs.map +0 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/getDateOfExpiration.js.map +0 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/getDateOfExpiration.mjs.map +0 -1
- package/dist/admin/src/pages/Settings/pages/ApiTokens/EditView/components/FormApiTokenContainer.d.ts +0 -20
- package/dist/admin/src/pages/Settings/pages/ApiTokens/EditView/constants.d.ts +0 -17
- package/dist/server/server/src/strategies/api-token.js +0 -144
- package/dist/server/server/src/strategies/api-token.js.map +0 -1
- package/dist/server/server/src/strategies/api-token.mjs +0 -138
- package/dist/server/server/src/strategies/api-token.mjs.map +0 -1
- package/dist/server/src/strategies/api-token.d.ts.map +0 -1
- /package/dist/admin/src/pages/Settings/{pages/ApiTokens/EditView → components/Tokens}/utils/getDateOfExpiration.d.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-token.js","sources":["../../../../../server/src/services/api-token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { omit, difference, isNil, isEmpty, map, isArray, uniq, isNumber } from 'lodash/fp';\nimport type { Core } from '@strapi/types';\nimport { errors } from '@strapi/utils';\nimport type { Update, ApiToken, ApiTokenBody } from '../../../shared/contracts/api-token';\nimport constants from './constants';\nimport { getService } from '../utils';\n\nconst { ValidationError, NotFoundError } = errors;\n\ntype ApiTokenPermission = {\n id: number | `${number}`;\n action: string;\n token: DBApiToken | number;\n};\n\ntype DBApiToken = ApiToken & {\n permissions: (number | ApiTokenPermission)[];\n};\n\nconst SELECT_FIELDS = [\n 'id',\n 'name',\n 'description',\n 'lastUsedAt',\n 'type',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n];\n\nconst POPULATE_FIELDS = ['permissions'];\n\n// TODO: we need to ensure the permissions are actually valid registered permissions!\n\n/**\n * Assert that a token's permissions attribute is valid for its type\n */\nconst assertCustomTokenPermissionsValidity = (\n type: ApiTokenBody['type'],\n permissions: ApiTokenBody['permissions']\n) => {\n // Ensure non-custom tokens doesn't have permissions\n if (type !== constants.API_TOKEN_TYPE.CUSTOM && !isEmpty(permissions)) {\n throw new ValidationError('Non-custom tokens should not reference permissions');\n }\n\n // Custom type tokens should always have permissions attached to them\n if (type === constants.API_TOKEN_TYPE.CUSTOM && !isArray(permissions)) {\n throw new ValidationError('Missing permissions attribute for custom token');\n }\n\n // Permissions provided for a custom type token should be valid/registered permissions UID\n if (type === constants.API_TOKEN_TYPE.CUSTOM) {\n const validPermissions = strapi.contentAPI.permissions.providers.action.keys();\n const invalidPermissions = difference(permissions, validPermissions) as string[];\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (!isNumber(lifespan) || !Object.values(constants.API_TOKEN_LIFESPANS).includes(lifespan)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.API_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (token: DBApiToken): ApiToken => {\n if (!token) {\n return token;\n }\n\n return {\n ...token,\n permissions: isArray(token.permissions) ? map('action', token.permissions) : token.permissions,\n };\n};\n\ntype WhereParams = {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n};\n\n/**\n * Get a token\n */\nconst getBy = async (whereParams: WhereParams = {}): Promise<ApiToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const token = await strapi.db.query('admin::api-token').findOne({\n select: [...SELECT_FIELDS, 'encryptedKey'],\n populate: POPULATE_FIELDS,\n where: whereParams,\n });\n\n if (!token) {\n return token;\n }\n\n const { encryptedKey, ...rest } = token;\n\n if (!encryptedKey) {\n return flattenTokenPermissions(rest);\n }\n\n const accessKey = getService('encryption').decrypt(encryptedKey);\n\n return flattenTokenPermissions({\n ...rest,\n accessKey,\n });\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (whereParams: WhereParams = {}): Promise<boolean> => {\n const apiToken = await getBy(whereParams);\n\n return !!apiToken;\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string) => {\n const apiTokenCfg = strapi.config.get<Core.Config.Admin['apiToken']>('admin.apiToken');\n const salt = apiTokenCfg.salt;\n\n return crypto.createHmac('sha512', salt).update(accessKey).digest('hex');\n};\n\nconst getExpirationFields = (lifespan: ApiTokenBody['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan || null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async (attributes: ApiTokenBody): Promise<ApiToken> => {\n const encryptionService = getService('encryption');\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n assertCustomTokenPermissionsValidity(attributes.type, attributes.permissions);\n assertValidLifespan(attributes.lifespan);\n\n // Create the token\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...omit('permissions', attributes),\n accessKey: hash(accessKey),\n encryptedKey,\n ...getExpirationFields(attributes.lifespan),\n },\n });\n\n const result: ApiToken = { ...apiToken, accessKey };\n\n // If this is a custom type token, create and the related permissions\n if (attributes.type === constants.API_TOKEN_TYPE.CUSTOM) {\n // TODO: createMany doesn't seem to create relation properly, implement a better way rather than a ton of queries\n // const permissionsCount = await strapi.db.query('admin::api-token-permission').createMany({\n // populate: POPULATE_FIELDS,\n // data: attributes.permissions.map(action => ({ action, token: apiToken })),\n // });\n await Promise.all(\n uniq(attributes.permissions).map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: apiToken },\n })\n )\n );\n\n const currentPermissions = await strapi.db\n .query('admin::api-token')\n .load(apiToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(result, { permissions: map('action', currentPermissions) });\n }\n }\n\n return result;\n};\n\nconst regenerate = async (id: string | number): Promise<ApiToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptionService = getService('encryption');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n const apiToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: ['id', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n encryptedKey,\n },\n });\n\n if (!apiToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n return {\n ...apiToken,\n accessKey,\n };\n};\n\nconst checkSaltIsDefined = () => {\n const apiTokenCfg = strapi.config.get<Core.Config.Admin['apiToken']>('admin.apiToken');\n if (!apiTokenCfg?.salt) {\n // TODO V5: stop reading API_TOKEN_SALT\n if (process.env.API_TOKEN_SALT) {\n process.emitWarning(`[deprecated] In future versions, Strapi will stop reading directly from the environment variable API_TOKEN_SALT. Please set apiToken.salt in config/admin.js instead.\nFor security reasons, keep storing the secret in an environment variable and use env() to read it in config/admin.js (ex: \\`apiToken: { salt: env('API_TOKEN_SALT') }\\`). See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`);\n\n strapi.config.set('admin.apiToken.salt', process.env.API_TOKEN_SALT);\n } else {\n throw new Error(\n `Missing apiToken.salt. Please set apiToken.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`).\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n }\n};\n\n/**\n * Return a list of all tokens and their permissions\n */\nconst list = async (): Promise<Array<ApiToken>> => {\n const tokens: Array<DBApiToken> = await strapi.db.query('admin::api-token').findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n });\n\n if (!tokens) {\n return tokens;\n }\n\n return tokens.map((token) => flattenTokenPermissions(token));\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<ApiToken> => {\n return strapi.db\n .query('admin::api-token')\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } });\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number) => {\n return getBy({ id });\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string) => {\n return getBy({ name });\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: Update.Request['body']\n): Promise<ApiToken> => {\n // retrieve token without permissions\n const originalToken: DBApiToken = await strapi.db\n .query('admin::api-token')\n .findOne({ where: { id } });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n const changingTypeToCustom =\n attributes.type === constants.API_TOKEN_TYPE.CUSTOM &&\n originalToken.type !== constants.API_TOKEN_TYPE.CUSTOM;\n\n // if we're updating the permissions on any token type, or changing from non-custom to custom, ensure they're still valid\n // if neither type nor permissions are changing, we don't need to validate again or else we can't allow partial update\n if (attributes.permissions || changingTypeToCustom) {\n assertCustomTokenPermissionsValidity(\n attributes.type || originalToken.type,\n attributes.permissions || originalToken.permissions\n );\n }\n\n assertValidLifespan(attributes.lifespan);\n\n const updatedToken: ApiToken = await strapi.db.query('admin::api-token').update({\n select: SELECT_FIELDS,\n where: { id },\n data: omit('permissions', attributes),\n });\n\n // custom tokens need to have their permissions updated as well\n if (updatedToken.type === constants.API_TOKEN_TYPE.CUSTOM && attributes.permissions) {\n const currentPermissionsResult = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(attributes.permissions);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n // method using a loop -- works but very inefficient\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query('admin::api-token-permission').delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n // using a loop -- works but very inefficient\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: id },\n })\n )\n );\n }\n // if type is not custom, make sure any old permissions get removed\n else if (updatedToken.type !== constants.API_TOKEN_TYPE.CUSTOM) {\n await strapi.db.query('admin::api-token-permission').delete({\n where: { token: id },\n });\n }\n\n // retrieve permissions\n const permissionsFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p: any) => p.action) : undefined,\n };\n};\n\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::api-token').count({ where });\n};\n\nexport {\n create,\n count,\n regenerate,\n exists,\n checkSaltIsDefined,\n hash,\n list,\n revoke,\n getById,\n update,\n getByName,\n getBy,\n};\n"],"names":["ValidationError","NotFoundError","errors","SELECT_FIELDS","POPULATE_FIELDS","assertCustomTokenPermissionsValidity","type","permissions","constants","API_TOKEN_TYPE","CUSTOM","isEmpty","isArray","validPermissions","strapi","contentAPI","providers","action","keys","invalidPermissions","difference","join","isValidLifespan","lifespan","isNil","isNumber","Object","values","API_TOKEN_LIFESPANS","includes","assertValidLifespan","flattenTokenPermissions","token","map","getBy","whereParams","length","db","query","findOne","select","populate","where","encryptedKey","rest","accessKey","getService","decrypt","exists","apiToken","hash","apiTokenCfg","config","get","salt","crypto","createHmac","update","digest","getExpirationFields","isValidNumber","Number","isFinite","expiresAt","Date","now","create","attributes","encryptionService","randomBytes","toString","encrypt","data","omit","result","Promise","all","uniq","currentPermissions","load","assign","regenerate","id","checkSaltIsDefined","process","env","API_TOKEN_SALT","emitWarning","set","Error","list","tokens","findMany","orderBy","name","revoke","delete","getById","getByName","originalToken","changingTypeToCustom","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","actionsToAdd","permissionsFromDb","p","undefined","count"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api-token.js","sources":["../../../../../server/src/services/api-token.ts"],"sourcesContent":["import crypto from 'crypto';\nimport {\n omit,\n difference,\n isNil,\n isEmpty,\n map,\n isArray,\n uniq,\n isNumber,\n differenceWith,\n isEqual,\n pick,\n prop,\n} from 'lodash/fp';\nimport type { Core, Data } from '@strapi/types';\nimport { errors } from '@strapi/utils';\nimport type {\n Update,\n ContentApiApiToken,\n ContentApiApiTokenBody,\n} from '../../../shared/contracts/api-token';\nimport type { AdminApiToken, AdminTokenBody } from '../../../shared/contracts/admin-token';\nimport type { AdminTokenOwner, AdminUser, Permission } from '../../../shared/contracts/shared';\nimport constants from './constants';\nimport { getService } from '../utils';\nimport permissionDomain from '../domain/permission';\nimport { validatePermissionsExist } from '../validation/permission';\n\ntype AnyApiToken = ContentApiApiToken | AdminApiToken;\n\nconst { SUPER_ADMIN_CODE } = constants;\n\nconst { ValidationError, NotFoundError } = errors;\n\nconst assertOwnerMatchesCallingUser = async (\n adminUserOwner: Data.ID,\n callingUser: AdminUser | undefined\n): Promise<void> => {\n if (callingUser === undefined || callingUser === null) {\n throw new ValidationError('adminUserOwner requires an authenticated admin user');\n }\n\n const ownerId = String(adminUserOwner);\n const callingUserId = String(callingUser.id);\n\n if (ownerId !== callingUserId) {\n throw new ValidationError('adminUserOwner must match the authenticated admin user');\n }\n\n const existingUser = await strapi.db.query('admin::user').findOne({\n select: ['id'],\n where: { id: callingUser.id },\n });\n\n if (existingUser === null || existingUser === undefined) {\n throw new ValidationError('adminUserOwner must reference an existing admin user');\n }\n};\n\nconst isSuperAdmin = (user: AdminUser | undefined): boolean =>\n user?.roles?.some((r) => r.code === SUPER_ADMIN_CODE) === true;\n\nconst getOwnerId = (token: AdminApiToken): string => {\n const owner = token.adminUserOwner;\n return String(typeof owner === 'object' ? owner.id : owner);\n};\n\nconst toAdminTokenOwner = (\n owner: AdminApiToken['adminUserOwner'] | null | undefined\n): Data.ID | AdminTokenOwner => {\n if (owner === null || owner === undefined) {\n throw new Error('adminUserOwner is required');\n }\n\n // Bare id\n if (typeof owner === 'number' || typeof owner === 'string') {\n return owner;\n }\n\n return {\n id: owner.id,\n firstname: owner.firstname,\n lastname: owner.lastname,\n username: owner.username,\n email: owner.email,\n };\n};\n\nconst SELECT_FIELDS = [\n 'id',\n 'kind',\n 'name',\n 'description',\n 'lastUsedAt',\n 'type',\n 'lifespan',\n 'expiresAt',\n 'createdAt',\n 'updatedAt',\n];\n\nconst POPULATE_FIELDS = ['permissions', 'adminPermissions', 'adminUserOwner'];\n\n// TODO: we need to ensure the permissions are actually valid registered permissions!\n\n/**\n * Assert that a token's permissions attribute is valid for its type\n */\nconst assertCustomTokenPermissionsValidity = (\n type: ContentApiApiToken['type'],\n permissions: string[] | null | undefined\n) => {\n // Ensure non-custom tokens doesn't have permissions\n if (type !== constants.API_TOKEN_TYPE.CUSTOM && !isEmpty(permissions)) {\n throw new ValidationError('Non-custom tokens should not reference permissions');\n }\n\n // Custom type tokens should always have permissions attached to them\n if (type === constants.API_TOKEN_TYPE.CUSTOM && !isArray(permissions)) {\n throw new ValidationError('Missing permissions attribute for custom token');\n }\n\n // Permissions provided for a custom type token should be valid/registered permissions UID\n if (type === constants.API_TOKEN_TYPE.CUSTOM) {\n const validPermissions = strapi.contentAPI.permissions.providers.action.keys();\n const invalidPermissions = difference(permissions, validPermissions) as string[];\n\n if (!isEmpty(invalidPermissions)) {\n throw new ValidationError(`Unknown permissions provided: ${invalidPermissions.join(', ')}`);\n }\n }\n};\n\n/**\n * Check if a token's lifespan is valid\n */\nconst isValidLifespan = (lifespan: unknown) => {\n if (isNil(lifespan)) {\n return true;\n }\n\n if (!isNumber(lifespan) || !Object.values(constants.API_TOKEN_LIFESPANS).includes(lifespan)) {\n return false;\n }\n\n return true;\n};\n\n/**\n * Assert that a token's lifespan is valid\n */\nconst assertValidLifespan = (lifespan: unknown) => {\n if (!isValidLifespan(lifespan)) {\n throw new ValidationError(\n `lifespan must be one of the following values:\n ${Object.values(constants.API_TOKEN_LIFESPANS).join(', ')}`\n );\n }\n};\n\n/** API/body shape: permission without ids/timestamps and without actionParameters (defaulted by domain when creating). */\ntype PermissionInput = Omit<Permission, 'id' | 'createdAt' | 'updatedAt' | 'actionParameters'>;\n\n/**\n * Assert that a legacy-kind token body does not carry admin-only fields\n */\nconst assertLegacyKindFields = (attributes: ContentApiApiTokenBody): void => {\n const raw = attributes as Record<string, unknown>;\n if (raw.adminPermissions !== undefined && raw.adminPermissions !== null) {\n throw new ValidationError('Legacy tokens cannot carry admin permissions');\n }\n if (raw.adminUserOwner !== undefined && raw.adminUserOwner !== null) {\n throw new ValidationError('Legacy tokens cannot have an admin user owner');\n }\n};\n\n/**\n * Assert that an admin-kind token body does not carry legacy-only fields\n */\nconst assertAdminKindFields = (attributes: AdminTokenBody): void => {\n const raw = attributes as Record<string, unknown>;\n if (raw.type !== undefined && raw.type !== null) {\n throw new ValidationError(\n 'Admin tokens cannot carry a legacy type (custom/read-only/full-access)'\n );\n }\n if (raw.permissions !== undefined && raw.permissions !== null) {\n throw new ValidationError('Admin tokens cannot carry legacy content-API permissions');\n }\n};\n\n/**\n * Assert that admin permissions are valid\n */\nconst assertAdminPermissionsValidity = async (adminPermissions?: PermissionInput[]) => {\n if (!adminPermissions || adminPermissions.length === 0) {\n return;\n }\n\n // Validate that all actions exist in the admin action provider\n const validActions = getService('permission').actionProvider.keys();\n\n for (const perm of adminPermissions) {\n if (!validActions.includes(perm.action)) {\n throw new ValidationError(`Unknown admin action: ${perm.action}`);\n }\n }\n\n // Use existing permission validation\n await validatePermissionsExist(adminPermissions as any);\n};\n\n/**\n * Enforce that every requested admin permission stays within the calling\n * user's own permission ceiling, then return the clamped permissions.\n *\n * Super-admins bypass this (they hold every permission).\n * When admin permissions are requested, an authenticated user is required (no bypass when user is missing).\n *\n * For each requested permission:\n * - action + subject must match at least one user permission\n * - properties.fields must be ⊆ user's properties.fields\n * (if the user's permission defines no fields, all fields are allowed)\n * - conditions are inherited from the user's matching permission(s);\n * the caller cannot configure conditions on their own tokens\n *\n * Returns the permissions with conditions enforced from the user's role.\n * Throws ValidationError if any permission exceeds the user's ceiling.\n *\n * Guaranteed postcondition: all returned permissions have conditions filtered to\n * registered conditions only, regardless of the user type.\n */\nconst enforceAdminPermissionsCeiling = async (\n user: AdminUser | undefined | null,\n requestedPermissions?: PermissionInput[]\n): Promise<PermissionInput[]> => {\n if (!requestedPermissions || requestedPermissions.length === 0) {\n return requestedPermissions || [];\n }\n if (user === undefined || user === null) {\n throw new ValidationError(\n 'Admin permission ceiling cannot be enforced without an authenticated user'\n );\n }\n if (isSuperAdmin(user)) {\n // Sanitize conditions even for super-admins so this function is a complete boundary.\n // createApiTokenAdminPermissions also sanitizes, but relying on that downstream\n // is fragile — any future call path that skips it would store invalid conditions.\n const { conditionProvider } = getService('permission');\n const sanitize = permissionDomain.sanitizeConditions(conditionProvider as any);\n return requestedPermissions.map((perm) => {\n const sanitized = sanitize({ ...perm, actionParameters: {} } as Permission);\n return { ...perm, conditions: sanitized.conditions };\n });\n }\n\n const userPermissions: Permission[] = await getService('permission').findUserPermissions(user);\n\n const exceeding: string[] = [];\n\n const clamped = requestedPermissions.map((requested) => {\n const requestedSubject = requested.subject || null;\n\n // Find all user permissions matching action + subject\n const matchingUserPerms = userPermissions.filter((userPerm: Permission) => {\n if (userPerm.action !== requested.action) return false;\n const userSubject = userPerm.subject || null;\n return requestedSubject === userSubject;\n });\n\n const label =\n requestedSubject !== null ? `${requested.action} on ${requestedSubject}` : requested.action;\n\n if (matchingUserPerms.length === 0) {\n exceeding.push(label);\n return requested;\n }\n\n // --- Field-level ceiling ---\n // If any matching user perm has no fields defined → all fields are allowed.\n // Otherwise, effective user fields = union of all matching perms' fields.\n const anyUserPermHasAllFields = matchingUserPerms.some(\n (p) => !p.properties?.fields || p.properties.fields.length === 0\n );\n\n const requestedFields = requested.properties?.fields;\n\n if (!anyUserPermHasAllFields) {\n const effectiveUserFields = uniq(\n matchingUserPerms.flatMap((p) => p.properties?.fields || [])\n );\n\n // When the owner is field-restricted, omitting fields would widen access to all fields.\n // Force explicit field selection so token scope can't exceed the owner's ceiling.\n if (requestedFields === undefined || requestedFields === null) {\n exceeding.push(`${label} (fields are required due to owner field restrictions)`);\n return requested;\n }\n\n if (requestedFields.length > 0) {\n const exceedingFields = requestedFields.filter((f) => !effectiveUserFields.includes(f));\n\n if (exceedingFields.length > 0) {\n exceeding.push(`${label} (fields: ${exceedingFields.join(', ')})`);\n return requested;\n }\n }\n }\n\n // --- Condition-level ceiling ---\n // Conditions are always inherited from the user's matching permission(s).\n // If any matching user perm is unconditional → token gets no conditions.\n // Otherwise → union of conditions across matching perms.\n const anyUserPermIsUnconditional = matchingUserPerms.some(\n (p) => !p.conditions || p.conditions.length === 0\n );\n\n const enforcedConditions: string[] = anyUserPermIsUnconditional\n ? []\n : (uniq(matchingUserPerms.flatMap((p) => p.conditions || [])) as string[]);\n\n return {\n ...requested,\n conditions: enforcedConditions,\n };\n });\n\n if (exceeding.length > 0) {\n throw new ValidationError(\n `Cannot assign admin permissions that exceed your own. ` +\n `Exceeding: ${exceeding.join(', ')}`\n );\n }\n\n return clamped;\n};\n\n/**\n * Create admin permissions for an API token\n */\nconst createApiTokenAdminPermissions = async (tokenId: Data.ID, permissions: PermissionInput[]) => {\n const { conditionProvider } = getService('permission');\n const sanitizeConditions = permissionDomain.sanitizeConditions(conditionProvider as any);\n\n const permissionsWithToken = permissions.map((perm) => {\n const permAsPermission = { ...perm, actionParameters: {} } as Permission;\n const sanitized = sanitizeConditions(permAsPermission);\n return permissionDomain.create({\n ...sanitized,\n apiToken: tokenId as any,\n role: null,\n } as any);\n });\n\n const createdPermissions = await getService('permission').createMany(permissionsWithToken as any);\n\n return createdPermissions;\n};\n\n/**\n * Fields to compare when checking if two permissions are equal\n */\nconst COMPARABLE_FIELDS = ['conditions', 'properties', 'subject', 'action', 'actionParameters'];\nconst pickComparableFields = pick(COMPARABLE_FIELDS);\n\n/**\n * Helper to clean JSON (remove undefined values)\n */\nconst jsonClean = <T extends object>(data: T): T => JSON.parse(JSON.stringify(data));\n\n/**\n * Compare two permissions for equality\n */\nconst arePermissionsEqual = (p1: Permission, p2: Permission): boolean => {\n if (p1.action === p2.action) {\n return isEqual(jsonClean(pickComparableFields(p1)), jsonClean(pickComparableFields(p2)));\n }\n return false;\n};\n\n/**\n * Assign admin permissions to an API token (similar to role permission assignment).\n * ceilingUser is the user whose permissions act as the ceiling — always the token owner,\n * regardless of who is making the request.\n */\nconst assignAdminPermissionsToToken = async (\n tokenId: Data.ID,\n permissions: PermissionInput[],\n ceilingUser: AdminUser\n): Promise<Permission[]> => {\n await validatePermissionsExist(permissions as any);\n const clampedPermissions = await enforceAdminPermissionsCeiling(ceilingUser, permissions);\n\n const permissionsWithToken = clampedPermissions.map((perm) =>\n permissionDomain.create({\n ...perm,\n apiToken: tokenId as any,\n role: null,\n } as any)\n );\n\n const existingPermissions = await getService('permission').findMany({\n where: { apiToken: { id: tokenId } },\n });\n\n const permissionsToAdd = differenceWith(\n arePermissionsEqual,\n permissionsWithToken,\n existingPermissions\n ) as any as Permission[];\n\n const permissionsToDelete = differenceWith(\n arePermissionsEqual,\n existingPermissions,\n permissionsWithToken\n ) as any as Permission[];\n\n if (permissionsToDelete.length > 0) {\n await getService('permission').deleteByIds(permissionsToDelete.map(prop('id')) as Data.ID[]);\n }\n\n if (permissionsToAdd.length > 0) {\n await createApiTokenAdminPermissions(tokenId, permissionsToAdd as any);\n }\n\n // Return all current permissions\n const allCurrentPermissions = await getService('permission').findMany({\n where: { apiToken: { id: tokenId } },\n });\n\n return allCurrentPermissions;\n};\n\n/**\n * Reconcile a token's admin permissions against the owner's current effective ceiling.\n *\n * Pure / sync — no DB calls. Returns two buckets:\n * toDelete – permissions that are no longer within the user's scope (action/subject missing\n * or requested fields exceed the allowed set)\n * toUpdate – permissions that are still in scope but whose conditions must be re-clamped\n * to the current union of the matching user permissions' conditions\n */\nconst reconcileTokenPermissionsToUserCeiling = (\n userPermissions: Permission[],\n tokenPermissions: Permission[]\n): { toDelete: Permission[]; toUpdate: { id: Data.ID; conditions: string[] }[] } => {\n const toDelete: Permission[] = [];\n const toUpdate: { id: Data.ID; conditions: string[] }[] = [];\n\n tokenPermissions.forEach((tokenPerm) => {\n const tokenSubject = tokenPerm.subject || null;\n\n const matchingUserPerms = userPermissions.filter(\n (userPerm) =>\n userPerm.action === tokenPerm.action && (userPerm.subject || null) === tokenSubject\n );\n\n if (matchingUserPerms.length === 0) {\n toDelete.push(tokenPerm);\n return;\n }\n\n // Field-level ceiling check (mirrors enforceAdminPermissionsCeiling)\n const anyUserPermHasAllFields = matchingUserPerms.some(\n (p) => !p.properties?.fields || p.properties.fields.length === 0\n );\n const tokenFields = tokenPerm.properties?.fields;\n\n const fieldCeilingExceeded =\n !anyUserPermHasAllFields &&\n tokenFields !== undefined &&\n tokenFields !== null &&\n tokenFields.length > 0 &&\n (() => {\n const effectiveUserFields = uniq(\n matchingUserPerms.flatMap((p) => p.properties?.fields || [])\n );\n return tokenFields.some((f) => !effectiveUserFields.includes(f));\n })();\n\n if (fieldCeilingExceeded) {\n toDelete.push(tokenPerm);\n return;\n }\n\n // Condition: force conditions to be the ones of the user permission(s)\n const anyUserPermIsUnconditional = matchingUserPerms.some(\n (p) => !p.conditions || p.conditions.length === 0\n );\n const enforcedConditions: string[] = anyUserPermIsUnconditional\n ? []\n : (uniq(matchingUserPerms.flatMap((p) => p.conditions || [])) as string[]);\n\n const currentConditions: string[] = (tokenPerm.conditions as string[]) || [];\n const conditionsChanged =\n enforcedConditions.length !== currentConditions.length ||\n enforcedConditions.some((c) => !currentConditions.includes(c));\n\n if (conditionsChanged) {\n toUpdate.push({ id: tokenPerm.id as Data.ID, conditions: enforcedConditions });\n }\n });\n\n return { toDelete, toUpdate };\n};\n\n/**\n * Re-sync all admin token permissions for a given user against their current effective ceiling.\n *\n * Skips super-admins (no ceiling). For each admin token owned by the user:\n * - Deletes permissions that are no longer within the user's scope\n * - Updates conditions on permissions whose conditions have drifted from the role's current set\n */\nconst syncApiTokenPermissionsForUser = async (userId: Data.ID): Promise<void> => {\n const user = await strapi.db.query('admin::user').findOne({\n where: { id: userId },\n populate: ['roles'],\n });\n\n if (user === null || user === undefined) return;\n if (isSuperAdmin(user as AdminUser)) return;\n\n const userEffectivePermissions: Permission[] = await getService('permission').findUserPermissions(\n user as AdminUser\n );\n\n const tokens = await strapi.db.query('admin::api-token').findMany({\n where: { kind: 'admin', adminUserOwner: { id: userId } },\n populate: ['adminPermissions'],\n });\n\n const tokensWithPermissions = tokens.filter(\n (token: { adminPermissions?: Permission[] }) =>\n Array.isArray(token.adminPermissions) && token.adminPermissions.length > 0\n );\n\n for (const token of tokensWithPermissions) {\n const tokenPermissions: Permission[] = token.adminPermissions as Permission[];\n\n const { toDelete, toUpdate } = reconcileTokenPermissionsToUserCeiling(\n userEffectivePermissions,\n tokenPermissions\n );\n\n if (toDelete.length > 0) {\n await getService('permission').deleteByIds(toDelete.map((p) => p.id as Data.ID));\n }\n\n for (const { id, conditions } of toUpdate) {\n await strapi.db.query('admin::permission').update({ where: { id }, data: { conditions } });\n }\n }\n};\n\n/**\n * Re-sync admin token permissions for all admin users who hold a given role.\n * Called after role permissions are updated.\n */\nconst syncApiTokenPermissionsForRole = async (roleId: Data.ID): Promise<void> => {\n const users = await strapi.db.query('admin::user').findMany({\n where: { roles: { id: roleId } },\n populate: ['roles'],\n });\n\n await Promise.allSettled(users.map((user) => syncApiTokenPermissionsForUser(user.id as Data.ID)));\n};\n\n/**\n * Flatten a token's database permissions objects to an array of strings\n */\nconst flattenTokenPermissions = (permissions: { action: string }[] | undefined): string[] => {\n return isArray(permissions) ? map('action', permissions) : [];\n};\n\ntype WhereParams = {\n id?: string | number;\n name?: string;\n lastUsedAt?: number;\n description?: string;\n accessKey?: string;\n kind?: 'content-api' | 'admin';\n};\n\ntype GetByOptions = {\n includeDecryptedKey?: boolean;\n};\n\n/**\n * Get a token.\n * By default the plaintext accessKey is NOT included.\n * Pass { includeDecryptedKey: true } to decrypt and return it (owner-only paths).\n */\nconst getBy = async (\n whereParams: WhereParams = {},\n options: GetByOptions = {}\n): Promise<AnyApiToken | null> => {\n if (Object.keys(whereParams).length === 0) {\n return null;\n }\n\n const { includeDecryptedKey = false } = options;\n\n const selectFields = includeDecryptedKey ? [...SELECT_FIELDS, 'encryptedKey'] : SELECT_FIELDS;\n\n const token = await strapi.db.query('admin::api-token').findOne({\n select: selectFields,\n populate: POPULATE_FIELDS,\n where: whereParams,\n });\n\n if (!token) {\n return token;\n }\n\n // Tokens created before kind introduction case: force kind to be content-api\n const computedKind = token.kind ?? 'content-api';\n\n const result = omit(\n ['accessKey', 'encryptedKey', 'type', 'permissions', 'adminPermissions', 'adminUserOwner'],\n token\n );\n\n if (computedKind === 'content-api') {\n Object.assign(result, {\n kind: 'content-api',\n type: token.type,\n permissions: flattenTokenPermissions(token.permissions),\n });\n } else if (computedKind === 'admin') {\n Object.assign(result, {\n kind: 'admin',\n adminPermissions: token.adminPermissions,\n adminUserOwner: toAdminTokenOwner(token.adminUserOwner),\n });\n }\n\n if (includeDecryptedKey && token.encryptedKey) {\n Object.assign(result, { accessKey: getService('encryption').decrypt(token.encryptedKey) });\n }\n\n return result as AnyApiToken;\n};\n\n/**\n * Check if token exists\n */\nconst exists = async (whereParams: WhereParams = {}): Promise<boolean> => {\n const apiToken = await getBy(whereParams);\n\n return !!apiToken;\n};\n\n/**\n * Return a secure sha512 hash of an accessKey\n */\nconst hash = (accessKey: string) => {\n const apiTokenCfg = strapi.config.get<Core.Config.Admin['apiToken']>('admin.apiToken');\n const salt = apiTokenCfg.salt;\n\n return crypto.createHmac('sha512', salt).update(accessKey).digest('hex');\n};\n\nconst getExpirationFields = (lifespan: AnyApiToken['lifespan']) => {\n // it must be nil or a finite number >= 0\n const isValidNumber = isNumber(lifespan) && Number.isFinite(lifespan) && lifespan > 0;\n if (!isValidNumber && !isNil(lifespan)) {\n throw new ValidationError('lifespan must be a positive number or null');\n }\n\n return {\n lifespan: lifespan ?? null,\n expiresAt: lifespan ? Date.now() + lifespan : null,\n };\n};\n\n/**\n * Create a token and its permissions\n */\nconst create = async <K extends AnyApiToken['kind']>(\n attributes: { kind: K } & (ContentApiApiTokenBody | AdminTokenBody),\n callingUser?: AdminUser\n): Promise<\n K extends 'content-api' ? ContentApiApiToken : K extends 'admin' ? AdminApiToken : AnyApiToken\n> => {\n const encryptionService = getService('encryption');\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n assertValidLifespan(attributes.lifespan);\n\n if (attributes.kind === 'content-api') {\n const castedContentApiApiTokenBody = attributes as ContentApiApiTokenBody;\n assertLegacyKindFields(castedContentApiApiTokenBody);\n assertCustomTokenPermissionsValidity(\n castedContentApiApiTokenBody.type,\n castedContentApiApiTokenBody.permissions\n );\n\n // content api tokens have no owner\n const apiToken = await strapi.db.query('admin::api-token').create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...(omit(['permissions', 'adminPermissions', 'adminUserOwner'], attributes) as object),\n accessKey: hash(accessKey),\n encryptedKey,\n adminUserOwner: null,\n ...getExpirationFields(castedContentApiApiTokenBody.lifespan ?? null),\n },\n });\n\n const result: ContentApiApiToken = { ...apiToken, accessKey };\n\n // If this is a custom type token, create the related content-API permissions\n if (castedContentApiApiTokenBody.type === constants.API_TOKEN_TYPE.CUSTOM) {\n // TODO: createMany doesn't seem to create relation properly, implement a better way rather than a ton of queries\n await Promise.all(\n uniq(castedContentApiApiTokenBody.permissions).map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: apiToken },\n })\n )\n );\n\n const currentPermissions = await strapi.db\n .query('admin::api-token')\n .load(apiToken, 'permissions');\n\n if (currentPermissions) {\n Object.assign(result, { permissions: flattenTokenPermissions(currentPermissions) });\n }\n }\n\n // Casted to any to avoid complex type duplication\n return omit(['adminPermissions', 'adminUserOwner'], result) as any;\n }\n\n // kind === 'admin'\n assertAdminKindFields(attributes);\n const castedAdminTokenBody = attributes as AdminTokenBody;\n await assertAdminPermissionsValidity(castedAdminTokenBody.adminPermissions);\n const clampedAdminPermissions = await enforceAdminPermissionsCeiling(\n callingUser,\n castedAdminTokenBody.adminPermissions\n );\n\n // Owner: when explicitly provided, it must match the caller.\n // When omitted, always defaults to the calling user (including super admins).\n let ownerId: Data.ID;\n if (\n castedAdminTokenBody.adminUserOwner !== undefined &&\n castedAdminTokenBody.adminUserOwner !== null\n ) {\n await assertOwnerMatchesCallingUser(castedAdminTokenBody.adminUserOwner, callingUser);\n ownerId = castedAdminTokenBody.adminUserOwner;\n } else {\n if (callingUser === undefined || callingUser === null) {\n throw new ValidationError('Creating an admin token requires an authenticated admin user');\n }\n ownerId = callingUser.id as Data.ID;\n }\n\n const apiToken = await strapi.db.query('admin::api-token').create({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n data: {\n ...(omit(['permissions', 'adminPermissions', 'adminUserOwner'], attributes) as object),\n accessKey: hash(accessKey),\n encryptedKey,\n adminUserOwner: ownerId,\n ...getExpirationFields(castedAdminTokenBody.lifespan ?? null),\n },\n });\n\n const result = { ...apiToken, accessKey } as AnyApiToken;\n\n // Handle admin permissions (using ceiling-clamped permissions with inherited conditions)\n if (clampedAdminPermissions.length > 0) {\n await createApiTokenAdminPermissions(apiToken.id, clampedAdminPermissions);\n\n const currentAdminPermissions = await strapi.db\n .query('admin::api-token')\n .load(apiToken, 'adminPermissions');\n\n if (currentAdminPermissions) {\n Object.assign(result, { adminPermissions: currentAdminPermissions });\n }\n }\n\n // Casted to any to avoid complex type duplication\n return {\n ...(omit(['permissions'], result) as object),\n adminUserOwner: toAdminTokenOwner((result as AdminApiToken).adminUserOwner),\n } as any;\n};\n\nconst regenerate = async (id: string | number): Promise<ContentApiApiToken | AdminApiToken> => {\n const accessKey = crypto.randomBytes(128).toString('hex');\n const encryptionService = getService('encryption');\n const encryptedKey = encryptionService.encrypt(accessKey);\n\n const apiToken: AnyApiToken = await strapi.db.query('admin::api-token').update({\n select: ['id', 'accessKey'],\n where: { id },\n data: {\n accessKey: hash(accessKey),\n encryptedKey,\n },\n });\n\n if (!apiToken) {\n throw new NotFoundError('The provided token id does not exist');\n }\n\n return {\n ...apiToken,\n accessKey,\n };\n};\n\nconst checkSaltIsDefined = () => {\n const apiTokenCfg = strapi.config.get<Core.Config.Admin['apiToken']>('admin.apiToken');\n if (!apiTokenCfg?.salt) {\n // TODO V5: stop reading API_TOKEN_SALT\n if (process.env.API_TOKEN_SALT) {\n process.emitWarning(`[deprecated] In future versions, Strapi will stop reading directly from the environment variable API_TOKEN_SALT. Please set apiToken.salt in config/admin.js instead.\nFor security reasons, keep storing the secret in an environment variable and use env() to read it in config/admin.js (ex: \\`apiToken: { salt: env('API_TOKEN_SALT') }\\`). See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`);\n\n strapi.config.set('admin.apiToken.salt', process.env.API_TOKEN_SALT);\n } else {\n throw new Error(\n `Missing apiToken.salt. Please set apiToken.salt in config/admin.js (ex: you can generate one using Node with \\`crypto.randomBytes(16).toString('base64')\\`).\nFor security reasons, prefer storing the secret in an environment variable and read it in config/admin.js. See https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.html#configuration-using-environment-variables.`\n );\n }\n }\n};\n\n/**\n * Return a list of tokens visible to the calling user.\n * Super-admins see all tokens; regular admins see only ownerless tokens and their own.\n */\nconst list = async <K extends AnyApiToken['kind']>(\n callingUser: AdminUser,\n { filter }: { filter?: { kind?: K } } = {}\n): Promise<\n Array<\n K extends 'content-api' ? ContentApiApiToken : K extends 'admin' ? AdminApiToken : AnyApiToken\n >\n> => {\n const ownershipWhere = isSuperAdmin(callingUser)\n ? {}\n : { $or: [{ adminUserOwner: null }, { adminUserOwner: { id: callingUser.id } }] };\n\n // Tokens without a persisted kind are content-api tokens (pre-migration rows).\n let kindWhere: Record<string, unknown> = {};\n if (filter?.kind === 'content-api') {\n kindWhere = { $or: [{ kind: 'content-api' }, { kind: { $null: true } }] };\n } else if (filter?.kind !== undefined) {\n kindWhere = { kind: filter.kind };\n }\n\n const where = { ...ownershipWhere, ...kindWhere };\n\n const tokens = await strapi.db.query('admin::api-token').findMany({\n select: SELECT_FIELDS,\n populate: POPULATE_FIELDS,\n orderBy: { name: 'ASC' },\n where,\n });\n\n if (!tokens) {\n return tokens;\n }\n\n return tokens.map((token) =>\n token.kind === null || token.kind === 'content-api'\n ? omit(['adminPermissions', 'adminUserOwner'], {\n ...token,\n // Tokens created before kind introduction case: force kind to be content-api\n kind: 'content-api',\n permissions: flattenTokenPermissions(token.permissions),\n })\n : ({\n ...(omit(['permissions'], token) as object),\n adminUserOwner: toAdminTokenOwner(token.adminUserOwner),\n } as any)\n );\n};\n\n/**\n * Revoke (delete) a token\n */\nconst revoke = async (id: string | number): Promise<AnyApiToken> => {\n const token = await strapi.db.query('admin::api-token').findOne({\n where: { id },\n select: ['id'],\n populate: ['adminPermissions'],\n });\n\n if (token !== null && token !== undefined) {\n const permissionIds = ((token.adminPermissions as Array<{ id: Data.ID }>) ?? [])\n .map((p) => p.id)\n .filter((permId) => permId !== null && permId !== undefined);\n\n if (permissionIds.length > 0) {\n await getService('permission').deleteByIds(permissionIds);\n }\n }\n\n const deletedToken = await strapi.db\n .query('admin::api-token')\n .delete({ select: SELECT_FIELDS, populate: POPULATE_FIELDS, where: { id } });\n\n if (deletedToken === null || deletedToken === undefined || deletedToken.kind !== 'admin') {\n return deletedToken;\n }\n\n return {\n ...deletedToken,\n adminUserOwner: toAdminTokenOwner(deletedToken.adminUserOwner),\n };\n};\n\n/**\n * Retrieve a token by id\n */\nconst getById = async (id: string | number, options?: GetByOptions) => {\n return getBy({ id }, options);\n};\n\n/**\n * Retrieve a token by name\n */\nconst getByName = async (name: string, options?: GetByOptions) => {\n return getBy({ name }, options);\n};\n\n/**\n * Update a token and its permissions\n */\nconst update = async (\n id: string | number,\n attributes: Update.Request['body']\n): Promise<AnyApiToken> => {\n const originalToken = await strapi.db\n .query('admin::api-token')\n .findOne({ select: SELECT_FIELDS, populate: ['adminUserOwner'], where: { id } });\n\n if (!originalToken) {\n throw new NotFoundError('Token not found');\n }\n\n const raw = attributes as Record<string, unknown>;\n\n // kind is immutable after creation\n if (raw.kind !== undefined && raw.kind !== null && raw.kind !== originalToken.kind) {\n throw new ValidationError('kind is immutable after creation');\n }\n\n assertValidLifespan(attributes.lifespan);\n\n let clampedAdminPermissions: PermissionInput[] | undefined;\n let tokenOwnerUser: AdminUser | undefined;\n\n if (originalToken.kind === 'content-api') {\n assertLegacyKindFields(attributes as ContentApiApiTokenBody);\n\n const incomingType = raw.type as ContentApiApiToken['type'] | undefined;\n const incomingPermissions = raw.permissions as string[] | null | undefined;\n const resolvedType = incomingType ?? (originalToken.type as ContentApiApiToken['type']);\n const changingTypeToCustom =\n incomingType === constants.API_TOKEN_TYPE.CUSTOM &&\n originalToken.type !== constants.API_TOKEN_TYPE.CUSTOM;\n\n // Only re-validate if permissions or type are being changed\n if (incomingPermissions !== undefined || changingTypeToCustom) {\n assertCustomTokenPermissionsValidity(\n resolvedType,\n incomingPermissions ?? (originalToken.permissions as string[])\n );\n }\n } else if (originalToken.kind === 'admin') {\n assertAdminKindFields(attributes as AdminTokenBody);\n\n const incomingAdminPermissions = raw.adminPermissions as PermissionInput[] | undefined;\n if (incomingAdminPermissions !== undefined) {\n await assertAdminPermissionsValidity(incomingAdminPermissions);\n\n // Ceiling is always the owner's permissions, not the calling user's.\n // A super admin editing another user's token must not overflow that user's scope.\n const ownerId = getOwnerId(originalToken as AdminApiToken);\n const resolvedOwner = await getService('user').findOne(ownerId);\n if (resolvedOwner === null || resolvedOwner === undefined) {\n throw new ValidationError('Token owner no longer exists');\n }\n tokenOwnerUser = resolvedOwner;\n clampedAdminPermissions = await enforceAdminPermissionsCeiling(\n tokenOwnerUser,\n incomingAdminPermissions\n );\n }\n\n const incomingAdminUserOwner = raw.adminUserOwner;\n if (incomingAdminUserOwner !== undefined) {\n // Owner is immutable; the provided value must match the existing one\n const existingOwner = originalToken.adminUserOwner;\n const existingOwnerId =\n existingOwner === null || existingOwner === undefined\n ? null\n : String(typeof existingOwner === 'object' ? existingOwner.id : existingOwner);\n const requestedOwnerId =\n incomingAdminUserOwner === null ? null : String(incomingAdminUserOwner);\n\n if (requestedOwnerId !== existingOwnerId) {\n throw new ValidationError('adminUserOwner cannot be changed on update');\n }\n }\n }\n\n const updatedToken = await strapi.db.query('admin::api-token').update({\n select: SELECT_FIELDS,\n where: { id },\n // kind is immutable — strip it along with relation fields so the DB write is clean\n data: omit(['kind', 'permissions', 'adminPermissions', 'adminUserOwner'], attributes) as object,\n });\n\n if (originalToken.kind === 'content-api') {\n const incomingPermissions = raw.permissions as string[] | null | undefined;\n\n // custom tokens need to have their permissions updated as well\n if (\n updatedToken.type === constants.API_TOKEN_TYPE.CUSTOM &&\n incomingPermissions !== undefined\n ) {\n const currentPermissionsResult = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n const currentPermissions = map('action', currentPermissionsResult || []);\n const newPermissions = uniq(incomingPermissions || []);\n\n const actionsToDelete = difference(currentPermissions, newPermissions);\n const actionsToAdd = difference(newPermissions, currentPermissions);\n\n // TODO: improve efficiency here\n await Promise.all(\n actionsToDelete.map((action) =>\n strapi.db.query('admin::api-token-permission').delete({\n where: { action, token: id },\n })\n )\n );\n\n // TODO: improve efficiency here\n await Promise.all(\n actionsToAdd.map((action) =>\n strapi.db.query('admin::api-token-permission').create({\n data: { action, token: id },\n })\n )\n );\n }\n // if type is not custom, make sure any old permissions get removed\n else if (updatedToken.type !== constants.API_TOKEN_TYPE.CUSTOM) {\n await strapi.db.query('admin::api-token-permission').delete({\n where: { token: id },\n });\n }\n\n const permissionsFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'permissions');\n\n return {\n ...updatedToken,\n permissions: permissionsFromDb ? permissionsFromDb.map((p: any) => p.action) : undefined,\n } as AnyApiToken;\n }\n\n // kind === 'admin'\n if (clampedAdminPermissions !== undefined) {\n if (tokenOwnerUser === undefined) {\n throw new ValidationError('Updating admin permissions requires a resolved token owner');\n }\n await assignAdminPermissionsToToken(id, clampedAdminPermissions, tokenOwnerUser);\n }\n\n const adminPermissionsFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'adminPermissions');\n\n const adminUserOwnerFromDb = await strapi.db\n .query('admin::api-token')\n .load(updatedToken, 'adminUserOwner');\n\n return {\n ...updatedToken,\n adminPermissions: adminPermissionsFromDb || [],\n adminUserOwner: toAdminTokenOwner(adminUserOwnerFromDb),\n } as AnyApiToken;\n};\n\nconst count = async (where = {}): Promise<number> => {\n return strapi.db.query('admin::api-token').count({ where });\n};\n\n/**\n * Delete all admin API tokens owned by the given user, including their associated admin permissions.\n * Called when the owner user is deleted so tokens don't linger with a dangling owner FK.\n */\nconst deleteAdminTokensForUser = async (userId: Data.ID): Promise<void> => {\n const tokens = await strapi.db.query('admin::api-token').findMany({\n where: { kind: 'admin', adminUserOwner: { id: userId } },\n select: ['id'],\n populate: ['adminPermissions'],\n });\n\n for (const token of tokens) {\n const permissionIds = ((token.adminPermissions as Array<{ id: Data.ID }>) ?? [])\n .map((p) => p.id)\n .filter((id) => id !== null && id !== undefined);\n\n if (permissionIds.length > 0) {\n await getService('permission').deleteByIds(permissionIds);\n }\n\n await strapi.db.query('admin::api-token').delete({ where: { id: token.id } });\n }\n};\n\n// -------------------------------------------------------------------------\n// Service interfaces\n// -------------------------------------------------------------------------\n\ninterface SharedTokenMethods {\n hash(accessKey: string): string;\n checkSaltIsDefined(): void;\n /** Kind-agnostic lookup by hashed access key — used by the auth strategy. */\n getByAccessKey(accessKeyHash: string, options?: GetByOptions): Promise<AnyApiToken | null>;\n /** Total count across all kinds. */\n countAll(where?: object): Promise<number>;\n reconcileTokenPermissionsToUserCeiling(\n userPermissions: Permission[],\n tokenPermissions: Permission[]\n ): { toDelete: Permission[]; toUpdate: { id: Data.ID; conditions: string[] }[] };\n}\n\nexport interface ContentApiTokenService extends SharedTokenMethods {\n create(attributes: ContentApiApiTokenBody, callingUser?: AdminUser): Promise<ContentApiApiToken>;\n list(callingUser: AdminUser): Promise<ContentApiApiToken[]>;\n getById(id: string | number, options?: GetByOptions): Promise<ContentApiApiToken | null>;\n getByName(name: string, options?: GetByOptions): Promise<ContentApiApiToken | null>;\n update(\n id: string | number,\n attributes: Partial<ContentApiApiTokenBody>\n ): Promise<ContentApiApiToken>;\n revoke(id: string | number): Promise<ContentApiApiToken>;\n regenerate(id: string | number): Promise<ContentApiApiToken>;\n exists(where: WhereParams): Promise<boolean>;\n count(where?: object): Promise<number>;\n}\n\nexport interface AdminTokenService extends SharedTokenMethods {\n create(attributes: AdminTokenBody, callingUser: AdminUser): Promise<AdminApiToken>;\n list(callingUser: AdminUser): Promise<AdminApiToken[]>;\n getById(id: string | number, options?: GetByOptions): Promise<AdminApiToken | null>;\n getByName(name: string, options?: GetByOptions): Promise<AdminApiToken | null>;\n update(id: string | number, attributes: Partial<AdminTokenBody>): Promise<AdminApiToken>;\n revoke(id: string | number): Promise<AdminApiToken>;\n regenerate(id: string | number): Promise<AdminApiToken>;\n exists(where: WhereParams): Promise<boolean>;\n count(where?: object): Promise<number>;\n assignAdminPermissionsToToken(\n tokenId: Data.ID,\n permissions: PermissionInput[],\n ceilingUser: AdminUser\n ): Promise<Permission[]>;\n syncPermissionsForUser(userId: Data.ID): Promise<void>;\n syncPermissionsForRole(roleId: Data.ID): Promise<void>;\n deleteTokensForUser(userId: Data.ID): Promise<void>;\n}\n\n// -------------------------------------------------------------------------\n// Factory\n// -------------------------------------------------------------------------\n\nfunction createTokenService(kind: 'content-api'): ContentApiTokenService;\nfunction createTokenService(kind: 'admin'): AdminTokenService;\nfunction createTokenService(\n kind: 'content-api' | 'admin'\n): ContentApiTokenService | AdminTokenService {\n const shared: SharedTokenMethods = {\n hash,\n checkSaltIsDefined,\n getByAccessKey: (accessKeyHash, options) => getBy({ accessKey: accessKeyHash }, options),\n countAll: count,\n reconcileTokenPermissionsToUserCeiling,\n };\n\n if (kind === 'content-api') {\n const svc: ContentApiTokenService = {\n ...shared,\n create: (attributes: ContentApiApiTokenBody, callingUser?: AdminUser) =>\n create({ ...attributes, kind: 'content-api' }, callingUser) as Promise<ContentApiApiToken>,\n list: (callingUser: AdminUser) =>\n list(callingUser, { filter: { kind: 'content-api' } }) as Promise<ContentApiApiToken[]>,\n getById: (id: string | number, options?: GetByOptions) =>\n getBy(\n {\n $and: [{ id }, { $or: [{ kind: 'content-api' }, { kind: { $null: true } }] }],\n } as any,\n options\n ) as Promise<ContentApiApiToken | null>,\n getByName: (name: string, options?: GetByOptions) =>\n getBy(\n {\n $and: [{ name }, { $or: [{ kind: 'content-api' }, { kind: { $null: true } }] }],\n } as any,\n options\n ) as Promise<ContentApiApiToken | null>,\n update: (id: string | number, attributes: Partial<ContentApiApiTokenBody>) =>\n update(id, attributes) as Promise<ContentApiApiToken>,\n revoke: (id: string | number) => revoke(id) as Promise<ContentApiApiToken>,\n regenerate: (id: string | number) => regenerate(id) as Promise<ContentApiApiToken>,\n exists,\n count,\n };\n return svc;\n }\n\n const svc: AdminTokenService = {\n ...shared,\n create: (attributes: AdminTokenBody, callingUser: AdminUser) =>\n create({ ...attributes, kind: 'admin' }, callingUser) as Promise<AdminApiToken>,\n list: (callingUser: AdminUser) =>\n list(callingUser, { filter: { kind: 'admin' } }) as Promise<AdminApiToken[]>,\n getById: (id: string | number, options?: GetByOptions) =>\n getBy({ id, kind: 'admin' }, options) as Promise<AdminApiToken | null>,\n getByName: (name: string, options?: GetByOptions) =>\n getBy({ name, kind: 'admin' }, options) as Promise<AdminApiToken | null>,\n update: (id: string | number, attributes: Partial<AdminTokenBody>) =>\n update(id, attributes) as Promise<AdminApiToken>,\n revoke: (id: string | number) => revoke(id) as Promise<AdminApiToken>,\n regenerate: (id: string | number) => regenerate(id) as Promise<AdminApiToken>,\n exists,\n count,\n assignAdminPermissionsToToken,\n syncPermissionsForUser: syncApiTokenPermissionsForUser,\n syncPermissionsForRole: syncApiTokenPermissionsForRole,\n deleteTokensForUser: deleteAdminTokensForUser,\n };\n return svc;\n}\n\nexport type { GetByOptions };\n\nexport {\n createTokenService,\n create,\n count,\n regenerate,\n exists,\n checkSaltIsDefined,\n hash,\n list,\n revoke,\n getById,\n update,\n getByName,\n getBy,\n assignAdminPermissionsToToken,\n enforceAdminPermissionsCeiling,\n reconcileTokenPermissionsToUserCeiling,\n syncApiTokenPermissionsForUser,\n syncApiTokenPermissionsForRole,\n deleteAdminTokensForUser,\n};\n"],"names":["SUPER_ADMIN_CODE","constants","ValidationError","NotFoundError","errors","assertOwnerMatchesCallingUser","adminUserOwner","callingUser","undefined","ownerId","String","callingUserId","id","existingUser","strapi","db","query","findOne","select","where","isSuperAdmin","user","roles","some","r","code","getOwnerId","token","owner","toAdminTokenOwner","Error","firstname","lastname","username","email","SELECT_FIELDS","POPULATE_FIELDS","assertCustomTokenPermissionsValidity","type","permissions","API_TOKEN_TYPE","CUSTOM","isEmpty","isArray","validPermissions","contentAPI","providers","action","keys","invalidPermissions","difference","join","isValidLifespan","lifespan","isNil","isNumber","Object","values","API_TOKEN_LIFESPANS","includes","assertValidLifespan","assertLegacyKindFields","attributes","raw","adminPermissions","assertAdminKindFields","assertAdminPermissionsValidity","length","validActions","getService","actionProvider","perm","validatePermissionsExist","enforceAdminPermissionsCeiling","requestedPermissions","conditionProvider","sanitize","permissionDomain","sanitizeConditions","map","sanitized","actionParameters","conditions","userPermissions","findUserPermissions","exceeding","clamped","requested","requestedSubject","subject","matchingUserPerms","filter","userPerm","userSubject","label","push","anyUserPermHasAllFields","p","properties","fields","requestedFields","effectiveUserFields","uniq","flatMap","exceedingFields","f","anyUserPermIsUnconditional","enforcedConditions","createApiTokenAdminPermissions","tokenId","permissionsWithToken","permAsPermission","create","apiToken","role","createdPermissions","createMany","COMPARABLE_FIELDS","pickComparableFields","pick","jsonClean","data","JSON","parse","stringify","arePermissionsEqual","p1","p2","isEqual","assignAdminPermissionsToToken","ceilingUser","clampedPermissions","existingPermissions","findMany","permissionsToAdd","differenceWith","permissionsToDelete","deleteByIds","prop","allCurrentPermissions","reconcileTokenPermissionsToUserCeiling","tokenPermissions","toDelete","toUpdate","forEach","tokenPerm","tokenSubject","tokenFields","fieldCeilingExceeded","currentConditions","conditionsChanged","c","syncApiTokenPermissionsForUser","userId","populate","userEffectivePermissions","tokens","kind","tokensWithPermissions","Array","update","syncApiTokenPermissionsForRole","roleId","users","Promise","allSettled","flattenTokenPermissions","getBy","whereParams","options","includeDecryptedKey","selectFields","computedKind","result","omit","assign","encryptedKey","accessKey","decrypt","exists","hash","apiTokenCfg","config","get","salt","crypto","createHmac","digest","getExpirationFields","isValidNumber","Number","isFinite","expiresAt","Date","now","encryptionService","randomBytes","toString","encrypt","castedContentApiApiTokenBody","all","currentPermissions","load","castedAdminTokenBody","clampedAdminPermissions","currentAdminPermissions","regenerate","checkSaltIsDefined","process","env","API_TOKEN_SALT","emitWarning","set","list","ownershipWhere","$or","kindWhere","$null","orderBy","name","revoke","permissionIds","permId","deletedToken","delete","originalToken","tokenOwnerUser","incomingType","incomingPermissions","resolvedType","changingTypeToCustom","incomingAdminPermissions","resolvedOwner","incomingAdminUserOwner","existingOwner","existingOwnerId","requestedOwnerId","updatedToken","currentPermissionsResult","newPermissions","actionsToDelete","actionsToAdd","permissionsFromDb","adminPermissionsFromDb","adminUserOwnerFromDb","count","deleteAdminTokensForUser","createTokenService","shared","getByAccessKey","accessKeyHash","countAll","svc","getById","$and","getByName","syncPermissionsForUser","syncPermissionsForRole","deleteTokensForUser"],"mappings":"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"}
|