@strapi/admin 5.56.0 → 5.57.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/Filters.js +1 -1
- package/dist/admin/admin/src/components/Filters.js.map +1 -1
- package/dist/admin/admin/src/components/Filters.mjs +1 -1
- package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.js +2 -2
- package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +2 -2
- package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
- package/dist/admin/admin/src/components/MediaLibraryBanner.js +38 -2
- package/dist/admin/admin/src/components/MediaLibraryBanner.js.map +1 -1
- package/dist/admin/admin/src/components/MediaLibraryBanner.mjs +18 -2
- package/dist/admin/admin/src/components/MediaLibraryBanner.mjs.map +1 -1
- package/dist/admin/admin/src/components/RelativeTime.js +9 -0
- package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
- package/dist/admin/admin/src/components/RelativeTime.mjs +10 -1
- package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
- package/dist/admin/admin/src/components/TopBanners.js +52 -0
- package/dist/admin/admin/src/components/TopBanners.js.map +1 -0
- package/dist/admin/admin/src/components/TopBanners.mjs +30 -0
- package/dist/admin/admin/src/components/TopBanners.mjs.map +1 -0
- package/dist/admin/admin/src/features/Tracking.js +28 -8
- package/dist/admin/admin/src/features/Tracking.js.map +1 -1
- package/dist/admin/admin/src/features/Tracking.mjs +29 -10
- package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +4 -20
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +4 -20
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
- package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js +59 -0
- package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.js.map +1 -0
- package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs +37 -0
- package/dist/admin/admin/src/layouts/useAuthenticatedAccessTracking.mjs.map +1 -0
- package/dist/admin/admin/src/translations/en.json.js +5 -0
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +5 -0
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js +3 -3
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs +2 -2
- package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +6 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +6 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
- package/dist/admin/src/components/MediaLibraryBanner.d.ts +10 -1
- package/dist/admin/src/components/TopBanners.d.ts +8 -0
- package/dist/admin/src/features/Tracking.d.ts +12 -1
- package/dist/admin/src/layouts/useAuthenticatedAccessTracking.d.ts +6 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +5 -0
- package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts +8 -2
- package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/authentication.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/user.d.ts.map +1 -1
- package/dist/ee/server/src/index.d.ts +4 -1
- package/dist/ee/server/src/index.d.ts.map +1 -1
- package/dist/ee/server/src/services/index.d.ts +4 -1
- package/dist/ee/server/src/services/index.d.ts.map +1 -1
- package/dist/ee/server/src/services/metrics.d.ts.map +1 -1
- package/dist/ee/server/src/services/persist-tables.d.ts.map +1 -1
- package/dist/ee/server/src/services/seat-enforcement.d.ts +3 -1
- package/dist/ee/server/src/services/seat-enforcement.d.ts.map +1 -1
- package/dist/server/ee/server/src/controllers/admin.js +3 -4
- package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
- package/dist/server/ee/server/src/controllers/admin.mjs +3 -4
- package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
- package/dist/server/ee/server/src/controllers/authentication-utils/utils.js +2 -2
- package/dist/server/ee/server/src/controllers/authentication-utils/utils.js.map +1 -1
- package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs +2 -2
- package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs.map +1 -1
- package/dist/server/ee/server/src/controllers/authentication.js +11 -11
- package/dist/server/ee/server/src/controllers/authentication.js.map +1 -1
- package/dist/server/ee/server/src/controllers/authentication.mjs +11 -11
- package/dist/server/ee/server/src/controllers/authentication.mjs.map +1 -1
- package/dist/server/ee/server/src/controllers/user.js +7 -8
- package/dist/server/ee/server/src/controllers/user.js.map +1 -1
- package/dist/server/ee/server/src/controllers/user.mjs +8 -9
- package/dist/server/ee/server/src/controllers/user.mjs.map +1 -1
- package/dist/server/ee/server/src/services/metrics.js +9 -7
- package/dist/server/ee/server/src/services/metrics.js.map +1 -1
- package/dist/server/ee/server/src/services/metrics.mjs +9 -7
- package/dist/server/ee/server/src/services/metrics.mjs.map +1 -1
- package/dist/server/ee/server/src/services/persist-tables.js +3 -4
- package/dist/server/ee/server/src/services/persist-tables.js.map +1 -1
- package/dist/server/ee/server/src/services/persist-tables.mjs +3 -4
- package/dist/server/ee/server/src/services/persist-tables.mjs.map +1 -1
- package/dist/server/ee/server/src/services/role.js +2 -2
- package/dist/server/ee/server/src/services/role.js.map +1 -1
- package/dist/server/ee/server/src/services/role.mjs +1 -1
- package/dist/server/ee/server/src/services/role.mjs.map +1 -1
- package/dist/server/ee/server/src/services/seat-enforcement.js +20 -20
- package/dist/server/ee/server/src/services/seat-enforcement.js.map +1 -1
- package/dist/server/ee/server/src/services/seat-enforcement.mjs +20 -20
- package/dist/server/ee/server/src/services/seat-enforcement.mjs.map +1 -1
- package/dist/server/ee/server/src/services/user.js +1 -2
- package/dist/server/ee/server/src/services/user.js.map +1 -1
- package/dist/server/ee/server/src/services/user.mjs +2 -3
- package/dist/server/ee/server/src/services/user.mjs.map +1 -1
- package/dist/server/ee/server/src/utils/sso-lock.js +2 -2
- package/dist/server/ee/server/src/utils/sso-lock.js.map +1 -1
- package/dist/server/ee/server/src/utils/sso-lock.mjs +1 -1
- package/dist/server/ee/server/src/utils/sso-lock.mjs.map +1 -1
- package/dist/server/server/src/audit-logs/admin-users.js +3 -3
- package/dist/server/server/src/audit-logs/admin-users.js.map +1 -1
- package/dist/server/server/src/audit-logs/admin-users.mjs +2 -2
- package/dist/server/server/src/audit-logs/admin-users.mjs.map +1 -1
- package/dist/server/server/src/audit-logs/tokens.js +3 -3
- package/dist/server/server/src/audit-logs/tokens.js.map +1 -1
- package/dist/server/server/src/audit-logs/tokens.mjs +2 -2
- package/dist/server/server/src/audit-logs/tokens.mjs.map +1 -1
- package/dist/server/server/src/audit-logs/webhooks.js +2 -2
- package/dist/server/server/src/audit-logs/webhooks.js.map +1 -1
- package/dist/server/server/src/audit-logs/webhooks.mjs +1 -1
- package/dist/server/server/src/audit-logs/webhooks.mjs.map +1 -1
- package/dist/server/server/src/bootstrap.js +6 -4
- package/dist/server/server/src/bootstrap.js.map +1 -1
- package/dist/server/server/src/bootstrap.mjs +6 -4
- package/dist/server/server/src/bootstrap.mjs.map +1 -1
- package/dist/server/server/src/controllers/admin-token.js +8 -8
- package/dist/server/server/src/controllers/admin-token.js.map +1 -1
- package/dist/server/server/src/controllers/admin-token.mjs +4 -4
- package/dist/server/server/src/controllers/admin-token.mjs.map +1 -1
- package/dist/server/server/src/controllers/admin.js +3 -5
- package/dist/server/server/src/controllers/admin.js.map +1 -1
- package/dist/server/server/src/controllers/admin.mjs +2 -4
- package/dist/server/server/src/controllers/admin.mjs.map +1 -1
- package/dist/server/server/src/controllers/api-token.js +8 -8
- package/dist/server/server/src/controllers/api-token.js.map +1 -1
- package/dist/server/server/src/controllers/api-token.mjs +4 -4
- package/dist/server/server/src/controllers/api-token.mjs.map +1 -1
- package/dist/server/server/src/controllers/formatters/conditions.js +2 -2
- package/dist/server/server/src/controllers/formatters/conditions.js.map +1 -1
- package/dist/server/server/src/controllers/formatters/conditions.mjs +2 -2
- package/dist/server/server/src/controllers/formatters/conditions.mjs.map +1 -1
- package/dist/server/server/src/controllers/transfer/index.js +2 -2
- package/dist/server/server/src/controllers/transfer/index.js.map +1 -1
- package/dist/server/server/src/controllers/transfer/index.mjs +2 -2
- package/dist/server/server/src/controllers/transfer/index.mjs.map +1 -1
- package/dist/server/server/src/controllers/transfer/token.js +8 -8
- package/dist/server/server/src/controllers/transfer/token.js.map +1 -1
- package/dist/server/server/src/controllers/transfer/token.mjs +4 -4
- package/dist/server/server/src/controllers/transfer/token.mjs.map +1 -1
- package/dist/server/server/src/domain/action/index.js +18 -16
- package/dist/server/server/src/domain/action/index.js.map +1 -1
- package/dist/server/server/src/domain/action/index.mjs +16 -14
- package/dist/server/server/src/domain/action/index.mjs.map +1 -1
- package/dist/server/server/src/domain/action/provider.mjs +4 -4
- package/dist/server/server/src/domain/action/provider.mjs.map +1 -1
- package/dist/server/server/src/domain/condition/index.js +7 -4
- package/dist/server/server/src/domain/condition/index.js.map +1 -1
- package/dist/server/server/src/domain/condition/index.mjs +7 -4
- package/dist/server/server/src/domain/condition/index.mjs.map +1 -1
- package/dist/server/server/src/domain/permission/index.js +24 -15
- package/dist/server/server/src/domain/permission/index.js.map +1 -1
- package/dist/server/server/src/domain/permission/index.mjs +21 -12
- package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
- package/dist/server/server/src/middlewares/rateLimit.js +5 -5
- package/dist/server/server/src/middlewares/rateLimit.js.map +1 -1
- package/dist/server/server/src/middlewares/rateLimit.mjs +4 -4
- package/dist/server/server/src/middlewares/rateLimit.mjs.map +1 -1
- package/dist/server/server/src/register.js +6 -0
- package/dist/server/server/src/register.js.map +1 -1
- package/dist/server/server/src/register.mjs +6 -0
- package/dist/server/server/src/register.mjs.map +1 -1
- package/dist/server/server/src/services/action.js +1 -2
- package/dist/server/server/src/services/action.js.map +1 -1
- package/dist/server/server/src/services/action.mjs +1 -2
- package/dist/server/server/src/services/action.mjs.map +1 -1
- package/dist/server/server/src/services/api-token.js +61 -49
- package/dist/server/server/src/services/api-token.js.map +1 -1
- package/dist/server/server/src/services/api-token.mjs +53 -41
- package/dist/server/server/src/services/api-token.mjs.map +1 -1
- package/dist/server/server/src/services/condition.js +2 -2
- package/dist/server/server/src/services/condition.js.map +1 -1
- package/dist/server/server/src/services/condition.mjs +1 -1
- package/dist/server/server/src/services/condition.mjs.map +1 -1
- package/dist/server/server/src/services/content-type.js +5 -4
- package/dist/server/server/src/services/content-type.js.map +1 -1
- package/dist/server/server/src/services/content-type.mjs +8 -7
- package/dist/server/server/src/services/content-type.mjs.map +1 -1
- package/dist/server/server/src/services/homepage.js +2 -1
- package/dist/server/server/src/services/homepage.js.map +1 -1
- package/dist/server/server/src/services/homepage.mjs +2 -1
- package/dist/server/server/src/services/homepage.mjs.map +1 -1
- package/dist/server/server/src/services/passport/local-strategy.js +2 -2
- package/dist/server/server/src/services/passport/local-strategy.js.map +1 -1
- package/dist/server/server/src/services/passport/local-strategy.mjs +1 -1
- package/dist/server/server/src/services/passport/local-strategy.mjs.map +1 -1
- package/dist/server/server/src/services/passport.js +1 -2
- package/dist/server/server/src/services/passport.js.map +1 -1
- package/dist/server/server/src/services/passport.mjs +1 -2
- package/dist/server/server/src/services/passport.mjs.map +1 -1
- package/dist/server/server/src/services/permission/engine.js +4 -4
- package/dist/server/server/src/services/permission/engine.js.map +1 -1
- package/dist/server/server/src/services/permission/engine.mjs +2 -2
- package/dist/server/server/src/services/permission/engine.mjs.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/index.js +2 -3
- package/dist/server/server/src/services/permission/permissions-manager/index.js.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/index.mjs +1 -2
- package/dist/server/server/src/services/permission/permissions-manager/index.mjs.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js +6 -6
- package/dist/server/server/src/services/permission/permissions-manager/permission-fields.js.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs +4 -4
- package/dist/server/server/src/services/permission/permissions-manager/permission-fields.mjs.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/sanitize.js +47 -41
- package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs +44 -38
- package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/validate.js +30 -26
- package/dist/server/server/src/services/permission/permissions-manager/validate.js.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/validate.mjs +28 -24
- package/dist/server/server/src/services/permission/permissions-manager/validate.mjs.map +1 -1
- package/dist/server/server/src/services/permission/queries.js +9 -9
- package/dist/server/server/src/services/permission/queries.js.map +1 -1
- package/dist/server/server/src/services/permission/queries.mjs +9 -9
- package/dist/server/server/src/services/permission/queries.mjs.map +1 -1
- package/dist/server/server/src/services/permission/rename-fields.js +118 -0
- package/dist/server/server/src/services/permission/rename-fields.js.map +1 -0
- package/dist/server/server/src/services/permission/rename-fields.mjs +116 -0
- package/dist/server/server/src/services/permission/rename-fields.mjs.map +1 -0
- package/dist/server/server/src/services/permission/sections-builder/index.js +2 -2
- package/dist/server/server/src/services/permission/sections-builder/index.js.map +1 -1
- package/dist/server/server/src/services/permission/sections-builder/index.mjs +2 -2
- package/dist/server/server/src/services/permission/sections-builder/index.mjs.map +1 -1
- package/dist/server/server/src/services/permission/sections-builder/section.js +1 -2
- package/dist/server/server/src/services/permission/sections-builder/section.js.map +1 -1
- package/dist/server/server/src/services/permission/sections-builder/section.mjs +1 -2
- package/dist/server/server/src/services/permission/sections-builder/section.mjs.map +1 -1
- package/dist/server/server/src/services/permission/sections-builder/utils.js +6 -6
- package/dist/server/server/src/services/permission/sections-builder/utils.js.map +1 -1
- package/dist/server/server/src/services/permission/sections-builder/utils.mjs +4 -4
- package/dist/server/server/src/services/permission/sections-builder/utils.mjs.map +1 -1
- package/dist/server/server/src/services/role.js +20 -19
- package/dist/server/server/src/services/role.js.map +1 -1
- package/dist/server/server/src/services/role.mjs +20 -19
- package/dist/server/server/src/services/role.mjs.map +1 -1
- package/dist/server/server/src/services/transfer/token.js +20 -16
- package/dist/server/server/src/services/transfer/token.js.map +1 -1
- package/dist/server/server/src/services/transfer/token.mjs +14 -10
- package/dist/server/server/src/services/transfer/token.mjs.map +1 -1
- package/dist/server/server/src/services/user.js +2 -3
- package/dist/server/server/src/services/user.js.map +1 -1
- package/dist/server/server/src/services/user.mjs +3 -4
- package/dist/server/server/src/services/user.mjs.map +1 -1
- package/dist/server/server/src/strategies/api-token-utils.js +2 -3
- package/dist/server/server/src/strategies/api-token-utils.js.map +1 -1
- package/dist/server/server/src/strategies/api-token-utils.mjs +2 -3
- package/dist/server/server/src/strategies/api-token-utils.mjs.map +1 -1
- package/dist/server/server/src/strategies/content-api-token.js +3 -3
- package/dist/server/server/src/strategies/content-api-token.js.map +1 -1
- package/dist/server/server/src/strategies/content-api-token.mjs +1 -1
- package/dist/server/server/src/strategies/content-api-token.mjs.map +1 -1
- package/dist/server/server/src/strategies/data-transfer.js +4 -4
- package/dist/server/server/src/strategies/data-transfer.js.map +1 -1
- package/dist/server/server/src/strategies/data-transfer.mjs +3 -3
- package/dist/server/server/src/strategies/data-transfer.mjs.map +1 -1
- package/dist/server/server/src/validation/common-validators.js +9 -10
- package/dist/server/server/src/validation/common-validators.js.map +1 -1
- package/dist/server/server/src/validation/common-validators.mjs +13 -14
- package/dist/server/server/src/validation/common-validators.mjs.map +1 -1
- package/dist/server/server/src/validation/user.js +1 -2
- package/dist/server/server/src/validation/user.js.map +1 -1
- package/dist/server/server/src/validation/user.mjs +1 -2
- package/dist/server/server/src/validation/user.mjs.map +1 -1
- package/dist/server/src/audit-logs/tokens.d.ts.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-token.d.ts.map +1 -1
- package/dist/server/src/controllers/admin.d.ts.map +1 -1
- package/dist/server/src/controllers/api-token.d.ts.map +1 -1
- package/dist/server/src/controllers/formatters/conditions.d.ts +1 -1
- package/dist/server/src/controllers/formatters/conditions.d.ts.map +1 -1
- package/dist/server/src/controllers/homepage.d.ts +1 -1
- package/dist/server/src/controllers/index.d.ts +1 -1
- package/dist/server/src/controllers/transfer/index.d.ts.map +1 -1
- package/dist/server/src/controllers/transfer/token.d.ts.map +1 -1
- package/dist/server/src/domain/action/index.d.ts +1 -0
- package/dist/server/src/domain/action/index.d.ts.map +1 -1
- package/dist/server/src/domain/condition/index.d.ts +2 -2
- package/dist/server/src/domain/condition/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 +3 -3
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/middlewares/index.d.ts.map +1 -1
- package/dist/server/src/middlewares/rateLimit.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/services/action.d.ts.map +1 -1
- package/dist/server/src/services/api-token.d.ts.map +1 -1
- package/dist/server/src/services/condition.d.ts.map +1 -1
- package/dist/server/src/services/content-type.d.ts.map +1 -1
- package/dist/server/src/services/homepage.d.ts +1 -1
- package/dist/server/src/services/homepage.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/passport/local-strategy.d.ts.map +1 -1
- package/dist/server/src/services/passport.d.ts.map +1 -1
- package/dist/server/src/services/permission/engine.d.ts.map +1 -1
- package/dist/server/src/services/permission/permissions-manager/permission-fields.d.ts.map +1 -1
- package/dist/server/src/services/permission/permissions-manager/sanitize.d.ts.map +1 -1
- package/dist/server/src/services/permission/permissions-manager/validate.d.ts.map +1 -1
- package/dist/server/src/services/permission/queries.d.ts.map +1 -1
- package/dist/server/src/services/permission/rename-fields.d.ts +21 -0
- package/dist/server/src/services/permission/rename-fields.d.ts.map +1 -0
- package/dist/server/src/services/permission/sections-builder/section.d.ts.map +1 -1
- package/dist/server/src/services/permission/sections-builder/utils.d.ts +1 -1
- package/dist/server/src/services/permission/sections-builder/utils.d.ts.map +1 -1
- package/dist/server/src/services/role.d.ts +1 -1
- package/dist/server/src/services/role.d.ts.map +1 -1
- package/dist/server/src/services/transfer/token.d.ts.map +1 -1
- package/dist/server/src/strategies/content-api-token.d.ts.map +1 -1
- package/dist/server/src/validation/user.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { differenceWith, xor,
|
|
1
|
+
import { differenceWith, xor, get } from 'lodash';
|
|
2
2
|
import pmap from 'p-map';
|
|
3
3
|
import { getService } from '../../utils/index.mjs';
|
|
4
4
|
import permissionDomain from '../../domain/permission/index.mjs';
|
|
@@ -18,7 +18,7 @@ import permissionDomain from '../../domain/permission/index.mjs';
|
|
|
18
18
|
}
|
|
19
19
|
});
|
|
20
20
|
if (permissionsToDelete.length > 0) {
|
|
21
|
-
await deleteByIds(permissionsToDelete.map(
|
|
21
|
+
await deleteByIds(permissionsToDelete.map((permission)=>permission?.id));
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
@@ -99,13 +99,13 @@ const filterPermissionsToRemove = async (permissions)=>{
|
|
|
99
99
|
const { applyToProperties } = options;
|
|
100
100
|
const invalidProperties = await Promise.all((applyToProperties || []).map(async (property)=>{
|
|
101
101
|
const applies = await actionProvider.appliesToProperty(property, permission.action, permission.subject);
|
|
102
|
-
return applies &&
|
|
102
|
+
return applies && permissionDomain.getProperty(property, permission) == null;
|
|
103
103
|
}));
|
|
104
104
|
const isRegisteredAction = actionProvider.has(permission.action);
|
|
105
|
-
const hasInvalidProperties = isArray(applyToProperties) && invalidProperties.every(
|
|
106
|
-
const isInvalidSubject = isArray(subjects) && !subjects.includes(permission.subject);
|
|
105
|
+
const hasInvalidProperties = Array.isArray(applyToProperties) && invalidProperties.every((result)=>result === true);
|
|
106
|
+
const isInvalidSubject = Array.isArray(subjects) && !subjects.includes(permission.subject);
|
|
107
107
|
// On an api token permission, nil properties mean "everything", not "invalid"
|
|
108
|
-
const hasApiToken =
|
|
108
|
+
const hasApiToken = get(permission, 'apiToken') != null;
|
|
109
109
|
// If the permission has an invalid action, an invalid subject or invalid properties, then add it to the toBeRemoved collection
|
|
110
110
|
if (!isRegisteredAction || isInvalidSubject || hasInvalidProperties && !hasApiToken) {
|
|
111
111
|
permissionsToRemove.push(permission);
|
|
@@ -142,9 +142,9 @@ const filterPermissionsToRemove = async (permissions)=>{
|
|
|
142
142
|
const remainingPermissions = permissions.filter((permission)=>!permissionsIdToRemove.includes(permission.id));
|
|
143
143
|
const permissionsWithCleanFields = contentTypeService.cleanPermissionFields(remainingPermissions);
|
|
144
144
|
// Update only the ones that need to be updated
|
|
145
|
-
const permissionsNeedingToBeUpdated = differenceWith((a, b)=>{
|
|
146
|
-
return a.id === b.id && xor(
|
|
147
|
-
}
|
|
145
|
+
const permissionsNeedingToBeUpdated = differenceWith(permissionsWithCleanFields, remainingPermissions, (a, b)=>{
|
|
146
|
+
return a.id === b.id && xor(b.properties.fields, a.properties.fields).length === 0;
|
|
147
|
+
});
|
|
148
148
|
const updatePromiseProvider = (permission)=>{
|
|
149
149
|
return update({
|
|
150
150
|
id: permission.id
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.mjs","sources":["../../../../../../server/src/services/permission/queries.ts"],"sourcesContent":["import { isNil, isArray, prop, xor, eq, differenceWith } from 'lodash/fp';\nimport pmap from 'p-map';\nimport type { Data } from '@strapi/types';\nimport { getService } from '../../utils';\nimport permissionDomain, { CreatePermissionPayload } from '../../domain/permission';\nimport type { AdminUser, Permission } from '../../../../shared/contracts/shared';\nimport { Action } from '../../domain/action';\n\n/**\n * Delete permissions of roles in database\n * @param rolesIds ids of roles\n */\nexport const deleteByRolesIds = async (rolesIds: Data.ID[]): Promise<void> => {\n const permissionsToDelete = await strapi.db.query('admin::permission').findMany({\n select: ['id'],\n where: {\n role: { id: rolesIds },\n },\n });\n\n if (permissionsToDelete.length > 0) {\n await deleteByIds(permissionsToDelete.map(prop('id')));\n }\n};\n\n/**\n * Delete permissions\n * @param ids ids of permissions\n */\nexport const deleteByIds = async (ids: Data.ID[]): Promise<void> => {\n const result: unknown[] = [];\n for (const id of ids) {\n const queryResult = await strapi.db.query('admin::permission').delete({ where: { id } });\n result.push(queryResult);\n }\n strapi.eventHub.emit('permission.delete', { permissions: result });\n};\n\n/**\n * Create many permissions\n * @param permissions\n */\nexport const createMany = async (permissions: CreatePermissionPayload[]): Promise<Permission[]> => {\n const createdPermissions: CreatePermissionPayload[] = [];\n for (const permission of permissions) {\n const newPerm = await strapi.db.query('admin::permission').create({ data: permission });\n createdPermissions.push(newPerm);\n }\n\n const permissionsToReturn = permissionDomain.toPermission(createdPermissions);\n strapi.eventHub.emit('permission.create', { permissions: permissionsToReturn });\n\n return permissionsToReturn;\n};\n\n/**\n * Update a permission\n * @param params\n * @param attributes\n */\nconst update = async (params: unknown, attributes: Partial<Permission>) => {\n const updatedPermission = (await strapi.db\n .query('admin::permission')\n .update({ where: params, data: attributes })) as Permission;\n\n const permissionToReturn = permissionDomain.toPermission(updatedPermission);\n strapi.eventHub.emit('permission.update', { permissions: permissionToReturn });\n\n return permissionToReturn;\n};\n\n/**\n * Find assigned permissions in the database\n * @param params query params to find the permissions\n */\nexport const findMany = async (params = {}): Promise<Permission[]> => {\n const rawPermissions = await strapi.db.query('admin::permission').findMany(params);\n\n return permissionDomain.toPermission(rawPermissions);\n};\n\n/**\n * Find all permissions for a user\n * @param user - user\n */\nexport const findUserPermissions = async (user: AdminUser): Promise<Permission[]> => {\n return findMany({ where: { role: { users: { id: user.id } } } });\n};\n\nconst filterPermissionsToRemove = async (permissions: Permission[]) => {\n const { actionProvider } = getService('permission');\n\n const permissionsToRemove: Permission[] = [];\n\n for (const permission of permissions) {\n const { subjects, options = {} as Action['options'] } =\n (actionProvider.get(permission.action) as Action) || {};\n const { applyToProperties } = options;\n\n const invalidProperties = await Promise.all(\n (applyToProperties || []).map(async (property) => {\n const applies = await actionProvider.appliesToProperty(\n property,\n permission.action,\n permission.subject\n );\n\n return applies && isNil(permissionDomain.getProperty(property, permission));\n })\n );\n\n const isRegisteredAction = actionProvider.has(permission.action);\n const hasInvalidProperties = isArray(applyToProperties) && invalidProperties.every(eq(true));\n const isInvalidSubject = isArray(subjects) && !subjects.includes(permission.subject as string);\n // On an api token permission, nil properties mean \"everything\", not \"invalid\"\n const hasApiToken = !isNil(prop('apiToken', permission));\n\n // If the permission has an invalid action, an invalid subject or invalid properties, then add it to the toBeRemoved collection\n if (!isRegisteredAction || isInvalidSubject || (hasInvalidProperties && !hasApiToken)) {\n permissionsToRemove.push(permission);\n }\n }\n\n return permissionsToRemove;\n};\n\n/**\n * Removes permissions in database that don't exist anymore\n */\nexport const cleanPermissionsInDatabase = async (): Promise<void> => {\n const pageSize = 200;\n\n const contentTypeService = getService('content-type');\n\n const total = await strapi.db.query('admin::permission').count();\n const pageCount = Math.ceil(total / pageSize);\n\n for (let page = 0; page < pageCount; page += 1) {\n // 1. Find invalid permissions and collect their ID to delete them later\n const results = (await strapi.db.query('admin::permission').findMany({\n limit: pageSize,\n offset: page * pageSize,\n populate: ['role', 'apiToken'],\n })) as Permission[];\n\n const permissions = permissionDomain.toPermission(results);\n const permissionsToRemove = await filterPermissionsToRemove(permissions);\n\n // Also remove orphaned permissions (no role AND no apiToken)\n const orphanedPermissions = permissions.filter(\n (permission: any) => !permission.role && !permission.apiToken\n );\n\n const permissionsIdToRemove = Array.from(\n new Set([...permissionsToRemove, ...orphanedPermissions].map((p) => p.id))\n );\n\n // 2. Clean permissions' fields (add required ones, remove the non-existing ones)\n const remainingPermissions = permissions.filter(\n (permission: Permission) => !permissionsIdToRemove.includes(permission.id)\n );\n\n const permissionsWithCleanFields = contentTypeService.cleanPermissionFields(\n remainingPermissions\n ) as Permission[];\n\n // Update only the ones that need to be updated\n const permissionsNeedingToBeUpdated = differenceWith(\n (a: Permission, b: Permission) => {\n return a.id === b.id && xor(a.properties.fields, b.properties.fields).length === 0;\n },\n permissionsWithCleanFields,\n remainingPermissions\n );\n\n const updatePromiseProvider = (permission: Permission) => {\n return update({ id: permission.id }, permission);\n };\n\n // Execute all the queries, update the database\n await Promise.all([\n deleteByIds(permissionsIdToRemove),\n pmap(permissionsNeedingToBeUpdated, updatePromiseProvider, {\n concurrency: 100,\n stopOnError: true,\n }),\n ]);\n }\n};\n\nexport default {\n createMany,\n findMany,\n deleteByRolesIds,\n deleteByIds,\n findUserPermissions,\n cleanPermissionsInDatabase,\n};\n"],"names":["deleteByRolesIds","rolesIds","permissionsToDelete","strapi","db","query","findMany","select","where","role","id","length","deleteByIds","map","prop","ids","result","queryResult","delete","push","eventHub","emit","permissions","createMany","createdPermissions","permission","newPerm","create","data","permissionsToReturn","permissionDomain","toPermission","update","params","attributes","updatedPermission","permissionToReturn","rawPermissions","findUserPermissions","user","users","filterPermissionsToRemove","actionProvider","getService","permissionsToRemove","subjects","options","get","action","applyToProperties","invalidProperties","Promise","all","property","applies","appliesToProperty","subject","isNil","getProperty","isRegisteredAction","has","hasInvalidProperties","isArray","every","eq","isInvalidSubject","includes","hasApiToken","cleanPermissionsInDatabase","pageSize","contentTypeService","total","count","pageCount","Math","ceil","page","results","limit","offset","populate","orphanedPermissions","filter","apiToken","permissionsIdToRemove","Array","from","Set","p","remainingPermissions","permissionsWithCleanFields","cleanPermissionFields","permissionsNeedingToBeUpdated","differenceWith","a","b","xor","properties","fields","updatePromiseProvider","pmap","concurrency","stopOnError"],"mappings":";;;;;AAQA;;;IAIO,MAAMA,gBAAAA,GAAmB,OAAOC,QAAAA,GAAAA;IACrC,MAAMC,mBAAAA,GAAsB,MAAMC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBC,QAAQ,CAAC;QAC9EC,MAAAA,EAAQ;AAAC,YAAA;AAAK,SAAA;QACdC,KAAAA,EAAO;YACLC,IAAAA,EAAM;gBAAEC,EAAAA,EAAIT;AAAS;AACvB;AACF,KAAA,CAAA;IAEA,IAAIC,mBAAAA,CAAoBS,MAAM,GAAG,CAAA,EAAG;AAClC,QAAA,MAAMC,WAAAA,CAAYV,mBAAAA,CAAoBW,GAAG,CAACC,IAAAA,CAAK,IAAA,CAAA,CAAA,CAAA;AACjD,IAAA;AACF;AAEA;;;IAIO,MAAMF,WAAAA,GAAc,OAAOG,GAAAA,GAAAA;AAChC,IAAA,MAAMC,SAAoB,EAAE;IAC5B,KAAK,MAAMN,MAAMK,GAAAA,CAAK;QACpB,MAAME,WAAAA,GAAc,MAAMd,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBa,MAAM,CAAC;YAAEV,KAAAA,EAAO;AAAEE,gBAAAA;AAAG;AAAE,SAAA,CAAA;AACtFM,QAAAA,MAAAA,CAAOG,IAAI,CAACF,WAAAA,CAAAA;AACd,IAAA;AACAd,IAAAA,MAAAA,CAAOiB,QAAQ,CAACC,IAAI,CAAC,mBAAA,EAAqB;QAAEC,WAAAA,EAAaN;AAAO,KAAA,CAAA;AAClE;AAEA;;;IAIO,MAAMO,UAAAA,GAAa,OAAOD,WAAAA,GAAAA;AAC/B,IAAA,MAAME,qBAAgD,EAAE;IACxD,KAAK,MAAMC,cAAcH,WAAAA,CAAa;QACpC,MAAMI,OAAAA,GAAU,MAAMvB,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBsB,MAAM,CAAC;YAAEC,IAAAA,EAAMH;AAAW,SAAA,CAAA;AACrFD,QAAAA,kBAAAA,CAAmBL,IAAI,CAACO,OAAAA,CAAAA;AAC1B,IAAA;IAEA,MAAMG,mBAAAA,GAAsBC,gBAAAA,CAAiBC,YAAY,CAACP,kBAAAA,CAAAA;AAC1DrB,IAAAA,MAAAA,CAAOiB,QAAQ,CAACC,IAAI,CAAC,mBAAA,EAAqB;QAAEC,WAAAA,EAAaO;AAAoB,KAAA,CAAA;IAE7E,OAAOA,mBAAAA;AACT;AAEA;;;;IAKA,MAAMG,MAAAA,GAAS,OAAOC,MAAAA,EAAiBC,UAAAA,GAAAA;IACrC,MAAMC,iBAAAA,GAAqB,MAAMhC,MAAAA,CAAOC,EAAE,CACvCC,KAAK,CAAC,mBAAA,CAAA,CACN2B,MAAM,CAAC;QAAExB,KAAAA,EAAOyB,MAAAA;QAAQL,IAAAA,EAAMM;AAAW,KAAA,CAAA;IAE5C,MAAME,kBAAAA,GAAqBN,gBAAAA,CAAiBC,YAAY,CAACI,iBAAAA,CAAAA;AACzDhC,IAAAA,MAAAA,CAAOiB,QAAQ,CAACC,IAAI,CAAC,mBAAA,EAAqB;QAAEC,WAAAA,EAAac;AAAmB,KAAA,CAAA;IAE5E,OAAOA,kBAAAA;AACT,CAAA;AAEA;;;AAGC,IACM,MAAM9B,QAAAA,GAAW,OAAO2B,MAAAA,GAAS,EAAE,GAAA;IACxC,MAAMI,cAAAA,GAAiB,MAAMlC,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBC,QAAQ,CAAC2B,MAAAA,CAAAA;IAE3E,OAAOH,gBAAAA,CAAiBC,YAAY,CAACM,cAAAA,CAAAA;AACvC;AAEA;;;IAIO,MAAMC,mBAAAA,GAAsB,OAAOC,IAAAA,GAAAA;AACxC,IAAA,OAAOjC,QAAAA,CAAS;QAAEE,KAAAA,EAAO;YAAEC,IAAAA,EAAM;gBAAE+B,KAAAA,EAAO;AAAE9B,oBAAAA,EAAAA,EAAI6B,KAAK7B;AAAG;AAAE;AAAE;AAAE,KAAA,CAAA;AAChE;AAEA,MAAM+B,4BAA4B,OAAOnB,WAAAA,GAAAA;AACvC,IAAA,MAAM,EAAEoB,cAAc,EAAE,GAAGC,UAAAA,CAAW,YAAA,CAAA;AAEtC,IAAA,MAAMC,sBAAoC,EAAE;IAE5C,KAAK,MAAMnB,cAAcH,WAAAA,CAAa;AACpC,QAAA,MAAM,EAAEuB,QAAQ,EAAEC,OAAAA,GAAU,EAAuB,EAAE,GAClDJ,eAAeK,GAAG,CAACtB,UAAAA,CAAWuB,MAAM,KAAgB,EAAC;QACxD,MAAM,EAAEC,iBAAiB,EAAE,GAAGH,OAAAA;AAE9B,QAAA,MAAMI,iBAAAA,GAAoB,MAAMC,OAAAA,CAAQC,GAAG,CACxCH,CAAAA,iBAAAA,IAAqB,EAAC,EAAGpC,GAAG,CAAC,OAAOwC,QAAAA,GAAAA;YACnC,MAAMC,OAAAA,GAAU,MAAMZ,cAAAA,CAAea,iBAAiB,CACpDF,UACA5B,UAAAA,CAAWuB,MAAM,EACjBvB,UAAAA,CAAW+B,OAAO,CAAA;AAGpB,YAAA,OAAOF,OAAAA,IAAWG,KAAAA,CAAM3B,gBAAAA,CAAiB4B,WAAW,CAACL,QAAAA,EAAU5B,UAAAA,CAAAA,CAAAA;AACjE,QAAA,CAAA,CAAA,CAAA;AAGF,QAAA,MAAMkC,kBAAAA,GAAqBjB,cAAAA,CAAekB,GAAG,CAACnC,WAAWuB,MAAM,CAAA;AAC/D,QAAA,MAAMa,uBAAuBC,OAAAA,CAAQb,iBAAAA,CAAAA,IAAsBC,iBAAAA,CAAkBa,KAAK,CAACC,EAAAA,CAAG,IAAA,CAAA,CAAA;QACtF,MAAMC,gBAAAA,GAAmBH,QAAQjB,QAAAA,CAAAA,IAAa,CAACA,SAASqB,QAAQ,CAACzC,WAAW+B,OAAO,CAAA;;AAEnF,QAAA,MAAMW,WAAAA,GAAc,CAACV,KAAAA,CAAM3C,IAAAA,CAAK,UAAA,EAAYW,UAAAA,CAAAA,CAAAA;;AAG5C,QAAA,IAAI,CAACkC,kBAAAA,IAAsBM,gBAAAA,IAAqBJ,oBAAAA,IAAwB,CAACM,WAAAA,EAAc;AACrFvB,YAAAA,mBAAAA,CAAoBzB,IAAI,CAACM,UAAAA,CAAAA;AAC3B,QAAA;AACF,IAAA;IAEA,OAAOmB,mBAAAA;AACT,CAAA;AAEA;;UAGawB,0BAAAA,GAA6B,UAAA;AACxC,IAAA,MAAMC,QAAAA,GAAW,GAAA;AAEjB,IAAA,MAAMC,qBAAqB3B,UAAAA,CAAW,cAAA,CAAA;IAEtC,MAAM4B,KAAAA,GAAQ,MAAMpE,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,qBAAqBmE,KAAK,EAAA;AAC9D,IAAA,MAAMC,SAAAA,GAAYC,IAAAA,CAAKC,IAAI,CAACJ,KAAAA,GAAQF,QAAAA,CAAAA;AAEpC,IAAA,IAAK,IAAIO,IAAAA,GAAO,CAAA,EAAGA,IAAAA,GAAOH,SAAAA,EAAWG,QAAQ,CAAA,CAAG;;QAE9C,MAAMC,OAAAA,GAAW,MAAM1E,MAAAA,CAAOC,EAAE,CAACC,KAAK,CAAC,mBAAA,CAAA,CAAqBC,QAAQ,CAAC;YACnEwE,KAAAA,EAAOT,QAAAA;AACPU,YAAAA,MAAAA,EAAQH,IAAAA,GAAOP,QAAAA;YACfW,QAAAA,EAAU;AAAC,gBAAA,MAAA;AAAQ,gBAAA;AAAW;AAChC,SAAA,CAAA;QAEA,MAAM1D,WAAAA,GAAcQ,gBAAAA,CAAiBC,YAAY,CAAC8C,OAAAA,CAAAA;QAClD,MAAMjC,mBAAAA,GAAsB,MAAMH,yBAAAA,CAA0BnB,WAAAA,CAAAA;;AAG5D,QAAA,MAAM2D,mBAAAA,GAAsB3D,WAAAA,CAAY4D,MAAM,CAC5C,CAACzD,UAAAA,GAAoB,CAACA,UAAAA,CAAWhB,IAAI,IAAI,CAACgB,UAAAA,CAAW0D,QAAQ,CAAA;AAG/D,QAAA,MAAMC,qBAAAA,GAAwBC,KAAAA,CAAMC,IAAI,CACtC,IAAIC,GAAAA,CAAI;AAAI3C,YAAAA,GAAAA,mBAAAA;AAAwBqC,YAAAA,GAAAA;AAAoB,SAAA,CAACpE,GAAG,CAAC,CAAC2E,CAAAA,GAAMA,EAAE9E,EAAE,CAAA,CAAA,CAAA;;QAI1E,MAAM+E,oBAAAA,GAAuBnE,WAAAA,CAAY4D,MAAM,CAC7C,CAACzD,UAAAA,GAA2B,CAAC2D,qBAAAA,CAAsBlB,QAAQ,CAACzC,UAAAA,CAAWf,EAAE,CAAA,CAAA;QAG3E,MAAMgF,0BAAAA,GAA6BpB,kBAAAA,CAAmBqB,qBAAqB,CACzEF,oBAAAA,CAAAA;;QAIF,MAAMG,6BAAAA,GAAgCC,cAAAA,CACpC,CAACC,CAAAA,EAAeC,CAAAA,GAAAA;AACd,YAAA,OAAOD,EAAEpF,EAAE,KAAKqF,EAAErF,EAAE,IAAIsF,IAAIF,CAAAA,CAAEG,UAAU,CAACC,MAAM,EAAEH,CAAAA,CAAEE,UAAU,CAACC,MAAM,CAAA,CAAEvF,MAAM,KAAK,CAAA;AACnF,QAAA,CAAA,EACA+E,0BAAAA,EACAD,oBAAAA,CAAAA;AAGF,QAAA,MAAMU,wBAAwB,CAAC1E,UAAAA,GAAAA;AAC7B,YAAA,OAAOO,MAAAA,CAAO;AAAEtB,gBAAAA,EAAAA,EAAIe,WAAWf;aAAG,EAAGe,UAAAA,CAAAA;AACvC,QAAA,CAAA;;QAGA,MAAM0B,OAAAA,CAAQC,GAAG,CAAC;YAChBxC,WAAAA,CAAYwE,qBAAAA,CAAAA;AACZgB,YAAAA,IAAAA,CAAKR,+BAA+BO,qBAAAA,EAAuB;gBACzDE,WAAAA,EAAa,GAAA;gBACbC,WAAAA,EAAa;AACf,aAAA;AACD,SAAA,CAAA;AACH,IAAA;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"queries.mjs","sources":["../../../../../../server/src/services/permission/queries.ts"],"sourcesContent":["import { get, xor, differenceWith } from 'lodash';\n\nimport pmap from 'p-map';\nimport type { Data } from '@strapi/types';\nimport { getService } from '../../utils';\nimport permissionDomain, { CreatePermissionPayload } from '../../domain/permission';\nimport type { AdminUser, Permission } from '../../../../shared/contracts/shared';\nimport { Action } from '../../domain/action';\n\n/**\n * Delete permissions of roles in database\n * @param rolesIds ids of roles\n */\nexport const deleteByRolesIds = async (rolesIds: Data.ID[]): Promise<void> => {\n const permissionsToDelete = await strapi.db.query('admin::permission').findMany({\n select: ['id'],\n where: {\n role: { id: rolesIds },\n },\n });\n\n if (permissionsToDelete.length > 0) {\n await deleteByIds(permissionsToDelete.map((permission) => permission?.id));\n }\n};\n\n/**\n * Delete permissions\n * @param ids ids of permissions\n */\nexport const deleteByIds = async (ids: Data.ID[]): Promise<void> => {\n const result: unknown[] = [];\n for (const id of ids) {\n const queryResult = await strapi.db.query('admin::permission').delete({ where: { id } });\n result.push(queryResult);\n }\n strapi.eventHub.emit('permission.delete', { permissions: result });\n};\n\n/**\n * Create many permissions\n * @param permissions\n */\nexport const createMany = async (permissions: CreatePermissionPayload[]): Promise<Permission[]> => {\n const createdPermissions: CreatePermissionPayload[] = [];\n for (const permission of permissions) {\n const newPerm = await strapi.db.query('admin::permission').create({ data: permission });\n createdPermissions.push(newPerm);\n }\n\n const permissionsToReturn = permissionDomain.toPermission(createdPermissions);\n strapi.eventHub.emit('permission.create', { permissions: permissionsToReturn });\n\n return permissionsToReturn;\n};\n\n/**\n * Update a permission\n * @param params\n * @param attributes\n */\nconst update = async (params: unknown, attributes: Partial<Permission>) => {\n const updatedPermission = (await strapi.db\n .query('admin::permission')\n .update({ where: params, data: attributes })) as Permission;\n\n const permissionToReturn = permissionDomain.toPermission(updatedPermission);\n strapi.eventHub.emit('permission.update', { permissions: permissionToReturn });\n\n return permissionToReturn;\n};\n\n/**\n * Find assigned permissions in the database\n * @param params query params to find the permissions\n */\nexport const findMany = async (params = {}): Promise<Permission[]> => {\n const rawPermissions = await strapi.db.query('admin::permission').findMany(params);\n\n return permissionDomain.toPermission(rawPermissions);\n};\n\n/**\n * Find all permissions for a user\n * @param user - user\n */\nexport const findUserPermissions = async (user: AdminUser): Promise<Permission[]> => {\n return findMany({ where: { role: { users: { id: user.id } } } });\n};\n\nconst filterPermissionsToRemove = async (permissions: Permission[]) => {\n const { actionProvider } = getService('permission');\n\n const permissionsToRemove: Permission[] = [];\n\n for (const permission of permissions) {\n const { subjects, options = {} as Action['options'] } =\n (actionProvider.get(permission.action) as Action) || {};\n const { applyToProperties } = options;\n\n const invalidProperties = await Promise.all(\n (applyToProperties || []).map(async (property) => {\n const applies = await actionProvider.appliesToProperty(\n property,\n permission.action,\n permission.subject\n );\n\n return applies && permissionDomain.getProperty(property, permission) == null;\n })\n );\n\n const isRegisteredAction = actionProvider.has(permission.action);\n const hasInvalidProperties =\n Array.isArray(applyToProperties) && invalidProperties.every((result) => result === true);\n const isInvalidSubject =\n Array.isArray(subjects) && !subjects.includes(permission.subject as string);\n // On an api token permission, nil properties mean \"everything\", not \"invalid\"\n const hasApiToken = get(permission, 'apiToken') != null;\n\n // If the permission has an invalid action, an invalid subject or invalid properties, then add it to the toBeRemoved collection\n if (!isRegisteredAction || isInvalidSubject || (hasInvalidProperties && !hasApiToken)) {\n permissionsToRemove.push(permission);\n }\n }\n\n return permissionsToRemove;\n};\n\n/**\n * Removes permissions in database that don't exist anymore\n */\nexport const cleanPermissionsInDatabase = async (): Promise<void> => {\n const pageSize = 200;\n\n const contentTypeService = getService('content-type');\n\n const total = await strapi.db.query('admin::permission').count();\n const pageCount = Math.ceil(total / pageSize);\n\n for (let page = 0; page < pageCount; page += 1) {\n // 1. Find invalid permissions and collect their ID to delete them later\n const results = (await strapi.db.query('admin::permission').findMany({\n limit: pageSize,\n offset: page * pageSize,\n populate: ['role', 'apiToken'],\n })) as Permission[];\n\n const permissions = permissionDomain.toPermission(results);\n const permissionsToRemove = await filterPermissionsToRemove(permissions);\n\n // Also remove orphaned permissions (no role AND no apiToken)\n const orphanedPermissions = permissions.filter(\n (permission: any) => !permission.role && !permission.apiToken\n );\n\n const permissionsIdToRemove = Array.from(\n new Set([...permissionsToRemove, ...orphanedPermissions].map((p) => p.id))\n );\n\n // 2. Clean permissions' fields (add required ones, remove the non-existing ones)\n const remainingPermissions = permissions.filter(\n (permission: Permission) => !permissionsIdToRemove.includes(permission.id)\n );\n\n const permissionsWithCleanFields = contentTypeService.cleanPermissionFields(\n remainingPermissions\n ) as Permission[];\n\n // Update only the ones that need to be updated\n const permissionsNeedingToBeUpdated = differenceWith(\n permissionsWithCleanFields,\n remainingPermissions,\n (a: Permission, b: Permission) => {\n return a.id === b.id && xor(b.properties.fields, a.properties.fields).length === 0;\n }\n );\n\n const updatePromiseProvider = (permission: Permission) => {\n return update({ id: permission.id }, permission);\n };\n\n // Execute all the queries, update the database\n await Promise.all([\n deleteByIds(permissionsIdToRemove),\n pmap(permissionsNeedingToBeUpdated, updatePromiseProvider, {\n concurrency: 100,\n stopOnError: true,\n }),\n ]);\n }\n};\n\nexport default {\n createMany,\n findMany,\n deleteByRolesIds,\n deleteByIds,\n findUserPermissions,\n cleanPermissionsInDatabase,\n};\n"],"names":["deleteByRolesIds","rolesIds","permissionsToDelete","strapi","db","query","findMany","select","where","role","id","length","deleteByIds","map","permission","ids","result","queryResult","delete","push","eventHub","emit","permissions","createMany","createdPermissions","newPerm","create","data","permissionsToReturn","permissionDomain","toPermission","update","params","attributes","updatedPermission","permissionToReturn","rawPermissions","findUserPermissions","user","users","filterPermissionsToRemove","actionProvider","getService","permissionsToRemove","subjects","options","get","action","applyToProperties","invalidProperties","Promise","all","property","applies","appliesToProperty","subject","getProperty","isRegisteredAction","has","hasInvalidProperties","Array","isArray","every","isInvalidSubject","includes","hasApiToken","cleanPermissionsInDatabase","pageSize","contentTypeService","total","count","pageCount","Math","ceil","page","results","limit","offset","populate","orphanedPermissions","filter","apiToken","permissionsIdToRemove","from","Set","p","remainingPermissions","permissionsWithCleanFields","cleanPermissionFields","permissionsNeedingToBeUpdated","differenceWith","a","b","xor","properties","fields","updatePromiseProvider","pmap","concurrency","stopOnError"],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _ = require('lodash');
|
|
4
|
+
var contentType = require('../content-type.js');
|
|
5
|
+
|
|
6
|
+
const PERMISSION_UID = 'admin::permission';
|
|
7
|
+
/**
|
|
8
|
+
* Carries attribute renames to the `properties.fields` of admin permissions
|
|
9
|
+
* (roles and admin API tokens).
|
|
10
|
+
*
|
|
11
|
+
* Runs from the generated rename migration, inside its transaction, before the
|
|
12
|
+
* admin bootstrap cleans permission fields against the new schema. Without it,
|
|
13
|
+
* the cleanup drops every renamed field from every role but the super admin.
|
|
14
|
+
*
|
|
15
|
+
* `strapi.contentTypes` / `strapi.components` already hold the new schema at
|
|
16
|
+
* that point, so every new field path is mapped back to the path it had before
|
|
17
|
+
* the renames, segment by segment (a component field path goes through its
|
|
18
|
+
* parent's component). This also composes a parent rename with a rename inside
|
|
19
|
+
* its component in the same save.
|
|
20
|
+
*/ const createPermissionFieldRenamer = ({ strapi })=>{
|
|
21
|
+
const getOldPath = (subject, path, originsOf)=>{
|
|
22
|
+
let ownerUid = subject;
|
|
23
|
+
let owner = strapi.contentTypes[subject];
|
|
24
|
+
return path.split('.').map((segment)=>{
|
|
25
|
+
const origin = originsOf[ownerUid]?.[segment] ?? segment;
|
|
26
|
+
const attribute = owner?.attributes?.[segment];
|
|
27
|
+
if (attribute?.type === 'component' && attribute.component) {
|
|
28
|
+
ownerUid = attribute.component;
|
|
29
|
+
owner = strapi.components[attribute.component];
|
|
30
|
+
} else {
|
|
31
|
+
owner = undefined;
|
|
32
|
+
}
|
|
33
|
+
return origin;
|
|
34
|
+
}).join('.');
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* `old path -> new path` per subject, for the subjects with at least one
|
|
38
|
+
* renamed path.
|
|
39
|
+
*/ const getRenamedPaths = (renames)=>{
|
|
40
|
+
// Per model: final name -> origin name.
|
|
41
|
+
const originsOf = {};
|
|
42
|
+
for (const [uid, mapping] of Object.entries(renames)){
|
|
43
|
+
originsOf[uid] = _.invert(mapping);
|
|
44
|
+
}
|
|
45
|
+
const renamedPaths = new Map();
|
|
46
|
+
for (const [subject, contentType$1] of Object.entries(strapi.contentTypes)){
|
|
47
|
+
const paths = contentType.getNestedFieldsWithIntermediate(contentType$1, {
|
|
48
|
+
components: strapi.components
|
|
49
|
+
});
|
|
50
|
+
const byOldPath = {};
|
|
51
|
+
for (const path of paths){
|
|
52
|
+
const oldPath = getOldPath(subject, path, originsOf);
|
|
53
|
+
if (oldPath !== path) {
|
|
54
|
+
byOldPath[oldPath] = path;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!_.isEmpty(byOldPath)) {
|
|
58
|
+
renamedPaths.set(subject, byOldPath);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return renamedPaths;
|
|
62
|
+
};
|
|
63
|
+
return async (trx, renames)=>{
|
|
64
|
+
if (_.isEmpty(renames)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Fresh database: the table is created by schema sync after the migrations.
|
|
68
|
+
const { tableName } = strapi.db.metadata.get(PERMISSION_UID);
|
|
69
|
+
if (!await strapi.db.getSchemaConnection(trx).hasTable(tableName)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const renamedPaths = getRenamedPaths(renames);
|
|
73
|
+
if (renamedPaths.size === 0) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// Joins the migration transaction.
|
|
77
|
+
const permissions = await strapi.db.query(PERMISSION_UID).findMany({
|
|
78
|
+
select: [
|
|
79
|
+
'id',
|
|
80
|
+
'subject',
|
|
81
|
+
'properties'
|
|
82
|
+
],
|
|
83
|
+
where: {
|
|
84
|
+
subject: {
|
|
85
|
+
$in: [
|
|
86
|
+
...renamedPaths.keys()
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
for (const permission of permissions){
|
|
92
|
+
const fields = permission.properties?.fields;
|
|
93
|
+
const byOldPath = permission.subject ? renamedPaths.get(permission.subject) : undefined;
|
|
94
|
+
if (!Array.isArray(fields) || !byOldPath) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// One pass over the old paths, so a swap is applied once.
|
|
98
|
+
const newFields = _.uniq(fields.map((field)=>byOldPath[field] ?? field));
|
|
99
|
+
if (_.xor(fields, newFields).length === 0) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
await strapi.db.query(PERMISSION_UID).update({
|
|
103
|
+
where: {
|
|
104
|
+
id: permission.id
|
|
105
|
+
},
|
|
106
|
+
data: {
|
|
107
|
+
properties: {
|
|
108
|
+
...permission.properties,
|
|
109
|
+
fields: newFields
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
exports.createPermissionFieldRenamer = createPermissionFieldRenamer;
|
|
118
|
+
//# sourceMappingURL=rename-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename-fields.js","sources":["../../../../../../server/src/services/permission/rename-fields.ts"],"sourcesContent":["import { invert, isEmpty, uniq, xor } from 'lodash';\nimport type { Core, Struct } from '@strapi/types';\n\nimport { getNestedFieldsWithIntermediate } from '../content-type';\n\ntype AttributeRenameHandler = Parameters<\n Core.Strapi['db']['schema']['registerAttributeRenameHandler']\n>[0];\n\ntype AttributeRenames = Parameters<AttributeRenameHandler>[1];\n\ninterface PermissionRow {\n id: number | string;\n subject: string | null;\n properties?: { fields?: unknown } | null;\n}\n\nconst PERMISSION_UID = 'admin::permission';\n\n/**\n * Carries attribute renames to the `properties.fields` of admin permissions\n * (roles and admin API tokens).\n *\n * Runs from the generated rename migration, inside its transaction, before the\n * admin bootstrap cleans permission fields against the new schema. Without it,\n * the cleanup drops every renamed field from every role but the super admin.\n *\n * `strapi.contentTypes` / `strapi.components` already hold the new schema at\n * that point, so every new field path is mapped back to the path it had before\n * the renames, segment by segment (a component field path goes through its\n * parent's component). This also composes a parent rename with a rename inside\n * its component in the same save.\n */\nexport const createPermissionFieldRenamer = ({\n strapi,\n}: {\n strapi: Core.Strapi;\n}): AttributeRenameHandler => {\n const getOldPath = (\n subject: string,\n path: string,\n originsOf: Record<string, Record<string, string>>\n ): string => {\n let ownerUid = subject;\n let owner: Struct.Schema | undefined =\n strapi.contentTypes[subject as keyof typeof strapi.contentTypes];\n\n return path\n .split('.')\n .map((segment) => {\n const origin = originsOf[ownerUid]?.[segment] ?? segment;\n const attribute = owner?.attributes?.[segment] as\n | { type?: string; component?: string }\n | undefined;\n\n if (attribute?.type === 'component' && attribute.component) {\n ownerUid = attribute.component;\n owner = strapi.components[attribute.component as keyof typeof strapi.components];\n } else {\n owner = undefined;\n }\n\n return origin;\n })\n .join('.');\n };\n\n /**\n * `old path -> new path` per subject, for the subjects with at least one\n * renamed path.\n */\n const getRenamedPaths = (renames: AttributeRenames): Map<string, Record<string, string>> => {\n // Per model: final name -> origin name.\n const originsOf: Record<string, Record<string, string>> = {};\n for (const [uid, mapping] of Object.entries(renames)) {\n originsOf[uid] = invert(mapping);\n }\n\n const renamedPaths = new Map<string, Record<string, string>>();\n\n for (const [subject, contentType] of Object.entries(strapi.contentTypes)) {\n const paths = getNestedFieldsWithIntermediate(contentType as Struct.ContentTypeSchema, {\n components: strapi.components,\n });\n\n const byOldPath: Record<string, string> = {};\n for (const path of paths) {\n const oldPath = getOldPath(subject, path, originsOf);\n if (oldPath !== path) {\n byOldPath[oldPath] = path;\n }\n }\n\n if (!isEmpty(byOldPath)) {\n renamedPaths.set(subject, byOldPath);\n }\n }\n\n return renamedPaths;\n };\n\n return async (trx, renames) => {\n if (isEmpty(renames)) {\n return;\n }\n\n // Fresh database: the table is created by schema sync after the migrations.\n const { tableName } = strapi.db.metadata.get(PERMISSION_UID);\n if (!(await strapi.db.getSchemaConnection(trx).hasTable(tableName))) {\n return;\n }\n\n const renamedPaths = getRenamedPaths(renames);\n if (renamedPaths.size === 0) {\n return;\n }\n\n // Joins the migration transaction.\n const permissions = (await strapi.db.query(PERMISSION_UID).findMany({\n select: ['id', 'subject', 'properties'],\n where: { subject: { $in: [...renamedPaths.keys()] } },\n })) as PermissionRow[];\n\n for (const permission of permissions) {\n const fields = permission.properties?.fields;\n const byOldPath = permission.subject ? renamedPaths.get(permission.subject) : undefined;\n\n if (!Array.isArray(fields) || !byOldPath) {\n continue;\n }\n\n // One pass over the old paths, so a swap is applied once.\n const newFields = uniq(fields.map((field: string) => byOldPath[field] ?? field));\n\n if (xor(fields, newFields).length === 0) {\n continue;\n }\n\n await strapi.db.query(PERMISSION_UID).update({\n where: { id: permission.id },\n data: { properties: { ...permission.properties, fields: newFields } },\n });\n }\n };\n};\n"],"names":["PERMISSION_UID","createPermissionFieldRenamer","strapi","getOldPath","subject","path","originsOf","ownerUid","owner","contentTypes","split","map","segment","origin","attribute","attributes","type","component","components","undefined","join","getRenamedPaths","renames","uid","mapping","Object","entries","invert","renamedPaths","Map","contentType","paths","getNestedFieldsWithIntermediate","byOldPath","oldPath","isEmpty","set","trx","tableName","db","metadata","get","getSchemaConnection","hasTable","size","permissions","query","findMany","select","where","$in","keys","permission","fields","properties","Array","isArray","newFields","uniq","field","xor","length","update","id","data"],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { isEmpty, uniq, xor, invert } from 'lodash';
|
|
2
|
+
import { getNestedFieldsWithIntermediate } from '../content-type.mjs';
|
|
3
|
+
|
|
4
|
+
const PERMISSION_UID = 'admin::permission';
|
|
5
|
+
/**
|
|
6
|
+
* Carries attribute renames to the `properties.fields` of admin permissions
|
|
7
|
+
* (roles and admin API tokens).
|
|
8
|
+
*
|
|
9
|
+
* Runs from the generated rename migration, inside its transaction, before the
|
|
10
|
+
* admin bootstrap cleans permission fields against the new schema. Without it,
|
|
11
|
+
* the cleanup drops every renamed field from every role but the super admin.
|
|
12
|
+
*
|
|
13
|
+
* `strapi.contentTypes` / `strapi.components` already hold the new schema at
|
|
14
|
+
* that point, so every new field path is mapped back to the path it had before
|
|
15
|
+
* the renames, segment by segment (a component field path goes through its
|
|
16
|
+
* parent's component). This also composes a parent rename with a rename inside
|
|
17
|
+
* its component in the same save.
|
|
18
|
+
*/ const createPermissionFieldRenamer = ({ strapi })=>{
|
|
19
|
+
const getOldPath = (subject, path, originsOf)=>{
|
|
20
|
+
let ownerUid = subject;
|
|
21
|
+
let owner = strapi.contentTypes[subject];
|
|
22
|
+
return path.split('.').map((segment)=>{
|
|
23
|
+
const origin = originsOf[ownerUid]?.[segment] ?? segment;
|
|
24
|
+
const attribute = owner?.attributes?.[segment];
|
|
25
|
+
if (attribute?.type === 'component' && attribute.component) {
|
|
26
|
+
ownerUid = attribute.component;
|
|
27
|
+
owner = strapi.components[attribute.component];
|
|
28
|
+
} else {
|
|
29
|
+
owner = undefined;
|
|
30
|
+
}
|
|
31
|
+
return origin;
|
|
32
|
+
}).join('.');
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* `old path -> new path` per subject, for the subjects with at least one
|
|
36
|
+
* renamed path.
|
|
37
|
+
*/ const getRenamedPaths = (renames)=>{
|
|
38
|
+
// Per model: final name -> origin name.
|
|
39
|
+
const originsOf = {};
|
|
40
|
+
for (const [uid, mapping] of Object.entries(renames)){
|
|
41
|
+
originsOf[uid] = invert(mapping);
|
|
42
|
+
}
|
|
43
|
+
const renamedPaths = new Map();
|
|
44
|
+
for (const [subject, contentType] of Object.entries(strapi.contentTypes)){
|
|
45
|
+
const paths = getNestedFieldsWithIntermediate(contentType, {
|
|
46
|
+
components: strapi.components
|
|
47
|
+
});
|
|
48
|
+
const byOldPath = {};
|
|
49
|
+
for (const path of paths){
|
|
50
|
+
const oldPath = getOldPath(subject, path, originsOf);
|
|
51
|
+
if (oldPath !== path) {
|
|
52
|
+
byOldPath[oldPath] = path;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!isEmpty(byOldPath)) {
|
|
56
|
+
renamedPaths.set(subject, byOldPath);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return renamedPaths;
|
|
60
|
+
};
|
|
61
|
+
return async (trx, renames)=>{
|
|
62
|
+
if (isEmpty(renames)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Fresh database: the table is created by schema sync after the migrations.
|
|
66
|
+
const { tableName } = strapi.db.metadata.get(PERMISSION_UID);
|
|
67
|
+
if (!await strapi.db.getSchemaConnection(trx).hasTable(tableName)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const renamedPaths = getRenamedPaths(renames);
|
|
71
|
+
if (renamedPaths.size === 0) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Joins the migration transaction.
|
|
75
|
+
const permissions = await strapi.db.query(PERMISSION_UID).findMany({
|
|
76
|
+
select: [
|
|
77
|
+
'id',
|
|
78
|
+
'subject',
|
|
79
|
+
'properties'
|
|
80
|
+
],
|
|
81
|
+
where: {
|
|
82
|
+
subject: {
|
|
83
|
+
$in: [
|
|
84
|
+
...renamedPaths.keys()
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
for (const permission of permissions){
|
|
90
|
+
const fields = permission.properties?.fields;
|
|
91
|
+
const byOldPath = permission.subject ? renamedPaths.get(permission.subject) : undefined;
|
|
92
|
+
if (!Array.isArray(fields) || !byOldPath) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
// One pass over the old paths, so a swap is applied once.
|
|
96
|
+
const newFields = uniq(fields.map((field)=>byOldPath[field] ?? field));
|
|
97
|
+
if (xor(fields, newFields).length === 0) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
await strapi.db.query(PERMISSION_UID).update({
|
|
101
|
+
where: {
|
|
102
|
+
id: permission.id
|
|
103
|
+
},
|
|
104
|
+
data: {
|
|
105
|
+
properties: {
|
|
106
|
+
...permission.properties,
|
|
107
|
+
fields: newFields
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export { createPermissionFieldRenamer };
|
|
116
|
+
//# sourceMappingURL=rename-fields.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename-fields.mjs","sources":["../../../../../../server/src/services/permission/rename-fields.ts"],"sourcesContent":["import { invert, isEmpty, uniq, xor } from 'lodash';\nimport type { Core, Struct } from '@strapi/types';\n\nimport { getNestedFieldsWithIntermediate } from '../content-type';\n\ntype AttributeRenameHandler = Parameters<\n Core.Strapi['db']['schema']['registerAttributeRenameHandler']\n>[0];\n\ntype AttributeRenames = Parameters<AttributeRenameHandler>[1];\n\ninterface PermissionRow {\n id: number | string;\n subject: string | null;\n properties?: { fields?: unknown } | null;\n}\n\nconst PERMISSION_UID = 'admin::permission';\n\n/**\n * Carries attribute renames to the `properties.fields` of admin permissions\n * (roles and admin API tokens).\n *\n * Runs from the generated rename migration, inside its transaction, before the\n * admin bootstrap cleans permission fields against the new schema. Without it,\n * the cleanup drops every renamed field from every role but the super admin.\n *\n * `strapi.contentTypes` / `strapi.components` already hold the new schema at\n * that point, so every new field path is mapped back to the path it had before\n * the renames, segment by segment (a component field path goes through its\n * parent's component). This also composes a parent rename with a rename inside\n * its component in the same save.\n */\nexport const createPermissionFieldRenamer = ({\n strapi,\n}: {\n strapi: Core.Strapi;\n}): AttributeRenameHandler => {\n const getOldPath = (\n subject: string,\n path: string,\n originsOf: Record<string, Record<string, string>>\n ): string => {\n let ownerUid = subject;\n let owner: Struct.Schema | undefined =\n strapi.contentTypes[subject as keyof typeof strapi.contentTypes];\n\n return path\n .split('.')\n .map((segment) => {\n const origin = originsOf[ownerUid]?.[segment] ?? segment;\n const attribute = owner?.attributes?.[segment] as\n | { type?: string; component?: string }\n | undefined;\n\n if (attribute?.type === 'component' && attribute.component) {\n ownerUid = attribute.component;\n owner = strapi.components[attribute.component as keyof typeof strapi.components];\n } else {\n owner = undefined;\n }\n\n return origin;\n })\n .join('.');\n };\n\n /**\n * `old path -> new path` per subject, for the subjects with at least one\n * renamed path.\n */\n const getRenamedPaths = (renames: AttributeRenames): Map<string, Record<string, string>> => {\n // Per model: final name -> origin name.\n const originsOf: Record<string, Record<string, string>> = {};\n for (const [uid, mapping] of Object.entries(renames)) {\n originsOf[uid] = invert(mapping);\n }\n\n const renamedPaths = new Map<string, Record<string, string>>();\n\n for (const [subject, contentType] of Object.entries(strapi.contentTypes)) {\n const paths = getNestedFieldsWithIntermediate(contentType as Struct.ContentTypeSchema, {\n components: strapi.components,\n });\n\n const byOldPath: Record<string, string> = {};\n for (const path of paths) {\n const oldPath = getOldPath(subject, path, originsOf);\n if (oldPath !== path) {\n byOldPath[oldPath] = path;\n }\n }\n\n if (!isEmpty(byOldPath)) {\n renamedPaths.set(subject, byOldPath);\n }\n }\n\n return renamedPaths;\n };\n\n return async (trx, renames) => {\n if (isEmpty(renames)) {\n return;\n }\n\n // Fresh database: the table is created by schema sync after the migrations.\n const { tableName } = strapi.db.metadata.get(PERMISSION_UID);\n if (!(await strapi.db.getSchemaConnection(trx).hasTable(tableName))) {\n return;\n }\n\n const renamedPaths = getRenamedPaths(renames);\n if (renamedPaths.size === 0) {\n return;\n }\n\n // Joins the migration transaction.\n const permissions = (await strapi.db.query(PERMISSION_UID).findMany({\n select: ['id', 'subject', 'properties'],\n where: { subject: { $in: [...renamedPaths.keys()] } },\n })) as PermissionRow[];\n\n for (const permission of permissions) {\n const fields = permission.properties?.fields;\n const byOldPath = permission.subject ? renamedPaths.get(permission.subject) : undefined;\n\n if (!Array.isArray(fields) || !byOldPath) {\n continue;\n }\n\n // One pass over the old paths, so a swap is applied once.\n const newFields = uniq(fields.map((field: string) => byOldPath[field] ?? field));\n\n if (xor(fields, newFields).length === 0) {\n continue;\n }\n\n await strapi.db.query(PERMISSION_UID).update({\n where: { id: permission.id },\n data: { properties: { ...permission.properties, fields: newFields } },\n });\n }\n };\n};\n"],"names":["PERMISSION_UID","createPermissionFieldRenamer","strapi","getOldPath","subject","path","originsOf","ownerUid","owner","contentTypes","split","map","segment","origin","attribute","attributes","type","component","components","undefined","join","getRenamedPaths","renames","uid","mapping","Object","entries","invert","renamedPaths","Map","contentType","paths","getNestedFieldsWithIntermediate","byOldPath","oldPath","isEmpty","set","trx","tableName","db","metadata","get","getSchemaConnection","hasTable","size","permissions","query","findMany","select","where","$in","keys","permission","fields","properties","Array","isArray","newFields","uniq","field","xor","length","update","id","data"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _ = require('lodash');
|
|
4
4
|
var builder = require('./builder.js');
|
|
5
5
|
var handlers = require('./handlers.js');
|
|
6
6
|
|
|
7
|
-
const sectionPropMatcher =
|
|
7
|
+
const sectionPropMatcher = (section)=>_.matchesProperty('section', section);
|
|
8
8
|
const createContentTypesInitialState = ()=>({
|
|
9
9
|
actions: [],
|
|
10
10
|
subjects: []
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../../../server/src/services/permission/sections-builder/index.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../../../server/src/services/permission/sections-builder/index.ts"],"sourcesContent":["import { matchesProperty } from 'lodash';\nimport createSectionBuilder from './builder';\nimport {\n subjectsHandlerFor,\n contentTypesBase,\n fieldsProperty,\n plugins as pluginsHandler,\n settings as settingsHandler,\n} from './handlers';\n\nconst sectionPropMatcher = (section: string) => matchesProperty('section', section);\n\nconst createContentTypesInitialState = () => ({\n actions: [],\n subjects: [],\n});\n\nconst createDefaultSectionBuilder = () => {\n const builder = createSectionBuilder();\n\n builder.createSection('plugins', {\n initialStateFactory: () => [],\n handlers: [pluginsHandler],\n matchers: [sectionPropMatcher('plugins')],\n });\n\n builder.createSection('settings', {\n initialStateFactory: () => [],\n handlers: [settingsHandler],\n matchers: [sectionPropMatcher('settings')],\n });\n\n builder.createSection('singleTypes', {\n initialStateFactory: createContentTypesInitialState,\n handlers: [contentTypesBase, subjectsHandlerFor('singleType'), fieldsProperty],\n matchers: [sectionPropMatcher('contentTypes')],\n });\n\n builder.createSection('collectionTypes', {\n initialStateFactory: createContentTypesInitialState,\n handlers: [contentTypesBase, subjectsHandlerFor('collectionType'), fieldsProperty],\n matchers: [sectionPropMatcher('contentTypes')],\n });\n\n return builder;\n};\n\nexport default createDefaultSectionBuilder;\n"],"names":["sectionPropMatcher","section","matchesProperty","createContentTypesInitialState","actions","subjects","createDefaultSectionBuilder","builder","createSectionBuilder","createSection","initialStateFactory","handlers","pluginsHandler","matchers","settingsHandler","contentTypesBase","subjectsHandlerFor","fieldsProperty"],"mappings":";;;;;;AAUA,MAAMA,kBAAAA,GAAqB,CAACC,OAAAA,GAAoBC,iBAAAA,CAAgB,SAAA,EAAWD,OAAAA,CAAAA;AAE3E,MAAME,8BAAAA,GAAiC,KAAO;AAC5CC,QAAAA,OAAAA,EAAS,EAAE;AACXC,QAAAA,QAAAA,EAAU;KACZ,CAAA;AAEA,MAAMC,2BAAAA,GAA8B,IAAA;AAClC,IAAA,MAAMC,SAAAA,GAAUC,OAAAA,EAAAA;IAEhBD,SAAAA,CAAQE,aAAa,CAAC,SAAA,EAAW;AAC/BC,QAAAA,mBAAAA,EAAqB,IAAM,EAAE;QAC7BC,QAAAA,EAAU;AAACC,YAAAA;AAAe,SAAA;QAC1BC,QAAAA,EAAU;YAACb,kBAAAA,CAAmB,SAAA;AAAW;AAC3C,KAAA,CAAA;IAEAO,SAAAA,CAAQE,aAAa,CAAC,UAAA,EAAY;AAChCC,QAAAA,mBAAAA,EAAqB,IAAM,EAAE;QAC7BC,QAAAA,EAAU;AAACG,YAAAA;AAAgB,SAAA;QAC3BD,QAAAA,EAAU;YAACb,kBAAAA,CAAmB,UAAA;AAAY;AAC5C,KAAA,CAAA;IAEAO,SAAAA,CAAQE,aAAa,CAAC,aAAA,EAAe;QACnCC,mBAAAA,EAAqBP,8BAAAA;QACrBQ,QAAAA,EAAU;AAACI,YAAAA,yBAAAA;YAAkBC,2BAAAA,CAAmB,YAAA,CAAA;AAAeC,YAAAA;AAAe,SAAA;QAC9EJ,QAAAA,EAAU;YAACb,kBAAAA,CAAmB,cAAA;AAAgB;AAChD,KAAA,CAAA;IAEAO,SAAAA,CAAQE,aAAa,CAAC,iBAAA,EAAmB;QACvCC,mBAAAA,EAAqBP,8BAAAA;QACrBQ,QAAAA,EAAU;AAACI,YAAAA,yBAAAA;YAAkBC,2BAAAA,CAAmB,gBAAA,CAAA;AAAmBC,YAAAA;AAAe,SAAA;QAClFJ,QAAAA,EAAU;YAACb,kBAAAA,CAAmB,cAAA;AAAgB;AAChD,KAAA,CAAA;IAEA,OAAOO,SAAAA;AACT;;;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { matchesProperty } from 'lodash';
|
|
2
2
|
import createSectionBuilder from './builder.mjs';
|
|
3
3
|
import { plugins, settings, contentTypesBase, fieldsProperty, subjectsHandlerFor } from './handlers.mjs';
|
|
4
4
|
|
|
5
|
-
const sectionPropMatcher =
|
|
5
|
+
const sectionPropMatcher = (section)=>matchesProperty('section', section);
|
|
6
6
|
const createContentTypesInitialState = ()=>({
|
|
7
7
|
actions: [],
|
|
8
8
|
subjects: []
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../../../../server/src/services/permission/sections-builder/index.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../../../../server/src/services/permission/sections-builder/index.ts"],"sourcesContent":["import { matchesProperty } from 'lodash';\nimport createSectionBuilder from './builder';\nimport {\n subjectsHandlerFor,\n contentTypesBase,\n fieldsProperty,\n plugins as pluginsHandler,\n settings as settingsHandler,\n} from './handlers';\n\nconst sectionPropMatcher = (section: string) => matchesProperty('section', section);\n\nconst createContentTypesInitialState = () => ({\n actions: [],\n subjects: [],\n});\n\nconst createDefaultSectionBuilder = () => {\n const builder = createSectionBuilder();\n\n builder.createSection('plugins', {\n initialStateFactory: () => [],\n handlers: [pluginsHandler],\n matchers: [sectionPropMatcher('plugins')],\n });\n\n builder.createSection('settings', {\n initialStateFactory: () => [],\n handlers: [settingsHandler],\n matchers: [sectionPropMatcher('settings')],\n });\n\n builder.createSection('singleTypes', {\n initialStateFactory: createContentTypesInitialState,\n handlers: [contentTypesBase, subjectsHandlerFor('singleType'), fieldsProperty],\n matchers: [sectionPropMatcher('contentTypes')],\n });\n\n builder.createSection('collectionTypes', {\n initialStateFactory: createContentTypesInitialState,\n handlers: [contentTypesBase, subjectsHandlerFor('collectionType'), fieldsProperty],\n matchers: [sectionPropMatcher('contentTypes')],\n });\n\n return builder;\n};\n\nexport default createDefaultSectionBuilder;\n"],"names":["sectionPropMatcher","section","matchesProperty","createContentTypesInitialState","actions","subjects","createDefaultSectionBuilder","builder","createSectionBuilder","createSection","initialStateFactory","handlers","pluginsHandler","matchers","settingsHandler","contentTypesBase","subjectsHandlerFor","fieldsProperty"],"mappings":";;;;AAUA,MAAMA,kBAAAA,GAAqB,CAACC,OAAAA,GAAoBC,eAAAA,CAAgB,SAAA,EAAWD,OAAAA,CAAAA;AAE3E,MAAME,8BAAAA,GAAiC,KAAO;AAC5CC,QAAAA,OAAAA,EAAS,EAAE;AACXC,QAAAA,QAAAA,EAAU;KACZ,CAAA;AAEA,MAAMC,2BAAAA,GAA8B,IAAA;AAClC,IAAA,MAAMC,OAAAA,GAAUC,oBAAAA,EAAAA;IAEhBD,OAAAA,CAAQE,aAAa,CAAC,SAAA,EAAW;AAC/BC,QAAAA,mBAAAA,EAAqB,IAAM,EAAE;QAC7BC,QAAAA,EAAU;AAACC,YAAAA;AAAe,SAAA;QAC1BC,QAAAA,EAAU;YAACb,kBAAAA,CAAmB,SAAA;AAAW;AAC3C,KAAA,CAAA;IAEAO,OAAAA,CAAQE,aAAa,CAAC,UAAA,EAAY;AAChCC,QAAAA,mBAAAA,EAAqB,IAAM,EAAE;QAC7BC,QAAAA,EAAU;AAACG,YAAAA;AAAgB,SAAA;QAC3BD,QAAAA,EAAU;YAACb,kBAAAA,CAAmB,UAAA;AAAY;AAC5C,KAAA,CAAA;IAEAO,OAAAA,CAAQE,aAAa,CAAC,aAAA,EAAe;QACnCC,mBAAAA,EAAqBP,8BAAAA;QACrBQ,QAAAA,EAAU;AAACI,YAAAA,gBAAAA;YAAkBC,kBAAAA,CAAmB,YAAA,CAAA;AAAeC,YAAAA;AAAe,SAAA;QAC9EJ,QAAAA,EAAU;YAACb,kBAAAA,CAAmB,cAAA;AAAgB;AAChD,KAAA,CAAA;IAEAO,OAAAA,CAAQE,aAAa,CAAC,iBAAA,EAAmB;QACvCC,mBAAAA,EAAqBP,8BAAAA;QACrBQ,QAAAA,EAAU;AAACI,YAAAA,gBAAAA;YAAkBC,kBAAAA,CAAmB,gBAAA,CAAA;AAAmBC,YAAAA;AAAe,SAAA;QAClFJ,QAAAA,EAAU;YAACb,kBAAAA,CAAmB,cAAA;AAAgB;AAChD,KAAA,CAAA;IAEA,OAAOO,OAAAA;AACT;;;;"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var fp = require('lodash/fp');
|
|
4
3
|
var utils = require('@strapi/utils');
|
|
5
4
|
|
|
6
5
|
const emptyObjectFactory = ()=>({});
|
|
@@ -23,7 +22,7 @@ const emptyObjectFactory = ()=>({});
|
|
|
23
22
|
* If any of the registered matcher functions returns true, then the condition applies.
|
|
24
23
|
*/ async appliesToAction (action) {
|
|
25
24
|
const results = await state.hooks.matchers.call(action);
|
|
26
|
-
return results.some(
|
|
25
|
+
return results.some((result)=>result === true);
|
|
27
26
|
},
|
|
28
27
|
/**
|
|
29
28
|
* Init, build and returns a section object based on the given actions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section.js","sources":["../../../../../../../server/src/services/permission/sections-builder/section.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"section.js","sources":["../../../../../../../server/src/services/permission/sections-builder/section.ts"],"sourcesContent":["import { hooks } from '@strapi/utils';\nimport type { Action } from '../../../domain/action';\n\nexport type SectionOptions = {\n initialStateFactory?: (...args: any) => unknown; // A factory function that returns the default shape of the section\n handlers?: ((...args: any) => unknown)[]; // An initial collection of handlers which will be registered in the handlers hook\n matchers?: ((...args: any) => unknown)[]; // An initial collection of matchers which will be registered in the matchers hook\n};\n\nconst emptyObjectFactory = () => ({});\n\n/**\n * Upon call, creates a new section object\n */\nconst createSection = (\n { initialStateFactory = emptyObjectFactory, handlers = [], matchers = [] } = {} as SectionOptions\n) => {\n const state = {\n hooks: {\n handlers: hooks.createAsyncSeriesHook(),\n matchers: hooks.createAsyncParallelHook(),\n },\n };\n\n // Register initial hooks\n handlers.forEach((handler) => state.hooks.handlers.register(handler));\n matchers.forEach((matcher) => state.hooks.matchers.register(matcher));\n\n return {\n hooks: state.hooks,\n\n /**\n * Verifies if an action can be applied to the section by running the matchers hook.\n * If any of the registered matcher functions returns true, then the condition applies.\n */\n async appliesToAction(action: Action): Promise<boolean> {\n const results = await state.hooks.matchers.call(action);\n\n return results.some((result) => result === true);\n },\n\n /**\n * Init, build and returns a section object based on the given actions\n * @param actions - A list of actions used to populate the section\n */\n async build(actions = [] as Action[]) {\n const section = initialStateFactory();\n\n for (const action of actions) {\n const applies = await this.appliesToAction(action);\n\n if (applies) {\n await state.hooks.handlers.call({ action, section });\n }\n }\n\n return section;\n },\n };\n};\n\nexport default createSection;\n"],"names":["emptyObjectFactory","createSection","initialStateFactory","handlers","matchers","state","hooks","createAsyncSeriesHook","createAsyncParallelHook","forEach","handler","register","matcher","appliesToAction","action","results","call","some","result","build","actions","section","applies"],"mappings":";;;;AASA,MAAMA,kBAAAA,GAAqB,KAAO,EAAC,CAAA;AAEnC;;AAEC,IACD,MAAMC,aAAAA,GAAgB,CACpB,EAAEC,sBAAsBF,kBAAkB,EAAEG,QAAAA,GAAW,EAAE,EAAEC,QAAAA,GAAW,EAAE,EAAE,GAAG,EAAoB,GAAA;AAEjG,IAAA,MAAMC,KAAAA,GAAQ;QACZC,KAAAA,EAAO;AACLH,YAAAA,QAAAA,EAAUG,YAAMC,qBAAqB,EAAA;AACrCH,YAAAA,QAAAA,EAAUE,YAAME,uBAAuB;AACzC;AACF,KAAA;;IAGAL,QAAAA,CAASM,OAAO,CAAC,CAACC,OAAAA,GAAYL,KAAAA,CAAMC,KAAK,CAACH,QAAQ,CAACQ,QAAQ,CAACD,OAAAA,CAAAA,CAAAA;IAC5DN,QAAAA,CAASK,OAAO,CAAC,CAACG,OAAAA,GAAYP,KAAAA,CAAMC,KAAK,CAACF,QAAQ,CAACO,QAAQ,CAACC,OAAAA,CAAAA,CAAAA;IAE5D,OAAO;AACLN,QAAAA,KAAAA,EAAOD,MAAMC,KAAK;AAElB;;;QAIA,MAAMO,iBAAgBC,MAAc,EAAA;YAClC,MAAMC,OAAAA,GAAU,MAAMV,KAAAA,CAAMC,KAAK,CAACF,QAAQ,CAACY,IAAI,CAACF,MAAAA,CAAAA;AAEhD,YAAA,OAAOC,OAAAA,CAAQE,IAAI,CAAC,CAACC,SAAWA,MAAAA,KAAW,IAAA,CAAA;AAC7C,QAAA,CAAA;AAEA;;;AAGC,QACD,MAAMC,KAAAA,CAAAA,CAAMC,OAAAA,GAAU,EAAE,EAAY;AAClC,YAAA,MAAMC,OAAAA,GAAUnB,mBAAAA,EAAAA;YAEhB,KAAK,MAAMY,UAAUM,OAAAA,CAAS;AAC5B,gBAAA,MAAME,OAAAA,GAAU,MAAM,IAAI,CAACT,eAAe,CAACC,MAAAA,CAAAA;AAE3C,gBAAA,IAAIQ,OAAAA,EAAS;AACX,oBAAA,MAAMjB,MAAMC,KAAK,CAACH,QAAQ,CAACa,IAAI,CAAC;AAAEF,wBAAAA,MAAAA;AAAQO,wBAAAA;AAAQ,qBAAA,CAAA;AACpD,gBAAA;AACF,YAAA;YAEA,OAAOA,OAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { eq } from 'lodash/fp';
|
|
2
1
|
import { hooks } from '@strapi/utils';
|
|
3
2
|
|
|
4
3
|
const emptyObjectFactory = ()=>({});
|
|
@@ -21,7 +20,7 @@ const emptyObjectFactory = ()=>({});
|
|
|
21
20
|
* If any of the registered matcher functions returns true, then the condition applies.
|
|
22
21
|
*/ async appliesToAction (action) {
|
|
23
22
|
const results = await state.hooks.matchers.call(action);
|
|
24
|
-
return results.some(
|
|
23
|
+
return results.some((result)=>result === true);
|
|
25
24
|
},
|
|
26
25
|
/**
|
|
27
26
|
* Init, build and returns a section object based on the given actions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section.mjs","sources":["../../../../../../../server/src/services/permission/sections-builder/section.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"section.mjs","sources":["../../../../../../../server/src/services/permission/sections-builder/section.ts"],"sourcesContent":["import { hooks } from '@strapi/utils';\nimport type { Action } from '../../../domain/action';\n\nexport type SectionOptions = {\n initialStateFactory?: (...args: any) => unknown; // A factory function that returns the default shape of the section\n handlers?: ((...args: any) => unknown)[]; // An initial collection of handlers which will be registered in the handlers hook\n matchers?: ((...args: any) => unknown)[]; // An initial collection of matchers which will be registered in the matchers hook\n};\n\nconst emptyObjectFactory = () => ({});\n\n/**\n * Upon call, creates a new section object\n */\nconst createSection = (\n { initialStateFactory = emptyObjectFactory, handlers = [], matchers = [] } = {} as SectionOptions\n) => {\n const state = {\n hooks: {\n handlers: hooks.createAsyncSeriesHook(),\n matchers: hooks.createAsyncParallelHook(),\n },\n };\n\n // Register initial hooks\n handlers.forEach((handler) => state.hooks.handlers.register(handler));\n matchers.forEach((matcher) => state.hooks.matchers.register(matcher));\n\n return {\n hooks: state.hooks,\n\n /**\n * Verifies if an action can be applied to the section by running the matchers hook.\n * If any of the registered matcher functions returns true, then the condition applies.\n */\n async appliesToAction(action: Action): Promise<boolean> {\n const results = await state.hooks.matchers.call(action);\n\n return results.some((result) => result === true);\n },\n\n /**\n * Init, build and returns a section object based on the given actions\n * @param actions - A list of actions used to populate the section\n */\n async build(actions = [] as Action[]) {\n const section = initialStateFactory();\n\n for (const action of actions) {\n const applies = await this.appliesToAction(action);\n\n if (applies) {\n await state.hooks.handlers.call({ action, section });\n }\n }\n\n return section;\n },\n };\n};\n\nexport default createSection;\n"],"names":["emptyObjectFactory","createSection","initialStateFactory","handlers","matchers","state","hooks","createAsyncSeriesHook","createAsyncParallelHook","forEach","handler","register","matcher","appliesToAction","action","results","call","some","result","build","actions","section","applies"],"mappings":";;AASA,MAAMA,kBAAAA,GAAqB,KAAO,EAAC,CAAA;AAEnC;;AAEC,IACD,MAAMC,aAAAA,GAAgB,CACpB,EAAEC,sBAAsBF,kBAAkB,EAAEG,QAAAA,GAAW,EAAE,EAAEC,QAAAA,GAAW,EAAE,EAAE,GAAG,EAAoB,GAAA;AAEjG,IAAA,MAAMC,KAAAA,GAAQ;QACZC,KAAAA,EAAO;AACLH,YAAAA,QAAAA,EAAUG,MAAMC,qBAAqB,EAAA;AACrCH,YAAAA,QAAAA,EAAUE,MAAME,uBAAuB;AACzC;AACF,KAAA;;IAGAL,QAAAA,CAASM,OAAO,CAAC,CAACC,OAAAA,GAAYL,KAAAA,CAAMC,KAAK,CAACH,QAAQ,CAACQ,QAAQ,CAACD,OAAAA,CAAAA,CAAAA;IAC5DN,QAAAA,CAASK,OAAO,CAAC,CAACG,OAAAA,GAAYP,KAAAA,CAAMC,KAAK,CAACF,QAAQ,CAACO,QAAQ,CAACC,OAAAA,CAAAA,CAAAA;IAE5D,OAAO;AACLN,QAAAA,KAAAA,EAAOD,MAAMC,KAAK;AAElB;;;QAIA,MAAMO,iBAAgBC,MAAc,EAAA;YAClC,MAAMC,OAAAA,GAAU,MAAMV,KAAAA,CAAMC,KAAK,CAACF,QAAQ,CAACY,IAAI,CAACF,MAAAA,CAAAA;AAEhD,YAAA,OAAOC,OAAAA,CAAQE,IAAI,CAAC,CAACC,SAAWA,MAAAA,KAAW,IAAA,CAAA;AAC7C,QAAA,CAAA;AAEA;;;AAGC,QACD,MAAMC,KAAAA,CAAAA,CAAMC,OAAAA,GAAU,EAAE,EAAY;AAClC,YAAA,MAAMC,OAAAA,GAAUnB,mBAAAA,EAAAA;YAEhB,KAAK,MAAMY,UAAUM,OAAAA,CAAS;AAC5B,gBAAA,MAAME,OAAAA,GAAU,MAAM,IAAI,CAACT,eAAe,CAACC,MAAAA,CAAAA;AAE3C,gBAAA,IAAIQ,OAAAA,EAAS;AACX,oBAAA,MAAMjB,MAAMC,KAAK,CAACH,QAAQ,CAACa,IAAI,CAAC;AAAEF,wBAAAA,MAAAA;AAAQO,wBAAAA;AAAQ,qBAAA,CAAA;AACpD,gBAAA;AACF,YAAA;YAEA,OAAOA,OAAAA;AACT,QAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _ = require('lodash');
|
|
4
4
|
|
|
5
|
-
const isOfKind = (kind)=>
|
|
5
|
+
const isOfKind = (kind)=>_.matchesProperty('kind', kind);
|
|
6
6
|
const resolveContentType = (uid)=>{
|
|
7
7
|
return strapi.contentTypes[uid];
|
|
8
8
|
};
|
|
9
9
|
const isNotInSubjects = (subjects)=>(uid)=>!subjects.find((subject)=>subject.uid === uid);
|
|
10
|
-
const hasProperty =
|
|
10
|
+
const hasProperty = _.curry((property, subject)=>{
|
|
11
11
|
return !!subject.properties.find((prop)=>prop.value === property);
|
|
12
12
|
});
|
|
13
|
-
const getValidOptions =
|
|
14
|
-
|
|
15
|
-
]);
|
|
13
|
+
const getValidOptions = (options)=>_.pick(options, [
|
|
14
|
+
'applyToProperties'
|
|
15
|
+
]);
|
|
16
16
|
const toSubjectTemplate = (ct)=>({
|
|
17
17
|
uid: ct.uid,
|
|
18
18
|
label: ct.info.singularName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../../../../../server/src/services/permission/sections-builder/utils.ts"],"sourcesContent":["import { curry, matchesProperty
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../../../../../server/src/services/permission/sections-builder/utils.ts"],"sourcesContent":["import { pick, curry, matchesProperty } from 'lodash';\n\nimport type { Internal, Struct } from '@strapi/types';\n\nconst isOfKind = (kind: unknown) => matchesProperty('kind', kind);\n\nconst resolveContentType = (uid: Internal.UID.ContentType): Struct.ContentTypeSchema => {\n return strapi.contentTypes[uid];\n};\n\nconst isNotInSubjects = (subjects: any) => (uid: unknown) =>\n !subjects.find((subject: any) => subject.uid === uid);\n\nconst hasProperty = curry((property: unknown, subject: any) => {\n return !!subject.properties.find((prop: any) => prop.value === property);\n});\n\nconst getValidOptions = (options: object) => pick(options, ['applyToProperties']);\n\nconst toSubjectTemplate = (ct: any) => ({\n uid: ct.uid,\n label: ct.info.singularName,\n properties: [],\n});\n\nexport {\n isOfKind,\n resolveContentType,\n isNotInSubjects,\n hasProperty,\n getValidOptions,\n toSubjectTemplate,\n};\n"],"names":["isOfKind","kind","matchesProperty","resolveContentType","uid","strapi","contentTypes","isNotInSubjects","subjects","find","subject","hasProperty","curry","property","properties","prop","value","getValidOptions","options","pick","toSubjectTemplate","ct","label","info","singularName"],"mappings":";;;;AAIA,MAAMA,QAAAA,GAAW,CAACC,IAAAA,GAAkBC,iBAAAA,CAAgB,MAAA,EAAQD,IAAAA;AAE5D,MAAME,qBAAqB,CAACC,GAAAA,GAAAA;IAC1B,OAAOC,MAAAA,CAAOC,YAAY,CAACF,GAAAA,CAAI;AACjC;AAEA,MAAMG,eAAAA,GAAkB,CAACC,QAAAA,GAAkB,CAACJ,GAAAA,GAC1C,CAACI,QAAAA,CAASC,IAAI,CAAC,CAACC,OAAAA,GAAiBA,OAAAA,CAAQN,GAAG,KAAKA,GAAAA;AAEnD,MAAMO,WAAAA,GAAcC,OAAAA,CAAM,CAACC,QAAAA,EAAmBH,OAAAA,GAAAA;IAC5C,OAAO,CAAC,CAACA,OAAAA,CAAQI,UAAU,CAACL,IAAI,CAAC,CAACM,IAAAA,GAAcA,IAAAA,CAAKC,KAAK,KAAKH,QAAAA,CAAAA;AACjE,CAAA;AAEA,MAAMI,eAAAA,GAAkB,CAACC,OAAAA,GAAoBC,MAAAA,CAAKD,OAAAA,EAAS;AAAC,QAAA;AAAoB,KAAA;AAEhF,MAAME,iBAAAA,GAAoB,CAACC,EAAAA,IAAa;AACtCjB,QAAAA,GAAAA,EAAKiB,GAAGjB,GAAG;QACXkB,KAAAA,EAAOD,EAAAA,CAAGE,IAAI,CAACC,YAAY;AAC3BV,QAAAA,UAAAA,EAAY;KACd;;;;;;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { curry, pick, matchesProperty } from 'lodash
|
|
1
|
+
import { curry, pick, matchesProperty } from 'lodash';
|
|
2
2
|
|
|
3
3
|
const isOfKind = (kind)=>matchesProperty('kind', kind);
|
|
4
4
|
const resolveContentType = (uid)=>{
|
|
@@ -8,9 +8,9 @@ const isNotInSubjects = (subjects)=>(uid)=>!subjects.find((subject)=>subject.uid
|
|
|
8
8
|
const hasProperty = curry((property, subject)=>{
|
|
9
9
|
return !!subject.properties.find((prop)=>prop.value === property);
|
|
10
10
|
});
|
|
11
|
-
const getValidOptions = pick([
|
|
12
|
-
|
|
13
|
-
]);
|
|
11
|
+
const getValidOptions = (options)=>pick(options, [
|
|
12
|
+
'applyToProperties'
|
|
13
|
+
]);
|
|
14
14
|
const toSubjectTemplate = (ct)=>({
|
|
15
15
|
uid: ct.uid,
|
|
16
16
|
label: ct.info.singularName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","sources":["../../../../../../../server/src/services/permission/sections-builder/utils.ts"],"sourcesContent":["import { curry, matchesProperty
|
|
1
|
+
{"version":3,"file":"utils.mjs","sources":["../../../../../../../server/src/services/permission/sections-builder/utils.ts"],"sourcesContent":["import { pick, curry, matchesProperty } from 'lodash';\n\nimport type { Internal, Struct } from '@strapi/types';\n\nconst isOfKind = (kind: unknown) => matchesProperty('kind', kind);\n\nconst resolveContentType = (uid: Internal.UID.ContentType): Struct.ContentTypeSchema => {\n return strapi.contentTypes[uid];\n};\n\nconst isNotInSubjects = (subjects: any) => (uid: unknown) =>\n !subjects.find((subject: any) => subject.uid === uid);\n\nconst hasProperty = curry((property: unknown, subject: any) => {\n return !!subject.properties.find((prop: any) => prop.value === property);\n});\n\nconst getValidOptions = (options: object) => pick(options, ['applyToProperties']);\n\nconst toSubjectTemplate = (ct: any) => ({\n uid: ct.uid,\n label: ct.info.singularName,\n properties: [],\n});\n\nexport {\n isOfKind,\n resolveContentType,\n isNotInSubjects,\n hasProperty,\n getValidOptions,\n toSubjectTemplate,\n};\n"],"names":["isOfKind","kind","matchesProperty","resolveContentType","uid","strapi","contentTypes","isNotInSubjects","subjects","find","subject","hasProperty","curry","property","properties","prop","value","getValidOptions","options","pick","toSubjectTemplate","ct","label","info","singularName"],"mappings":";;AAIA,MAAMA,QAAAA,GAAW,CAACC,IAAAA,GAAkBC,eAAAA,CAAgB,MAAA,EAAQD,IAAAA;AAE5D,MAAME,qBAAqB,CAACC,GAAAA,GAAAA;IAC1B,OAAOC,MAAAA,CAAOC,YAAY,CAACF,GAAAA,CAAI;AACjC;AAEA,MAAMG,eAAAA,GAAkB,CAACC,QAAAA,GAAkB,CAACJ,GAAAA,GAC1C,CAACI,QAAAA,CAASC,IAAI,CAAC,CAACC,OAAAA,GAAiBA,OAAAA,CAAQN,GAAG,KAAKA,GAAAA;AAEnD,MAAMO,WAAAA,GAAcC,KAAAA,CAAM,CAACC,QAAAA,EAAmBH,OAAAA,GAAAA;IAC5C,OAAO,CAAC,CAACA,OAAAA,CAAQI,UAAU,CAACL,IAAI,CAAC,CAACM,IAAAA,GAAcA,IAAAA,CAAKC,KAAK,KAAKH,QAAAA,CAAAA;AACjE,CAAA;AAEA,MAAMI,eAAAA,GAAkB,CAACC,OAAAA,GAAoBC,IAAAA,CAAKD,OAAAA,EAAS;AAAC,QAAA;AAAoB,KAAA;AAEhF,MAAME,iBAAAA,GAAoB,CAACC,EAAAA,IAAa;AACtCjB,QAAAA,GAAAA,EAAKiB,GAAGjB,GAAG;QACXkB,KAAAA,EAAOD,EAAAA,CAAGE,IAAI,CAACC,YAAY;AAC3BV,QAAAA,UAAAA,EAAY;KACd;;;;"}
|