canopycms 0.0.67-int.90 → 0.0.67
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/README.md +30 -3
- package/dist/ai/generate.js +1 -27
- package/dist/ai/handler.d.ts +0 -4
- package/dist/ai/handler.js +0 -11
- package/dist/ai/index.d.ts +1 -8
- package/dist/ai/index.js +1 -8
- package/dist/ai/json-to-markdown.js +15 -58
- package/dist/ai/resolve-branch.d.ts +2 -7
- package/dist/ai/resolve-branch.js +2 -8
- package/dist/ai/strip-mdx.d.ts +5 -13
- package/dist/ai/strip-mdx.js +5 -17
- package/dist/ai/to-plain-text.d.ts +10 -28
- package/dist/ai/to-plain-text.js +10 -28
- package/dist/ai/transform-components.d.ts +2 -4
- package/dist/ai/transform-components.js +8 -19
- package/dist/ai/types.d.ts +5 -10
- package/dist/api/admin-branch-health.d.ts +4 -12
- package/dist/api/admin-branch-health.js +26 -66
- package/dist/api/admin.d.ts +4 -12
- package/dist/api/admin.js +10 -26
- package/dist/api/assets.d.ts +0 -25
- package/dist/api/assets.js +50 -91
- package/dist/api/branch-merge.d.ts +1 -1
- package/dist/api/branch-merge.js +0 -2
- package/dist/api/branch-review.d.ts +0 -8
- package/dist/api/branch-review.js +0 -13
- package/dist/api/branch-status.d.ts +0 -3
- package/dist/api/branch-status.js +8 -33
- package/dist/api/branch-withdraw.d.ts +0 -1
- package/dist/api/branch-withdraw.js +6 -9
- package/dist/api/branch.d.ts +7 -12
- package/dist/api/branch.js +7 -44
- package/dist/api/client.d.ts +71 -224
- package/dist/api/client.js +82 -233
- package/dist/api/comments.d.ts +2 -4
- package/dist/api/comments.js +0 -17
- package/dist/api/content.d.ts +0 -6
- package/dist/api/content.js +66 -142
- package/dist/api/entries-constants.d.ts +5 -9
- package/dist/api/entries-constants.js +5 -9
- package/dist/api/entries.d.ts +8 -13
- package/dist/api/entries.js +20 -51
- package/dist/api/github-sync.d.ts +2 -4
- package/dist/api/github-sync.js +4 -8
- package/dist/api/groups.d.ts +3 -0
- package/dist/api/groups.js +8 -21
- package/dist/api/guards.d.ts +4 -16
- package/dist/api/guards.js +3 -22
- package/dist/api/index.d.ts +4 -4
- package/dist/api/permissions.d.ts +2 -0
- package/dist/api/permissions.js +18 -40
- package/dist/api/reference-options.d.ts +0 -1
- package/dist/api/reference-options.js +3 -11
- package/dist/api/request-body-hash.d.ts +12 -23
- package/dist/api/request-body-hash.js +12 -23
- package/dist/api/resolve-references.d.ts +0 -1
- package/dist/api/resolve-references.js +13 -28
- package/dist/api/route-builder.d.ts +3 -7
- package/dist/api/route-builder.js +1 -1
- package/dist/api/routes.d.ts +12 -0
- package/dist/api/routes.js +47 -0
- package/dist/api/schema.d.ts +23 -33
- package/dist/api/schema.js +20 -74
- package/dist/api/settings-helpers.js +4 -5
- package/dist/api/types.d.ts +0 -5
- package/dist/api/user.js +0 -5
- package/dist/api/validators.d.ts +14 -52
- package/dist/api/validators.js +14 -52
- package/dist/assets/asset-prefixes.d.ts +4 -8
- package/dist/assets/asset-prefixes.js +4 -8
- package/dist/assets/asset-src.d.ts +5 -22
- package/dist/assets/asset-src.js +5 -21
- package/dist/assets/factory.d.ts +1 -2
- package/dist/assets/factory.js +1 -2
- package/dist/assets/finalize.d.ts +3 -1
- package/dist/assets/finalize.js +3 -1
- package/dist/assets/index.d.ts +3 -3
- package/dist/assets/index.js +1 -1
- package/dist/assets/keys.d.ts +5 -3
- package/dist/assets/keys.js +6 -3
- package/dist/assets/pipeline.d.ts +3 -2
- package/dist/assets/pipeline.js +22 -56
- package/dist/assets/sharp-loader.d.ts +2 -10
- package/dist/assets/sharp-loader.js +2 -10
- package/dist/assets/store-local.d.ts +1 -2
- package/dist/assets/store-local.js +1 -2
- package/dist/assets/store-s3.d.ts +3 -4
- package/dist/assets/svg-sanitizer.d.ts +6 -14
- package/dist/assets/svg-sanitizer.js +6 -14
- package/dist/assets/transform-directives.d.ts +3 -4
- package/dist/assets/transform-directives.js +1 -1
- package/dist/assets/transform.d.ts +19 -30
- package/dist/assets/transform.js +18 -31
- package/dist/auth/cache.d.ts +2 -3
- package/dist/auth/cache.js +2 -3
- package/dist/auth/caching-auth-plugin.d.ts +11 -22
- package/dist/auth/caching-auth-plugin.js +12 -14
- package/dist/auth/context-helpers.d.ts +6 -20
- package/dist/auth/context-helpers.js +5 -17
- package/dist/auth/file-based-auth-cache.d.ts +10 -21
- package/dist/auth/file-based-auth-cache.js +23 -51
- package/dist/auth/plugin.d.ts +29 -61
- package/dist/auth/plugin.js +9 -13
- package/dist/auth/types.d.ts +11 -20
- package/dist/authorization/branch.d.ts +30 -49
- package/dist/authorization/branch.js +16 -42
- package/dist/authorization/content.d.ts +11 -40
- package/dist/authorization/content.js +13 -45
- package/dist/authorization/groups/index.d.ts +0 -3
- package/dist/authorization/groups/index.js +0 -3
- package/dist/authorization/groups/loader.d.ts +14 -28
- package/dist/authorization/groups/loader.js +14 -38
- package/dist/authorization/groups/schema.d.ts +0 -6
- package/dist/authorization/groups/schema.js +4 -7
- package/dist/authorization/helpers.d.ts +9 -28
- package/dist/authorization/helpers.js +9 -28
- package/dist/authorization/index.d.ts +3 -25
- package/dist/authorization/index.js +3 -35
- package/dist/authorization/path.d.ts +6 -13
- package/dist/authorization/path.js +8 -25
- package/dist/authorization/permissions/index.d.ts +0 -3
- package/dist/authorization/permissions/index.js +0 -3
- package/dist/authorization/permissions/loader.d.ts +14 -27
- package/dist/authorization/permissions/loader.js +14 -32
- package/dist/authorization/permissions/schema.d.ts +1 -6
- package/dist/authorization/permissions/schema.js +6 -13
- package/dist/authorization/protected-branch.d.ts +36 -65
- package/dist/authorization/protected-branch.js +29 -41
- package/dist/authorization/settings-file-store.d.ts +38 -81
- package/dist/authorization/settings-file-store.js +38 -79
- package/dist/authorization/types.d.ts +4 -26
- package/dist/authorization/types.js +0 -6
- package/dist/authorization/validation.d.ts +1 -23
- package/dist/authorization/validation.js +1 -24
- package/dist/branch-health.d.ts +39 -67
- package/dist/branch-health.js +27 -43
- package/dist/branch-metadata-file.d.ts +16 -32
- package/dist/branch-metadata-file.js +13 -26
- package/dist/branch-metadata.d.ts +49 -80
- package/dist/branch-metadata.js +57 -87
- package/dist/branch-registry.d.ts +26 -64
- package/dist/branch-registry.js +44 -93
- package/dist/branch-schema-cache.d.ts +34 -124
- package/dist/branch-schema-cache.js +49 -155
- package/dist/branch-workspace.d.ts +4 -4
- package/dist/branch-workspace.js +15 -19
- package/dist/build/generate-ai-content.d.ts +1 -0
- package/dist/build/generate-ai-content.js +12 -25
- package/dist/build-canopy.d.ts +17 -27
- package/dist/build-canopy.js +16 -23
- package/dist/build-mode.d.ts +25 -27
- package/dist/build-mode.js +25 -29
- package/dist/cli/cli.d.ts +15 -26
- package/dist/cli/cli.js +601 -978
- package/dist/cli/generate-ai-content.js +351 -628
- package/dist/cli/github-app-manifest.d.ts +84 -0
- package/dist/cli/github-app-manifest.js +161 -0
- package/dist/cli/init-github-app.d.ts +110 -444
- package/dist/cli/init-github-app.js +236 -773
- package/dist/cli/init.js +39 -80
- package/dist/cli/migrate.d.ts +13 -10
- package/dist/cli/migrate.js +22 -30
- package/dist/cli/project-detect.d.ts +17 -31
- package/dist/cli/project-detect.js +31 -42
- package/dist/cli/project-root.d.ts +4 -11
- package/dist/cli/project-root.js +4 -11
- package/dist/cli/prompt.d.ts +10 -0
- package/dist/cli/prompt.js +67 -0
- package/dist/cli/sync.d.ts +0 -8
- package/dist/cli/sync.js +8 -28
- package/dist/cli/template-files/middleware.ts.template +15 -29
- package/dist/cli/templates.d.ts +2 -12
- package/dist/cli/templates.js +4 -4
- package/dist/client.d.ts +1 -1
- package/dist/comment-store.d.ts +32 -53
- package/dist/comment-store.js +32 -52
- package/dist/config/flatten.d.ts +0 -3
- package/dist/config/flatten.js +2 -12
- package/dist/config/helpers.js +2 -2
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.js +1 -4
- package/dist/config/schemas/collection.d.ts +0 -8
- package/dist/config/schemas/collection.js +0 -10
- package/dist/config/schemas/config.d.ts +6 -78
- package/dist/config/schemas/config.js +38 -54
- package/dist/config/schemas/field.d.ts +2 -242
- package/dist/config/schemas/field.js +9 -20
- package/dist/config/schemas/media.js +1 -1
- package/dist/config/schemas/permissions.js +0 -2
- package/dist/config/schemas/url.d.ts +5 -6
- package/dist/config/schemas/url.js +5 -6
- package/dist/config/types.d.ts +45 -33
- package/dist/config/types.js +0 -1
- package/dist/config.d.ts +1 -8
- package/dist/config.js +1 -9
- package/dist/content-id-index.d.ts +76 -188
- package/dist/content-id-index.js +79 -230
- package/dist/content-index-generation.d.ts +27 -48
- package/dist/content-index-generation.js +35 -84
- package/dist/content-index-registry.d.ts +15 -24
- package/dist/content-index-registry.js +5 -9
- package/dist/content-listing.d.ts +64 -107
- package/dist/content-listing.js +68 -118
- package/dist/content-reader.d.ts +20 -29
- package/dist/content-reader.js +10 -18
- package/dist/content-store.d.ts +210 -336
- package/dist/content-store.js +413 -657
- package/dist/content-tree.d.ts +44 -86
- package/dist/content-tree.js +26 -54
- package/dist/context.d.ts +67 -94
- package/dist/context.js +53 -72
- package/dist/dev-content-watcher.d.ts +18 -18
- package/dist/dev-content-watcher.js +41 -44
- package/dist/editor/BranchManager.d.ts +3 -6
- package/dist/editor/BranchManager.js +24 -44
- package/dist/editor/CanopyEditor.js +5 -2
- package/dist/editor/CommentsPanel.js +0 -2
- package/dist/editor/Editor.js +19 -76
- package/dist/editor/EditorAuthGate.d.ts +27 -0
- package/dist/editor/EditorAuthGate.js +140 -0
- package/dist/editor/EntryNavigator.js +0 -20
- package/dist/editor/FormRenderer.d.ts +1 -2
- package/dist/editor/FormRenderer.js +8 -23
- package/dist/editor/admin/SystemHealthPanel.js +20 -37
- package/dist/editor/admin/useSystemHealth.d.ts +2 -3
- package/dist/editor/admin/useSystemHealth.js +10 -12
- package/dist/editor/client-reference-resolver.d.ts +2 -5
- package/dist/editor/client-reference-resolver.js +2 -19
- package/dist/editor/comments/BranchComments.js +0 -4
- package/dist/editor/comments/EntryComments.js +0 -4
- package/dist/editor/comments/FieldWrapper.js +0 -4
- package/dist/editor/comments/InlineCommentThread.js +0 -2
- package/dist/editor/comments/ThreadCarousel.d.ts +0 -58
- package/dist/editor/comments/ThreadCarousel.js +0 -12
- package/dist/editor/components/EditorFooter.d.ts +0 -8
- package/dist/editor/components/EditorFooter.js +0 -5
- package/dist/editor/components/EditorHeader.d.ts +0 -31
- package/dist/editor/components/EditorHeader.js +21 -71
- package/dist/editor/components/EditorSidebar.d.ts +0 -19
- package/dist/editor/components/EditorSidebar.js +0 -16
- package/dist/editor/components/EntryCreateModal.d.ts +4 -4
- package/dist/editor/components/EntryCreateModal.js +7 -22
- package/dist/editor/components/RenameEntryModal.js +0 -4
- package/dist/editor/components/UserBadge.js +0 -10
- package/dist/editor/components/index.js +0 -2
- package/dist/editor/context/ApiClientContext.d.ts +8 -7
- package/dist/editor/context/ApiClientContext.js +39 -11
- package/dist/editor/context/AssetContext.d.ts +7 -17
- package/dist/editor/context/AssetContext.js +7 -17
- package/dist/editor/context/EditorIdentityContext.d.ts +13 -0
- package/dist/editor/context/EditorIdentityContext.js +7 -0
- package/dist/editor/context/EditorStateContext.d.ts +10 -41
- package/dist/editor/context/EditorStateContext.js +7 -23
- package/dist/editor/context/SWRProvider.d.ts +3 -6
- package/dist/editor/context/index.d.ts +1 -20
- package/dist/editor/context/index.js +1 -20
- package/dist/editor/editor-utils.d.ts +8 -47
- package/dist/editor/editor-utils.js +19 -72
- package/dist/editor/fields/BlockField.d.ts +2 -2
- package/dist/editor/fields/BlockField.js +1 -2
- package/dist/editor/fields/CodeField.d.ts +0 -1
- package/dist/editor/fields/CodeField.js +0 -1
- package/dist/editor/fields/DateTimeField.d.ts +15 -22
- package/dist/editor/fields/DateTimeField.js +17 -26
- package/dist/editor/fields/ImageField.d.ts +2 -2
- package/dist/editor/fields/ImageField.js +8 -14
- package/dist/editor/fields/InlineGroupField.d.ts +0 -1
- package/dist/editor/fields/InlineGroupField.js +0 -1
- package/dist/editor/fields/MarkdownField.d.ts +0 -1
- package/dist/editor/fields/MarkdownField.js +6 -11
- package/dist/editor/fields/MdxImageDialog.d.ts +1 -1
- package/dist/editor/fields/MdxImageDialog.js +0 -1
- package/dist/editor/fields/NumberField.d.ts +9 -19
- package/dist/editor/fields/NumberField.js +11 -22
- package/dist/editor/fields/NumberListField.d.ts +7 -10
- package/dist/editor/fields/NumberListField.js +7 -10
- package/dist/editor/fields/ObjectField.d.ts +5 -8
- package/dist/editor/fields/ObjectField.js +0 -1
- package/dist/editor/fields/ReferenceField.d.ts +1 -1
- package/dist/editor/fields/ReferenceField.js +11 -16
- package/dist/editor/fields/SelectField.d.ts +2 -2
- package/dist/editor/fields/SelectField.js +0 -1
- package/dist/editor/fields/StringListField.d.ts +0 -4
- package/dist/editor/fields/StringListField.js +4 -9
- package/dist/editor/fields/TextField.d.ts +0 -1
- package/dist/editor/fields/TextField.js +0 -1
- package/dist/editor/fields/ToggleField.d.ts +0 -1
- package/dist/editor/fields/ToggleField.js +0 -1
- package/dist/editor/fields/entry-link/EntryLinkContext.js +2 -4
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +0 -3
- package/dist/editor/fields/entry-link/InsertEntryLink.js +0 -4
- package/dist/editor/group-manager/ExternalGroupsTab.d.ts +0 -3
- package/dist/editor/group-manager/ExternalGroupsTab.js +0 -1
- package/dist/editor/group-manager/GroupCard.d.ts +0 -3
- package/dist/editor/group-manager/GroupForm.d.ts +0 -3
- package/dist/editor/group-manager/InternalGroupsTab.d.ts +0 -3
- package/dist/editor/group-manager/InternalGroupsTab.js +0 -2
- package/dist/editor/group-manager/MemberList.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useExternalGroupSearch.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useExternalGroupSearch.js +0 -3
- package/dist/editor/group-manager/hooks/useGroupState.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useGroupState.js +0 -5
- package/dist/editor/group-manager/hooks/useUserSearch.d.ts +0 -3
- package/dist/editor/group-manager/hooks/useUserSearch.js +0 -3
- package/dist/editor/group-manager/index.d.ts +0 -6
- package/dist/editor/group-manager/index.js +0 -10
- package/dist/editor/group-manager/types.d.ts +2 -5
- package/dist/editor/group-manager/types.js +0 -3
- package/dist/editor/hooks/index.d.ts +6 -11
- package/dist/editor/hooks/index.js +6 -12
- package/dist/editor/hooks/useBranchActions.d.ts +0 -14
- package/dist/editor/hooks/useBranchActions.js +0 -22
- package/dist/editor/hooks/useBranchManager.d.ts +2 -48
- package/dist/editor/hooks/useBranchManager.js +4 -64
- package/dist/editor/hooks/useBranchesData.d.ts +7 -6
- package/dist/editor/hooks/useBranchesData.js +7 -6
- package/dist/editor/hooks/useCommentSystem.d.ts +0 -49
- package/dist/editor/hooks/useCommentSystem.js +1 -36
- package/dist/editor/hooks/useDraftManager.d.ts +2 -35
- package/dist/editor/hooks/useDraftManager.js +23 -64
- package/dist/editor/hooks/useEditorLayout.d.ts +0 -20
- package/dist/editor/hooks/useEditorLayout.js +0 -23
- package/dist/editor/hooks/useEntriesData.d.ts +1 -0
- package/dist/editor/hooks/useEntriesData.js +2 -3
- package/dist/editor/hooks/useEntryLinkResolution.d.ts +2 -2
- package/dist/editor/hooks/useEntryLinkResolution.js +2 -2
- package/dist/editor/hooks/useEntryManager.d.ts +2 -27
- package/dist/editor/hooks/useEntryManager.js +29 -78
- package/dist/editor/hooks/useGroupManager.d.ts +0 -21
- package/dist/editor/hooks/useGroupManager.js +0 -21
- package/dist/editor/hooks/usePermissionManager.d.ts +0 -20
- package/dist/editor/hooks/usePermissionManager.js +0 -20
- package/dist/editor/hooks/useReferenceResolution.d.ts +2 -33
- package/dist/editor/hooks/useReferenceResolution.js +1 -48
- package/dist/editor/hooks/useSchemaManager.d.ts +8 -27
- package/dist/editor/hooks/useSchemaManager.js +0 -19
- package/dist/editor/hooks/useUserContext.d.ts +2 -9
- package/dist/editor/hooks/useUserContext.js +10 -10
- package/dist/editor/hooks/useUserMetadata.d.ts +0 -2
- package/dist/editor/hooks/useUserMetadata.js +0 -3
- package/dist/editor/media/AssetCard.d.ts +0 -1
- package/dist/editor/media/AssetCard.js +1 -2
- package/dist/editor/media/CropStep.d.ts +0 -1
- package/dist/editor/media/CropStep.js +0 -1
- package/dist/editor/media/MediaLibrary.d.ts +1 -2
- package/dist/editor/media/MediaLibrary.js +1 -2
- package/dist/editor/media/MediaLibraryBody.d.ts +0 -1
- package/dist/editor/media/MediaLibraryBody.js +0 -1
- package/dist/editor/media/crop-math.d.ts +1 -1
- package/dist/editor/media/crop-math.js +1 -1
- package/dist/editor/permission-manager/GroupSelector.d.ts +0 -3
- package/dist/editor/permission-manager/PermissionEditor.d.ts +0 -4
- package/dist/editor/permission-manager/PermissionEditor.js +0 -1
- package/dist/editor/permission-manager/PermissionLevelBadge.d.ts +0 -7
- package/dist/editor/permission-manager/PermissionLevelBadge.js +0 -4
- package/dist/editor/permission-manager/PermissionTree.d.ts +0 -4
- package/dist/editor/permission-manager/UserSelector.d.ts +0 -3
- package/dist/editor/permission-manager/constants.d.ts +0 -3
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts +0 -3
- package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js +0 -10
- package/dist/editor/permission-manager/hooks/usePermissionTree.d.ts +0 -14
- package/dist/editor/permission-manager/hooks/usePermissionTree.js +0 -11
- package/dist/editor/permission-manager/index.d.ts +0 -7
- package/dist/editor/permission-manager/index.js +0 -16
- package/dist/editor/permission-manager/types.d.ts +2 -12
- package/dist/editor/permission-manager/types.js +0 -3
- package/dist/editor/permission-manager/utils.d.ts +0 -28
- package/dist/editor/permission-manager/utils.js +9 -23
- package/dist/editor/preview-bridge.d.ts +5 -1
- package/dist/editor/preview-bridge.js +4 -4
- package/dist/editor/schema-editor/CollectionEditor.d.ts +0 -5
- package/dist/editor/schema-editor/CollectionEditor.js +9 -31
- package/dist/editor/schema-editor/EntryTypeEditor.d.ts +0 -6
- package/dist/editor/schema-editor/EntryTypeEditor.js +3 -24
- package/dist/editor/schema-editor/index.d.ts +0 -7
- package/dist/editor/schema-editor/index.js +0 -7
- package/dist/editor/utils/env.d.ts +3 -18
- package/dist/editor/utils/env.js +6 -25
- package/dist/entry-link-resolver.d.ts +13 -35
- package/dist/entry-link-resolver.js +20 -53
- package/dist/entry-schema-registry.d.ts +20 -60
- package/dist/entry-schema-registry.js +20 -69
- package/dist/entry-schema.d.ts +118 -223
- package/dist/entry-schema.js +46 -91
- package/dist/git-manager.d.ts +101 -200
- package/dist/git-manager.js +211 -384
- package/dist/github-service.d.ts +34 -75
- package/dist/github-service.js +37 -91
- package/dist/http/handler.d.ts +6 -37
- package/dist/http/handler.js +65 -120
- package/dist/http/router.d.ts +15 -32
- package/dist/http/router.js +34 -99
- package/dist/http/types.d.ts +15 -40
- package/dist/http/types.js +3 -7
- package/dist/id.d.ts +4 -10
- package/dist/id.js +4 -10
- package/dist/index.js +6 -9
- package/dist/operating-mode/client-safe-strategy.d.ts +7 -14
- package/dist/operating-mode/client-safe-strategy.js +8 -28
- package/dist/operating-mode/client-unsafe-strategy.d.ts +6 -16
- package/dist/operating-mode/client-unsafe-strategy.js +9 -34
- package/dist/operating-mode/client.d.ts +3 -10
- package/dist/operating-mode/client.js +3 -8
- package/dist/operating-mode/deployment-name-fixtures.d.ts +14 -18
- package/dist/operating-mode/deployment-name-fixtures.js +14 -18
- package/dist/operating-mode/deployment-name.d.ts +19 -29
- package/dist/operating-mode/deployment-name.js +29 -47
- package/dist/operating-mode/index.d.ts +4 -25
- package/dist/operating-mode/index.js +9 -31
- package/dist/operating-mode/mode-env.d.ts +32 -54
- package/dist/operating-mode/mode-env.js +36 -58
- package/dist/operating-mode/types.d.ts +24 -72
- package/dist/operating-mode/types.js +1 -7
- package/dist/paths/branch-name.d.ts +30 -40
- package/dist/paths/branch-name.js +30 -40
- package/dist/paths/branch.d.ts +4 -18
- package/dist/paths/branch.js +6 -22
- package/dist/paths/index.d.ts +2 -13
- package/dist/paths/index.js +3 -23
- package/dist/paths/normalize-server.d.ts +3 -15
- package/dist/paths/normalize-server.js +3 -15
- package/dist/paths/normalize.d.ts +13 -33
- package/dist/paths/normalize.js +13 -33
- package/dist/paths/resolve.d.ts +4 -17
- package/dist/paths/resolve.js +4 -22
- package/dist/paths/types.d.ts +12 -34
- package/dist/paths/types.js +5 -7
- package/dist/paths/validation.d.ts +22 -119
- package/dist/paths/validation.js +30 -148
- package/dist/reference-resolver.d.ts +0 -13
- package/dist/reference-resolver.js +0 -18
- package/dist/resolve-canopy-user.d.ts +16 -18
- package/dist/resolve-canopy-user.js +17 -26
- package/dist/resource-generation.d.ts +16 -25
- package/dist/resource-generation.js +34 -97
- package/dist/schema/meta-loader.d.ts +2 -14
- package/dist/schema/meta-loader.js +15 -64
- package/dist/schema/resolver.d.ts +1 -4
- package/dist/schema/resolver.js +1 -6
- package/dist/schema/schema-store-types.d.ts +0 -12
- package/dist/schema/schema-store.d.ts +61 -138
- package/dist/schema/schema-store.js +85 -282
- package/dist/schema/types.d.ts +0 -4
- package/dist/server.d.ts +62 -93
- package/dist/server.js +63 -94
- package/dist/services.d.ts +23 -47
- package/dist/services.js +55 -98
- package/dist/settings-workspace.d.ts +17 -30
- package/dist/settings-workspace.js +51 -81
- package/dist/static/index.d.ts +26 -52
- package/dist/static/index.js +33 -67
- package/dist/{worker/task-queue.d.ts → task-queue/cms-task-queue.d.ts} +7 -9
- package/dist/task-queue/cms-task-queue.js +13 -0
- package/dist/task-queue/task-queue-config.d.ts +3 -0
- package/dist/{worker → task-queue}/task-queue-config.js +1 -6
- package/dist/task-queue/task-queue.d.ts +16 -22
- package/dist/task-queue/task-queue.js +20 -44
- package/dist/task-queue/types.d.ts +0 -1
- package/dist/task-queue/worker-status.d.ts +35 -0
- package/dist/task-queue/worker-status.js +40 -0
- package/dist/types.d.ts +40 -51
- package/dist/url-collision.d.ts +26 -40
- package/dist/url-collision.js +47 -63
- package/dist/url-exclusivity-fixtures.d.ts +15 -20
- package/dist/url-exclusivity-fixtures.js +14 -19
- package/dist/url-path-resolver.d.ts +8 -16
- package/dist/url-path-resolver.js +19 -29
- package/dist/user.d.ts +8 -21
- package/dist/user.js +10 -19
- package/dist/utils/async-mutex.js +4 -6
- package/dist/utils/atomic-write.d.ts +2 -11
- package/dist/utils/atomic-write.js +2 -11
- package/dist/utils/body-field.d.ts +8 -15
- package/dist/utils/body-field.js +8 -15
- package/dist/utils/content-serialize.d.ts +18 -24
- package/dist/utils/content-serialize.js +109 -160
- package/dist/utils/content-write-lock.d.ts +51 -106
- package/dist/utils/content-write-lock.js +66 -111
- package/dist/utils/debug.d.ts +7 -23
- package/dist/utils/debug.js +7 -23
- package/dist/utils/entry-url.d.ts +11 -23
- package/dist/utils/entry-url.js +11 -26
- package/dist/utils/error.d.ts +25 -90
- package/dist/utils/error.js +60 -147
- package/dist/utils/flatten-group-fields.d.ts +5 -7
- package/dist/utils/flatten-group-fields.js +5 -7
- package/dist/utils/format.d.ts +1 -5
- package/dist/utils/format.js +1 -5
- package/dist/utils/fs.d.ts +3 -4
- package/dist/utils/fs.js +3 -4
- package/dist/utils/git.d.ts +52 -83
- package/dist/utils/git.js +79 -125
- package/dist/utils/logger.d.ts +35 -50
- package/dist/utils/logger.js +35 -52
- package/dist/utils/provisioning-lock.d.ts +23 -35
- package/dist/utils/provisioning-lock.js +49 -69
- package/dist/utils/sanitize-href.d.ts +5 -10
- package/dist/utils/sanitize-href.js +8 -18
- package/dist/utils/title-field.d.ts +17 -20
- package/dist/utils/title-field.js +18 -27
- package/dist/utils/typed-filename.d.ts +20 -48
- package/dist/utils/typed-filename.js +25 -61
- package/dist/utils/url-prefix.d.ts +3 -3
- package/dist/utils/url-prefix.js +3 -3
- package/dist/validation/block-structural-keys.d.ts +16 -31
- package/dist/validation/block-structural-keys.js +19 -29
- package/dist/validation/deletion-checker.d.ts +0 -34
- package/dist/validation/deletion-checker.js +1 -43
- package/dist/validation/entry-link-validator.d.ts +6 -13
- package/dist/validation/entry-link-validator.js +4 -13
- package/dist/validation/entry-type-reference-validator.d.ts +13 -18
- package/dist/validation/entry-type-reference-validator.js +13 -18
- package/dist/validation/entry-validator.d.ts +13 -25
- package/dist/validation/entry-validator.js +15 -32
- package/dist/validation/field-traversal.d.ts +3 -30
- package/dist/validation/field-traversal.js +1 -32
- package/dist/validation/reference-validator.d.ts +5 -24
- package/dist/validation/reference-validator.js +5 -30
- package/dist/worker/cms-worker.d.ts +172 -232
- package/dist/worker/cms-worker.js +241 -333
- package/dist/worker/git-sync.d.ts +32 -133
- package/dist/worker/git-sync.js +129 -191
- package/dist/worker/github-auth.d.ts +13 -19
- package/dist/worker/github-auth.js +13 -19
- package/dist/worker/history-rewrite.d.ts +53 -66
- package/dist/worker/history-rewrite.js +54 -60
- package/dist/worker/log.d.ts +24 -41
- package/dist/worker/log.js +25 -42
- package/dist/worker/rebase.d.ts +20 -110
- package/dist/worker/rebase.js +279 -354
- package/dist/worker/task-runner.d.ts +32 -66
- package/dist/worker/task-runner.js +126 -162
- package/dist/worker/worker-context.d.ts +41 -81
- package/package.json +4 -4
- package/dist/cli/template-files/middleware-clerk.ts.template +0 -37
- package/dist/worker/task-queue-config.d.ts +0 -8
- package/dist/worker/task-queue.js +0 -19
- package/dist/worker/worker-status.d.ts +0 -47
- package/dist/worker/worker-status.js +0 -52
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Reserved groups for CanopyCMS permission system.
|
|
8
|
-
*
|
|
9
|
-
* These groups have special meaning and cannot be deleted or renamed.
|
|
10
|
-
* - Admins: Full access to all CMS operations
|
|
11
|
-
* - Reviewers: Can review branches, request changes, approve PRs
|
|
2
|
+
* Reserved groups for the CanopyCMS permission system; they cannot be deleted
|
|
3
|
+
* or renamed. Admins have full access to every CMS operation; Reviewers can
|
|
4
|
+
* review branches, request changes and approve PRs.
|
|
12
5
|
*
|
|
13
6
|
* SECURITY: membership in a reserved group grants privilege, so these IDs must
|
|
14
7
|
* only ever come from Canopy-managed sources (internal groups in
|
|
@@ -21,30 +14,18 @@ export declare const RESERVED_GROUPS: {
|
|
|
21
14
|
readonly REVIEWERS: "Reviewers";
|
|
22
15
|
};
|
|
23
16
|
export type ReservedGroupId = (typeof RESERVED_GROUPS)[keyof typeof RESERVED_GROUPS];
|
|
24
|
-
/**
|
|
25
|
-
* Check if a group ID is a reserved group
|
|
26
|
-
*/
|
|
27
17
|
export declare function isReservedGroup(groupId: string): groupId is ReservedGroupId;
|
|
28
18
|
/**
|
|
29
19
|
* Remove reserved privileged group IDs (Admins, Reviewers) from a group list.
|
|
30
20
|
*
|
|
31
|
-
* SECURITY
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* path/branch ACL membership.
|
|
21
|
+
* SECURITY: apply this to identity-provider group lists before merging them
|
|
22
|
+
* into a user's effective groups, so a provider-controlled group name can never
|
|
23
|
+
* grant CanopyCMS privilege. Non-reserved groups pass through unchanged and
|
|
24
|
+
* remain usable for ordinary path/branch ACL membership.
|
|
36
25
|
*/
|
|
37
26
|
export declare function stripReservedGroups<T extends string>(groups: readonly T[]): T[];
|
|
38
|
-
/**
|
|
39
|
-
* Check if user is in the Admins group
|
|
40
|
-
*/
|
|
41
27
|
export declare function isAdmin(groups: readonly string[] | undefined): boolean;
|
|
42
|
-
/**
|
|
43
|
-
* Check if user is in the Reviewers group (or is an Admin, since Admins can do everything)
|
|
44
|
-
*/
|
|
28
|
+
/** True for the Reviewers group and for Admins, who can do everything. */
|
|
45
29
|
export declare function isReviewer(groups: readonly string[] | undefined): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Check if user has privileged access (Admin or Reviewer)
|
|
48
|
-
* Used for operations that require elevated permissions but not full admin
|
|
49
|
-
*/
|
|
30
|
+
/** For operations that need elevated rights but not full admin. */
|
|
50
31
|
export declare function isPrivileged(groups: readonly string[] | undefined): boolean;
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Reserved groups for CanopyCMS permission system.
|
|
8
|
-
*
|
|
9
|
-
* These groups have special meaning and cannot be deleted or renamed.
|
|
10
|
-
* - Admins: Full access to all CMS operations
|
|
11
|
-
* - Reviewers: Can review branches, request changes, approve PRs
|
|
2
|
+
* Reserved groups for the CanopyCMS permission system; they cannot be deleted
|
|
3
|
+
* or renamed. Admins have full access to every CMS operation; Reviewers can
|
|
4
|
+
* review branches, request changes and approve PRs.
|
|
12
5
|
*
|
|
13
6
|
* SECURITY: membership in a reserved group grants privilege, so these IDs must
|
|
14
7
|
* only ever come from Canopy-managed sources (internal groups in
|
|
@@ -20,40 +13,28 @@ export const RESERVED_GROUPS = {
|
|
|
20
13
|
ADMINS: 'Admins',
|
|
21
14
|
REVIEWERS: 'Reviewers',
|
|
22
15
|
};
|
|
23
|
-
/**
|
|
24
|
-
* Check if a group ID is a reserved group
|
|
25
|
-
*/
|
|
26
16
|
export function isReservedGroup(groupId) {
|
|
27
17
|
return Object.values(RESERVED_GROUPS).includes(groupId);
|
|
28
18
|
}
|
|
29
19
|
/**
|
|
30
20
|
* Remove reserved privileged group IDs (Admins, Reviewers) from a group list.
|
|
31
21
|
*
|
|
32
|
-
* SECURITY
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* path/branch ACL membership.
|
|
22
|
+
* SECURITY: apply this to identity-provider group lists before merging them
|
|
23
|
+
* into a user's effective groups, so a provider-controlled group name can never
|
|
24
|
+
* grant CanopyCMS privilege. Non-reserved groups pass through unchanged and
|
|
25
|
+
* remain usable for ordinary path/branch ACL membership.
|
|
37
26
|
*/
|
|
38
27
|
export function stripReservedGroups(groups) {
|
|
39
28
|
return groups.filter((group) => !isReservedGroup(group));
|
|
40
29
|
}
|
|
41
|
-
/**
|
|
42
|
-
* Check if user is in the Admins group
|
|
43
|
-
*/
|
|
44
30
|
export function isAdmin(groups) {
|
|
45
31
|
return groups?.includes(RESERVED_GROUPS.ADMINS) ?? false;
|
|
46
32
|
}
|
|
47
|
-
/**
|
|
48
|
-
* Check if user is in the Reviewers group (or is an Admin, since Admins can do everything)
|
|
49
|
-
*/
|
|
33
|
+
/** True for the Reviewers group and for Admins, who can do everything. */
|
|
50
34
|
export function isReviewer(groups) {
|
|
51
35
|
return isAdmin(groups) || (groups?.includes(RESERVED_GROUPS.REVIEWERS) ?? false);
|
|
52
36
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Check if user has privileged access (Admin or Reviewer)
|
|
55
|
-
* Used for operations that require elevated permissions but not full admin
|
|
56
|
-
*/
|
|
37
|
+
/** For operations that need elevated rights but not full admin. */
|
|
57
38
|
export function isPrivileged(groups) {
|
|
58
39
|
return isReviewer(groups);
|
|
59
40
|
}
|
|
@@ -1,29 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Authorization
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* ## Quick Start
|
|
7
|
-
*
|
|
8
|
-
* For most use cases, use `checkContentAccess` which handles both branch and path permissions:
|
|
9
|
-
*
|
|
10
|
-
* ```ts
|
|
11
|
-
* import { checkContentAccess } from './authorization.js'
|
|
12
|
-
*
|
|
13
|
-
* const result = await checkContentAccess(deps, context, branchRoot, 'content/posts/post.mdx', user, 'edit')
|
|
14
|
-
* if (result.allowed) {
|
|
15
|
-
* // User can edit the file
|
|
16
|
-
* }
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* ## Module Structure
|
|
20
|
-
*
|
|
21
|
-
* - `content.ts` - Combined branch + path access (main entry point)
|
|
22
|
-
* - `branch.ts` - Branch-level access control
|
|
23
|
-
* - `path.ts` - Path-level permissions
|
|
24
|
-
* - `helpers.ts` - Utility functions (isAdmin, isReviewer, etc.)
|
|
25
|
-
* - `permissions/` - Permissions file schema and loader
|
|
26
|
-
* - `groups/` - Groups file schema and loader
|
|
2
|
+
* Authorization for CanopyCMS: checking user access to branches and content.
|
|
3
|
+
* Most callers want `checkContentAccess(deps, context, branchRoot, path, user,
|
|
4
|
+
* level)`, which covers both the branch and the path layer.
|
|
27
5
|
*/
|
|
28
6
|
export type { BranchAccessResult, PathPermissionResult, ContentAccessResult, ContentAccessDeps, PermissionPath, } from './types.js';
|
|
29
7
|
export { parsePermissionPath } from './validation.js';
|
|
@@ -1,46 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Authorization
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* ## Quick Start
|
|
7
|
-
*
|
|
8
|
-
* For most use cases, use `checkContentAccess` which handles both branch and path permissions:
|
|
9
|
-
*
|
|
10
|
-
* ```ts
|
|
11
|
-
* import { checkContentAccess } from './authorization.js'
|
|
12
|
-
*
|
|
13
|
-
* const result = await checkContentAccess(deps, context, branchRoot, 'content/posts/post.mdx', user, 'edit')
|
|
14
|
-
* if (result.allowed) {
|
|
15
|
-
* // User can edit the file
|
|
16
|
-
* }
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* ## Module Structure
|
|
20
|
-
*
|
|
21
|
-
* - `content.ts` - Combined branch + path access (main entry point)
|
|
22
|
-
* - `branch.ts` - Branch-level access control
|
|
23
|
-
* - `path.ts` - Path-level permissions
|
|
24
|
-
* - `helpers.ts` - Utility functions (isAdmin, isReviewer, etc.)
|
|
25
|
-
* - `permissions/` - Permissions file schema and loader
|
|
26
|
-
* - `groups/` - Groups file schema and loader
|
|
2
|
+
* Authorization for CanopyCMS: checking user access to branches and content.
|
|
3
|
+
* Most callers want `checkContentAccess(deps, context, branchRoot, path, user,
|
|
4
|
+
* level)`, which covers both the branch and the path layer.
|
|
27
5
|
*/
|
|
28
|
-
// Validation
|
|
29
6
|
export { parsePermissionPath } from './validation.js';
|
|
30
|
-
// Main content access (recommended for most cases)
|
|
31
7
|
export { checkContentAccess, createCheckContentAccess, createContentAccessChecker, } from './content.js';
|
|
32
|
-
// Branch-level access
|
|
33
8
|
export { checkBranchAccessWithDefault, createCheckBranchAccess, canPerformWorkflowAction, } from './branch.js';
|
|
34
|
-
// Protected base branch (submit-block + read-only predicate)
|
|
35
9
|
export { getBranchProtection, getBranchWriteProtection, } from './protected-branch.js';
|
|
36
|
-
// Path-level access
|
|
37
10
|
export { checkPathAccess, createCheckPathAccess, resolveDefaultPathAccess } from './path.js';
|
|
38
|
-
// Helper functions
|
|
39
11
|
export { RESERVED_GROUPS, isReservedGroup, stripReservedGroups, isAdmin, isReviewer, isPrivileged, } from './helpers.js';
|
|
40
|
-
// Permissions file handling
|
|
41
12
|
export { PermissionsFileSchema, createDefaultPermissionsFile, loadPermissionsFile, loadPathPermissions, mutatePermissionsFile, ensurePermissionsFile, } from './permissions/index.js';
|
|
42
|
-
// Groups file handling
|
|
43
13
|
export { GroupsFileSchema, createDefaultGroupsFile, loadGroupsFile, loadInternalGroups, deriveInternalGroups, mutateGroupsFile, } from './groups/index.js';
|
|
44
|
-
// Settings file store — cross-host layered locking shared by
|
|
45
|
-
// permissions.json and groups.json (see authorization/settings-file-store.ts)
|
|
46
14
|
export { mutateSettingsJsonFile, SettingsFileConflictError, SettingsVersionConflictError, } from './settings-file-store.js';
|
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Path-level authorization
|
|
3
|
-
*
|
|
4
|
-
* Handles checking if a user can access a specific path based on permission rules.
|
|
5
|
-
*/
|
|
6
1
|
import type { PathPermission, DefaultPathAccess, PermissionLevel } from '../config/index.js';
|
|
7
2
|
import type { CanopyUser } from '../user.js';
|
|
8
3
|
import type { PathPermissionResult } from './types.js';
|
|
9
4
|
import type { PhysicalPath } from '../paths/types.js';
|
|
10
5
|
/**
|
|
11
|
-
* Resolve
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
6
|
+
* Resolve `defaultPathAccess` to an 'allow'/'deny' verdict for one permission
|
|
7
|
+
* level. String form applies to every level; object form looks up the level,
|
|
8
|
+
* and an absent level resolves to 'deny' (fail-closed) so `{ read: 'allow' }`
|
|
9
|
+
* cannot accidentally open edit/review.
|
|
10
|
+
* @internal Exported for tests.
|
|
16
11
|
*/
|
|
17
12
|
export declare function resolveDefaultPathAccess(defaultAccess: DefaultPathAccess, level: PermissionLevel): 'allow' | 'deny';
|
|
18
13
|
/**
|
|
19
14
|
* Evaluate access for a relative path against config-defined rules.
|
|
20
15
|
* Uses defaultAccess when no rule matches. First matching rule wins.
|
|
16
|
+
* @internal Exported for tests.
|
|
21
17
|
*/
|
|
22
18
|
export declare function checkPathAccess({ rules, relativePath, user, defaultAccess, level, }: {
|
|
23
19
|
rules: PathPermission[];
|
|
@@ -26,9 +22,6 @@ export declare function checkPathAccess({ rules, relativePath, user, defaultAcce
|
|
|
26
22
|
defaultAccess: DefaultPathAccess;
|
|
27
23
|
level: PermissionLevel;
|
|
28
24
|
}): PathPermissionResult;
|
|
29
|
-
/**
|
|
30
|
-
* Factory to bind rules and defaultAccess once.
|
|
31
|
-
*/
|
|
32
25
|
export declare function createCheckPathAccess(rules: PathPermission[], defaultAccess: DefaultPathAccess): (input: {
|
|
33
26
|
relativePath: PhysicalPath;
|
|
34
27
|
user: CanopyUser;
|
|
@@ -1,31 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Path-level authorization
|
|
3
|
-
*
|
|
4
|
-
* Handles checking if a user can access a specific path based on permission rules.
|
|
5
|
-
*/
|
|
6
1
|
import path from 'node:path';
|
|
7
2
|
import { minimatch } from 'minimatch';
|
|
8
3
|
import { isAdmin } from './helpers.js';
|
|
9
|
-
/**
|
|
10
|
-
* Normalize a path for consistent matching
|
|
11
|
-
*/
|
|
12
4
|
function normalize(p) {
|
|
13
5
|
const normalized = p.split(path.sep).join('/');
|
|
14
6
|
return normalized.replace(/^\.?\/*/, '');
|
|
15
7
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Check if a path matches a permission rule
|
|
18
|
-
*/
|
|
19
8
|
function matchesRule(rule, relativePath) {
|
|
20
9
|
return minimatch(relativePath, rule.path, { dot: true });
|
|
21
10
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Check if user matches a permission target
|
|
24
|
-
*/
|
|
25
11
|
function isAllowedByTarget(target, user) {
|
|
26
12
|
const hasUserConstraint = !!target.allowedUsers?.length;
|
|
27
13
|
const hasGroupConstraint = !!target.allowedGroups?.length;
|
|
28
|
-
//
|
|
14
|
+
// A target with no constraints applies to everyone.
|
|
29
15
|
if (!hasUserConstraint && !hasGroupConstraint) {
|
|
30
16
|
return true;
|
|
31
17
|
}
|
|
@@ -34,11 +20,11 @@ function isAllowedByTarget(target, user) {
|
|
|
34
20
|
return Boolean(matchesUser || matchesGroup);
|
|
35
21
|
}
|
|
36
22
|
/**
|
|
37
|
-
* Resolve
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
23
|
+
* Resolve `defaultPathAccess` to an 'allow'/'deny' verdict for one permission
|
|
24
|
+
* level. String form applies to every level; object form looks up the level,
|
|
25
|
+
* and an absent level resolves to 'deny' (fail-closed) so `{ read: 'allow' }`
|
|
26
|
+
* cannot accidentally open edit/review.
|
|
27
|
+
* @internal Exported for tests.
|
|
42
28
|
*/
|
|
43
29
|
export function resolveDefaultPathAccess(defaultAccess, level) {
|
|
44
30
|
if (typeof defaultAccess === 'string')
|
|
@@ -48,6 +34,7 @@ export function resolveDefaultPathAccess(defaultAccess, level) {
|
|
|
48
34
|
/**
|
|
49
35
|
* Evaluate access for a relative path against config-defined rules.
|
|
50
36
|
* Uses defaultAccess when no rule matches. First matching rule wins.
|
|
37
|
+
* @internal Exported for tests.
|
|
51
38
|
*/
|
|
52
39
|
export function checkPathAccess({ rules, relativePath, user, defaultAccess, level, }) {
|
|
53
40
|
const normalizedPath = normalize(relativePath);
|
|
@@ -59,10 +46,9 @@ export function checkPathAccess({ rules, relativePath, user, defaultAccess, leve
|
|
|
59
46
|
if (!matchesRule(rule, normalizedPath)) {
|
|
60
47
|
continue;
|
|
61
48
|
}
|
|
62
|
-
// Get the permission target for this level
|
|
63
49
|
const target = rule[level];
|
|
64
50
|
if (!target) {
|
|
65
|
-
//
|
|
51
|
+
// A rule that defines nothing for this level does not decide it.
|
|
66
52
|
continue;
|
|
67
53
|
}
|
|
68
54
|
const allowed = isAllowedByTarget(target, user);
|
|
@@ -77,9 +63,6 @@ export function checkPathAccess({ rules, relativePath, user, defaultAccess, leve
|
|
|
77
63
|
reason: 'no_rule_match',
|
|
78
64
|
};
|
|
79
65
|
}
|
|
80
|
-
/**
|
|
81
|
-
* Factory to bind rules and defaultAccess once.
|
|
82
|
-
*/
|
|
83
66
|
export function createCheckPathAccess(rules, defaultAccess) {
|
|
84
67
|
return (input) => checkPathAccess({ ...input, rules, defaultAccess });
|
|
85
68
|
}
|
|
@@ -1,46 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Handles loading path permissions from the filesystem and mutating
|
|
5
|
-
* permissions.json under the cross-host layered lock in
|
|
6
|
-
* authorization/settings-file-store.ts.
|
|
2
|
+
* Loads path permissions, and mutates permissions.json under the cross-host
|
|
3
|
+
* layered lock in authorization/settings-file-store.ts.
|
|
7
4
|
*/
|
|
8
5
|
import type { PathPermission } from '../../config/index.js';
|
|
9
6
|
import type { PermissionsFile } from './schema.js';
|
|
10
7
|
import type { OperatingMode } from '../../operating-mode/index.js';
|
|
11
8
|
import type { OccWriteResult } from '../../utils/occ-json-write.js';
|
|
12
|
-
/**
|
|
13
|
-
* Load full permissions file (for version checking)
|
|
14
|
-
* Returns null if file doesn't exist.
|
|
15
|
-
*
|
|
16
|
-
* @param repoRoot - Repository root directory
|
|
17
|
-
* @param mode - Operating mode (determines file path)
|
|
18
|
-
*/
|
|
9
|
+
/** Returns null when the file doesn't exist. */
|
|
19
10
|
export declare function loadPermissionsFile(repoRoot: string, mode: OperatingMode): Promise<PermissionsFile | null>;
|
|
20
11
|
/**
|
|
21
|
-
*
|
|
22
|
-
* Returns empty array
|
|
23
|
-
*
|
|
24
|
-
* @param repoRoot - Repository root directory
|
|
25
|
-
* @param mode - Operating mode (determines file path)
|
|
12
|
+
* Loads .canopycms/permissions.json (permissions.local.json in dev mode).
|
|
13
|
+
* Returns an empty array when the file doesn't exist: no restrictions.
|
|
26
14
|
*/
|
|
27
15
|
export declare function loadPathPermissions(repoRoot: string, mode: OperatingMode): Promise<PathPermission[]>;
|
|
28
16
|
/**
|
|
29
|
-
* Mutate permissions.json (
|
|
30
|
-
* cross-host lock + OCC-retry stack (see
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* {@link PermissionsFileSchema} before being written, preserving the
|
|
36
|
-
* previous validate-before-write behavior of the old `savePathPermissions`.
|
|
17
|
+
* Mutate permissions.json (permissions.local.json in dev mode) under the full
|
|
18
|
+
* cross-host lock + OCC-retry stack (see authorization/settings-file-store.ts).
|
|
19
|
+
* `mutate` receives the current parsed file (`null` if absent) and the version
|
|
20
|
+
* to write under, and returns the next raw payload or `null` for a deliberate
|
|
21
|
+
* no-op. The payload is validated against {@link PermissionsFileSchema} before
|
|
22
|
+
* writing.
|
|
37
23
|
*/
|
|
38
24
|
export declare function mutatePermissionsFile(repoRoot: string, mode: OperatingMode, mutate: (current: PermissionsFile | null, version: number) => Record<string, unknown> | null, options?: {
|
|
39
25
|
settleMs?: number;
|
|
40
26
|
maxAttempts?: number;
|
|
41
27
|
}): Promise<OccWriteResult | null>;
|
|
42
28
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
29
|
+
* Create the permissions file if it doesn't exist; a no-op when it is already
|
|
30
|
+
* present (the mutator returns `null`, so no write happens).
|
|
31
|
+
* @internal Exported for tests.
|
|
45
32
|
*/
|
|
46
33
|
export declare function ensurePermissionsFile(repoRoot: string, userId: string, mode: OperatingMode): Promise<void>;
|
|
@@ -1,27 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Handles loading path permissions from the filesystem and mutating
|
|
5
|
-
* permissions.json under the cross-host layered lock in
|
|
6
|
-
* authorization/settings-file-store.ts.
|
|
2
|
+
* Loads path permissions, and mutates permissions.json under the cross-host
|
|
3
|
+
* layered lock in authorization/settings-file-store.ts.
|
|
7
4
|
*/
|
|
8
5
|
import fs from 'node:fs/promises';
|
|
9
6
|
import { PermissionsFileSchema } from './schema.js';
|
|
10
7
|
import { operatingStrategy } from '../../operating-mode/index.js';
|
|
11
8
|
import { mutateSettingsJsonFile } from '../settings-file-store.js';
|
|
12
|
-
/**
|
|
13
|
-
* Get the appropriate permissions file path based on mode
|
|
14
|
-
*/
|
|
15
9
|
function getPermissionsFilePath(repoRoot, mode) {
|
|
16
10
|
return operatingStrategy(mode).getPermissionsFilePath(repoRoot);
|
|
17
11
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Load full permissions file (for version checking)
|
|
20
|
-
* Returns null if file doesn't exist.
|
|
21
|
-
*
|
|
22
|
-
* @param repoRoot - Repository root directory
|
|
23
|
-
* @param mode - Operating mode (determines file path)
|
|
24
|
-
*/
|
|
12
|
+
/** Returns null when the file doesn't exist. */
|
|
25
13
|
export async function loadPermissionsFile(repoRoot, mode) {
|
|
26
14
|
const permissionsPath = getPermissionsFilePath(repoRoot, mode);
|
|
27
15
|
try {
|
|
@@ -31,35 +19,28 @@ export async function loadPermissionsFile(repoRoot, mode) {
|
|
|
31
19
|
return validated;
|
|
32
20
|
}
|
|
33
21
|
catch (error) {
|
|
34
|
-
// File doesn't exist
|
|
35
22
|
if (error.code === 'ENOENT') {
|
|
36
23
|
return null;
|
|
37
24
|
}
|
|
38
|
-
// Parse/validation error - this is more serious
|
|
39
25
|
console.error('CanopyCMS: Failed to parse permissions file', error);
|
|
40
26
|
throw new Error(`Invalid permissions file: ${error instanceof Error ? error.message : 'unknown error'}`);
|
|
41
27
|
}
|
|
42
28
|
}
|
|
43
29
|
/**
|
|
44
|
-
*
|
|
45
|
-
* Returns empty array
|
|
46
|
-
*
|
|
47
|
-
* @param repoRoot - Repository root directory
|
|
48
|
-
* @param mode - Operating mode (determines file path)
|
|
30
|
+
* Loads .canopycms/permissions.json (permissions.local.json in dev mode).
|
|
31
|
+
* Returns an empty array when the file doesn't exist: no restrictions.
|
|
49
32
|
*/
|
|
50
33
|
export async function loadPathPermissions(repoRoot, mode) {
|
|
51
34
|
const file = await loadPermissionsFile(repoRoot, mode);
|
|
52
35
|
return file?.pathPermissions ?? [];
|
|
53
36
|
}
|
|
54
37
|
/**
|
|
55
|
-
* Mutate permissions.json (
|
|
56
|
-
* cross-host lock + OCC-retry stack (see
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* {@link PermissionsFileSchema} before being written, preserving the
|
|
62
|
-
* previous validate-before-write behavior of the old `savePathPermissions`.
|
|
38
|
+
* Mutate permissions.json (permissions.local.json in dev mode) under the full
|
|
39
|
+
* cross-host lock + OCC-retry stack (see authorization/settings-file-store.ts).
|
|
40
|
+
* `mutate` receives the current parsed file (`null` if absent) and the version
|
|
41
|
+
* to write under, and returns the next raw payload or `null` for a deliberate
|
|
42
|
+
* no-op. The payload is validated against {@link PermissionsFileSchema} before
|
|
43
|
+
* writing.
|
|
63
44
|
*/
|
|
64
45
|
export async function mutatePermissionsFile(repoRoot, mode, mutate, options) {
|
|
65
46
|
const permissionsPath = getPermissionsFilePath(repoRoot, mode);
|
|
@@ -75,8 +56,9 @@ export async function mutatePermissionsFile(repoRoot, mode, mutate, options) {
|
|
|
75
56
|
});
|
|
76
57
|
}
|
|
77
58
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
59
|
+
* Create the permissions file if it doesn't exist; a no-op when it is already
|
|
60
|
+
* present (the mutator returns `null`, so no write happens).
|
|
61
|
+
* @internal Exported for tests.
|
|
80
62
|
*/
|
|
81
63
|
export async function ensurePermissionsFile(repoRoot, userId, mode) {
|
|
82
64
|
await mutatePermissionsFile(repoRoot, mode, (current) => {
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema for permissions.json file
|
|
3
|
-
*/
|
|
4
1
|
import { z } from 'zod';
|
|
5
2
|
import type { CanopyUserId } from '../../types.js';
|
|
6
3
|
import type { PermissionPath } from '../types.js';
|
|
7
4
|
/**
|
|
8
5
|
* Schema for .canopycms/permissions.json
|
|
9
|
-
*
|
|
10
|
-
* SECURITY: Permission paths are validated to prevent path traversal attacks.
|
|
11
|
-
* Any path containing '..' or other traversal sequences will be rejected.
|
|
12
6
|
*/
|
|
13
7
|
export declare const PermissionsFileSchema: z.ZodObject<{
|
|
14
8
|
version: z.ZodOptional<z.ZodNumber>;
|
|
@@ -129,5 +123,6 @@ export type PermissionsFile = z.infer<typeof PermissionsFileSchema>;
|
|
|
129
123
|
/**
|
|
130
124
|
* Default permissions file. Omits `version`/`writeId` — the writer
|
|
131
125
|
* (mutateSettingsJsonFile via writeOccJsonFile) manages those.
|
|
126
|
+
* @internal Exported for tests.
|
|
132
127
|
*/
|
|
133
128
|
export declare function createDefaultPermissionsFile(userId: CanopyUserId): PermissionsFile;
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema for permissions.json file
|
|
3
|
-
*/
|
|
4
1
|
import { z } from 'zod';
|
|
5
2
|
import { parsePermissionPath } from '../validation.js';
|
|
6
3
|
const permissionTargetSchema = z.object({
|
|
7
4
|
allowedUsers: z.array(z.string()).optional(),
|
|
8
5
|
allowedGroups: z.array(z.string()).optional(),
|
|
9
6
|
});
|
|
10
|
-
/**
|
|
11
|
-
* Zod schema for PermissionPath - validates and prevents path traversal attacks.
|
|
12
|
-
*/
|
|
7
|
+
/** PermissionPath field: rejects path traversal via parsePermissionPath. */
|
|
13
8
|
const permissionPathSchema = z
|
|
14
9
|
.string()
|
|
15
10
|
.min(1)
|
|
@@ -26,15 +21,12 @@ const permissionPathSchema = z
|
|
|
26
21
|
});
|
|
27
22
|
/**
|
|
28
23
|
* Schema for .canopycms/permissions.json
|
|
29
|
-
*
|
|
30
|
-
* SECURITY: Permission paths are validated to prevent path traversal attacks.
|
|
31
|
-
* Any path containing '..' or other traversal sequences will be rejected.
|
|
32
24
|
*/
|
|
33
25
|
export const PermissionsFileSchema = z.object({
|
|
34
|
-
// Managed by writeOccJsonFile (see authorization/settings-file-store.ts)
|
|
35
|
-
// the single OCC counter for this file. Optional so a hand-written file
|
|
36
|
-
//
|
|
37
|
-
//
|
|
26
|
+
// Managed by writeOccJsonFile (see authorization/settings-file-store.ts):
|
|
27
|
+
// the single OCC counter for this file. Optional so a hand-written file with
|
|
28
|
+
// no version field parses as version 0; a stray `contentVersion` key is
|
|
29
|
+
// silently stripped by this non-strict zod parse.
|
|
38
30
|
version: z.number().int().nonnegative().optional(),
|
|
39
31
|
writeId: z.string().optional(),
|
|
40
32
|
updatedAt: z.string().datetime(),
|
|
@@ -49,6 +41,7 @@ export const PermissionsFileSchema = z.object({
|
|
|
49
41
|
/**
|
|
50
42
|
* Default permissions file. Omits `version`/`writeId` — the writer
|
|
51
43
|
* (mutateSettingsJsonFile via writeOccJsonFile) manages those.
|
|
44
|
+
* @internal Exported for tests.
|
|
52
45
|
*/
|
|
53
46
|
export function createDefaultPermissionsFile(userId) {
|
|
54
47
|
return {
|