@strapi/admin 5.55.1 → 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/components/UpsellBanner.js +9 -16
- package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
- package/dist/admin/admin/src/components/UpsellBanner.mjs +11 -18
- package/dist/admin/admin/src/components/UpsellBanner.mjs.map +1 -1
- 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/render.js +4 -69
- package/dist/admin/admin/src/render.js.map +1 -1
- package/dist/admin/admin/src/render.mjs +4 -69
- package/dist/admin/admin/src/render.mjs.map +1 -1
- package/dist/admin/admin/src/translations/en.json.js +15 -0
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +15 -0
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/browserStrapi.js +93 -0
- package/dist/admin/admin/src/utils/browserStrapi.js.map +1 -0
- package/dist/admin/admin/src/utils/browserStrapi.mjs +91 -0
- package/dist/admin/admin/src/utils/browserStrapi.mjs.map +1 -0
- 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/hooks/useExportAuditLogs.js +2 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +2 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +16 -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 +16 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js +3 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs +3 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js +64 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs +60 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.mjs.map +1 -0
- package/dist/admin/ee/admin/src/services/auditLogs.js +2 -1
- package/dist/admin/ee/admin/src/services/auditLogs.js.map +1 -1
- package/dist/admin/ee/admin/src/services/auditLogs.mjs +2 -1
- package/dist/admin/ee/admin/src/services/auditLogs.mjs.map +1 -1
- package/dist/admin/src/components/MediaLibraryBanner.d.ts +10 -1
- package/dist/admin/src/components/SubNav.d.ts +2 -2
- 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/admin/src/utils/browserStrapi.d.ts +11 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +15 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/legacyActions.d.ts +14 -0
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +10 -1
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/admin.d.ts +2 -28
- 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/index.d.ts +1 -28
- package/dist/ee/server/src/controllers/index.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 +6 -30
- package/dist/ee/server/src/index.d.ts.map +1 -1
- package/dist/ee/server/src/services/auth.d.ts +1 -1
- package/dist/ee/server/src/services/auth.d.ts.map +1 -1
- package/dist/ee/server/src/services/index.d.ts +5 -2
- 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/ee/server/src/services/user.d.ts.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +37 -21
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +37 -21
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
- package/dist/server/ee/server/src/controllers/admin.js +8 -7
- package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
- package/dist/server/ee/server/src/controllers/admin.mjs +8 -7
- 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/index.js +4 -0
- package/dist/server/ee/server/src/index.js.map +1 -1
- package/dist/server/ee/server/src/index.mjs +4 -0
- package/dist/server/ee/server/src/index.mjs.map +1 -1
- package/dist/server/ee/server/src/services/auth.js +1 -6
- package/dist/server/ee/server/src/services/auth.js.map +1 -1
- package/dist/server/ee/server/src/services/auth.mjs +2 -7
- package/dist/server/ee/server/src/services/auth.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 +37 -6
- package/dist/server/ee/server/src/services/user.js.map +1 -1
- package/dist/server/ee/server/src/services/user.mjs +38 -7
- 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 +169 -0
- package/dist/server/server/src/audit-logs/admin-users.js.map +1 -0
- package/dist/server/server/src/audit-logs/admin-users.mjs +157 -0
- package/dist/server/server/src/audit-logs/admin-users.mjs.map +1 -0
- 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 +106 -0
- package/dist/server/server/src/audit-logs/webhooks.js.map +1 -0
- package/dist/server/server/src/audit-logs/webhooks.mjs +100 -0
- package/dist/server/server/src/audit-logs/webhooks.mjs.map +1 -0
- 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 +4 -5
- package/dist/server/server/src/controllers/admin.js.map +1 -1
- package/dist/server/server/src/controllers/admin.mjs +3 -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/authentication.js +8 -1
- package/dist/server/server/src/controllers/authentication.js.map +1 -1
- package/dist/server/server/src/controllers/authentication.mjs +8 -1
- package/dist/server/server/src/controllers/authentication.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/controllers/webhooks.js +26 -0
- package/dist/server/server/src/controllers/webhooks.js.map +1 -1
- package/dist/server/server/src/controllers/webhooks.mjs +27 -1
- package/dist/server/server/src/controllers/webhooks.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/auth.js +27 -6
- package/dist/server/server/src/services/auth.js.map +1 -1
- package/dist/server/server/src/services/auth.mjs +28 -8
- package/dist/server/server/src/services/auth.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 +50 -12
- package/dist/server/server/src/services/user.js.map +1 -1
- package/dist/server/server/src/services/user.mjs +52 -14
- 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/admin-users.d.ts +119 -0
- package/dist/server/src/audit-logs/admin-users.d.ts.map +1 -0
- package/dist/server/src/audit-logs/tokens.d.ts.map +1 -1
- package/dist/server/src/audit-logs/webhooks.d.ts +59 -0
- package/dist/server/src/audit-logs/webhooks.d.ts.map +1 -0
- 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 +2 -11
- 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/authentication.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 +2 -11
- package/dist/server/src/controllers/index.d.ts.map +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/controllers/webhooks.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/domain/user.d.ts +2 -2
- package/dist/server/src/index.d.ts +4 -13
- 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/auth.d.ts +6 -1
- package/dist/server/src/services/auth.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/services/user.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/dist/shared/contracts/admin.d.ts +36 -2
- package/dist/shared/contracts/admin.d.ts.map +1 -1
- package/package.json +13 -13
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import bcrypt from 'bcryptjs';
|
|
2
2
|
import ___default from 'lodash';
|
|
3
|
-
import { errors } from '@strapi/utils';
|
|
3
|
+
import { errors, emitAudit } from '@strapi/utils';
|
|
4
4
|
import { getService } from '../utils/index.mjs';
|
|
5
5
|
import { expiresInToSeconds } from './token.mjs';
|
|
6
|
+
import { AUDITED_EVENTS, toAdminUserEvent } from '../audit-logs/admin-users.mjs';
|
|
6
7
|
import '@strapi/types';
|
|
7
8
|
|
|
8
9
|
const { ApplicationError } = errors;
|
|
@@ -24,12 +25,35 @@ const DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';
|
|
|
24
25
|
*/ const assignResetPasswordToken = async (userId)=>{
|
|
25
26
|
const resetPasswordToken = getService('token').createToken();
|
|
26
27
|
const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());
|
|
27
|
-
await getService('user').updateById(userId, {
|
|
28
|
+
const user = await getService('user').updateById(userId, {
|
|
28
29
|
resetPasswordToken,
|
|
29
30
|
resetPasswordTokenExpiresAt
|
|
30
31
|
});
|
|
32
|
+
// null when the account was deleted between the caller's lookup and this write
|
|
33
|
+
if (user) {
|
|
34
|
+
await emitAudit({
|
|
35
|
+
strapi
|
|
36
|
+
}, AUDITED_EVENTS.PASSWORD_RESET_CREATE, {
|
|
37
|
+
...toAdminUserEvent(user),
|
|
38
|
+
expiresAt: user.resetPasswordTokenExpiresAt
|
|
39
|
+
});
|
|
40
|
+
}
|
|
31
41
|
return resetPasswordToken;
|
|
32
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* Set the new password and consume the reset token. Shared by the CE and EE auth
|
|
45
|
+
* services, after each has validated the token.
|
|
46
|
+
*/ const completePasswordReset = async (user, password)=>{
|
|
47
|
+
const updatedUser = await getService('user').updateById(user.id, {
|
|
48
|
+
password,
|
|
49
|
+
resetPasswordToken: null,
|
|
50
|
+
resetPasswordTokenExpiresAt: null
|
|
51
|
+
});
|
|
52
|
+
await emitAudit({
|
|
53
|
+
strapi
|
|
54
|
+
}, AUDITED_EVENTS.PASSWORD_RESET_CONFIRM, toAdminUserEvent(updatedUser));
|
|
55
|
+
return updatedUser;
|
|
56
|
+
};
|
|
33
57
|
/**
|
|
34
58
|
* Reject a reset-password token that has expired — or that has no expiry at all
|
|
35
59
|
* (tokens issued before this was introduced) — clearing the stale token so it
|
|
@@ -148,11 +172,7 @@ const DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';
|
|
|
148
172
|
throw new ApplicationError();
|
|
149
173
|
}
|
|
150
174
|
await assertResetPasswordTokenIsValid(matchingUser);
|
|
151
|
-
return
|
|
152
|
-
password,
|
|
153
|
-
resetPasswordToken: null,
|
|
154
|
-
resetPasswordTokenExpiresAt: null
|
|
155
|
-
});
|
|
175
|
+
return completePasswordReset(matchingUser, password);
|
|
156
176
|
};
|
|
157
177
|
var auth = {
|
|
158
178
|
checkCredentials,
|
|
@@ -162,5 +182,5 @@ var auth = {
|
|
|
162
182
|
resetPassword
|
|
163
183
|
};
|
|
164
184
|
|
|
165
|
-
export { assertResetPasswordTokenIsValid, assignResetPasswordToken, auth as default, getResetPasswordTokenTTL };
|
|
185
|
+
export { assertResetPasswordTokenIsValid, assignResetPasswordToken, completePasswordReset, auth as default, getResetPasswordTokenTTL };
|
|
166
186
|
//# sourceMappingURL=auth.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.mjs","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { expiresInToSeconds } from './token';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\n\n// Default lifetime of an admin reset-password token. Overridable via\n// `admin.forgotPassword.expiresIn` (number of seconds or a shorthand like '15m', '1h').\nconst DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';\n\n/**\n * Resolve the reset-password token lifetime, in milliseconds, from config.\n * Falls back to {@link DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN} for unset/invalid values.\n */\nconst getResetPasswordTokenTTL = (): number => {\n const configured = strapi.config.get(\n 'admin.forgotPassword.expiresIn',\n DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN\n );\n const seconds =\n expiresInToSeconds(configured) ??\n (expiresInToSeconds(DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN) as number);\n return seconds * 1000;\n};\n\n/**\n * Create a reset-password token with an expiry and persist it on the user.\n * Shared by the CE and EE auth services so the expiry behaviour can't drift.\n * @returns the generated reset-password token\n */\nconst assignResetPasswordToken = async (userId: AdminUser['id']): Promise<string> => {\n const resetPasswordToken = getService('token').createToken();\n const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());\n\n await getService('user').updateById(userId, {\n resetPasswordToken,\n resetPasswordTokenExpiresAt,\n });\n\n return resetPasswordToken;\n};\n\n/**\n * Reject a reset-password token that has expired — or that has no expiry at all\n * (tokens issued before this was introduced) — clearing the stale token so it\n * cannot be retried. Shared by the CE and EE auth services. (GH#25711)\n */\nconst assertResetPasswordTokenIsValid = async (user: AdminUser): Promise<void> => {\n const { resetPasswordTokenExpiresAt } = user;\n const isExpired =\n !resetPasswordTokenExpiresAt || new Date(resetPasswordTokenExpiresAt).getTime() <= Date.now();\n\n if (isExpired) {\n // Clear the stale token so it can no longer be retried.\n await getService('user').updateById(user.id, {\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n throw new ApplicationError('This reset password token has expired');\n }\n};\n\n/**\n * hashes a password\n * @param password - password to hash\n * @returns hashed password\n */\nconst hashPassword = (password: string) => bcrypt.hash(password, 10);\n\n/**\n * Validate a password\n * @param password\n * @param hash\n * @returns {Promise<boolean>} is the password valid\n */\nconst validatePassword = (password: string, hash: string) => bcrypt.compare(password, hash);\n\n/**\n * Check login credentials\n * @param email the users email address\n * @param password the users password\n */\nconst checkCredentials = async ({ email, password }: { email: string; password: string }) => {\n const user: AdminUser = await strapi.db.query('admin::user').findOne({ where: { email } });\n\n if (!user || !user.password) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n const isValid = await validatePassword(password, user.password);\n\n if (!isValid) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n if (!(user.isActive === true)) {\n return [null, false, { message: 'User not active' }];\n }\n\n return [null, user];\n};\n\n/**\n * Send an email to the user if it exists or do nothing\n * @param email user email for which to reset the password\n */\nconst forgotPassword = async ({ email } = {} as { email: string }) => {\n const user: AdminUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { email, isActive: true } });\n if (!user) {\n return;\n }\n\n const resetPasswordToken = await assignResetPasswordToken(user.id);\n\n // Send an email to the admin.\n const url = `${strapi.config.get(\n 'admin.absoluteUrl'\n )}/auth/reset-password?code=${resetPasswordToken}`;\n\n return strapi\n .plugin('email')\n .service('email')\n .sendTemplatedEmail(\n {\n to: user.email,\n from: strapi.config.get('admin.forgotPassword.from'),\n replyTo: strapi.config.get('admin.forgotPassword.replyTo'),\n },\n strapi.config.get('admin.forgotPassword.emailTemplate'),\n {\n url,\n user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),\n }\n )\n .catch((err: unknown) => {\n // log error server side but do not disclose it to the user to avoid leaking informations\n strapi.log.error(err);\n });\n};\n\n/**\n * Reset a user password\n * @param resetPasswordToken token generated to request a password reset\n * @param password new user password\n */\nconst resetPassword = async (\n { resetPasswordToken, password } = {} as { resetPasswordToken: string; password: string }\n) => {\n const matchingUser: AdminUser | undefined = await strapi.db\n .query('admin::user')\n .findOne({ where: { resetPasswordToken, isActive: true } });\n\n if (!matchingUser) {\n throw new ApplicationError();\n }\n\n await assertResetPasswordTokenIsValid(matchingUser);\n\n return getService('user').updateById(matchingUser.id, {\n password,\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\nexport { getResetPasswordTokenTTL, assignResetPasswordToken, assertResetPasswordTokenIsValid };\n"],"names":["ApplicationError","errors","DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN","getResetPasswordTokenTTL","configured","strapi","config","get","seconds","expiresInToSeconds","assignResetPasswordToken","userId","resetPasswordToken","getService","createToken","resetPasswordTokenExpiresAt","Date","now","updateById","assertResetPasswordTokenIsValid","user","isExpired","getTime","id","hashPassword","password","bcrypt","hash","validatePassword","compare","checkCredentials","email","db","query","findOne","where","message","isValid","isActive","forgotPassword","url","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth.mjs","sources":["../../../../../server/src/services/auth.ts"],"sourcesContent":["import bcrypt from 'bcryptjs';\nimport _ from 'lodash';\nimport { errors, emitAudit } from '@strapi/utils';\nimport { getService } from '../utils';\nimport { expiresInToSeconds } from './token';\nimport { AUDITED_EVENTS, toAdminUserEvent } from '../audit-logs/admin-users';\nimport type { AdminUser } from '../../../shared/contracts/shared';\nimport '@strapi/types';\n\nconst { ApplicationError } = errors;\n\n// Default lifetime of an admin reset-password token. Overridable via\n// `admin.forgotPassword.expiresIn` (number of seconds or a shorthand like '15m', '1h').\nconst DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN = '1h';\n\n/**\n * Resolve the reset-password token lifetime, in milliseconds, from config.\n * Falls back to {@link DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN} for unset/invalid values.\n */\nconst getResetPasswordTokenTTL = (): number => {\n const configured = strapi.config.get(\n 'admin.forgotPassword.expiresIn',\n DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN\n );\n const seconds =\n expiresInToSeconds(configured) ??\n (expiresInToSeconds(DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN) as number);\n return seconds * 1000;\n};\n\n/**\n * Create a reset-password token with an expiry and persist it on the user.\n * Shared by the CE and EE auth services so the expiry behaviour can't drift.\n * @returns the generated reset-password token\n */\nconst assignResetPasswordToken = async (userId: AdminUser['id']): Promise<string> => {\n const resetPasswordToken = getService('token').createToken();\n const resetPasswordTokenExpiresAt = new Date(Date.now() + getResetPasswordTokenTTL());\n\n const user = await getService('user').updateById(userId, {\n resetPasswordToken,\n resetPasswordTokenExpiresAt,\n });\n\n // null when the account was deleted between the caller's lookup and this write\n if (user) {\n await emitAudit({ strapi }, AUDITED_EVENTS.PASSWORD_RESET_CREATE, {\n ...toAdminUserEvent(user),\n expiresAt: user.resetPasswordTokenExpiresAt,\n });\n }\n\n return resetPasswordToken;\n};\n\n/**\n * Set the new password and consume the reset token. Shared by the CE and EE auth\n * services, after each has validated the token.\n */\nconst completePasswordReset = async (user: AdminUser, password: string): Promise<AdminUser> => {\n const updatedUser = await getService('user').updateById(user.id, {\n password,\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n\n await emitAudit({ strapi }, AUDITED_EVENTS.PASSWORD_RESET_CONFIRM, toAdminUserEvent(updatedUser));\n\n return updatedUser;\n};\n\n/**\n * Reject a reset-password token that has expired — or that has no expiry at all\n * (tokens issued before this was introduced) — clearing the stale token so it\n * cannot be retried. Shared by the CE and EE auth services. (GH#25711)\n */\nconst assertResetPasswordTokenIsValid = async (user: AdminUser): Promise<void> => {\n const { resetPasswordTokenExpiresAt } = user;\n const isExpired =\n !resetPasswordTokenExpiresAt || new Date(resetPasswordTokenExpiresAt).getTime() <= Date.now();\n\n if (isExpired) {\n // Clear the stale token so it can no longer be retried.\n await getService('user').updateById(user.id, {\n resetPasswordToken: null,\n resetPasswordTokenExpiresAt: null,\n });\n throw new ApplicationError('This reset password token has expired');\n }\n};\n\n/**\n * hashes a password\n * @param password - password to hash\n * @returns hashed password\n */\nconst hashPassword = (password: string) => bcrypt.hash(password, 10);\n\n/**\n * Validate a password\n * @param password\n * @param hash\n * @returns {Promise<boolean>} is the password valid\n */\nconst validatePassword = (password: string, hash: string) => bcrypt.compare(password, hash);\n\n/**\n * Check login credentials\n * @param email the users email address\n * @param password the users password\n */\nconst checkCredentials = async ({ email, password }: { email: string; password: string }) => {\n const user: AdminUser = await strapi.db.query('admin::user').findOne({ where: { email } });\n\n if (!user || !user.password) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n const isValid = await validatePassword(password, user.password);\n\n if (!isValid) {\n return [null, false, { message: 'Invalid credentials' }];\n }\n\n if (!(user.isActive === true)) {\n return [null, false, { message: 'User not active' }];\n }\n\n return [null, user];\n};\n\n/**\n * Send an email to the user if it exists or do nothing\n * @param email user email for which to reset the password\n */\nconst forgotPassword = async ({ email } = {} as { email: string }) => {\n const user: AdminUser = await strapi.db\n .query('admin::user')\n .findOne({ where: { email, isActive: true } });\n if (!user) {\n return;\n }\n\n const resetPasswordToken = await assignResetPasswordToken(user.id);\n\n // Send an email to the admin.\n const url = `${strapi.config.get(\n 'admin.absoluteUrl'\n )}/auth/reset-password?code=${resetPasswordToken}`;\n\n return strapi\n .plugin('email')\n .service('email')\n .sendTemplatedEmail(\n {\n to: user.email,\n from: strapi.config.get('admin.forgotPassword.from'),\n replyTo: strapi.config.get('admin.forgotPassword.replyTo'),\n },\n strapi.config.get('admin.forgotPassword.emailTemplate'),\n {\n url,\n user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),\n }\n )\n .catch((err: unknown) => {\n // log error server side but do not disclose it to the user to avoid leaking informations\n strapi.log.error(err);\n });\n};\n\n/**\n * Reset a user password\n * @param resetPasswordToken token generated to request a password reset\n * @param password new user password\n */\nconst resetPassword = async (\n { resetPasswordToken, password } = {} as { resetPasswordToken: string; password: string }\n) => {\n const matchingUser: AdminUser | undefined = await strapi.db\n .query('admin::user')\n .findOne({ where: { resetPasswordToken, isActive: true } });\n\n if (!matchingUser) {\n throw new ApplicationError();\n }\n\n await assertResetPasswordTokenIsValid(matchingUser);\n\n return completePasswordReset(matchingUser, password);\n};\n\nexport default { checkCredentials, validatePassword, hashPassword, forgotPassword, resetPassword };\nexport {\n getResetPasswordTokenTTL,\n assignResetPasswordToken,\n assertResetPasswordTokenIsValid,\n completePasswordReset,\n};\n"],"names":["ApplicationError","errors","DEFAULT_RESET_PASSWORD_TOKEN_EXPIRES_IN","getResetPasswordTokenTTL","configured","strapi","config","get","seconds","expiresInToSeconds","assignResetPasswordToken","userId","resetPasswordToken","getService","createToken","resetPasswordTokenExpiresAt","Date","now","user","updateById","emitAudit","AUDITED_EVENTS","PASSWORD_RESET_CREATE","toAdminUserEvent","expiresAt","completePasswordReset","password","updatedUser","id","PASSWORD_RESET_CONFIRM","assertResetPasswordTokenIsValid","isExpired","getTime","hashPassword","bcrypt","hash","validatePassword","compare","checkCredentials","email","db","query","findOne","where","message","isValid","isActive","forgotPassword","url","plugin","service","sendTemplatedEmail","to","from","replyTo","_","pick","catch","err","log","error","resetPassword","matchingUser"],"mappings":";;;;;;;;AASA,MAAM,EAAEA,gBAAgB,EAAE,GAAGC,MAAAA;AAE7B;AACA;AACA,MAAMC,uCAAAA,GAA0C,IAAA;AAEhD;;;AAGC,UACKC,wBAAAA,GAA2B,IAAA;AAC/B,IAAA,MAAMC,aAAaC,MAAAA,CAAOC,MAAM,CAACC,GAAG,CAClC,gCAAA,EACAL,uCAAAA,CAAAA;IAEF,MAAMM,OAAAA,GACJC,kBAAAA,CAAmBL,UAAAA,CAAAA,IAClBK,kBAAAA,CAAmBP,uCAAAA,CAAAA;AACtB,IAAA,OAAOM,OAAAA,GAAU,IAAA;AACnB;AAEA;;;;IAKA,MAAME,2BAA2B,OAAOC,MAAAA,GAAAA;IACtC,MAAMC,kBAAAA,GAAqBC,UAAAA,CAAW,OAAA,CAAA,CAASC,WAAW,EAAA;AAC1D,IAAA,MAAMC,2BAAAA,GAA8B,IAAIC,IAAAA,CAAKA,IAAAA,CAAKC,GAAG,EAAA,GAAKd,wBAAAA,EAAAA,CAAAA;AAE1D,IAAA,MAAMe,OAAO,MAAML,UAAAA,CAAW,MAAA,CAAA,CAAQM,UAAU,CAACR,MAAAA,EAAQ;AACvDC,QAAAA,kBAAAA;AACAG,QAAAA;AACF,KAAA,CAAA;;AAGA,IAAA,IAAIG,IAAAA,EAAM;AACR,QAAA,MAAME,SAAAA,CAAU;AAAEf,YAAAA;SAAO,EAAGgB,cAAAA,CAAeC,qBAAqB,EAAE;AAChE,YAAA,GAAGC,iBAAiBL,IAAAA,CAAK;AACzBM,YAAAA,SAAAA,EAAWN,KAAKH;AAClB,SAAA,CAAA;AACF,IAAA;IAEA,OAAOH,kBAAAA;AACT;AAEA;;;IAIA,MAAMa,qBAAAA,GAAwB,OAAOP,IAAAA,EAAiBQ,QAAAA,GAAAA;IACpD,MAAMC,WAAAA,GAAc,MAAMd,UAAAA,CAAW,MAAA,CAAA,CAAQM,UAAU,CAACD,IAAAA,CAAKU,EAAE,EAAE;AAC/DF,QAAAA,QAAAA;QACAd,kBAAAA,EAAoB,IAAA;QACpBG,2BAAAA,EAA6B;AAC/B,KAAA,CAAA;AAEA,IAAA,MAAMK,SAAAA,CAAU;AAAEf,QAAAA;KAAO,EAAGgB,cAAAA,CAAeQ,sBAAsB,EAAEN,gBAAAA,CAAiBI,WAAAA,CAAAA,CAAAA;IAEpF,OAAOA,WAAAA;AACT;AAEA;;;;IAKA,MAAMG,kCAAkC,OAAOZ,IAAAA,GAAAA;IAC7C,MAAM,EAAEH,2BAA2B,EAAE,GAAGG,IAAAA;IACxC,MAAMa,SAAAA,GACJ,CAAChB,2BAAAA,IAA+B,IAAIC,KAAKD,2BAAAA,CAAAA,CAA6BiB,OAAO,EAAA,IAAMhB,IAAAA,CAAKC,GAAG,EAAA;AAE7F,IAAA,IAAIc,SAAAA,EAAW;;AAEb,QAAA,MAAMlB,WAAW,MAAA,CAAA,CAAQM,UAAU,CAACD,IAAAA,CAAKU,EAAE,EAAE;YAC3ChB,kBAAAA,EAAoB,IAAA;YACpBG,2BAAAA,EAA6B;AAC/B,SAAA,CAAA;AACA,QAAA,MAAM,IAAIf,gBAAAA,CAAiB,uCAAA,CAAA;AAC7B,IAAA;AACF;AAEA;;;;AAIC,IACD,MAAMiC,YAAAA,GAAe,CAACP,WAAqBQ,MAAAA,CAAOC,IAAI,CAACT,QAAAA,EAAU,EAAA,CAAA;AAEjE;;;;;IAMA,MAAMU,mBAAmB,CAACV,QAAAA,EAAkBS,OAAiBD,MAAAA,CAAOG,OAAO,CAACX,QAAAA,EAAUS,IAAAA,CAAAA;AAEtF;;;;AAIC,IACD,MAAMG,gBAAAA,GAAmB,OAAO,EAAEC,KAAK,EAAEb,QAAQ,EAAuC,GAAA;IACtF,MAAMR,IAAAA,GAAkB,MAAMb,MAAAA,CAAOmC,EAAE,CAACC,KAAK,CAAC,aAAA,CAAA,CAAeC,OAAO,CAAC;QAAEC,KAAAA,EAAO;AAAEJ,YAAAA;AAAM;AAAE,KAAA,CAAA;AAExF,IAAA,IAAI,CAACrB,IAAAA,IAAQ,CAACA,IAAAA,CAAKQ,QAAQ,EAAE;QAC3B,OAAO;AAAC,YAAA,IAAA;AAAM,YAAA,KAAA;AAAO,YAAA;gBAAEkB,OAAAA,EAAS;AAAsB;AAAE,SAAA;AAC1D,IAAA;AAEA,IAAA,MAAMC,OAAAA,GAAU,MAAMT,gBAAAA,CAAiBV,QAAAA,EAAUR,KAAKQ,QAAQ,CAAA;AAE9D,IAAA,IAAI,CAACmB,OAAAA,EAAS;QACZ,OAAO;AAAC,YAAA,IAAA;AAAM,YAAA,KAAA;AAAO,YAAA;gBAAED,OAAAA,EAAS;AAAsB;AAAE,SAAA;AAC1D,IAAA;AAEA,IAAA,IAAI,EAAE1B,IAAAA,CAAK4B,QAAQ,KAAK,IAAG,CAAA,EAAI;QAC7B,OAAO;AAAC,YAAA,IAAA;AAAM,YAAA,KAAA;AAAO,YAAA;gBAAEF,OAAAA,EAAS;AAAkB;AAAE,SAAA;AACtD,IAAA;IAEA,OAAO;AAAC,QAAA,IAAA;AAAM1B,QAAAA;AAAK,KAAA;AACrB,CAAA;AAEA;;;IAIA,MAAM6B,iBAAiB,OAAO,EAAER,KAAK,EAAE,GAAG,EAAuB,GAAA;IAC/D,MAAMrB,IAAAA,GAAkB,MAAMb,MAAAA,CAAOmC,EAAE,CACpCC,KAAK,CAAC,aAAA,CAAA,CACNC,OAAO,CAAC;QAAEC,KAAAA,EAAO;AAAEJ,YAAAA,KAAAA;YAAOO,QAAAA,EAAU;AAAK;AAAE,KAAA,CAAA;AAC9C,IAAA,IAAI,CAAC5B,IAAAA,EAAM;AACT,QAAA;AACF,IAAA;AAEA,IAAA,MAAMN,kBAAAA,GAAqB,MAAMF,wBAAAA,CAAyBQ,IAAAA,CAAKU,EAAE,CAAA;;IAGjE,MAAMoB,GAAAA,GAAM,CAAA,EAAG3C,MAAAA,CAAOC,MAAM,CAACC,GAAG,CAC9B,mBAAA,CAAA,CACA,0BAA0B,EAAEK,kBAAAA,CAAAA,CAAoB;IAElD,OAAOP,MAAAA,CACJ4C,MAAM,CAAC,OAAA,CAAA,CACPC,OAAO,CAAC,OAAA,CAAA,CACRC,kBAAkB,CACjB;AACEC,QAAAA,EAAAA,EAAIlC,KAAKqB,KAAK;AACdc,QAAAA,IAAAA,EAAMhD,MAAAA,CAAOC,MAAM,CAACC,GAAG,CAAC,2BAAA,CAAA;AACxB+C,QAAAA,OAAAA,EAASjD,MAAAA,CAAOC,MAAM,CAACC,GAAG,CAAC,8BAAA;AAC7B,KAAA,EACAF,MAAAA,CAAOC,MAAM,CAACC,GAAG,CAAC,oCAAA,CAAA,EAClB;AACEyC,QAAAA,GAAAA;QACA9B,IAAAA,EAAMqC,UAAAA,CAAEC,IAAI,CAACtC,IAAAA,EAAM;AAAC,YAAA,OAAA;AAAS,YAAA,WAAA;AAAa,YAAA,UAAA;AAAY,YAAA;AAAW,SAAA;KACnE,CAAA,CAEDuC,KAAK,CAAC,CAACC,GAAAA,GAAAA;;QAENrD,MAAAA,CAAOsD,GAAG,CAACC,KAAK,CAACF,GAAAA,CAAAA;AACnB,IAAA,CAAA,CAAA;AACJ,CAAA;AAEA;;;;IAKA,MAAMG,aAAAA,GAAgB,OACpB,EAAEjD,kBAAkB,EAAEc,QAAQ,EAAE,GAAG,EAAsD,GAAA;IAEzF,MAAMoC,YAAAA,GAAsC,MAAMzD,MAAAA,CAAOmC,EAAE,CACxDC,KAAK,CAAC,aAAA,CAAA,CACNC,OAAO,CAAC;QAAEC,KAAAA,EAAO;AAAE/B,YAAAA,kBAAAA;YAAoBkC,QAAAA,EAAU;AAAK;AAAE,KAAA,CAAA;AAE3D,IAAA,IAAI,CAACgB,YAAAA,EAAc;AACjB,QAAA,MAAM,IAAI9D,gBAAAA,EAAAA;AACZ,IAAA;AAEA,IAAA,MAAM8B,+BAAAA,CAAgCgC,YAAAA,CAAAA;AAEtC,IAAA,OAAOrC,sBAAsBqC,YAAAA,EAAcpC,QAAAA,CAAAA;AAC7C,CAAA;AAEA,WAAe;AAAEY,IAAAA,gBAAAA;AAAkBF,IAAAA,gBAAAA;AAAkBH,IAAAA,YAAAA;AAAcc,IAAAA,cAAAA;AAAgBc,IAAAA;AAAc,CAAA;;;;"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _ = require('lodash');
|
|
4
4
|
var index = require('../utils/index.js');
|
|
5
5
|
|
|
6
6
|
const isValidCondition = (condition)=>{
|
|
7
7
|
const { conditionProvider } = index.getService('permission');
|
|
8
|
-
return
|
|
8
|
+
return _.isString(condition) && conditionProvider.has(condition);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
exports.isValidCondition = isValidCondition;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"condition.js","sources":["../../../../../server/src/services/condition.ts"],"sourcesContent":["import { isString } from 'lodash
|
|
1
|
+
{"version":3,"file":"condition.js","sources":["../../../../../server/src/services/condition.ts"],"sourcesContent":["import { isString } from 'lodash';\n\nimport { getService } from '../utils';\n\nconst isValidCondition = (condition: unknown) => {\n const { conditionProvider } = getService('permission');\n\n return isString(condition) && conditionProvider.has(condition);\n};\n\nexport { isValidCondition };\n"],"names":["isValidCondition","condition","conditionProvider","getService","isString","has"],"mappings":";;;;;AAIA,MAAMA,mBAAmB,CAACC,SAAAA,GAAAA;AACxB,IAAA,MAAM,EAAEC,iBAAiB,EAAE,GAAGC,gBAAAA,CAAW,YAAA,CAAA;AAEzC,IAAA,OAAOC,UAAAA,CAASH,SAAAA,CAAAA,IAAcC,iBAAAA,CAAkBG,GAAG,CAACJ,SAAAA,CAAAA;AACtD;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"condition.mjs","sources":["../../../../../server/src/services/condition.ts"],"sourcesContent":["import { isString } from 'lodash
|
|
1
|
+
{"version":3,"file":"condition.mjs","sources":["../../../../../server/src/services/condition.ts"],"sourcesContent":["import { isString } from 'lodash';\n\nimport { getService } from '../utils';\n\nconst isValidCondition = (condition: unknown) => {\n const { conditionProvider } = getService('permission');\n\n return isString(condition) && conditionProvider.has(condition);\n};\n\nexport { isValidCondition };\n"],"names":["isValidCondition","condition","conditionProvider","getService","isString","has"],"mappings":";;;AAIA,MAAMA,mBAAmB,CAACC,SAAAA,GAAAA;AACxB,IAAA,MAAM,EAAEC,iBAAiB,EAAE,GAAGC,UAAAA,CAAW,YAAA,CAAA;AAEzC,IAAA,OAAOC,QAAAA,CAASH,SAAAA,CAAAA,IAAcC,iBAAAA,CAAkBG,GAAG,CAACJ,SAAAA,CAAAA;AACtD;;;;"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var _ = require('lodash');
|
|
4
|
-
var fp = require('lodash/fp');
|
|
5
4
|
var utils = require('@strapi/utils');
|
|
6
5
|
var index = require('../utils/index.js');
|
|
7
6
|
var index$1 = require('../domain/action/index.js');
|
|
@@ -24,7 +23,7 @@ var ___default = /*#__PURE__*/_interopDefault(_);
|
|
|
24
23
|
if (nonAuthorizableFields.includes(key)) return fields;
|
|
25
24
|
const fieldPath = prefix ? `${prefix}.${key}` : key;
|
|
26
25
|
const shouldBeIncluded = !requiredOnly || attr.required === true;
|
|
27
|
-
const insideExistingFields = existingFields && existingFields.some(
|
|
26
|
+
const insideExistingFields = existingFields && existingFields.some((field)=>field.startsWith(fieldPath));
|
|
28
27
|
if (attr.type === 'component') {
|
|
29
28
|
if (shouldBeIncluded || insideExistingFields) {
|
|
30
29
|
const compoFields = getNestedFields(components[attr.component], {
|
|
@@ -115,11 +114,13 @@ var ___default = /*#__PURE__*/_interopDefault(_);
|
|
|
115
114
|
nestedFieldsCache.set(subject, possibleFields);
|
|
116
115
|
}
|
|
117
116
|
const currentFields = fields || [];
|
|
118
|
-
const validUserFields =
|
|
117
|
+
const validUserFields = [
|
|
118
|
+
...new Set(possibleFields.filter((pf)=>currentFields.some((cf)=>pf === cf || pf.startsWith(`${cf}.`))))
|
|
119
|
+
];
|
|
119
120
|
// A field is considered "not nested" if no other valid user field starts with this field's path followed by a dot.
|
|
120
121
|
// This helps to remove redundant parent paths when a more specific child path is already included.
|
|
121
122
|
// For example, if 'component.title' is present, 'component' would be filtered out by this condition.
|
|
122
|
-
const isNotNestedField = (field)=>!validUserFields.some((validUserField)=>validUserField !== field &&
|
|
123
|
+
const isNotNestedField = (field)=>!validUserFields.some((validUserField)=>validUserField !== field && validUserField.startsWith(`${field}.`));
|
|
123
124
|
// Filter out fields that are parent paths of other included fields.
|
|
124
125
|
const newFields = validUserFields.filter(isNotNestedField);
|
|
125
126
|
return index$2.default.setProperty('fields', newFields, permission);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-type.js","sources":["../../../../../server/src/services/content-type.ts"],"sourcesContent":["import _ from 'lodash';\nimport { uniq, startsWith } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\nimport type { Modules, Struct } from '@strapi/types';\nimport { getService } from '../utils';\nimport actionDomain from '../domain/action';\nimport permissionDomain from '../domain/permission';\n\ninterface FieldOptions {\n prefix?: string; // prefix to add to the path\n nestingLevel?: number; // level of nesting to achieve\n requiredOnly?: boolean; // only returns required nestedFields\n existingFields?: string[]; // fields that are already selected, meaning that some sub-fields may be required\n restrictedSubjects?: string[]; // subjectsId to ignore\n components?: {\n // components where components attributes can be found\n [key: string]: any;\n };\n}\n\n/**\n * Creates an array of paths to the fields and nested fields, without path nodes\n */\nconst getNestedFields = (\n model: Struct.ContentTypeSchema,\n {\n prefix = '',\n nestingLevel = 15,\n components = {},\n requiredOnly = false,\n existingFields = [],\n }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return prefix ? [prefix] : [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n const shouldBeIncluded = !requiredOnly || attr.required === true;\n const insideExistingFields = existingFields && existingFields.some(startsWith(fieldPath));\n\n if (attr.type === 'component') {\n if (shouldBeIncluded || insideExistingFields) {\n const compoFields = getNestedFields(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n requiredOnly,\n existingFields,\n });\n\n if (compoFields.length === 0 && shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields.concat(compoFields);\n }\n return fields;\n }\n\n if (shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of paths to the fields and nested fields, with path nodes\n */\nconst getNestedFieldsWithIntermediate = (\n model: Struct.ContentTypeSchema,\n { prefix = '', nestingLevel = 15, components = {} }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n fields.push(fieldPath);\n\n if (attr.type === 'component') {\n const compoFields = getNestedFieldsWithIntermediate(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n });\n\n fields.push(...compoFields);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of permissions with the \"properties.fields\" attribute filled\n */\nconst getPermissionsWithNestedFields = (\n actions: any[],\n { nestingLevel, restrictedSubjects = [] }: FieldOptions = {}\n): Modules.Permissions.PermissionRule[] => {\n return actions.reduce((permissions, action) => {\n const validSubjects = action.subjects.filter(\n (subject: any) => !restrictedSubjects.includes(subject)\n );\n\n // Create a Permission for each subject (content-type uid) within the action\n for (const subject of validSubjects) {\n const fields = actionDomain.appliesToProperty('fields', action)\n ? getNestedFields(strapi.contentTypes[subject], {\n components: strapi.components,\n nestingLevel,\n })\n : undefined;\n\n const permission = permissionDomain.create({\n action: action.actionId,\n subject,\n properties: { fields },\n });\n\n permissions.push(permission);\n }\n\n return permissions;\n }, []);\n};\n\n/**\n * Cleans permissions' fields (add required ones, remove the non-existing ones)\n */\nconst cleanPermissionFields = (\n permissions: Modules.Permissions.PermissionRule[]\n): Modules.Permissions.PermissionRule[] => {\n const { actionProvider } = getService('permission');\n const nestedFieldsCache = new Map<string, string[]>();\n\n return permissions.map((permission: any) => {\n const {\n action: actionId,\n subject,\n properties: { fields },\n } = permission;\n\n const action = actionProvider.get(actionId) as any;\n\n // todo see if it's possible to check property on action + subject (async)\n if (!actionDomain.appliesToProperty('fields', action)) {\n return permissionDomain.deleteProperty('fields', permission);\n }\n\n if (!subject || !strapi.contentTypes[subject]) {\n return permission;\n }\n\n let possibleFields = nestedFieldsCache.get(subject);\n if (!possibleFields) {\n possibleFields = getNestedFieldsWithIntermediate(strapi.contentTypes[subject], {\n components: strapi.components,\n });\n nestedFieldsCache.set(subject, possibleFields);\n }\n\n const currentFields: string[] = fields || [];\n\n const validUserFields: string[] = uniq(\n possibleFields.filter((pf) =>\n currentFields.some((cf) => pf === cf || startsWith(`${cf}.`, pf))\n )\n );\n\n // A field is considered \"not nested\" if no other valid user field starts with this field's path followed by a dot.\n // This helps to remove redundant parent paths when a more specific child path is already included.\n // For example, if 'component.title' is present, 'component' would be filtered out by this condition.\n const isNotNestedField = (field: string) =>\n !validUserFields.some(\n (validUserField: string) =>\n validUserField !== field && startsWith(`${field}.`, validUserField)\n );\n\n // Filter out fields that are parent paths of other included fields.\n const newFields = validUserFields.filter(isNotNestedField);\n\n return permissionDomain.setProperty('fields', newFields, permission);\n }, []);\n};\n\nexport {\n getNestedFields,\n getPermissionsWithNestedFields,\n cleanPermissionFields,\n getNestedFieldsWithIntermediate,\n};\n"],"names":["getNestedFields","model","prefix","nestingLevel","components","requiredOnly","existingFields","nonAuthorizableFields","contentTypesUtils","getNonVisibleAttributes","_","reduce","attributes","fields","attr","key","includes","fieldPath","shouldBeIncluded","required","insideExistingFields","some","startsWith","type","compoFields","component","length","concat","getNestedFieldsWithIntermediate","push","getPermissionsWithNestedFields","actions","restrictedSubjects","permissions","action","validSubjects","subjects","filter","subject","actionDomain","appliesToProperty","strapi","contentTypes","undefined","permission","permissionDomain","create","actionId","properties","cleanPermissionFields","actionProvider","getService","nestedFieldsCache","Map","map","get","deleteProperty","possibleFields","set","currentFields","validUserFields","uniq","pf","cf","isNotNestedField","field","validUserField","newFields","setProperty"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"content-type.js","sources":["../../../../../server/src/services/content-type.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\nimport type { Modules, Struct } from '@strapi/types';\nimport { getService } from '../utils';\nimport actionDomain from '../domain/action';\nimport permissionDomain from '../domain/permission';\n\ninterface FieldOptions {\n prefix?: string; // prefix to add to the path\n nestingLevel?: number; // level of nesting to achieve\n requiredOnly?: boolean; // only returns required nestedFields\n existingFields?: string[]; // fields that are already selected, meaning that some sub-fields may be required\n restrictedSubjects?: string[]; // subjectsId to ignore\n components?: {\n // components where components attributes can be found\n [key: string]: any;\n };\n}\n\n/**\n * Creates an array of paths to the fields and nested fields, without path nodes\n */\nconst getNestedFields = (\n model: Struct.ContentTypeSchema,\n {\n prefix = '',\n nestingLevel = 15,\n components = {},\n requiredOnly = false,\n existingFields = [],\n }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return prefix ? [prefix] : [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n const shouldBeIncluded = !requiredOnly || attr.required === true;\n const insideExistingFields =\n existingFields && existingFields.some((field) => field.startsWith(fieldPath));\n\n if (attr.type === 'component') {\n if (shouldBeIncluded || insideExistingFields) {\n const compoFields = getNestedFields(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n requiredOnly,\n existingFields,\n });\n\n if (compoFields.length === 0 && shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields.concat(compoFields);\n }\n return fields;\n }\n\n if (shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of paths to the fields and nested fields, with path nodes\n */\nconst getNestedFieldsWithIntermediate = (\n model: Struct.ContentTypeSchema,\n { prefix = '', nestingLevel = 15, components = {} }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n fields.push(fieldPath);\n\n if (attr.type === 'component') {\n const compoFields = getNestedFieldsWithIntermediate(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n });\n\n fields.push(...compoFields);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of permissions with the \"properties.fields\" attribute filled\n */\nconst getPermissionsWithNestedFields = (\n actions: any[],\n { nestingLevel, restrictedSubjects = [] }: FieldOptions = {}\n): Modules.Permissions.PermissionRule[] => {\n return actions.reduce((permissions, action) => {\n const validSubjects = action.subjects.filter(\n (subject: any) => !restrictedSubjects.includes(subject)\n );\n\n // Create a Permission for each subject (content-type uid) within the action\n for (const subject of validSubjects) {\n const fields = actionDomain.appliesToProperty('fields', action)\n ? getNestedFields(strapi.contentTypes[subject], {\n components: strapi.components,\n nestingLevel,\n })\n : undefined;\n\n const permission = permissionDomain.create({\n action: action.actionId,\n subject,\n properties: { fields },\n });\n\n permissions.push(permission);\n }\n\n return permissions;\n }, []);\n};\n\n/**\n * Cleans permissions' fields (add required ones, remove the non-existing ones)\n */\nconst cleanPermissionFields = (\n permissions: Modules.Permissions.PermissionRule[]\n): Modules.Permissions.PermissionRule[] => {\n const { actionProvider } = getService('permission');\n const nestedFieldsCache = new Map<string, string[]>();\n\n return permissions.map((permission: any) => {\n const {\n action: actionId,\n subject,\n properties: { fields },\n } = permission;\n\n const action = actionProvider.get(actionId) as any;\n\n // todo see if it's possible to check property on action + subject (async)\n if (!actionDomain.appliesToProperty('fields', action)) {\n return permissionDomain.deleteProperty('fields', permission);\n }\n\n if (!subject || !strapi.contentTypes[subject]) {\n return permission;\n }\n\n let possibleFields = nestedFieldsCache.get(subject);\n if (!possibleFields) {\n possibleFields = getNestedFieldsWithIntermediate(strapi.contentTypes[subject], {\n components: strapi.components,\n });\n nestedFieldsCache.set(subject, possibleFields);\n }\n\n const currentFields: string[] = fields || [];\n\n const validUserFields: string[] = [\n ...new Set(\n possibleFields.filter((pf) =>\n currentFields.some((cf) => pf === cf || pf.startsWith(`${cf}.`))\n )\n ),\n ];\n\n // A field is considered \"not nested\" if no other valid user field starts with this field's path followed by a dot.\n // This helps to remove redundant parent paths when a more specific child path is already included.\n // For example, if 'component.title' is present, 'component' would be filtered out by this condition.\n const isNotNestedField = (field: string) =>\n !validUserFields.some(\n (validUserField: string) =>\n validUserField !== field && validUserField.startsWith(`${field}.`)\n );\n\n // Filter out fields that are parent paths of other included fields.\n const newFields = validUserFields.filter(isNotNestedField);\n\n return permissionDomain.setProperty('fields', newFields, permission);\n }, []);\n};\n\nexport {\n getNestedFields,\n getPermissionsWithNestedFields,\n cleanPermissionFields,\n getNestedFieldsWithIntermediate,\n};\n"],"names":["getNestedFields","model","prefix","nestingLevel","components","requiredOnly","existingFields","nonAuthorizableFields","contentTypesUtils","getNonVisibleAttributes","_","reduce","attributes","fields","attr","key","includes","fieldPath","shouldBeIncluded","required","insideExistingFields","some","field","startsWith","type","compoFields","component","length","concat","getNestedFieldsWithIntermediate","push","getPermissionsWithNestedFields","actions","restrictedSubjects","permissions","action","validSubjects","subjects","filter","subject","actionDomain","appliesToProperty","strapi","contentTypes","undefined","permission","permissionDomain","create","actionId","properties","cleanPermissionFields","actionProvider","getService","nestedFieldsCache","Map","map","get","deleteProperty","possibleFields","set","currentFields","validUserFields","Set","pf","cf","isNotNestedField","validUserField","newFields","setProperty"],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import ___default from 'lodash';
|
|
2
|
-
import { uniq, startsWith } from 'lodash/fp';
|
|
3
2
|
import { contentTypes } from '@strapi/utils';
|
|
4
3
|
import { getService } from '../utils/index.mjs';
|
|
5
|
-
import
|
|
4
|
+
import domain from '../domain/action/index.mjs';
|
|
6
5
|
import permissionDomain from '../domain/permission/index.mjs';
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -18,7 +17,7 @@ import permissionDomain from '../domain/permission/index.mjs';
|
|
|
18
17
|
if (nonAuthorizableFields.includes(key)) return fields;
|
|
19
18
|
const fieldPath = prefix ? `${prefix}.${key}` : key;
|
|
20
19
|
const shouldBeIncluded = !requiredOnly || attr.required === true;
|
|
21
|
-
const insideExistingFields = existingFields && existingFields.some(startsWith(fieldPath));
|
|
20
|
+
const insideExistingFields = existingFields && existingFields.some((field)=>field.startsWith(fieldPath));
|
|
22
21
|
if (attr.type === 'component') {
|
|
23
22
|
if (shouldBeIncluded || insideExistingFields) {
|
|
24
23
|
const compoFields = getNestedFields(components[attr.component], {
|
|
@@ -70,7 +69,7 @@ import permissionDomain from '../domain/permission/index.mjs';
|
|
|
70
69
|
const validSubjects = action.subjects.filter((subject)=>!restrictedSubjects.includes(subject));
|
|
71
70
|
// Create a Permission for each subject (content-type uid) within the action
|
|
72
71
|
for (const subject of validSubjects){
|
|
73
|
-
const fields =
|
|
72
|
+
const fields = domain.appliesToProperty('fields', action) ? getNestedFields(strapi.contentTypes[subject], {
|
|
74
73
|
components: strapi.components,
|
|
75
74
|
nestingLevel
|
|
76
75
|
}) : undefined;
|
|
@@ -95,7 +94,7 @@ import permissionDomain from '../domain/permission/index.mjs';
|
|
|
95
94
|
const { action: actionId, subject, properties: { fields } } = permission;
|
|
96
95
|
const action = actionProvider.get(actionId);
|
|
97
96
|
// todo see if it's possible to check property on action + subject (async)
|
|
98
|
-
if (!
|
|
97
|
+
if (!domain.appliesToProperty('fields', action)) {
|
|
99
98
|
return permissionDomain.deleteProperty('fields', permission);
|
|
100
99
|
}
|
|
101
100
|
if (!subject || !strapi.contentTypes[subject]) {
|
|
@@ -109,11 +108,13 @@ import permissionDomain from '../domain/permission/index.mjs';
|
|
|
109
108
|
nestedFieldsCache.set(subject, possibleFields);
|
|
110
109
|
}
|
|
111
110
|
const currentFields = fields || [];
|
|
112
|
-
const validUserFields =
|
|
111
|
+
const validUserFields = [
|
|
112
|
+
...new Set(possibleFields.filter((pf)=>currentFields.some((cf)=>pf === cf || pf.startsWith(`${cf}.`))))
|
|
113
|
+
];
|
|
113
114
|
// A field is considered "not nested" if no other valid user field starts with this field's path followed by a dot.
|
|
114
115
|
// This helps to remove redundant parent paths when a more specific child path is already included.
|
|
115
116
|
// For example, if 'component.title' is present, 'component' would be filtered out by this condition.
|
|
116
|
-
const isNotNestedField = (field)=>!validUserFields.some((validUserField)=>validUserField !== field && startsWith(`${field}
|
|
117
|
+
const isNotNestedField = (field)=>!validUserFields.some((validUserField)=>validUserField !== field && validUserField.startsWith(`${field}.`));
|
|
117
118
|
// Filter out fields that are parent paths of other included fields.
|
|
118
119
|
const newFields = validUserFields.filter(isNotNestedField);
|
|
119
120
|
return permissionDomain.setProperty('fields', newFields, permission);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-type.mjs","sources":["../../../../../server/src/services/content-type.ts"],"sourcesContent":["import _ from 'lodash';\nimport { uniq, startsWith } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\nimport type { Modules, Struct } from '@strapi/types';\nimport { getService } from '../utils';\nimport actionDomain from '../domain/action';\nimport permissionDomain from '../domain/permission';\n\ninterface FieldOptions {\n prefix?: string; // prefix to add to the path\n nestingLevel?: number; // level of nesting to achieve\n requiredOnly?: boolean; // only returns required nestedFields\n existingFields?: string[]; // fields that are already selected, meaning that some sub-fields may be required\n restrictedSubjects?: string[]; // subjectsId to ignore\n components?: {\n // components where components attributes can be found\n [key: string]: any;\n };\n}\n\n/**\n * Creates an array of paths to the fields and nested fields, without path nodes\n */\nconst getNestedFields = (\n model: Struct.ContentTypeSchema,\n {\n prefix = '',\n nestingLevel = 15,\n components = {},\n requiredOnly = false,\n existingFields = [],\n }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return prefix ? [prefix] : [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n const shouldBeIncluded = !requiredOnly || attr.required === true;\n const insideExistingFields = existingFields && existingFields.some(startsWith(fieldPath));\n\n if (attr.type === 'component') {\n if (shouldBeIncluded || insideExistingFields) {\n const compoFields = getNestedFields(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n requiredOnly,\n existingFields,\n });\n\n if (compoFields.length === 0 && shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields.concat(compoFields);\n }\n return fields;\n }\n\n if (shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of paths to the fields and nested fields, with path nodes\n */\nconst getNestedFieldsWithIntermediate = (\n model: Struct.ContentTypeSchema,\n { prefix = '', nestingLevel = 15, components = {} }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n fields.push(fieldPath);\n\n if (attr.type === 'component') {\n const compoFields = getNestedFieldsWithIntermediate(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n });\n\n fields.push(...compoFields);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of permissions with the \"properties.fields\" attribute filled\n */\nconst getPermissionsWithNestedFields = (\n actions: any[],\n { nestingLevel, restrictedSubjects = [] }: FieldOptions = {}\n): Modules.Permissions.PermissionRule[] => {\n return actions.reduce((permissions, action) => {\n const validSubjects = action.subjects.filter(\n (subject: any) => !restrictedSubjects.includes(subject)\n );\n\n // Create a Permission for each subject (content-type uid) within the action\n for (const subject of validSubjects) {\n const fields = actionDomain.appliesToProperty('fields', action)\n ? getNestedFields(strapi.contentTypes[subject], {\n components: strapi.components,\n nestingLevel,\n })\n : undefined;\n\n const permission = permissionDomain.create({\n action: action.actionId,\n subject,\n properties: { fields },\n });\n\n permissions.push(permission);\n }\n\n return permissions;\n }, []);\n};\n\n/**\n * Cleans permissions' fields (add required ones, remove the non-existing ones)\n */\nconst cleanPermissionFields = (\n permissions: Modules.Permissions.PermissionRule[]\n): Modules.Permissions.PermissionRule[] => {\n const { actionProvider } = getService('permission');\n const nestedFieldsCache = new Map<string, string[]>();\n\n return permissions.map((permission: any) => {\n const {\n action: actionId,\n subject,\n properties: { fields },\n } = permission;\n\n const action = actionProvider.get(actionId) as any;\n\n // todo see if it's possible to check property on action + subject (async)\n if (!actionDomain.appliesToProperty('fields', action)) {\n return permissionDomain.deleteProperty('fields', permission);\n }\n\n if (!subject || !strapi.contentTypes[subject]) {\n return permission;\n }\n\n let possibleFields = nestedFieldsCache.get(subject);\n if (!possibleFields) {\n possibleFields = getNestedFieldsWithIntermediate(strapi.contentTypes[subject], {\n components: strapi.components,\n });\n nestedFieldsCache.set(subject, possibleFields);\n }\n\n const currentFields: string[] = fields || [];\n\n const validUserFields: string[] = uniq(\n possibleFields.filter((pf) =>\n currentFields.some((cf) => pf === cf || startsWith(`${cf}.`, pf))\n )\n );\n\n // A field is considered \"not nested\" if no other valid user field starts with this field's path followed by a dot.\n // This helps to remove redundant parent paths when a more specific child path is already included.\n // For example, if 'component.title' is present, 'component' would be filtered out by this condition.\n const isNotNestedField = (field: string) =>\n !validUserFields.some(\n (validUserField: string) =>\n validUserField !== field && startsWith(`${field}.`, validUserField)\n );\n\n // Filter out fields that are parent paths of other included fields.\n const newFields = validUserFields.filter(isNotNestedField);\n\n return permissionDomain.setProperty('fields', newFields, permission);\n }, []);\n};\n\nexport {\n getNestedFields,\n getPermissionsWithNestedFields,\n cleanPermissionFields,\n getNestedFieldsWithIntermediate,\n};\n"],"names":["getNestedFields","model","prefix","nestingLevel","components","requiredOnly","existingFields","nonAuthorizableFields","contentTypesUtils","getNonVisibleAttributes","_","reduce","attributes","fields","attr","key","includes","fieldPath","shouldBeIncluded","required","insideExistingFields","some","startsWith","type","compoFields","component","length","concat","getNestedFieldsWithIntermediate","push","getPermissionsWithNestedFields","actions","restrictedSubjects","permissions","action","validSubjects","subjects","filter","subject","actionDomain","appliesToProperty","strapi","contentTypes","undefined","permission","permissionDomain","create","actionId","properties","cleanPermissionFields","actionProvider","getService","nestedFieldsCache","Map","map","get","deleteProperty","possibleFields","set","currentFields","validUserFields","uniq","pf","cf","isNotNestedField","field","validUserField","newFields","setProperty"],"mappings":";;;;;;;AAoBA;;IAGA,MAAMA,kBAAkB,CACtBC,KAAAA,EACA,EACEC,MAAAA,GAAS,EAAE,EACXC,YAAAA,GAAe,EAAE,EACjBC,UAAAA,GAAa,EAAE,EACfC,YAAAA,GAAe,KAAK,EACpBC,cAAAA,GAAiB,EAAE,EACN,GAAA;AAEf,IAAA,IAAIH,iBAAiB,CAAA,EAAG;AACtB,QAAA,OAAOD,MAAAA,GAAS;AAACA,YAAAA;AAAO,SAAA,GAAG,EAAE;AAC/B,IAAA;IAEA,MAAMK,qBAAAA,GAAwBC,YAAAA,CAAkBC,uBAAuB,CAACR,KAAAA,CAAAA;IAExE,OAAOS,UAAAA,CAAEC,MAAM,CACbV,KAAAA,CAAMW,UAAU,EAChB,CAACC,QAAaC,IAAAA,EAAWC,GAAAA,GAAAA;AACvB,QAAA,IAAIR,qBAAAA,CAAsBS,QAAQ,CAACD,GAAAA,CAAAA,EAAM,OAAOF,MAAAA;AAEhD,QAAA,MAAMI,YAAYf,MAAAA,GAAS,CAAA,EAAGA,OAAO,CAAC,EAAEa,KAAK,GAAGA,GAAAA;AAChD,QAAA,MAAMG,gBAAAA,GAAmB,CAACb,YAAAA,IAAgBS,IAAAA,CAAKK,QAAQ,KAAK,IAAA;AAC5D,QAAA,MAAMC,oBAAAA,GAAuBd,cAAAA,IAAkBA,cAAAA,CAAee,IAAI,CAACC,UAAAA,CAAWL,SAAAA,CAAAA,CAAAA;QAE9E,IAAIH,IAAAA,CAAKS,IAAI,KAAK,WAAA,EAAa;AAC7B,YAAA,IAAIL,oBAAoBE,oBAAAA,EAAsB;AAC5C,gBAAA,MAAMI,cAAcxB,eAAAA,CAAgBI,UAAU,CAACU,IAAAA,CAAKW,SAAS,CAAC,EAAE;AAC9DtB,oBAAAA,YAAAA,EAAcA,YAAAA,GAAe,CAAA;oBAC7BD,MAAAA,EAAQe,SAAAA;AACRb,oBAAAA,UAAAA;AACAC,oBAAAA,YAAAA;AACAC,oBAAAA;AACF,iBAAA,CAAA;AAEA,gBAAA,IAAIkB,WAAAA,CAAYE,MAAM,KAAK,CAAA,IAAKR,gBAAAA,EAAkB;oBAChD,OAAOL,MAAAA,CAAOc,MAAM,CAACV,SAAAA,CAAAA;AACvB,gBAAA;gBAEA,OAAOJ,MAAAA,CAAOc,MAAM,CAACH,WAAAA,CAAAA;AACvB,YAAA;YACA,OAAOX,MAAAA;AACT,QAAA;AAEA,QAAA,IAAIK,gBAAAA,EAAkB;YACpB,OAAOL,MAAAA,CAAOc,MAAM,CAACV,SAAAA,CAAAA;AACvB,QAAA;QAEA,OAAOJ,MAAAA;AACT,IAAA,CAAA,EACA,EAAE,CAAA;AAEN;AAEA;;AAEC,IACD,MAAMe,+BAAAA,GAAkC,CACtC3B,KAAAA,EACA,EAAEC,MAAAA,GAAS,EAAE,EAAEC,YAAAA,GAAe,EAAE,EAAEC,UAAAA,GAAa,EAAE,EAAgB,GAAA;AAEjE,IAAA,IAAID,iBAAiB,CAAA,EAAG;AACtB,QAAA,OAAO,EAAE;AACX,IAAA;IAEA,MAAMI,qBAAAA,GAAwBC,YAAAA,CAAkBC,uBAAuB,CAACR,KAAAA,CAAAA;IAExE,OAAOS,UAAAA,CAAEC,MAAM,CACbV,KAAAA,CAAMW,UAAU,EAChB,CAACC,QAAaC,IAAAA,EAAWC,GAAAA,GAAAA;AACvB,QAAA,IAAIR,qBAAAA,CAAsBS,QAAQ,CAACD,GAAAA,CAAAA,EAAM,OAAOF,MAAAA;AAEhD,QAAA,MAAMI,YAAYf,MAAAA,GAAS,CAAA,EAAGA,OAAO,CAAC,EAAEa,KAAK,GAAGA,GAAAA;AAChDF,QAAAA,MAAAA,CAAOgB,IAAI,CAACZ,SAAAA,CAAAA;QAEZ,IAAIH,IAAAA,CAAKS,IAAI,KAAK,WAAA,EAAa;AAC7B,YAAA,MAAMC,cAAcI,+BAAAA,CAAgCxB,UAAU,CAACU,IAAAA,CAAKW,SAAS,CAAC,EAAE;AAC9EtB,gBAAAA,YAAAA,EAAcA,YAAAA,GAAe,CAAA;gBAC7BD,MAAAA,EAAQe,SAAAA;AACRb,gBAAAA;AACF,aAAA,CAAA;AAEAS,YAAAA,MAAAA,CAAOgB,IAAI,CAAA,GAAIL,WAAAA,CAAAA;AACjB,QAAA;QAEA,OAAOX,MAAAA;AACT,IAAA,CAAA,EACA,EAAE,CAAA;AAEN;AAEA;;AAEC,IACD,MAAMiB,8BAAAA,GAAiC,CACrCC,OAAAA,EACA,EAAE5B,YAAY,EAAE6B,kBAAAA,GAAqB,EAAE,EAAgB,GAAG,EAAE,GAAA;AAE5D,IAAA,OAAOD,OAAAA,CAAQpB,MAAM,CAAC,CAACsB,WAAAA,EAAaC,MAAAA,GAAAA;QAClC,MAAMC,aAAAA,GAAgBD,MAAAA,CAAOE,QAAQ,CAACC,MAAM,CAC1C,CAACC,OAAAA,GAAiB,CAACN,kBAAAA,CAAmBhB,QAAQ,CAACsB,OAAAA,CAAAA,CAAAA;;QAIjD,KAAK,MAAMA,WAAWH,aAAAA,CAAe;YACnC,MAAMtB,MAAAA,GAAS0B,YAAAA,CAAaC,iBAAiB,CAAC,QAAA,EAAUN,MAAAA,CAAAA,GACpDlC,eAAAA,CAAgByC,MAAAA,CAAOC,YAAY,CAACJ,OAAAA,CAAQ,EAAE;AAC5ClC,gBAAAA,UAAAA,EAAYqC,OAAOrC,UAAU;AAC7BD,gBAAAA;aACF,CAAA,GACAwC,SAAAA;YAEJ,MAAMC,UAAAA,GAAaC,gBAAAA,CAAiBC,MAAM,CAAC;AACzCZ,gBAAAA,MAAAA,EAAQA,OAAOa,QAAQ;AACvBT,gBAAAA,OAAAA;gBACAU,UAAAA,EAAY;AAAEnC,oBAAAA;AAAO;AACvB,aAAA,CAAA;AAEAoB,YAAAA,WAAAA,CAAYJ,IAAI,CAACe,UAAAA,CAAAA;AACnB,QAAA;QAEA,OAAOX,WAAAA;AACT,IAAA,CAAA,EAAG,EAAE,CAAA;AACP;AAEA;;IAGA,MAAMgB,wBAAwB,CAC5BhB,WAAAA,GAAAA;AAEA,IAAA,MAAM,EAAEiB,cAAc,EAAE,GAAGC,UAAAA,CAAW,YAAA,CAAA;AACtC,IAAA,MAAMC,oBAAoB,IAAIC,GAAAA,EAAAA;IAE9B,OAAOpB,WAAAA,CAAYqB,GAAG,CAAC,CAACV,UAAAA,GAAAA;QACtB,MAAM,EACJV,MAAAA,EAAQa,QAAQ,EAChBT,OAAO,EACPU,UAAAA,EAAY,EAAEnC,MAAM,EAAE,EACvB,GAAG+B,UAAAA;QAEJ,MAAMV,MAAAA,GAASgB,cAAAA,CAAeK,GAAG,CAACR,QAAAA,CAAAA;;AAGlC,QAAA,IAAI,CAACR,YAAAA,CAAaC,iBAAiB,CAAC,UAAUN,MAAAA,CAAAA,EAAS;YACrD,OAAOW,gBAAAA,CAAiBW,cAAc,CAAC,QAAA,EAAUZ,UAAAA,CAAAA;AACnD,QAAA;AAEA,QAAA,IAAI,CAACN,OAAAA,IAAW,CAACG,OAAOC,YAAY,CAACJ,QAAQ,EAAE;YAC7C,OAAOM,UAAAA;AACT,QAAA;QAEA,IAAIa,cAAAA,GAAiBL,iBAAAA,CAAkBG,GAAG,CAACjB,OAAAA,CAAAA;AAC3C,QAAA,IAAI,CAACmB,cAAAA,EAAgB;AACnBA,YAAAA,cAAAA,GAAiB7B,+BAAAA,CAAgCa,MAAAA,CAAOC,YAAY,CAACJ,QAAQ,EAAE;AAC7ElC,gBAAAA,UAAAA,EAAYqC,OAAOrC;AACrB,aAAA,CAAA;YACAgD,iBAAAA,CAAkBM,GAAG,CAACpB,OAAAA,EAASmB,cAAAA,CAAAA;AACjC,QAAA;QAEA,MAAME,aAAAA,GAA0B9C,UAAU,EAAE;AAE5C,QAAA,MAAM+C,kBAA4BC,IAAAA,CAChCJ,cAAAA,CAAepB,MAAM,CAAC,CAACyB,KACrBH,aAAAA,CAActC,IAAI,CAAC,CAAC0C,EAAAA,GAAOD,OAAOC,EAAAA,IAAMzC,UAAAA,CAAW,GAAGyC,EAAAA,CAAG,CAAC,CAAC,EAAED,EAAAA,CAAAA,CAAAA,CAAAA,CAAAA;;;;AAOjE,QAAA,MAAME,mBAAmB,CAACC,KAAAA,GACxB,CAACL,eAAAA,CAAgBvC,IAAI,CACnB,CAAC6C,cAAAA,GACCA,cAAAA,KAAmBD,SAAS3C,UAAAA,CAAW,CAAA,EAAG2C,KAAAA,CAAM,CAAC,CAAC,EAAEC,cAAAA,CAAAA,CAAAA;;QAI1D,MAAMC,SAAAA,GAAYP,eAAAA,CAAgBvB,MAAM,CAAC2B,gBAAAA,CAAAA;AAEzC,QAAA,OAAOnB,gBAAAA,CAAiBuB,WAAW,CAAC,QAAA,EAAUD,SAAAA,EAAWvB,UAAAA,CAAAA;AAC3D,IAAA,CAAA,EAAG,EAAE,CAAA;AACP;;;;"}
|
|
1
|
+
{"version":3,"file":"content-type.mjs","sources":["../../../../../server/src/services/content-type.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport { contentTypes as contentTypesUtils } from '@strapi/utils';\nimport type { Modules, Struct } from '@strapi/types';\nimport { getService } from '../utils';\nimport actionDomain from '../domain/action';\nimport permissionDomain from '../domain/permission';\n\ninterface FieldOptions {\n prefix?: string; // prefix to add to the path\n nestingLevel?: number; // level of nesting to achieve\n requiredOnly?: boolean; // only returns required nestedFields\n existingFields?: string[]; // fields that are already selected, meaning that some sub-fields may be required\n restrictedSubjects?: string[]; // subjectsId to ignore\n components?: {\n // components where components attributes can be found\n [key: string]: any;\n };\n}\n\n/**\n * Creates an array of paths to the fields and nested fields, without path nodes\n */\nconst getNestedFields = (\n model: Struct.ContentTypeSchema,\n {\n prefix = '',\n nestingLevel = 15,\n components = {},\n requiredOnly = false,\n existingFields = [],\n }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return prefix ? [prefix] : [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n const shouldBeIncluded = !requiredOnly || attr.required === true;\n const insideExistingFields =\n existingFields && existingFields.some((field) => field.startsWith(fieldPath));\n\n if (attr.type === 'component') {\n if (shouldBeIncluded || insideExistingFields) {\n const compoFields = getNestedFields(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n requiredOnly,\n existingFields,\n });\n\n if (compoFields.length === 0 && shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields.concat(compoFields);\n }\n return fields;\n }\n\n if (shouldBeIncluded) {\n return fields.concat(fieldPath);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of paths to the fields and nested fields, with path nodes\n */\nconst getNestedFieldsWithIntermediate = (\n model: Struct.ContentTypeSchema,\n { prefix = '', nestingLevel = 15, components = {} }: FieldOptions\n): string[] => {\n if (nestingLevel === 0) {\n return [];\n }\n\n const nonAuthorizableFields = contentTypesUtils.getNonVisibleAttributes(model);\n\n return _.reduce(\n model.attributes,\n (fields: any, attr: any, key: any) => {\n if (nonAuthorizableFields.includes(key)) return fields;\n\n const fieldPath = prefix ? `${prefix}.${key}` : key;\n fields.push(fieldPath);\n\n if (attr.type === 'component') {\n const compoFields = getNestedFieldsWithIntermediate(components[attr.component], {\n nestingLevel: nestingLevel - 1,\n prefix: fieldPath,\n components,\n });\n\n fields.push(...compoFields);\n }\n\n return fields;\n },\n []\n );\n};\n\n/**\n * Creates an array of permissions with the \"properties.fields\" attribute filled\n */\nconst getPermissionsWithNestedFields = (\n actions: any[],\n { nestingLevel, restrictedSubjects = [] }: FieldOptions = {}\n): Modules.Permissions.PermissionRule[] => {\n return actions.reduce((permissions, action) => {\n const validSubjects = action.subjects.filter(\n (subject: any) => !restrictedSubjects.includes(subject)\n );\n\n // Create a Permission for each subject (content-type uid) within the action\n for (const subject of validSubjects) {\n const fields = actionDomain.appliesToProperty('fields', action)\n ? getNestedFields(strapi.contentTypes[subject], {\n components: strapi.components,\n nestingLevel,\n })\n : undefined;\n\n const permission = permissionDomain.create({\n action: action.actionId,\n subject,\n properties: { fields },\n });\n\n permissions.push(permission);\n }\n\n return permissions;\n }, []);\n};\n\n/**\n * Cleans permissions' fields (add required ones, remove the non-existing ones)\n */\nconst cleanPermissionFields = (\n permissions: Modules.Permissions.PermissionRule[]\n): Modules.Permissions.PermissionRule[] => {\n const { actionProvider } = getService('permission');\n const nestedFieldsCache = new Map<string, string[]>();\n\n return permissions.map((permission: any) => {\n const {\n action: actionId,\n subject,\n properties: { fields },\n } = permission;\n\n const action = actionProvider.get(actionId) as any;\n\n // todo see if it's possible to check property on action + subject (async)\n if (!actionDomain.appliesToProperty('fields', action)) {\n return permissionDomain.deleteProperty('fields', permission);\n }\n\n if (!subject || !strapi.contentTypes[subject]) {\n return permission;\n }\n\n let possibleFields = nestedFieldsCache.get(subject);\n if (!possibleFields) {\n possibleFields = getNestedFieldsWithIntermediate(strapi.contentTypes[subject], {\n components: strapi.components,\n });\n nestedFieldsCache.set(subject, possibleFields);\n }\n\n const currentFields: string[] = fields || [];\n\n const validUserFields: string[] = [\n ...new Set(\n possibleFields.filter((pf) =>\n currentFields.some((cf) => pf === cf || pf.startsWith(`${cf}.`))\n )\n ),\n ];\n\n // A field is considered \"not nested\" if no other valid user field starts with this field's path followed by a dot.\n // This helps to remove redundant parent paths when a more specific child path is already included.\n // For example, if 'component.title' is present, 'component' would be filtered out by this condition.\n const isNotNestedField = (field: string) =>\n !validUserFields.some(\n (validUserField: string) =>\n validUserField !== field && validUserField.startsWith(`${field}.`)\n );\n\n // Filter out fields that are parent paths of other included fields.\n const newFields = validUserFields.filter(isNotNestedField);\n\n return permissionDomain.setProperty('fields', newFields, permission);\n }, []);\n};\n\nexport {\n getNestedFields,\n getPermissionsWithNestedFields,\n cleanPermissionFields,\n getNestedFieldsWithIntermediate,\n};\n"],"names":["getNestedFields","model","prefix","nestingLevel","components","requiredOnly","existingFields","nonAuthorizableFields","contentTypesUtils","getNonVisibleAttributes","_","reduce","attributes","fields","attr","key","includes","fieldPath","shouldBeIncluded","required","insideExistingFields","some","field","startsWith","type","compoFields","component","length","concat","getNestedFieldsWithIntermediate","push","getPermissionsWithNestedFields","actions","restrictedSubjects","permissions","action","validSubjects","subjects","filter","subject","actionDomain","appliesToProperty","strapi","contentTypes","undefined","permission","permissionDomain","create","actionId","properties","cleanPermissionFields","actionProvider","getService","nestedFieldsCache","Map","map","get","deleteProperty","possibleFields","set","currentFields","validUserFields","Set","pf","cf","isNotNestedField","validUserField","newFields","setProperty"],"mappings":"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"}
|
|
@@ -17,7 +17,8 @@ const homepageService = ({ strapi })=>{
|
|
|
17
17
|
});
|
|
18
18
|
const countApiTokens = await index.getService('api-token-admin').countAll();
|
|
19
19
|
const countAdmins = await index.getService('user').count();
|
|
20
|
-
|
|
20
|
+
// null tells the homepage no localization plugin is installed, unlike 0 locales
|
|
21
|
+
const countLocales = strapi.localization.isEnabled() === true ? (await strapi.localization.getLocales()).length : null;
|
|
21
22
|
const countsAssets = await strapi.db.query('plugin::upload.file').count();
|
|
22
23
|
const countWebhooks = await strapi.db.query('strapi::webhook').count();
|
|
23
24
|
const componentCategories = new Set(Object.values(strapi.components).map((component)=>component.category));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"homepage.js","sources":["../../../../../server/src/services/homepage.ts"],"sourcesContent":["import { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport {\n HomepageLayout,\n HomepageLayoutSchema,\n HomepageLayoutWrite,\n HomepageLayoutWriteSchema,\n} from '../controllers/validation/schema';\n\nconst DEFAULT_WIDTH = 6 as const;\nconst keyFor = (userId: number) => `homepage-layout:${userId}`;\n\nconst isContentTypeVisible = (model: any) =>\n model?.pluginOptions?.['content-type-builder']?.visible !== false;\n\nexport const homepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const adminStore = strapi.store({ type: 'core', name: 'admin' });\n const getKeyStatistics = async () => {\n const contentTypes = Object.entries(strapi.contentTypes).filter(([, contentType]) => {\n return isContentTypeVisible(contentType);\n });\n\n const countApiTokens = await getService('api-token-admin').countAll();\n const countAdmins = await getService('user').count();\n const countLocales
|
|
1
|
+
{"version":3,"file":"homepage.js","sources":["../../../../../server/src/services/homepage.ts"],"sourcesContent":["import { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport {\n HomepageLayout,\n HomepageLayoutSchema,\n HomepageLayoutWrite,\n HomepageLayoutWriteSchema,\n} from '../controllers/validation/schema';\n\nconst DEFAULT_WIDTH = 6 as const;\nconst keyFor = (userId: number) => `homepage-layout:${userId}`;\n\nconst isContentTypeVisible = (model: any) =>\n model?.pluginOptions?.['content-type-builder']?.visible !== false;\n\nexport const homepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const adminStore = strapi.store({ type: 'core', name: 'admin' });\n const getKeyStatistics = async () => {\n const contentTypes = Object.entries(strapi.contentTypes).filter(([, contentType]) => {\n return isContentTypeVisible(contentType);\n });\n\n const countApiTokens = await getService('api-token-admin').countAll();\n const countAdmins = await getService('user').count();\n // null tells the homepage no localization plugin is installed, unlike 0 locales\n const countLocales =\n strapi.localization.isEnabled() === true\n ? (await strapi.localization.getLocales()).length\n : null;\n const countsAssets = await strapi.db.query('plugin::upload.file').count();\n const countWebhooks = await strapi.db.query('strapi::webhook').count();\n\n const componentCategories = new Set(\n Object.values(strapi.components).map((component) => component.category)\n );\n const components = Array.from(componentCategories);\n\n return {\n assets: countsAssets,\n contentTypes: contentTypes.length,\n components: components.length,\n locales: countLocales,\n admins: countAdmins,\n webhooks: countWebhooks,\n apiTokens: countApiTokens,\n };\n };\n\n const getHomepageLayout = async (userId: number): Promise<HomepageLayout | null> => {\n const key = keyFor(userId);\n const value = await adminStore.get({ key });\n if (!value) {\n // nothing saved yet\n return null;\n }\n\n return HomepageLayoutSchema.parse(value);\n };\n\n const updateHomepageLayout = async (userId: number, input: unknown): Promise<HomepageLayout> => {\n const write: HomepageLayoutWrite = HomepageLayoutWriteSchema.parse(input);\n\n const key = keyFor(userId);\n\n const currentRaw = await adminStore.get({ key });\n const current: HomepageLayout | null = currentRaw\n ? HomepageLayoutSchema.parse(currentRaw)\n : null;\n\n const widgetsNext = write.widgets ?? current?.widgets ?? [];\n\n // Normalize widths (fill defaults where missing)\n const normalizedWidgets = widgetsNext.map((w) => {\n const prev = current?.widgets.find((cw) => cw.uid === w.uid);\n return {\n uid: w.uid,\n width: w.width ?? prev?.width ?? DEFAULT_WIDTH,\n };\n });\n\n const next: HomepageLayout = {\n version: write.version ?? 1,\n widgets: normalizedWidgets,\n updatedAt: write.updatedAt ?? new Date().toISOString(),\n };\n\n await adminStore.set({ key, value: next });\n return next;\n };\n return {\n getKeyStatistics,\n getHomepageLayout,\n updateHomepageLayout,\n };\n};\n"],"names":["DEFAULT_WIDTH","keyFor","userId","isContentTypeVisible","model","pluginOptions","visible","homepageService","strapi","adminStore","store","type","name","getKeyStatistics","contentTypes","Object","entries","filter","contentType","countApiTokens","getService","countAll","countAdmins","count","countLocales","localization","isEnabled","getLocales","length","countsAssets","db","query","countWebhooks","componentCategories","Set","values","components","map","component","category","Array","from","assets","locales","admins","webhooks","apiTokens","getHomepageLayout","key","value","get","HomepageLayoutSchema","parse","updateHomepageLayout","input","write","HomepageLayoutWriteSchema","currentRaw","current","widgetsNext","widgets","normalizedWidgets","w","prev","find","cw","uid","width","next","version","updatedAt","Date","toISOString","set"],"mappings":"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"}
|
|
@@ -15,7 +15,8 @@ const homepageService = ({ strapi })=>{
|
|
|
15
15
|
});
|
|
16
16
|
const countApiTokens = await getService('api-token-admin').countAll();
|
|
17
17
|
const countAdmins = await getService('user').count();
|
|
18
|
-
|
|
18
|
+
// null tells the homepage no localization plugin is installed, unlike 0 locales
|
|
19
|
+
const countLocales = strapi.localization.isEnabled() === true ? (await strapi.localization.getLocales()).length : null;
|
|
19
20
|
const countsAssets = await strapi.db.query('plugin::upload.file').count();
|
|
20
21
|
const countWebhooks = await strapi.db.query('strapi::webhook').count();
|
|
21
22
|
const componentCategories = new Set(Object.values(strapi.components).map((component)=>component.category));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"homepage.mjs","sources":["../../../../../server/src/services/homepage.ts"],"sourcesContent":["import { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport {\n HomepageLayout,\n HomepageLayoutSchema,\n HomepageLayoutWrite,\n HomepageLayoutWriteSchema,\n} from '../controllers/validation/schema';\n\nconst DEFAULT_WIDTH = 6 as const;\nconst keyFor = (userId: number) => `homepage-layout:${userId}`;\n\nconst isContentTypeVisible = (model: any) =>\n model?.pluginOptions?.['content-type-builder']?.visible !== false;\n\nexport const homepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const adminStore = strapi.store({ type: 'core', name: 'admin' });\n const getKeyStatistics = async () => {\n const contentTypes = Object.entries(strapi.contentTypes).filter(([, contentType]) => {\n return isContentTypeVisible(contentType);\n });\n\n const countApiTokens = await getService('api-token-admin').countAll();\n const countAdmins = await getService('user').count();\n const countLocales
|
|
1
|
+
{"version":3,"file":"homepage.mjs","sources":["../../../../../server/src/services/homepage.ts"],"sourcesContent":["import { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport {\n HomepageLayout,\n HomepageLayoutSchema,\n HomepageLayoutWrite,\n HomepageLayoutWriteSchema,\n} from '../controllers/validation/schema';\n\nconst DEFAULT_WIDTH = 6 as const;\nconst keyFor = (userId: number) => `homepage-layout:${userId}`;\n\nconst isContentTypeVisible = (model: any) =>\n model?.pluginOptions?.['content-type-builder']?.visible !== false;\n\nexport const homepageService = ({ strapi }: { strapi: Core.Strapi }) => {\n const adminStore = strapi.store({ type: 'core', name: 'admin' });\n const getKeyStatistics = async () => {\n const contentTypes = Object.entries(strapi.contentTypes).filter(([, contentType]) => {\n return isContentTypeVisible(contentType);\n });\n\n const countApiTokens = await getService('api-token-admin').countAll();\n const countAdmins = await getService('user').count();\n // null tells the homepage no localization plugin is installed, unlike 0 locales\n const countLocales =\n strapi.localization.isEnabled() === true\n ? (await strapi.localization.getLocales()).length\n : null;\n const countsAssets = await strapi.db.query('plugin::upload.file').count();\n const countWebhooks = await strapi.db.query('strapi::webhook').count();\n\n const componentCategories = new Set(\n Object.values(strapi.components).map((component) => component.category)\n );\n const components = Array.from(componentCategories);\n\n return {\n assets: countsAssets,\n contentTypes: contentTypes.length,\n components: components.length,\n locales: countLocales,\n admins: countAdmins,\n webhooks: countWebhooks,\n apiTokens: countApiTokens,\n };\n };\n\n const getHomepageLayout = async (userId: number): Promise<HomepageLayout | null> => {\n const key = keyFor(userId);\n const value = await adminStore.get({ key });\n if (!value) {\n // nothing saved yet\n return null;\n }\n\n return HomepageLayoutSchema.parse(value);\n };\n\n const updateHomepageLayout = async (userId: number, input: unknown): Promise<HomepageLayout> => {\n const write: HomepageLayoutWrite = HomepageLayoutWriteSchema.parse(input);\n\n const key = keyFor(userId);\n\n const currentRaw = await adminStore.get({ key });\n const current: HomepageLayout | null = currentRaw\n ? HomepageLayoutSchema.parse(currentRaw)\n : null;\n\n const widgetsNext = write.widgets ?? current?.widgets ?? [];\n\n // Normalize widths (fill defaults where missing)\n const normalizedWidgets = widgetsNext.map((w) => {\n const prev = current?.widgets.find((cw) => cw.uid === w.uid);\n return {\n uid: w.uid,\n width: w.width ?? prev?.width ?? DEFAULT_WIDTH,\n };\n });\n\n const next: HomepageLayout = {\n version: write.version ?? 1,\n widgets: normalizedWidgets,\n updatedAt: write.updatedAt ?? new Date().toISOString(),\n };\n\n await adminStore.set({ key, value: next });\n return next;\n };\n return {\n getKeyStatistics,\n getHomepageLayout,\n updateHomepageLayout,\n };\n};\n"],"names":["DEFAULT_WIDTH","keyFor","userId","isContentTypeVisible","model","pluginOptions","visible","homepageService","strapi","adminStore","store","type","name","getKeyStatistics","contentTypes","Object","entries","filter","contentType","countApiTokens","getService","countAll","countAdmins","count","countLocales","localization","isEnabled","getLocales","length","countsAssets","db","query","countWebhooks","componentCategories","Set","values","components","map","component","category","Array","from","assets","locales","admins","webhooks","apiTokens","getHomepageLayout","key","value","get","HomepageLayoutSchema","parse","updateHomepageLayout","input","write","HomepageLayoutWriteSchema","currentRaw","current","widgetsNext","widgets","normalizedWidgets","w","prev","find","cw","uid","width","next","version","updatedAt","Date","toISOString","set"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _ = require('lodash');
|
|
4
4
|
var passportLocal = require('passport-local');
|
|
5
5
|
var index = require('../../utils/index.js');
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ const createLocalStrategy = (strapi, middleware)=>{
|
|
|
11
11
|
session: false
|
|
12
12
|
}, (email, password, done)=>{
|
|
13
13
|
return index.getService('auth').checkCredentials({
|
|
14
|
-
email:
|
|
14
|
+
email: _.toLower(email),
|
|
15
15
|
password
|
|
16
16
|
}).then(async ([error, user, message])=>{
|
|
17
17
|
if (middleware) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-strategy.js","sources":["../../../../../../server/src/services/passport/local-strategy.ts"],"sourcesContent":["import { toLower } from 'lodash
|
|
1
|
+
{"version":3,"file":"local-strategy.js","sources":["../../../../../../server/src/services/passport/local-strategy.ts"],"sourcesContent":["import { toLower } from 'lodash';\n\nimport { Strategy as LocalStrategy } from 'passport-local';\nimport type { Core } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst createLocalStrategy = (strapi: Core.Strapi, middleware?: any) => {\n return new LocalStrategy(\n {\n usernameField: 'email',\n passwordField: 'password',\n session: false,\n },\n (email: string, password: string, done: any) => {\n return getService('auth')\n .checkCredentials({ email: toLower(email), password })\n .then(async ([error, user, message]) => {\n if (middleware) {\n return middleware([error, user, message], done);\n }\n\n return done(error, user, message);\n })\n .catch((error) => done(error));\n }\n );\n};\n\nexport default createLocalStrategy;\n"],"names":["createLocalStrategy","strapi","middleware","LocalStrategy","usernameField","passwordField","session","email","password","done","getService","checkCredentials","toLower","then","error","user","message","catch"],"mappings":";;;;;;AAMA,MAAMA,mBAAAA,GAAsB,CAACC,MAAAA,EAAqBC,UAAAA,GAAAA;AAChD,IAAA,OAAO,IAAIC,sBAAAA,CACT;QACEC,aAAAA,EAAe,OAAA;QACfC,aAAAA,EAAe,UAAA;QACfC,OAAAA,EAAS;KACX,EACA,CAACC,OAAeC,QAAAA,EAAkBC,IAAAA,GAAAA;QAChC,OAAOC,gBAAAA,CAAW,MAAA,CAAA,CACfC,gBAAgB,CAAC;AAAEJ,YAAAA,KAAAA,EAAOK,SAAAA,CAAQL,KAAAA,CAAAA;AAAQC,YAAAA;AAAS,SAAA,CAAA,CACnDK,IAAI,CAAC,OAAO,CAACC,KAAAA,EAAOC,MAAMC,OAAAA,CAAQ,GAAA;AACjC,YAAA,IAAId,UAAAA,EAAY;AACd,gBAAA,OAAOA,UAAAA,CAAW;AAACY,oBAAAA,KAAAA;AAAOC,oBAAAA,IAAAA;AAAMC,oBAAAA;iBAAQ,EAAEP,IAAAA,CAAAA;AAC5C,YAAA;YAEA,OAAOA,IAAAA,CAAKK,OAAOC,IAAAA,EAAMC,OAAAA,CAAAA;AAC3B,QAAA,CAAA,CAAA,CACCC,KAAK,CAAC,CAACH,KAAAA,GAAUL,IAAAA,CAAKK,KAAAA,CAAAA,CAAAA;AAC3B,IAAA,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-strategy.mjs","sources":["../../../../../../server/src/services/passport/local-strategy.ts"],"sourcesContent":["import { toLower } from 'lodash
|
|
1
|
+
{"version":3,"file":"local-strategy.mjs","sources":["../../../../../../server/src/services/passport/local-strategy.ts"],"sourcesContent":["import { toLower } from 'lodash';\n\nimport { Strategy as LocalStrategy } from 'passport-local';\nimport type { Core } from '@strapi/types';\nimport { getService } from '../../utils';\n\nconst createLocalStrategy = (strapi: Core.Strapi, middleware?: any) => {\n return new LocalStrategy(\n {\n usernameField: 'email',\n passwordField: 'password',\n session: false,\n },\n (email: string, password: string, done: any) => {\n return getService('auth')\n .checkCredentials({ email: toLower(email), password })\n .then(async ([error, user, message]) => {\n if (middleware) {\n return middleware([error, user, message], done);\n }\n\n return done(error, user, message);\n })\n .catch((error) => done(error));\n }\n );\n};\n\nexport default createLocalStrategy;\n"],"names":["createLocalStrategy","strapi","middleware","LocalStrategy","usernameField","passwordField","session","email","password","done","getService","checkCredentials","toLower","then","error","user","message","catch"],"mappings":";;;;AAMA,MAAMA,mBAAAA,GAAsB,CAACC,MAAAA,EAAqBC,UAAAA,GAAAA;AAChD,IAAA,OAAO,IAAIC,QAAAA,CACT;QACEC,aAAAA,EAAe,OAAA;QACfC,aAAAA,EAAe,UAAA;QACfC,OAAAA,EAAS;KACX,EACA,CAACC,OAAeC,QAAAA,EAAkBC,IAAAA,GAAAA;QAChC,OAAOC,UAAAA,CAAW,MAAA,CAAA,CACfC,gBAAgB,CAAC;AAAEJ,YAAAA,KAAAA,EAAOK,OAAAA,CAAQL,KAAAA,CAAAA;AAAQC,YAAAA;AAAS,SAAA,CAAA,CACnDK,IAAI,CAAC,OAAO,CAACC,KAAAA,EAAOC,MAAMC,OAAAA,CAAQ,GAAA;AACjC,YAAA,IAAId,UAAAA,EAAY;AACd,gBAAA,OAAOA,UAAAA,CAAW;AAACY,oBAAAA,KAAAA;AAAOC,oBAAAA,IAAAA;AAAMC,oBAAAA;iBAAQ,EAAEP,IAAAA,CAAAA;AAC5C,YAAA;YAEA,OAAOA,IAAAA,CAAKK,OAAOC,IAAAA,EAAMC,OAAAA,CAAAA;AAC3B,QAAA,CAAA,CAAA,CACCC,KAAK,CAAC,CAACH,KAAAA,GAAUL,IAAAA,CAAKK,KAAAA,CAAAA,CAAAA;AAC3B,IAAA,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var passport$1 = require('koa-passport');
|
|
4
|
-
var fp = require('lodash/fp');
|
|
5
4
|
var localStrategy = require('./passport/local-strategy.js');
|
|
6
5
|
|
|
7
6
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -12,7 +11,7 @@ const authEventsMapper = {
|
|
|
12
11
|
onConnectionSuccess: 'admin.auth.success',
|
|
13
12
|
onConnectionError: 'admin.auth.error'
|
|
14
13
|
};
|
|
15
|
-
const valueIsFunctionType = ([, value])=>
|
|
14
|
+
const valueIsFunctionType = ([, value])=>typeof value === 'function';
|
|
16
15
|
const keyIsValidEventName = ([key])=>{
|
|
17
16
|
return Object.keys(strapi.service('admin::passport').authEventsMapper).includes(key);
|
|
18
17
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passport.js","sources":["../../../../../server/src/services/passport.ts"],"sourcesContent":["import passport from 'koa-passport';\nimport type { Strategy } from 'passport-local';\
|
|
1
|
+
{"version":3,"file":"passport.js","sources":["../../../../../server/src/services/passport.ts"],"sourcesContent":["import passport from 'koa-passport';\nimport type { Strategy } from 'passport-local';\n\nimport createLocalStrategy from './passport/local-strategy';\n\nconst authEventsMapper = {\n onConnectionSuccess: 'admin.auth.success',\n onConnectionError: 'admin.auth.error',\n};\n\nconst valueIsFunctionType = ([, value]: [any, any]) => typeof value === 'function';\nconst keyIsValidEventName = ([key]: any) => {\n return Object.keys(strapi.service('admin::passport').authEventsMapper).includes(key);\n};\n\nconst getPassportStrategies = () => [createLocalStrategy(strapi)] as Strategy[];\n\nconst registerAuthEvents = () => {\n // @ts-expect-error - TODO: migrate auth service to TS\n const { events = {} } = strapi.config.get('admin.auth', {});\n const { authEventsMapper } = strapi.service('admin::passport');\n\n const eventList = Object.entries(events).filter(keyIsValidEventName).filter(valueIsFunctionType);\n\n for (const [eventName, handler] of eventList) {\n // TODO - TS: ensure the handler is an EventHub.Listener\n strapi.eventHub.on(authEventsMapper[eventName], handler as any);\n }\n};\n\nconst init = () => {\n strapi\n .service('admin::passport')\n .getPassportStrategies()\n .forEach((strategy: Strategy) => passport.use(strategy));\n\n registerAuthEvents();\n\n return passport.initialize();\n};\n\nexport default { init, getPassportStrategies, authEventsMapper };\n"],"names":["authEventsMapper","onConnectionSuccess","onConnectionError","valueIsFunctionType","value","keyIsValidEventName","key","Object","keys","strapi","service","includes","getPassportStrategies","createLocalStrategy","registerAuthEvents","events","config","get","eventList","entries","filter","eventName","handler","eventHub","on","init","forEach","strategy","passport","use","initialize"],"mappings":";;;;;;;;;AAKA,MAAMA,gBAAAA,GAAmB;IACvBC,mBAAAA,EAAqB,oBAAA;IACrBC,iBAAAA,EAAmB;AACrB,CAAA;AAEA,MAAMC,sBAAsB,CAAC,GAAGC,KAAAA,CAAkB,GAAK,OAAOA,KAAAA,KAAU,UAAA;AACxE,MAAMC,mBAAAA,GAAsB,CAAC,CAACC,GAAAA,CAAS,GAAA;IACrC,OAAOC,MAAAA,CAAOC,IAAI,CAACC,MAAAA,CAAOC,OAAO,CAAC,iBAAA,CAAA,CAAmBV,gBAAgB,CAAA,CAAEW,QAAQ,CAACL,GAAAA,CAAAA;AAClF,CAAA;AAEA,MAAMM,wBAAwB,IAAM;QAACC,aAAAA,CAAoBJ,MAAAA;AAAQ,KAAA;AAEjE,MAAMK,kBAAAA,GAAqB,IAAA;;AAEzB,IAAA,MAAM,EAAEC,MAAAA,GAAS,EAAE,EAAE,GAAGN,MAAAA,CAAOO,MAAM,CAACC,GAAG,CAAC,YAAA,EAAc,EAAC,CAAA;AACzD,IAAA,MAAM,EAAEjB,gBAAgB,EAAE,GAAGS,MAAAA,CAAOC,OAAO,CAAC,iBAAA,CAAA;IAE5C,MAAMQ,SAAAA,GAAYX,OAAOY,OAAO,CAACJ,QAAQK,MAAM,CAACf,mBAAAA,CAAAA,CAAqBe,MAAM,CAACjB,mBAAAA,CAAAA;AAE5E,IAAA,KAAK,MAAM,CAACkB,SAAAA,EAAWC,OAAAA,CAAQ,IAAIJ,SAAAA,CAAW;;AAE5CT,QAAAA,MAAAA,CAAOc,QAAQ,CAACC,EAAE,CAACxB,gBAAgB,CAACqB,UAAU,EAAEC,OAAAA,CAAAA;AAClD,IAAA;AACF,CAAA;AAEA,MAAMG,IAAAA,GAAO,IAAA;IACXhB,MAAAA,CACGC,OAAO,CAAC,iBAAA,CAAA,CACRE,qBAAqB,EAAA,CACrBc,OAAO,CAAC,CAACC,QAAAA,GAAuBC,yBAAAA,CAASC,GAAG,CAACF,QAAAA,CAAAA,CAAAA;AAEhDb,IAAAA,kBAAAA,EAAAA;AAEA,IAAA,OAAOc,0BAASE,UAAU,EAAA;AAC5B,CAAA;AAEA,eAAe;AAAEL,IAAAA,IAAAA;AAAMb,IAAAA,qBAAAA;AAAuBZ,IAAAA;AAAiB,CAAA;;;;"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import passport$1 from 'koa-passport';
|
|
2
|
-
import { isFunction } from 'lodash/fp';
|
|
3
2
|
import createLocalStrategy from './passport/local-strategy.mjs';
|
|
4
3
|
|
|
5
4
|
const authEventsMapper = {
|
|
6
5
|
onConnectionSuccess: 'admin.auth.success',
|
|
7
6
|
onConnectionError: 'admin.auth.error'
|
|
8
7
|
};
|
|
9
|
-
const valueIsFunctionType = ([, value])=>
|
|
8
|
+
const valueIsFunctionType = ([, value])=>typeof value === 'function';
|
|
10
9
|
const keyIsValidEventName = ([key])=>{
|
|
11
10
|
return Object.keys(strapi.service('admin::passport').authEventsMapper).includes(key);
|
|
12
11
|
};
|