@strapi/admin 5.43.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/StrapiApp.js +17 -4
- package/dist/admin/admin/src/StrapiApp.js.map +1 -1
- package/dist/admin/admin/src/StrapiApp.mjs +18 -5
- package/dist/admin/admin/src/StrapiApp.mjs.map +1 -1
- package/dist/admin/admin/src/components/Form.js +18 -8
- package/dist/admin/admin/src/components/Form.js.map +1 -1
- package/dist/admin/admin/src/components/Form.mjs +18 -8
- package/dist/admin/admin/src/components/Form.mjs.map +1 -1
- package/dist/admin/admin/src/components/Layouts/Layout.js +1 -0
- package/dist/admin/admin/src/components/Layouts/Layout.js.map +1 -1
- package/dist/admin/admin/src/components/Layouts/Layout.mjs +1 -0
- package/dist/admin/admin/src/components/Layouts/Layout.mjs.map +1 -1
- 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/components/Widgets.js +52 -0
- package/dist/admin/admin/src/components/Widgets.js.map +1 -1
- package/dist/admin/admin/src/components/Widgets.mjs +54 -3
- package/dist/admin/admin/src/components/Widgets.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/ar.json.js +4 -1
- package/dist/admin/admin/src/translations/ar.json.js.map +1 -1
- package/dist/admin/admin/src/translations/ar.json.mjs +4 -1
- package/dist/admin/admin/src/translations/ar.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/cs.json.js +736 -13
- package/dist/admin/admin/src/translations/cs.json.js.map +1 -1
- package/dist/admin/admin/src/translations/cs.json.mjs +728 -14
- package/dist/admin/admin/src/translations/cs.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/de.json.js +4 -1
- package/dist/admin/admin/src/translations/de.json.js.map +1 -1
- package/dist/admin/admin/src/translations/de.json.mjs +4 -1
- package/dist/admin/admin/src/translations/de.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/en.json.js +20 -2
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +20 -2
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/es.json.js +4 -1
- package/dist/admin/admin/src/translations/es.json.js.map +1 -1
- package/dist/admin/admin/src/translations/es.json.mjs +4 -1
- package/dist/admin/admin/src/translations/es.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/fr.json.js +4 -1
- package/dist/admin/admin/src/translations/fr.json.js.map +1 -1
- package/dist/admin/admin/src/translations/fr.json.mjs +4 -1
- package/dist/admin/admin/src/translations/fr.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/it.json.js +4 -1
- package/dist/admin/admin/src/translations/it.json.js.map +1 -1
- package/dist/admin/admin/src/translations/it.json.mjs +4 -1
- package/dist/admin/admin/src/translations/it.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/ru.json.js +32 -19
- package/dist/admin/admin/src/translations/ru.json.js.map +1 -1
- package/dist/admin/admin/src/translations/ru.json.mjs +32 -19
- package/dist/admin/admin/src/translations/ru.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/zh-Hans.json.js +4 -1
- package/dist/admin/admin/src/translations/zh-Hans.json.js.map +1 -1
- package/dist/admin/admin/src/translations/zh-Hans.json.mjs +4 -1
- package/dist/admin/admin/src/translations/zh-Hans.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js +33 -4
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs +33 -4
- 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/components/Widgets.d.ts +2 -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/admin/src/utils/getFetchClient.d.ts +14 -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 +10 -10
- 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.mjs","sources":["../../../../../server/src/content-types/api-token.ts"],"sourcesContent":["import constants from '../services/constants';\n\nexport default {\n collectionName: 'strapi_api_tokens',\n info: {\n name: 'Api Token',\n singularName: 'api-token',\n pluralName: 'api-tokens',\n displayName: 'Api Token',\n description: '',\n },\n options: {},\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n name: {\n type: 'string',\n minLength: 1,\n configurable: false,\n required: true,\n unique: true,\n },\n description: {\n type: 'string',\n minLength: 1,\n configurable: false,\n required: false,\n default: '',\n },\n type: {\n type: 'enumeration',\n enum: Object.values(constants.API_TOKEN_TYPE),\n configurable: false,\n required:
|
|
1
|
+
{"version":3,"file":"api-token.mjs","sources":["../../../../../server/src/content-types/api-token.ts"],"sourcesContent":["import constants from '../services/constants';\n\nexport default {\n collectionName: 'strapi_api_tokens',\n info: {\n name: 'Api Token',\n singularName: 'api-token',\n pluralName: 'api-tokens',\n displayName: 'Api Token',\n description: '',\n },\n options: {},\n pluginOptions: {\n 'content-manager': {\n visible: false,\n },\n 'content-type-builder': {\n visible: false,\n },\n },\n attributes: {\n name: {\n type: 'string',\n minLength: 1,\n configurable: false,\n required: true,\n unique: true,\n },\n description: {\n type: 'string',\n minLength: 1,\n configurable: false,\n required: false,\n default: '',\n },\n kind: {\n type: 'enumeration',\n enum: ['content-api', 'admin'],\n configurable: false,\n required: true,\n default: 'content-api',\n },\n type: {\n type: 'enumeration',\n enum: Object.values(constants.API_TOKEN_TYPE),\n configurable: false,\n required: false,\n default: constants.API_TOKEN_TYPE.READ_ONLY,\n },\n accessKey: {\n type: 'string',\n minLength: 1,\n configurable: false,\n required: true,\n searchable: false,\n },\n encryptedKey: {\n type: 'text',\n minLength: 1,\n configurable: false,\n required: false,\n searchable: false,\n },\n lastUsedAt: {\n type: 'datetime',\n configurable: false,\n required: false,\n },\n permissions: {\n type: 'relation',\n target: 'admin::api-token-permission',\n relation: 'oneToMany',\n mappedBy: 'token',\n configurable: false,\n required: false,\n },\n adminPermissions: {\n type: 'relation',\n target: 'admin::permission',\n relation: 'oneToMany',\n mappedBy: 'apiToken',\n configurable: false,\n required: false,\n },\n adminUserOwner: {\n type: 'relation',\n target: 'admin::user',\n relation: 'manyToOne',\n inversedBy: 'apiTokens',\n configurable: false,\n required: false,\n },\n expiresAt: {\n type: 'datetime',\n configurable: false,\n required: false,\n },\n lifespan: {\n type: 'biginteger',\n configurable: false,\n required: false,\n },\n },\n};\n"],"names":["collectionName","info","name","singularName","pluralName","displayName","description","options","pluginOptions","visible","attributes","type","minLength","configurable","required","unique","default","kind","enum","Object","values","constants","API_TOKEN_TYPE","READ_ONLY","accessKey","searchable","encryptedKey","lastUsedAt","permissions","target","relation","mappedBy","adminPermissions","adminUserOwner","inversedBy","expiresAt","lifespan"],"mappings":";;AAEA,eAAe;IACbA,cAAAA,EAAgB,mBAAA;IAChBC,IAAAA,EAAM;QACJC,IAAAA,EAAM,WAAA;QACNC,YAAAA,EAAc,WAAA;QACdC,UAAAA,EAAY,YAAA;QACZC,WAAAA,EAAa,WAAA;QACbC,WAAAA,EAAa;AACf,KAAA;AACAC,IAAAA,OAAAA,EAAS,EAAC;IACVC,aAAAA,EAAe;QACb,iBAAA,EAAmB;YACjBC,OAAAA,EAAS;AACX,SAAA;QACA,sBAAA,EAAwB;YACtBA,OAAAA,EAAS;AACX;AACF,KAAA;IACAC,UAAAA,EAAY;QACVR,IAAAA,EAAM;YACJS,IAAAA,EAAM,QAAA;YACNC,SAAAA,EAAW,CAAA;YACXC,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU,IAAA;YACVC,MAAAA,EAAQ;AACV,SAAA;QACAT,WAAAA,EAAa;YACXK,IAAAA,EAAM,QAAA;YACNC,SAAAA,EAAW,CAAA;YACXC,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU,KAAA;YACVE,OAAAA,EAAS;AACX,SAAA;QACAC,IAAAA,EAAM;YACJN,IAAAA,EAAM,aAAA;YACNO,IAAAA,EAAM;AAAC,gBAAA,aAAA;AAAe,gBAAA;AAAQ,aAAA;YAC9BL,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU,IAAA;YACVE,OAAAA,EAAS;AACX,SAAA;QACAL,IAAAA,EAAM;YACJA,IAAAA,EAAM,aAAA;AACNO,YAAAA,IAAAA,EAAMC,MAAAA,CAAOC,MAAM,CAACC,SAAAA,CAAUC,cAAc,CAAA;YAC5CT,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU,KAAA;YACVE,OAAAA,EAASK,SAAAA,CAAUC,cAAc,CAACC;AACpC,SAAA;QACAC,SAAAA,EAAW;YACTb,IAAAA,EAAM,QAAA;YACNC,SAAAA,EAAW,CAAA;YACXC,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU,IAAA;YACVW,UAAAA,EAAY;AACd,SAAA;QACAC,YAAAA,EAAc;YACZf,IAAAA,EAAM,MAAA;YACNC,SAAAA,EAAW,CAAA;YACXC,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU,KAAA;YACVW,UAAAA,EAAY;AACd,SAAA;QACAE,UAAAA,EAAY;YACVhB,IAAAA,EAAM,UAAA;YACNE,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU;AACZ,SAAA;QACAc,WAAAA,EAAa;YACXjB,IAAAA,EAAM,UAAA;YACNkB,MAAAA,EAAQ,6BAAA;YACRC,QAAAA,EAAU,WAAA;YACVC,QAAAA,EAAU,OAAA;YACVlB,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU;AACZ,SAAA;QACAkB,gBAAAA,EAAkB;YAChBrB,IAAAA,EAAM,UAAA;YACNkB,MAAAA,EAAQ,mBAAA;YACRC,QAAAA,EAAU,WAAA;YACVC,QAAAA,EAAU,UAAA;YACVlB,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU;AACZ,SAAA;QACAmB,cAAAA,EAAgB;YACdtB,IAAAA,EAAM,UAAA;YACNkB,MAAAA,EAAQ,aAAA;YACRC,QAAAA,EAAU,WAAA;YACVI,UAAAA,EAAY,WAAA;YACZrB,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU;AACZ,SAAA;QACAqB,SAAAA,EAAW;YACTxB,IAAAA,EAAM,UAAA;YACNE,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU;AACZ,SAAA;QACAsB,QAAAA,EAAU;YACRzB,IAAAA,EAAM,YAAA;YACNE,YAAAA,EAAc,KAAA;YACdC,QAAAA,EAAU;AACZ;AACF;AACF,CAAA;;;;"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('@strapi/utils');
|
|
4
|
+
var fp = require('lodash/fp');
|
|
5
|
+
var index = require('../utils/index.js');
|
|
6
|
+
var constants = require('../services/constants.js');
|
|
7
|
+
var adminTokens = require('../validation/admin-tokens.js');
|
|
8
|
+
|
|
9
|
+
const { ApplicationError } = utils.errors;
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Access-control helpers
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
const isSuperAdmin = (user)=>user.roles.some((r)=>r.code === constants.SUPER_ADMIN_CODE) === true;
|
|
14
|
+
const getOwnerId = (token)=>{
|
|
15
|
+
const owner = token.adminUserOwner;
|
|
16
|
+
return String(typeof owner === 'object' ? owner.id : owner);
|
|
17
|
+
};
|
|
18
|
+
/** Returns true when user is the recorded owner of an admin token. */ const isTokenOwner = (user, token)=>getOwnerId(token) === String(user.id);
|
|
19
|
+
/** Owner OR super-admin can manage an admin token (read metadata, update…). */ const canAccessAdminToken = (user, token)=>isTokenOwner(user, token) || isSuperAdmin(user);
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Controller
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
var adminToken = {
|
|
24
|
+
// -------------------------------------------------------------------------
|
|
25
|
+
// Create
|
|
26
|
+
// -------------------------------------------------------------------------
|
|
27
|
+
async create (ctx) {
|
|
28
|
+
const { body } = ctx.request;
|
|
29
|
+
const apiTokenService = index.getService('api-token-admin');
|
|
30
|
+
if (body.type !== undefined) {
|
|
31
|
+
return ctx.badRequest('Type is not allowed for admin tokens');
|
|
32
|
+
}
|
|
33
|
+
if (body.permissions !== undefined) {
|
|
34
|
+
return ctx.badRequest('Permissions are not allowed for admin tokens');
|
|
35
|
+
}
|
|
36
|
+
const attributes = {
|
|
37
|
+
kind: 'admin',
|
|
38
|
+
name: fp.trim(body.name),
|
|
39
|
+
description: fp.trim(body.description),
|
|
40
|
+
adminPermissions: body.adminPermissions,
|
|
41
|
+
lifespan: body.lifespan,
|
|
42
|
+
adminUserOwner: ctx.state.user.id
|
|
43
|
+
};
|
|
44
|
+
await adminTokens.validateAdminTokenCreationInput(attributes);
|
|
45
|
+
const alreadyExists = await apiTokenService.exists({
|
|
46
|
+
name: attributes.name
|
|
47
|
+
});
|
|
48
|
+
if (alreadyExists) {
|
|
49
|
+
throw new ApplicationError('Name already taken');
|
|
50
|
+
}
|
|
51
|
+
const apiToken = await apiTokenService.create(attributes, ctx.state.user);
|
|
52
|
+
ctx.created({
|
|
53
|
+
data: apiToken
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
// -------------------------------------------------------------------------
|
|
57
|
+
// Regenerate — owner-only, super-admin does NOT bypass
|
|
58
|
+
// -------------------------------------------------------------------------
|
|
59
|
+
async regenerate (ctx) {
|
|
60
|
+
const { id } = ctx.params;
|
|
61
|
+
const apiTokenService = index.getService('api-token-admin');
|
|
62
|
+
const token = await apiTokenService.getById(id);
|
|
63
|
+
if (!token) {
|
|
64
|
+
ctx.notFound('API Token not found');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (!isTokenOwner(ctx.state.user, token)) {
|
|
68
|
+
return ctx.forbidden();
|
|
69
|
+
}
|
|
70
|
+
const accessToken = await apiTokenService.regenerate(id);
|
|
71
|
+
ctx.created({
|
|
72
|
+
data: accessToken
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
// -------------------------------------------------------------------------
|
|
76
|
+
// List — always filtered to kind: 'admin'
|
|
77
|
+
// -------------------------------------------------------------------------
|
|
78
|
+
async list (ctx) {
|
|
79
|
+
const apiTokenService = index.getService('api-token-admin');
|
|
80
|
+
const apiTokens = await apiTokenService.list(ctx.state.user);
|
|
81
|
+
ctx.send({
|
|
82
|
+
data: apiTokens
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
// -------------------------------------------------------------------------
|
|
86
|
+
// Revoke
|
|
87
|
+
// -------------------------------------------------------------------------
|
|
88
|
+
async revoke (ctx) {
|
|
89
|
+
const { id } = ctx.params;
|
|
90
|
+
const apiTokenService = index.getService('api-token-admin');
|
|
91
|
+
const existingToken = await apiTokenService.getById(id);
|
|
92
|
+
if (existingToken === null) {
|
|
93
|
+
return ctx.notFound('API Token not found');
|
|
94
|
+
}
|
|
95
|
+
if (canAccessAdminToken(ctx.state.user, existingToken) === false) {
|
|
96
|
+
return ctx.forbidden();
|
|
97
|
+
}
|
|
98
|
+
const apiToken = await apiTokenService.revoke(id);
|
|
99
|
+
ctx.deleted({
|
|
100
|
+
data: apiToken
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
// -------------------------------------------------------------------------
|
|
104
|
+
// Get — key exposed only to owner
|
|
105
|
+
// -------------------------------------------------------------------------
|
|
106
|
+
async get (ctx) {
|
|
107
|
+
const { id } = ctx.params;
|
|
108
|
+
const apiTokenService = index.getService('api-token-admin');
|
|
109
|
+
const token = await apiTokenService.getById(id);
|
|
110
|
+
if (!token) {
|
|
111
|
+
ctx.notFound('API Token not found');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (canAccessAdminToken(ctx.state.user, token) === false) {
|
|
115
|
+
ctx.notFound('API Token not found');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (isTokenOwner(ctx.state.user, token)) {
|
|
119
|
+
const withKey = await apiTokenService.getById(id, {
|
|
120
|
+
includeDecryptedKey: true
|
|
121
|
+
});
|
|
122
|
+
ctx.send({
|
|
123
|
+
data: withKey ?? token
|
|
124
|
+
});
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
ctx.send({
|
|
128
|
+
data: token
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
// -------------------------------------------------------------------------
|
|
132
|
+
// Update — owner or super-admin only
|
|
133
|
+
// -------------------------------------------------------------------------
|
|
134
|
+
async update (ctx) {
|
|
135
|
+
const { body } = ctx.request;
|
|
136
|
+
const { id } = ctx.params;
|
|
137
|
+
const apiTokenService = index.getService('api-token-admin');
|
|
138
|
+
const mutableBody = body;
|
|
139
|
+
if (fp.has('name', mutableBody)) {
|
|
140
|
+
mutableBody.name = fp.trim(body.name ?? '');
|
|
141
|
+
}
|
|
142
|
+
if (fp.has('description', mutableBody) || mutableBody.description === null) {
|
|
143
|
+
mutableBody.description = fp.trim(body.description ?? '');
|
|
144
|
+
}
|
|
145
|
+
await adminTokens.validateAdminTokenUpdateInput(body);
|
|
146
|
+
const existingToken = await apiTokenService.getById(id);
|
|
147
|
+
if (!existingToken) {
|
|
148
|
+
return ctx.notFound('API Token not found');
|
|
149
|
+
}
|
|
150
|
+
if (fp.has('name', body)) {
|
|
151
|
+
const nameAlreadyTaken = await apiTokenService.getByName(body.name);
|
|
152
|
+
if (nameAlreadyTaken !== null && !utils.strings.isEqual(nameAlreadyTaken.id, id)) {
|
|
153
|
+
throw new ApplicationError('Name already taken');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (!canAccessAdminToken(ctx.state.user, existingToken)) {
|
|
157
|
+
return ctx.forbidden();
|
|
158
|
+
}
|
|
159
|
+
const apiToken = await apiTokenService.update(id, body);
|
|
160
|
+
ctx.send({
|
|
161
|
+
data: apiToken
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
// -------------------------------------------------------------------------
|
|
165
|
+
// Owner permissions — effective permissions of the token owner
|
|
166
|
+
// -------------------------------------------------------------------------
|
|
167
|
+
async getOwnerPermissions (ctx) {
|
|
168
|
+
const { id } = ctx.params;
|
|
169
|
+
const apiTokenService = index.getService('api-token-admin');
|
|
170
|
+
const permissionService = index.getService('permission');
|
|
171
|
+
const userService = index.getService('user');
|
|
172
|
+
const token = await apiTokenService.getById(id);
|
|
173
|
+
if (!token) {
|
|
174
|
+
return ctx.notFound('apiToken.notFound');
|
|
175
|
+
}
|
|
176
|
+
if (!canAccessAdminToken(ctx.state.user, token)) {
|
|
177
|
+
return ctx.forbidden();
|
|
178
|
+
}
|
|
179
|
+
const ownerId = getOwnerId(token);
|
|
180
|
+
const ownerUser = await userService.findOne(ownerId);
|
|
181
|
+
if (!ownerUser) {
|
|
182
|
+
return ctx.notFound('owner.notFound');
|
|
183
|
+
}
|
|
184
|
+
const ownerPermissions = await permissionService.findUserPermissions(ownerUser);
|
|
185
|
+
const sanitizedPermissions = ownerPermissions.map(permissionService.sanitizePermission);
|
|
186
|
+
// @ts-expect-error - transform response type to sanitized permission
|
|
187
|
+
ctx.body = {
|
|
188
|
+
data: sanitizedPermissions
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
module.exports = adminToken;
|
|
194
|
+
//# sourceMappingURL=admin-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-token.js","sources":["../../../../../server/src/controllers/admin-token.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport { strings, errors } from '@strapi/utils';\nimport { trim, has } from 'lodash/fp';\nimport { getService } from '../utils';\nimport constants from '../services/constants';\nimport {\n validateAdminTokenCreationInput,\n validateAdminTokenUpdateInput,\n} from '../validation/admin-tokens';\nimport {\n Create,\n List,\n Revoke,\n Get,\n Update,\n GetOwnerPermissions,\n AdminApiToken,\n} from '../../../shared/contracts/admin-token';\nimport type { ContentApiApiToken } from '../../../shared/contracts/api-token';\nimport type { AdminUser } from '../../../shared/contracts/shared';\n\nconst { ApplicationError } = errors;\n\n// ---------------------------------------------------------------------------\n// Access-control helpers\n// ---------------------------------------------------------------------------\n\nconst isSuperAdmin = (user: AdminUser): boolean =>\n user.roles.some((r) => r.code === constants.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\n/** Returns true when user is the recorded owner of an admin token. */\nconst isTokenOwner = (user: AdminUser, token: AdminApiToken): boolean =>\n getOwnerId(token) === String(user.id);\n\n/** Owner OR super-admin can manage an admin token (read metadata, update…). */\nconst canAccessAdminToken = (user: AdminUser, token: AdminApiToken): boolean =>\n isTokenOwner(user, token) || isSuperAdmin(user);\n\n// ---------------------------------------------------------------------------\n// Controller\n// ---------------------------------------------------------------------------\n\nexport default {\n // -------------------------------------------------------------------------\n // Create\n // -------------------------------------------------------------------------\n async create(ctx: Context) {\n const { body } = ctx.request as Create.Request;\n const apiTokenService = getService('api-token-admin');\n\n if ((body as ContentApiApiToken).type !== undefined) {\n return ctx.badRequest('Type is not allowed for admin tokens');\n }\n if ((body as ContentApiApiToken).permissions !== undefined) {\n return ctx.badRequest('Permissions are not allowed for admin tokens');\n }\n\n const attributes = {\n kind: 'admin' as const,\n name: trim(body.name),\n description: trim(body.description),\n adminPermissions: body.adminPermissions,\n lifespan: body.lifespan,\n adminUserOwner: ctx.state.user.id,\n };\n\n await validateAdminTokenCreationInput(attributes);\n\n const alreadyExists = await apiTokenService.exists({ name: attributes.name });\n if (alreadyExists) {\n throw new ApplicationError('Name already taken');\n }\n\n const apiToken = await apiTokenService.create(attributes, ctx.state.user);\n ctx.created({ data: apiToken });\n },\n\n // -------------------------------------------------------------------------\n // Regenerate — owner-only, super-admin does NOT bypass\n // -------------------------------------------------------------------------\n async regenerate(ctx: Context) {\n const { id } = ctx.params;\n const apiTokenService = getService('api-token-admin');\n\n const token = await apiTokenService.getById(id);\n if (!token) {\n ctx.notFound('API Token not found');\n return;\n }\n\n if (!isTokenOwner(ctx.state.user, token)) {\n return ctx.forbidden();\n }\n\n const accessToken = await apiTokenService.regenerate(id);\n ctx.created({ data: accessToken });\n },\n\n // -------------------------------------------------------------------------\n // List — always filtered to kind: 'admin'\n // -------------------------------------------------------------------------\n async list(ctx: Context) {\n const apiTokenService = getService('api-token-admin');\n const apiTokens = await apiTokenService.list(ctx.state.user);\n\n ctx.send({ data: apiTokens } satisfies List.Response);\n },\n\n // -------------------------------------------------------------------------\n // Revoke\n // -------------------------------------------------------------------------\n async revoke(ctx: Context) {\n const { id } = ctx.params as Revoke.Params;\n const apiTokenService = getService('api-token-admin');\n\n const existingToken = await apiTokenService.getById(id);\n if (existingToken === null) {\n return ctx.notFound('API Token not found');\n }\n\n if (canAccessAdminToken(ctx.state.user, existingToken) === false) {\n return ctx.forbidden();\n }\n\n const apiToken = await apiTokenService.revoke(id);\n ctx.deleted({ data: apiToken } satisfies Revoke.Response);\n },\n\n // -------------------------------------------------------------------------\n // Get — key exposed only to owner\n // -------------------------------------------------------------------------\n async get(ctx: Context) {\n const { id } = ctx.params;\n const apiTokenService = getService('api-token-admin');\n\n const token = await apiTokenService.getById(id);\n if (!token) {\n ctx.notFound('API Token not found');\n return;\n }\n\n if (canAccessAdminToken(ctx.state.user, token) === false) {\n ctx.notFound('API Token not found');\n return;\n }\n\n if (isTokenOwner(ctx.state.user, token)) {\n const withKey = await apiTokenService.getById(id, { includeDecryptedKey: true });\n ctx.send({ data: withKey ?? token } satisfies Get.Response);\n return;\n }\n\n ctx.send({ data: token } satisfies Get.Response);\n },\n\n // -------------------------------------------------------------------------\n // Update — owner or super-admin only\n // -------------------------------------------------------------------------\n async update(ctx: Context) {\n const { body } = ctx.request as Update.Request;\n const { id } = ctx.params as Update.Params;\n const apiTokenService = getService('api-token-admin');\n\n const mutableBody = body as Record<string, unknown>;\n if (has('name', mutableBody)) {\n mutableBody.name = trim(body.name ?? '');\n }\n if (has('description', mutableBody) || mutableBody.description === null) {\n mutableBody.description = trim(body.description ?? '');\n }\n\n await validateAdminTokenUpdateInput(body);\n\n const existingToken = await apiTokenService.getById(id);\n if (!existingToken) {\n return ctx.notFound('API Token not found');\n }\n\n if (has('name', body)) {\n const nameAlreadyTaken = await apiTokenService.getByName(body.name!);\n if (nameAlreadyTaken !== null && !strings.isEqual(nameAlreadyTaken.id, id)) {\n throw new ApplicationError('Name already taken');\n }\n }\n\n if (!canAccessAdminToken(ctx.state.user, existingToken)) {\n return ctx.forbidden();\n }\n\n const apiToken = await apiTokenService.update(id, body);\n ctx.send({ data: apiToken } satisfies Update.Response);\n },\n\n // -------------------------------------------------------------------------\n // Owner permissions — effective permissions of the token owner\n // -------------------------------------------------------------------------\n async getOwnerPermissions(ctx: Context) {\n const { id } = ctx.params as GetOwnerPermissions.Request['params'];\n const apiTokenService = getService('api-token-admin');\n const permissionService = getService('permission');\n const userService = getService('user');\n\n const token = await apiTokenService.getById(id);\n if (!token) {\n return ctx.notFound('apiToken.notFound');\n }\n\n if (!canAccessAdminToken(ctx.state.user, token)) {\n return ctx.forbidden();\n }\n\n const ownerId = getOwnerId(token);\n const ownerUser = await userService.findOne(ownerId);\n if (!ownerUser) {\n return ctx.notFound('owner.notFound');\n }\n\n const ownerPermissions = await permissionService.findUserPermissions(ownerUser);\n const sanitizedPermissions = ownerPermissions.map(permissionService.sanitizePermission);\n\n // @ts-expect-error - transform response type to sanitized permission\n ctx.body = { data: sanitizedPermissions } satisfies GetOwnerPermissions.Response;\n },\n};\n"],"names":["ApplicationError","errors","isSuperAdmin","user","roles","some","r","code","constants","SUPER_ADMIN_CODE","getOwnerId","token","owner","adminUserOwner","String","id","isTokenOwner","canAccessAdminToken","create","ctx","body","request","apiTokenService","getService","type","undefined","badRequest","permissions","attributes","kind","name","trim","description","adminPermissions","lifespan","state","validateAdminTokenCreationInput","alreadyExists","exists","apiToken","created","data","regenerate","params","getById","notFound","forbidden","accessToken","list","apiTokens","send","revoke","existingToken","deleted","get","withKey","includeDecryptedKey","update","mutableBody","has","validateAdminTokenUpdateInput","nameAlreadyTaken","getByName","strings","isEqual","getOwnerPermissions","permissionService","userService","ownerId","ownerUser","findOne","ownerPermissions","findUserPermissions","sanitizedPermissions","map","sanitizePermission"],"mappings":"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"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { errors, strings } from '@strapi/utils';
|
|
2
|
+
import { has, trim } from 'lodash/fp';
|
|
3
|
+
import { getService } from '../utils/index.mjs';
|
|
4
|
+
import constants from '../services/constants.mjs';
|
|
5
|
+
import { validateAdminTokenUpdateInput, validateAdminTokenCreationInput } from '../validation/admin-tokens.mjs';
|
|
6
|
+
|
|
7
|
+
const { ApplicationError } = errors;
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Access-control helpers
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
const isSuperAdmin = (user)=>user.roles.some((r)=>r.code === constants.SUPER_ADMIN_CODE) === true;
|
|
12
|
+
const getOwnerId = (token)=>{
|
|
13
|
+
const owner = token.adminUserOwner;
|
|
14
|
+
return String(typeof owner === 'object' ? owner.id : owner);
|
|
15
|
+
};
|
|
16
|
+
/** Returns true when user is the recorded owner of an admin token. */ const isTokenOwner = (user, token)=>getOwnerId(token) === String(user.id);
|
|
17
|
+
/** Owner OR super-admin can manage an admin token (read metadata, update…). */ const canAccessAdminToken = (user, token)=>isTokenOwner(user, token) || isSuperAdmin(user);
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Controller
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
var adminToken = {
|
|
22
|
+
// -------------------------------------------------------------------------
|
|
23
|
+
// Create
|
|
24
|
+
// -------------------------------------------------------------------------
|
|
25
|
+
async create (ctx) {
|
|
26
|
+
const { body } = ctx.request;
|
|
27
|
+
const apiTokenService = getService('api-token-admin');
|
|
28
|
+
if (body.type !== undefined) {
|
|
29
|
+
return ctx.badRequest('Type is not allowed for admin tokens');
|
|
30
|
+
}
|
|
31
|
+
if (body.permissions !== undefined) {
|
|
32
|
+
return ctx.badRequest('Permissions are not allowed for admin tokens');
|
|
33
|
+
}
|
|
34
|
+
const attributes = {
|
|
35
|
+
kind: 'admin',
|
|
36
|
+
name: trim(body.name),
|
|
37
|
+
description: trim(body.description),
|
|
38
|
+
adminPermissions: body.adminPermissions,
|
|
39
|
+
lifespan: body.lifespan,
|
|
40
|
+
adminUserOwner: ctx.state.user.id
|
|
41
|
+
};
|
|
42
|
+
await validateAdminTokenCreationInput(attributes);
|
|
43
|
+
const alreadyExists = await apiTokenService.exists({
|
|
44
|
+
name: attributes.name
|
|
45
|
+
});
|
|
46
|
+
if (alreadyExists) {
|
|
47
|
+
throw new ApplicationError('Name already taken');
|
|
48
|
+
}
|
|
49
|
+
const apiToken = await apiTokenService.create(attributes, ctx.state.user);
|
|
50
|
+
ctx.created({
|
|
51
|
+
data: apiToken
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
// -------------------------------------------------------------------------
|
|
55
|
+
// Regenerate — owner-only, super-admin does NOT bypass
|
|
56
|
+
// -------------------------------------------------------------------------
|
|
57
|
+
async regenerate (ctx) {
|
|
58
|
+
const { id } = ctx.params;
|
|
59
|
+
const apiTokenService = getService('api-token-admin');
|
|
60
|
+
const token = await apiTokenService.getById(id);
|
|
61
|
+
if (!token) {
|
|
62
|
+
ctx.notFound('API Token not found');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (!isTokenOwner(ctx.state.user, token)) {
|
|
66
|
+
return ctx.forbidden();
|
|
67
|
+
}
|
|
68
|
+
const accessToken = await apiTokenService.regenerate(id);
|
|
69
|
+
ctx.created({
|
|
70
|
+
data: accessToken
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
// -------------------------------------------------------------------------
|
|
74
|
+
// List — always filtered to kind: 'admin'
|
|
75
|
+
// -------------------------------------------------------------------------
|
|
76
|
+
async list (ctx) {
|
|
77
|
+
const apiTokenService = getService('api-token-admin');
|
|
78
|
+
const apiTokens = await apiTokenService.list(ctx.state.user);
|
|
79
|
+
ctx.send({
|
|
80
|
+
data: apiTokens
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
// -------------------------------------------------------------------------
|
|
84
|
+
// Revoke
|
|
85
|
+
// -------------------------------------------------------------------------
|
|
86
|
+
async revoke (ctx) {
|
|
87
|
+
const { id } = ctx.params;
|
|
88
|
+
const apiTokenService = getService('api-token-admin');
|
|
89
|
+
const existingToken = await apiTokenService.getById(id);
|
|
90
|
+
if (existingToken === null) {
|
|
91
|
+
return ctx.notFound('API Token not found');
|
|
92
|
+
}
|
|
93
|
+
if (canAccessAdminToken(ctx.state.user, existingToken) === false) {
|
|
94
|
+
return ctx.forbidden();
|
|
95
|
+
}
|
|
96
|
+
const apiToken = await apiTokenService.revoke(id);
|
|
97
|
+
ctx.deleted({
|
|
98
|
+
data: apiToken
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
// -------------------------------------------------------------------------
|
|
102
|
+
// Get — key exposed only to owner
|
|
103
|
+
// -------------------------------------------------------------------------
|
|
104
|
+
async get (ctx) {
|
|
105
|
+
const { id } = ctx.params;
|
|
106
|
+
const apiTokenService = getService('api-token-admin');
|
|
107
|
+
const token = await apiTokenService.getById(id);
|
|
108
|
+
if (!token) {
|
|
109
|
+
ctx.notFound('API Token not found');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (canAccessAdminToken(ctx.state.user, token) === false) {
|
|
113
|
+
ctx.notFound('API Token not found');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (isTokenOwner(ctx.state.user, token)) {
|
|
117
|
+
const withKey = await apiTokenService.getById(id, {
|
|
118
|
+
includeDecryptedKey: true
|
|
119
|
+
});
|
|
120
|
+
ctx.send({
|
|
121
|
+
data: withKey ?? token
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
ctx.send({
|
|
126
|
+
data: token
|
|
127
|
+
});
|
|
128
|
+
},
|
|
129
|
+
// -------------------------------------------------------------------------
|
|
130
|
+
// Update — owner or super-admin only
|
|
131
|
+
// -------------------------------------------------------------------------
|
|
132
|
+
async update (ctx) {
|
|
133
|
+
const { body } = ctx.request;
|
|
134
|
+
const { id } = ctx.params;
|
|
135
|
+
const apiTokenService = getService('api-token-admin');
|
|
136
|
+
const mutableBody = body;
|
|
137
|
+
if (has('name', mutableBody)) {
|
|
138
|
+
mutableBody.name = trim(body.name ?? '');
|
|
139
|
+
}
|
|
140
|
+
if (has('description', mutableBody) || mutableBody.description === null) {
|
|
141
|
+
mutableBody.description = trim(body.description ?? '');
|
|
142
|
+
}
|
|
143
|
+
await validateAdminTokenUpdateInput(body);
|
|
144
|
+
const existingToken = await apiTokenService.getById(id);
|
|
145
|
+
if (!existingToken) {
|
|
146
|
+
return ctx.notFound('API Token not found');
|
|
147
|
+
}
|
|
148
|
+
if (has('name', body)) {
|
|
149
|
+
const nameAlreadyTaken = await apiTokenService.getByName(body.name);
|
|
150
|
+
if (nameAlreadyTaken !== null && !strings.isEqual(nameAlreadyTaken.id, id)) {
|
|
151
|
+
throw new ApplicationError('Name already taken');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!canAccessAdminToken(ctx.state.user, existingToken)) {
|
|
155
|
+
return ctx.forbidden();
|
|
156
|
+
}
|
|
157
|
+
const apiToken = await apiTokenService.update(id, body);
|
|
158
|
+
ctx.send({
|
|
159
|
+
data: apiToken
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
// -------------------------------------------------------------------------
|
|
163
|
+
// Owner permissions — effective permissions of the token owner
|
|
164
|
+
// -------------------------------------------------------------------------
|
|
165
|
+
async getOwnerPermissions (ctx) {
|
|
166
|
+
const { id } = ctx.params;
|
|
167
|
+
const apiTokenService = getService('api-token-admin');
|
|
168
|
+
const permissionService = getService('permission');
|
|
169
|
+
const userService = getService('user');
|
|
170
|
+
const token = await apiTokenService.getById(id);
|
|
171
|
+
if (!token) {
|
|
172
|
+
return ctx.notFound('apiToken.notFound');
|
|
173
|
+
}
|
|
174
|
+
if (!canAccessAdminToken(ctx.state.user, token)) {
|
|
175
|
+
return ctx.forbidden();
|
|
176
|
+
}
|
|
177
|
+
const ownerId = getOwnerId(token);
|
|
178
|
+
const ownerUser = await userService.findOne(ownerId);
|
|
179
|
+
if (!ownerUser) {
|
|
180
|
+
return ctx.notFound('owner.notFound');
|
|
181
|
+
}
|
|
182
|
+
const ownerPermissions = await permissionService.findUserPermissions(ownerUser);
|
|
183
|
+
const sanitizedPermissions = ownerPermissions.map(permissionService.sanitizePermission);
|
|
184
|
+
// @ts-expect-error - transform response type to sanitized permission
|
|
185
|
+
ctx.body = {
|
|
186
|
+
data: sanitizedPermissions
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export { adminToken as default };
|
|
192
|
+
//# sourceMappingURL=admin-token.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-token.mjs","sources":["../../../../../server/src/controllers/admin-token.ts"],"sourcesContent":["import type { Context } from 'koa';\n\nimport { strings, errors } from '@strapi/utils';\nimport { trim, has } from 'lodash/fp';\nimport { getService } from '../utils';\nimport constants from '../services/constants';\nimport {\n validateAdminTokenCreationInput,\n validateAdminTokenUpdateInput,\n} from '../validation/admin-tokens';\nimport {\n Create,\n List,\n Revoke,\n Get,\n Update,\n GetOwnerPermissions,\n AdminApiToken,\n} from '../../../shared/contracts/admin-token';\nimport type { ContentApiApiToken } from '../../../shared/contracts/api-token';\nimport type { AdminUser } from '../../../shared/contracts/shared';\n\nconst { ApplicationError } = errors;\n\n// ---------------------------------------------------------------------------\n// Access-control helpers\n// ---------------------------------------------------------------------------\n\nconst isSuperAdmin = (user: AdminUser): boolean =>\n user.roles.some((r) => r.code === constants.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\n/** Returns true when user is the recorded owner of an admin token. */\nconst isTokenOwner = (user: AdminUser, token: AdminApiToken): boolean =>\n getOwnerId(token) === String(user.id);\n\n/** Owner OR super-admin can manage an admin token (read metadata, update…). */\nconst canAccessAdminToken = (user: AdminUser, token: AdminApiToken): boolean =>\n isTokenOwner(user, token) || isSuperAdmin(user);\n\n// ---------------------------------------------------------------------------\n// Controller\n// ---------------------------------------------------------------------------\n\nexport default {\n // -------------------------------------------------------------------------\n // Create\n // -------------------------------------------------------------------------\n async create(ctx: Context) {\n const { body } = ctx.request as Create.Request;\n const apiTokenService = getService('api-token-admin');\n\n if ((body as ContentApiApiToken).type !== undefined) {\n return ctx.badRequest('Type is not allowed for admin tokens');\n }\n if ((body as ContentApiApiToken).permissions !== undefined) {\n return ctx.badRequest('Permissions are not allowed for admin tokens');\n }\n\n const attributes = {\n kind: 'admin' as const,\n name: trim(body.name),\n description: trim(body.description),\n adminPermissions: body.adminPermissions,\n lifespan: body.lifespan,\n adminUserOwner: ctx.state.user.id,\n };\n\n await validateAdminTokenCreationInput(attributes);\n\n const alreadyExists = await apiTokenService.exists({ name: attributes.name });\n if (alreadyExists) {\n throw new ApplicationError('Name already taken');\n }\n\n const apiToken = await apiTokenService.create(attributes, ctx.state.user);\n ctx.created({ data: apiToken });\n },\n\n // -------------------------------------------------------------------------\n // Regenerate — owner-only, super-admin does NOT bypass\n // -------------------------------------------------------------------------\n async regenerate(ctx: Context) {\n const { id } = ctx.params;\n const apiTokenService = getService('api-token-admin');\n\n const token = await apiTokenService.getById(id);\n if (!token) {\n ctx.notFound('API Token not found');\n return;\n }\n\n if (!isTokenOwner(ctx.state.user, token)) {\n return ctx.forbidden();\n }\n\n const accessToken = await apiTokenService.regenerate(id);\n ctx.created({ data: accessToken });\n },\n\n // -------------------------------------------------------------------------\n // List — always filtered to kind: 'admin'\n // -------------------------------------------------------------------------\n async list(ctx: Context) {\n const apiTokenService = getService('api-token-admin');\n const apiTokens = await apiTokenService.list(ctx.state.user);\n\n ctx.send({ data: apiTokens } satisfies List.Response);\n },\n\n // -------------------------------------------------------------------------\n // Revoke\n // -------------------------------------------------------------------------\n async revoke(ctx: Context) {\n const { id } = ctx.params as Revoke.Params;\n const apiTokenService = getService('api-token-admin');\n\n const existingToken = await apiTokenService.getById(id);\n if (existingToken === null) {\n return ctx.notFound('API Token not found');\n }\n\n if (canAccessAdminToken(ctx.state.user, existingToken) === false) {\n return ctx.forbidden();\n }\n\n const apiToken = await apiTokenService.revoke(id);\n ctx.deleted({ data: apiToken } satisfies Revoke.Response);\n },\n\n // -------------------------------------------------------------------------\n // Get — key exposed only to owner\n // -------------------------------------------------------------------------\n async get(ctx: Context) {\n const { id } = ctx.params;\n const apiTokenService = getService('api-token-admin');\n\n const token = await apiTokenService.getById(id);\n if (!token) {\n ctx.notFound('API Token not found');\n return;\n }\n\n if (canAccessAdminToken(ctx.state.user, token) === false) {\n ctx.notFound('API Token not found');\n return;\n }\n\n if (isTokenOwner(ctx.state.user, token)) {\n const withKey = await apiTokenService.getById(id, { includeDecryptedKey: true });\n ctx.send({ data: withKey ?? token } satisfies Get.Response);\n return;\n }\n\n ctx.send({ data: token } satisfies Get.Response);\n },\n\n // -------------------------------------------------------------------------\n // Update — owner or super-admin only\n // -------------------------------------------------------------------------\n async update(ctx: Context) {\n const { body } = ctx.request as Update.Request;\n const { id } = ctx.params as Update.Params;\n const apiTokenService = getService('api-token-admin');\n\n const mutableBody = body as Record<string, unknown>;\n if (has('name', mutableBody)) {\n mutableBody.name = trim(body.name ?? '');\n }\n if (has('description', mutableBody) || mutableBody.description === null) {\n mutableBody.description = trim(body.description ?? '');\n }\n\n await validateAdminTokenUpdateInput(body);\n\n const existingToken = await apiTokenService.getById(id);\n if (!existingToken) {\n return ctx.notFound('API Token not found');\n }\n\n if (has('name', body)) {\n const nameAlreadyTaken = await apiTokenService.getByName(body.name!);\n if (nameAlreadyTaken !== null && !strings.isEqual(nameAlreadyTaken.id, id)) {\n throw new ApplicationError('Name already taken');\n }\n }\n\n if (!canAccessAdminToken(ctx.state.user, existingToken)) {\n return ctx.forbidden();\n }\n\n const apiToken = await apiTokenService.update(id, body);\n ctx.send({ data: apiToken } satisfies Update.Response);\n },\n\n // -------------------------------------------------------------------------\n // Owner permissions — effective permissions of the token owner\n // -------------------------------------------------------------------------\n async getOwnerPermissions(ctx: Context) {\n const { id } = ctx.params as GetOwnerPermissions.Request['params'];\n const apiTokenService = getService('api-token-admin');\n const permissionService = getService('permission');\n const userService = getService('user');\n\n const token = await apiTokenService.getById(id);\n if (!token) {\n return ctx.notFound('apiToken.notFound');\n }\n\n if (!canAccessAdminToken(ctx.state.user, token)) {\n return ctx.forbidden();\n }\n\n const ownerId = getOwnerId(token);\n const ownerUser = await userService.findOne(ownerId);\n if (!ownerUser) {\n return ctx.notFound('owner.notFound');\n }\n\n const ownerPermissions = await permissionService.findUserPermissions(ownerUser);\n const sanitizedPermissions = ownerPermissions.map(permissionService.sanitizePermission);\n\n // @ts-expect-error - transform response type to sanitized permission\n ctx.body = { data: sanitizedPermissions } satisfies GetOwnerPermissions.Response;\n },\n};\n"],"names":["ApplicationError","errors","isSuperAdmin","user","roles","some","r","code","constants","SUPER_ADMIN_CODE","getOwnerId","token","owner","adminUserOwner","String","id","isTokenOwner","canAccessAdminToken","create","ctx","body","request","apiTokenService","getService","type","undefined","badRequest","permissions","attributes","kind","name","trim","description","adminPermissions","lifespan","state","validateAdminTokenCreationInput","alreadyExists","exists","apiToken","created","data","regenerate","params","getById","notFound","forbidden","accessToken","list","apiTokens","send","revoke","existingToken","deleted","get","withKey","includeDecryptedKey","update","mutableBody","has","validateAdminTokenUpdateInput","nameAlreadyTaken","getByName","strings","isEqual","getOwnerPermissions","permissionService","userService","ownerId","ownerUser","findOne","ownerPermissions","findUserPermissions","sanitizedPermissions","map","sanitizePermission"],"mappings":";;;;;;AAsBA,MAAM,EAAEA,gBAAgB,EAAE,GAAGC,MAAAA;AAE7B;AACA;AACA;AAEA,MAAMC,YAAAA,GAAe,CAACC,IAAAA,GACpBA,IAAAA,CAAKC,KAAK,CAACC,IAAI,CAAC,CAACC,IAAMA,CAAAA,CAAEC,IAAI,KAAKC,SAAAA,CAAUC,gBAAgB,CAAA,KAAM,IAAA;AAEpE,MAAMC,aAAa,CAACC,KAAAA,GAAAA;IAClB,MAAMC,KAAAA,GAAQD,MAAME,cAAc;AAClC,IAAA,OAAOC,OAAO,OAAOF,KAAAA,KAAU,QAAA,GAAWA,KAAAA,CAAMG,EAAE,GAAGH,KAAAA,CAAAA;AACvD,CAAA;AAEA,uEACA,MAAMI,YAAAA,GAAe,CAACb,IAAAA,EAAiBQ,QACrCD,UAAAA,CAAWC,KAAAA,CAAAA,KAAWG,MAAAA,CAAOX,IAAAA,CAAKY,EAAE,CAAA;AAEtC,gFACA,MAAME,mBAAAA,GAAsB,CAACd,MAAiBQ,KAAAA,GAC5CK,YAAAA,CAAab,IAAAA,EAAMQ,KAAAA,CAAAA,IAAUT,YAAAA,CAAaC,IAAAA,CAAAA;AAE5C;AACA;AACA;AAEA,iBAAe;;;;AAIb,IAAA,MAAMe,QAAOC,GAAY,EAAA;AACvB,QAAA,MAAM,EAAEC,IAAI,EAAE,GAAGD,IAAIE,OAAO;AAC5B,QAAA,MAAMC,kBAAkBC,UAAAA,CAAW,iBAAA,CAAA;AAEnC,QAAA,IAAI,IAACH,CAA4BI,IAAI,KAAKC,SAAAA,EAAW;YACnD,OAAON,GAAAA,CAAIO,UAAU,CAAC,sCAAA,CAAA;AACxB,QAAA;AACA,QAAA,IAAI,IAACN,CAA4BO,WAAW,KAAKF,SAAAA,EAAW;YAC1D,OAAON,GAAAA,CAAIO,UAAU,CAAC,8CAAA,CAAA;AACxB,QAAA;AAEA,QAAA,MAAME,UAAAA,GAAa;YACjBC,IAAAA,EAAM,OAAA;YACNC,IAAAA,EAAMC,IAAAA,CAAKX,KAAKU,IAAI,CAAA;YACpBE,WAAAA,EAAaD,IAAAA,CAAKX,KAAKY,WAAW,CAAA;AAClCC,YAAAA,gBAAAA,EAAkBb,KAAKa,gBAAgB;AACvCC,YAAAA,QAAAA,EAAUd,KAAKc,QAAQ;AACvBrB,YAAAA,cAAAA,EAAgBM,GAAAA,CAAIgB,KAAK,CAAChC,IAAI,CAACY;AACjC,SAAA;AAEA,QAAA,MAAMqB,+BAAAA,CAAgCR,UAAAA,CAAAA;AAEtC,QAAA,MAAMS,aAAAA,GAAgB,MAAMf,eAAAA,CAAgBgB,MAAM,CAAC;AAAER,YAAAA,IAAAA,EAAMF,WAAWE;AAAK,SAAA,CAAA;AAC3E,QAAA,IAAIO,aAAAA,EAAe;AACjB,YAAA,MAAM,IAAIrC,gBAAAA,CAAiB,oBAAA,CAAA;AAC7B,QAAA;QAEA,MAAMuC,QAAAA,GAAW,MAAMjB,eAAAA,CAAgBJ,MAAM,CAACU,UAAAA,EAAYT,GAAAA,CAAIgB,KAAK,CAAChC,IAAI,CAAA;AACxEgB,QAAAA,GAAAA,CAAIqB,OAAO,CAAC;YAAEC,IAAAA,EAAMF;AAAS,SAAA,CAAA;AAC/B,IAAA,CAAA;;;;AAKA,IAAA,MAAMG,YAAWvB,GAAY,EAAA;AAC3B,QAAA,MAAM,EAAEJ,EAAE,EAAE,GAAGI,IAAIwB,MAAM;AACzB,QAAA,MAAMrB,kBAAkBC,UAAAA,CAAW,iBAAA,CAAA;AAEnC,QAAA,MAAMZ,KAAAA,GAAQ,MAAMW,eAAAA,CAAgBsB,OAAO,CAAC7B,EAAAA,CAAAA;AAC5C,QAAA,IAAI,CAACJ,KAAAA,EAAO;AACVQ,YAAAA,GAAAA,CAAI0B,QAAQ,CAAC,qBAAA,CAAA;AACb,YAAA;AACF,QAAA;AAEA,QAAA,IAAI,CAAC7B,YAAAA,CAAaG,GAAAA,CAAIgB,KAAK,CAAChC,IAAI,EAAEQ,KAAAA,CAAAA,EAAQ;AACxC,YAAA,OAAOQ,IAAI2B,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMC,WAAAA,GAAc,MAAMzB,eAAAA,CAAgBoB,UAAU,CAAC3B,EAAAA,CAAAA;AACrDI,QAAAA,GAAAA,CAAIqB,OAAO,CAAC;YAAEC,IAAAA,EAAMM;AAAY,SAAA,CAAA;AAClC,IAAA,CAAA;;;;AAKA,IAAA,MAAMC,MAAK7B,GAAY,EAAA;AACrB,QAAA,MAAMG,kBAAkBC,UAAAA,CAAW,iBAAA,CAAA;QACnC,MAAM0B,SAAAA,GAAY,MAAM3B,eAAAA,CAAgB0B,IAAI,CAAC7B,GAAAA,CAAIgB,KAAK,CAAChC,IAAI,CAAA;AAE3DgB,QAAAA,GAAAA,CAAI+B,IAAI,CAAC;YAAET,IAAAA,EAAMQ;AAAU,SAAA,CAAA;AAC7B,IAAA,CAAA;;;;AAKA,IAAA,MAAME,QAAOhC,GAAY,EAAA;AACvB,QAAA,MAAM,EAAEJ,EAAE,EAAE,GAAGI,IAAIwB,MAAM;AACzB,QAAA,MAAMrB,kBAAkBC,UAAAA,CAAW,iBAAA,CAAA;AAEnC,QAAA,MAAM6B,aAAAA,GAAgB,MAAM9B,eAAAA,CAAgBsB,OAAO,CAAC7B,EAAAA,CAAAA;AACpD,QAAA,IAAIqC,kBAAkB,IAAA,EAAM;YAC1B,OAAOjC,GAAAA,CAAI0B,QAAQ,CAAC,qBAAA,CAAA;AACtB,QAAA;AAEA,QAAA,IAAI5B,oBAAoBE,GAAAA,CAAIgB,KAAK,CAAChC,IAAI,EAAEiD,mBAAmB,KAAA,EAAO;AAChE,YAAA,OAAOjC,IAAI2B,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMP,QAAAA,GAAW,MAAMjB,eAAAA,CAAgB6B,MAAM,CAACpC,EAAAA,CAAAA;AAC9CI,QAAAA,GAAAA,CAAIkC,OAAO,CAAC;YAAEZ,IAAAA,EAAMF;AAAS,SAAA,CAAA;AAC/B,IAAA,CAAA;;;;AAKA,IAAA,MAAMe,KAAInC,GAAY,EAAA;AACpB,QAAA,MAAM,EAAEJ,EAAE,EAAE,GAAGI,IAAIwB,MAAM;AACzB,QAAA,MAAMrB,kBAAkBC,UAAAA,CAAW,iBAAA,CAAA;AAEnC,QAAA,MAAMZ,KAAAA,GAAQ,MAAMW,eAAAA,CAAgBsB,OAAO,CAAC7B,EAAAA,CAAAA;AAC5C,QAAA,IAAI,CAACJ,KAAAA,EAAO;AACVQ,YAAAA,GAAAA,CAAI0B,QAAQ,CAAC,qBAAA,CAAA;AACb,YAAA;AACF,QAAA;AAEA,QAAA,IAAI5B,oBAAoBE,GAAAA,CAAIgB,KAAK,CAAChC,IAAI,EAAEQ,WAAW,KAAA,EAAO;AACxDQ,YAAAA,GAAAA,CAAI0B,QAAQ,CAAC,qBAAA,CAAA;AACb,YAAA;AACF,QAAA;AAEA,QAAA,IAAI7B,aAAaG,GAAAA,CAAIgB,KAAK,CAAChC,IAAI,EAAEQ,KAAAA,CAAAA,EAAQ;AACvC,YAAA,MAAM4C,OAAAA,GAAU,MAAMjC,eAAAA,CAAgBsB,OAAO,CAAC7B,EAAAA,EAAI;gBAAEyC,mBAAAA,EAAqB;AAAK,aAAA,CAAA;AAC9ErC,YAAAA,GAAAA,CAAI+B,IAAI,CAAC;AAAET,gBAAAA,IAAAA,EAAMc,OAAAA,IAAW5C;AAAM,aAAA,CAAA;AAClC,YAAA;AACF,QAAA;AAEAQ,QAAAA,GAAAA,CAAI+B,IAAI,CAAC;YAAET,IAAAA,EAAM9B;AAAM,SAAA,CAAA;AACzB,IAAA,CAAA;;;;AAKA,IAAA,MAAM8C,QAAOtC,GAAY,EAAA;AACvB,QAAA,MAAM,EAAEC,IAAI,EAAE,GAAGD,IAAIE,OAAO;AAC5B,QAAA,MAAM,EAAEN,EAAE,EAAE,GAAGI,IAAIwB,MAAM;AACzB,QAAA,MAAMrB,kBAAkBC,UAAAA,CAAW,iBAAA,CAAA;AAEnC,QAAA,MAAMmC,WAAAA,GAActC,IAAAA;QACpB,IAAIuC,GAAAA,CAAI,QAAQD,WAAAA,CAAAA,EAAc;AAC5BA,YAAAA,WAAAA,CAAY5B,IAAI,GAAGC,IAAAA,CAAKX,IAAAA,CAAKU,IAAI,IAAI,EAAA,CAAA;AACvC,QAAA;AACA,QAAA,IAAI6B,IAAI,aAAA,EAAeD,WAAAA,CAAAA,IAAgBA,WAAAA,CAAY1B,WAAW,KAAK,IAAA,EAAM;AACvE0B,YAAAA,WAAAA,CAAY1B,WAAW,GAAGD,IAAAA,CAAKX,IAAAA,CAAKY,WAAW,IAAI,EAAA,CAAA;AACrD,QAAA;AAEA,QAAA,MAAM4B,6BAAAA,CAA8BxC,IAAAA,CAAAA;AAEpC,QAAA,MAAMgC,aAAAA,GAAgB,MAAM9B,eAAAA,CAAgBsB,OAAO,CAAC7B,EAAAA,CAAAA;AACpD,QAAA,IAAI,CAACqC,aAAAA,EAAe;YAClB,OAAOjC,GAAAA,CAAI0B,QAAQ,CAAC,qBAAA,CAAA;AACtB,QAAA;QAEA,IAAIc,GAAAA,CAAI,QAAQvC,IAAAA,CAAAA,EAAO;AACrB,YAAA,MAAMyC,mBAAmB,MAAMvC,eAAAA,CAAgBwC,SAAS,CAAC1C,KAAKU,IAAI,CAAA;YAClE,IAAI+B,gBAAAA,KAAqB,QAAQ,CAACE,OAAAA,CAAQC,OAAO,CAACH,gBAAAA,CAAiB9C,EAAE,EAAEA,EAAAA,CAAAA,EAAK;AAC1E,gBAAA,MAAM,IAAIf,gBAAAA,CAAiB,oBAAA,CAAA;AAC7B,YAAA;AACF,QAAA;AAEA,QAAA,IAAI,CAACiB,mBAAAA,CAAoBE,GAAAA,CAAIgB,KAAK,CAAChC,IAAI,EAAEiD,aAAAA,CAAAA,EAAgB;AACvD,YAAA,OAAOjC,IAAI2B,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMP,QAAAA,GAAW,MAAMjB,eAAAA,CAAgBmC,MAAM,CAAC1C,EAAAA,EAAIK,IAAAA,CAAAA;AAClDD,QAAAA,GAAAA,CAAI+B,IAAI,CAAC;YAAET,IAAAA,EAAMF;AAAS,SAAA,CAAA;AAC5B,IAAA,CAAA;;;;AAKA,IAAA,MAAM0B,qBAAoB9C,GAAY,EAAA;AACpC,QAAA,MAAM,EAAEJ,EAAE,EAAE,GAAGI,IAAIwB,MAAM;AACzB,QAAA,MAAMrB,kBAAkBC,UAAAA,CAAW,iBAAA,CAAA;AACnC,QAAA,MAAM2C,oBAAoB3C,UAAAA,CAAW,YAAA,CAAA;AACrC,QAAA,MAAM4C,cAAc5C,UAAAA,CAAW,MAAA,CAAA;AAE/B,QAAA,MAAMZ,KAAAA,GAAQ,MAAMW,eAAAA,CAAgBsB,OAAO,CAAC7B,EAAAA,CAAAA;AAC5C,QAAA,IAAI,CAACJ,KAAAA,EAAO;YACV,OAAOQ,GAAAA,CAAI0B,QAAQ,CAAC,mBAAA,CAAA;AACtB,QAAA;AAEA,QAAA,IAAI,CAAC5B,mBAAAA,CAAoBE,GAAAA,CAAIgB,KAAK,CAAChC,IAAI,EAAEQ,KAAAA,CAAAA,EAAQ;AAC/C,YAAA,OAAOQ,IAAI2B,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAMsB,UAAU1D,UAAAA,CAAWC,KAAAA,CAAAA;AAC3B,QAAA,MAAM0D,SAAAA,GAAY,MAAMF,WAAAA,CAAYG,OAAO,CAACF,OAAAA,CAAAA;AAC5C,QAAA,IAAI,CAACC,SAAAA,EAAW;YACd,OAAOlD,GAAAA,CAAI0B,QAAQ,CAAC,gBAAA,CAAA;AACtB,QAAA;AAEA,QAAA,MAAM0B,gBAAAA,GAAmB,MAAML,iBAAAA,CAAkBM,mBAAmB,CAACH,SAAAA,CAAAA;AACrE,QAAA,MAAMI,oBAAAA,GAAuBF,gBAAAA,CAAiBG,GAAG,CAACR,kBAAkBS,kBAAkB,CAAA;;AAGtFxD,QAAAA,GAAAA,CAAIC,IAAI,GAAG;YAAEqB,IAAAA,EAAMgC;AAAqB,SAAA;AAC1C,IAAA;AACF,CAAA;;;;"}
|
|
@@ -7,14 +7,14 @@ var apiTokens = require('../validation/api-tokens.js');
|
|
|
7
7
|
|
|
8
8
|
const { ApplicationError } = utils.errors;
|
|
9
9
|
var apiToken = {
|
|
10
|
+
// -------------------------------------------------------------------------
|
|
11
|
+
// Create
|
|
12
|
+
// -------------------------------------------------------------------------
|
|
10
13
|
async create (ctx) {
|
|
11
14
|
const { body } = ctx.request;
|
|
12
|
-
const apiTokenService = index.getService('api-token');
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* - having a space at the end or start of the value.
|
|
16
|
-
* - having only spaces as value;
|
|
17
|
-
*/ const attributes = {
|
|
15
|
+
const apiTokenService = index.getService('api-token-content-api');
|
|
16
|
+
const attributes = {
|
|
17
|
+
kind: 'content-api',
|
|
18
18
|
name: fp.trim(body.name),
|
|
19
19
|
description: fp.trim(body.description),
|
|
20
20
|
type: body.type,
|
|
@@ -28,16 +28,19 @@ var apiToken = {
|
|
|
28
28
|
if (alreadyExists) {
|
|
29
29
|
throw new ApplicationError('Name already taken');
|
|
30
30
|
}
|
|
31
|
-
const apiToken = await apiTokenService.create(attributes);
|
|
31
|
+
const apiToken = await apiTokenService.create(attributes, ctx.state.user);
|
|
32
32
|
ctx.created({
|
|
33
33
|
data: apiToken
|
|
34
34
|
});
|
|
35
35
|
},
|
|
36
|
+
// -------------------------------------------------------------------------
|
|
37
|
+
// Regenerate
|
|
38
|
+
// -------------------------------------------------------------------------
|
|
36
39
|
async regenerate (ctx) {
|
|
37
40
|
const { id } = ctx.params;
|
|
38
|
-
const apiTokenService = index.getService('api-token');
|
|
39
|
-
const
|
|
40
|
-
if (!
|
|
41
|
+
const apiTokenService = index.getService('api-token-content-api');
|
|
42
|
+
const token = await apiTokenService.getById(id);
|
|
43
|
+
if (!token) {
|
|
41
44
|
ctx.notFound('API Token not found');
|
|
42
45
|
return;
|
|
43
46
|
}
|
|
@@ -46,76 +49,74 @@ var apiToken = {
|
|
|
46
49
|
data: accessToken
|
|
47
50
|
});
|
|
48
51
|
},
|
|
52
|
+
// -------------------------------------------------------------------------
|
|
53
|
+
// List — always content-api
|
|
54
|
+
// -------------------------------------------------------------------------
|
|
49
55
|
async list (ctx) {
|
|
50
|
-
const apiTokenService = index.getService('api-token');
|
|
51
|
-
const apiTokens = await apiTokenService.list();
|
|
56
|
+
const apiTokenService = index.getService('api-token-content-api');
|
|
57
|
+
const apiTokens = await apiTokenService.list(ctx.state.user);
|
|
52
58
|
ctx.send({
|
|
53
59
|
data: apiTokens
|
|
54
60
|
});
|
|
55
61
|
},
|
|
62
|
+
// -------------------------------------------------------------------------
|
|
63
|
+
// Revoke
|
|
64
|
+
// -------------------------------------------------------------------------
|
|
56
65
|
async revoke (ctx) {
|
|
57
66
|
const { id } = ctx.params;
|
|
58
|
-
const apiTokenService = index.getService('api-token');
|
|
67
|
+
const apiTokenService = index.getService('api-token-content-api');
|
|
59
68
|
const apiToken = await apiTokenService.revoke(id);
|
|
60
69
|
ctx.deleted({
|
|
61
70
|
data: apiToken
|
|
62
71
|
});
|
|
63
72
|
},
|
|
73
|
+
// -------------------------------------------------------------------------
|
|
74
|
+
// Get — always expose the decrypted key (content-api back-compat)
|
|
75
|
+
// -------------------------------------------------------------------------
|
|
64
76
|
async get (ctx) {
|
|
65
77
|
const { id } = ctx.params;
|
|
66
|
-
const apiTokenService = index.getService('api-token');
|
|
67
|
-
const
|
|
68
|
-
if (!
|
|
78
|
+
const apiTokenService = index.getService('api-token-content-api');
|
|
79
|
+
const token = await apiTokenService.getById(id);
|
|
80
|
+
if (!token) {
|
|
69
81
|
ctx.notFound('API Token not found');
|
|
70
82
|
return;
|
|
71
83
|
}
|
|
84
|
+
const withKey = await apiTokenService.getById(id, {
|
|
85
|
+
includeDecryptedKey: true
|
|
86
|
+
});
|
|
72
87
|
ctx.send({
|
|
73
|
-
data:
|
|
88
|
+
data: withKey ?? token
|
|
74
89
|
});
|
|
75
90
|
},
|
|
91
|
+
// -------------------------------------------------------------------------
|
|
92
|
+
// Update
|
|
93
|
+
// -------------------------------------------------------------------------
|
|
76
94
|
async update (ctx) {
|
|
77
95
|
const { body } = ctx.request;
|
|
78
96
|
const { id } = ctx.params;
|
|
79
|
-
const apiTokenService = index.getService('api-token');
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
* - having a space at the end or start of the value.
|
|
84
|
-
* - having only spaces as value;
|
|
85
|
-
*/ if (fp.has('name', attributes)) {
|
|
86
|
-
attributes.name = fp.trim(body.name);
|
|
97
|
+
const apiTokenService = index.getService('api-token-content-api');
|
|
98
|
+
const mutableBody = body;
|
|
99
|
+
if (fp.has('name', mutableBody)) {
|
|
100
|
+
mutableBody.name = fp.trim(body.name ?? '');
|
|
87
101
|
}
|
|
88
|
-
if (fp.has('description',
|
|
89
|
-
|
|
102
|
+
if (fp.has('description', mutableBody) || mutableBody.description === null) {
|
|
103
|
+
mutableBody.description = fp.trim(body.description ?? '');
|
|
90
104
|
}
|
|
91
|
-
await apiTokens.validateApiTokenUpdateInput(
|
|
92
|
-
const
|
|
93
|
-
if (!
|
|
105
|
+
await apiTokens.validateApiTokenUpdateInput(body);
|
|
106
|
+
const existingToken = await apiTokenService.getById(id);
|
|
107
|
+
if (!existingToken) {
|
|
94
108
|
return ctx.notFound('API Token not found');
|
|
95
109
|
}
|
|
96
|
-
if (fp.has('name',
|
|
97
|
-
const nameAlreadyTaken = await apiTokenService.getByName(
|
|
98
|
-
|
|
99
|
-
* We cast the ids as string as the one coming from the ctx isn't cast
|
|
100
|
-
* as a Number in case it is supposed to be an integer. It remains
|
|
101
|
-
* as a string. This way we avoid issues with integers in the db.
|
|
102
|
-
*/ if (!!nameAlreadyTaken && !utils.strings.isEqual(nameAlreadyTaken.id, id)) {
|
|
110
|
+
if (fp.has('name', body)) {
|
|
111
|
+
const nameAlreadyTaken = await apiTokenService.getByName(body.name);
|
|
112
|
+
if (nameAlreadyTaken !== null && !utils.strings.isEqual(nameAlreadyTaken.id, id)) {
|
|
103
113
|
throw new ApplicationError('Name already taken');
|
|
104
114
|
}
|
|
105
115
|
}
|
|
106
|
-
const apiToken = await apiTokenService.update(id,
|
|
116
|
+
const apiToken = await apiTokenService.update(id, body);
|
|
107
117
|
ctx.send({
|
|
108
118
|
data: apiToken
|
|
109
119
|
});
|
|
110
|
-
},
|
|
111
|
-
async getLayout (ctx) {
|
|
112
|
-
const apiTokenService = index.getService('api-token');
|
|
113
|
-
// TODO
|
|
114
|
-
// @ts-expect-error remove this controller if not used
|
|
115
|
-
const layout = await apiTokenService.getApiTokenLayout();
|
|
116
|
-
ctx.send({
|
|
117
|
-
data: layout
|
|
118
|
-
});
|
|
119
120
|
}
|
|
120
121
|
};
|
|
121
122
|
|