@jini-ai/cms 0.1.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/LICENSE +201 -0
- package/README.md +84 -0
- package/dist/content-types/agent-tools.d.ts +65 -0
- package/dist/content-types/agent-tools.d.ts.map +1 -0
- package/dist/content-types/agent-tools.js +172 -0
- package/dist/content-types/agent-tools.js.map +1 -0
- package/dist/content-types/cleanup.d.ts +118 -0
- package/dist/content-types/cleanup.d.ts.map +1 -0
- package/dist/content-types/cleanup.js +65 -0
- package/dist/content-types/cleanup.js.map +1 -0
- package/dist/content-types/errors.d.ts +90 -0
- package/dist/content-types/errors.d.ts.map +1 -0
- package/dist/content-types/errors.js +119 -0
- package/dist/content-types/errors.js.map +1 -0
- package/dist/content-types/field-defs.d.ts +25 -0
- package/dist/content-types/field-defs.d.ts.map +1 -0
- package/dist/content-types/field-defs.js +155 -0
- package/dist/content-types/field-defs.js.map +1 -0
- package/dist/content-types/index-provisioning.d.ts +94 -0
- package/dist/content-types/index-provisioning.d.ts.map +1 -0
- package/dist/content-types/index-provisioning.js +133 -0
- package/dist/content-types/index-provisioning.js.map +1 -0
- package/dist/content-types/index.d.ts +63 -0
- package/dist/content-types/index.d.ts.map +1 -0
- package/dist/content-types/index.js +36 -0
- package/dist/content-types/index.js.map +1 -0
- package/dist/content-types/lifecycle-dispatch.d.ts +38 -0
- package/dist/content-types/lifecycle-dispatch.d.ts.map +1 -0
- package/dist/content-types/lifecycle-dispatch.js +28 -0
- package/dist/content-types/lifecycle-dispatch.js.map +1 -0
- package/dist/content-types/lifecycle.d.ts +104 -0
- package/dist/content-types/lifecycle.d.ts.map +1 -0
- package/dist/content-types/lifecycle.js +143 -0
- package/dist/content-types/lifecycle.js.map +1 -0
- package/dist/content-types/list.d.ts +44 -0
- package/dist/content-types/list.d.ts.map +1 -0
- package/dist/content-types/list.js +13 -0
- package/dist/content-types/list.js.map +1 -0
- package/dist/content-types/repo.memory.d.ts +72 -0
- package/dist/content-types/repo.memory.d.ts.map +1 -0
- package/dist/content-types/repo.memory.js +71 -0
- package/dist/content-types/repo.memory.js.map +1 -0
- package/dist/content-types/tool-registrations.d.ts +65 -0
- package/dist/content-types/tool-registrations.d.ts.map +1 -0
- package/dist/content-types/tool-registrations.js +180 -0
- package/dist/content-types/tool-registrations.js.map +1 -0
- package/dist/content-types/types.d.ts +78 -0
- package/dist/content-types/types.d.ts.map +1 -0
- package/dist/content-types/types.js +32 -0
- package/dist/content-types/types.js.map +1 -0
- package/dist/content-types/write-service.d.ts +141 -0
- package/dist/content-types/write-service.d.ts.map +1 -0
- package/dist/content-types/write-service.js +180 -0
- package/dist/content-types/write-service.js.map +1 -0
- package/dist/core/commands/change-set.d.ts +98 -0
- package/dist/core/commands/change-set.d.ts.map +1 -0
- package/dist/core/commands/change-set.js +2 -0
- package/dist/core/commands/change-set.js.map +1 -0
- package/dist/core/commands/command.d.ts +168 -0
- package/dist/core/commands/command.d.ts.map +1 -0
- package/dist/core/commands/command.js +173 -0
- package/dist/core/commands/command.js.map +1 -0
- package/dist/core/index.d.ts +45 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +43 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/ports.d.ts +139 -0
- package/dist/core/ports.d.ts.map +1 -0
- package/dist/core/ports.js +2 -0
- package/dist/core/ports.js.map +1 -0
- package/dist/core/tools/registration-kit.d.ts +308 -0
- package/dist/core/tools/registration-kit.d.ts.map +1 -0
- package/dist/core/tools/registration-kit.js +381 -0
- package/dist/core/tools/registration-kit.js.map +1 -0
- package/dist/entries/agent-tools.d.ts +78 -0
- package/dist/entries/agent-tools.d.ts.map +1 -0
- package/dist/entries/agent-tools.js +158 -0
- package/dist/entries/agent-tools.js.map +1 -0
- package/dist/entries/errors.d.ts +43 -0
- package/dist/entries/errors.d.ts.map +1 -0
- package/dist/entries/errors.js +59 -0
- package/dist/entries/errors.js.map +1 -0
- package/dist/entries/field-validation.d.ts +70 -0
- package/dist/entries/field-validation.d.ts.map +1 -0
- package/dist/entries/field-validation.js +87 -0
- package/dist/entries/field-validation.js.map +1 -0
- package/dist/entries/index.d.ts +55 -0
- package/dist/entries/index.d.ts.map +1 -0
- package/dist/entries/index.js +38 -0
- package/dist/entries/index.js.map +1 -0
- package/dist/entries/lifecycle-dispatch.d.ts +15 -0
- package/dist/entries/lifecycle-dispatch.d.ts.map +1 -0
- package/dist/entries/lifecycle-dispatch.js +16 -0
- package/dist/entries/lifecycle-dispatch.js.map +1 -0
- package/dist/entries/list.d.ts +47 -0
- package/dist/entries/list.d.ts.map +1 -0
- package/dist/entries/list.js +12 -0
- package/dist/entries/list.js.map +1 -0
- package/dist/entries/repo.memory.d.ts +64 -0
- package/dist/entries/repo.memory.d.ts.map +1 -0
- package/dist/entries/repo.memory.js +73 -0
- package/dist/entries/repo.memory.js.map +1 -0
- package/dist/entries/tool-registrations.d.ts +52 -0
- package/dist/entries/tool-registrations.d.ts.map +1 -0
- package/dist/entries/tool-registrations.js +141 -0
- package/dist/entries/tool-registrations.js.map +1 -0
- package/dist/entries/types.d.ts +55 -0
- package/dist/entries/types.d.ts.map +1 -0
- package/dist/entries/types.js +2 -0
- package/dist/entries/types.js.map +1 -0
- package/dist/entries/write-service.d.ts +202 -0
- package/dist/entries/write-service.d.ts.map +1 -0
- package/dist/entries/write-service.js +204 -0
- package/dist/entries/write-service.js.map +1 -0
- package/dist/identity/admin-crud-service.d.ts +252 -0
- package/dist/identity/admin-crud-service.d.ts.map +1 -0
- package/dist/identity/admin-crud-service.js +437 -0
- package/dist/identity/admin-crud-service.js.map +1 -0
- package/dist/identity/agent-tool-input.d.ts +58 -0
- package/dist/identity/agent-tool-input.d.ts.map +1 -0
- package/dist/identity/agent-tool-input.js +126 -0
- package/dist/identity/agent-tool-input.js.map +1 -0
- package/dist/identity/agent-tools.d.ts +101 -0
- package/dist/identity/agent-tools.d.ts.map +1 -0
- package/dist/identity/agent-tools.js +290 -0
- package/dist/identity/agent-tools.js.map +1 -0
- package/dist/identity/auth-service.d.ts +87 -0
- package/dist/identity/auth-service.d.ts.map +1 -0
- package/dist/identity/auth-service.js +141 -0
- package/dist/identity/auth-service.js.map +1 -0
- package/dist/identity/authorize.d.ts +90 -0
- package/dist/identity/authorize.d.ts.map +1 -0
- package/dist/identity/authorize.js +94 -0
- package/dist/identity/authorize.js.map +1 -0
- package/dist/identity/grant-service.d.ts +198 -0
- package/dist/identity/grant-service.d.ts.map +1 -0
- package/dist/identity/grant-service.js +361 -0
- package/dist/identity/grant-service.js.map +1 -0
- package/dist/identity/hasher.d.ts +39 -0
- package/dist/identity/hasher.d.ts.map +1 -0
- package/dist/identity/hasher.js +39 -0
- package/dist/identity/hasher.js.map +1 -0
- package/dist/identity/index.d.ts +59 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +51 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/password-policy.d.ts +58 -0
- package/dist/identity/password-policy.d.ts.map +1 -0
- package/dist/identity/password-policy.js +67 -0
- package/dist/identity/password-policy.js.map +1 -0
- package/dist/identity/permission-migrations.d.ts +86 -0
- package/dist/identity/permission-migrations.d.ts.map +1 -0
- package/dist/identity/permission-migrations.js +67 -0
- package/dist/identity/permission-migrations.js.map +1 -0
- package/dist/identity/permissions.d.ts +35 -0
- package/dist/identity/permissions.d.ts.map +1 -0
- package/dist/identity/permissions.js +603 -0
- package/dist/identity/permissions.js.map +1 -0
- package/dist/identity/ports.d.ts +201 -0
- package/dist/identity/ports.d.ts.map +1 -0
- package/dist/identity/ports.js +2 -0
- package/dist/identity/ports.js.map +1 -0
- package/dist/identity/repo.memory.d.ts +164 -0
- package/dist/identity/repo.memory.d.ts.map +1 -0
- package/dist/identity/repo.memory.js +224 -0
- package/dist/identity/repo.memory.js.map +1 -0
- package/dist/identity/seed.d.ts +42 -0
- package/dist/identity/seed.d.ts.map +1 -0
- package/dist/identity/seed.js +277 -0
- package/dist/identity/seed.js.map +1 -0
- package/dist/identity/tool-registrations.d.ts +50 -0
- package/dist/identity/tool-registrations.d.ts.map +1 -0
- package/dist/identity/tool-registrations.js +419 -0
- package/dist/identity/tool-registrations.js.map +1 -0
- package/dist/identity/types.d.ts +185 -0
- package/dist/identity/types.d.ts.map +1 -0
- package/dist/identity/types.js +64 -0
- package/dist/identity/types.js.map +1 -0
- package/dist/identity/username.d.ts +12 -0
- package/dist/identity/username.d.ts.map +1 -0
- package/dist/identity/username.js +14 -0
- package/dist/identity/username.js.map +1 -0
- package/dist/media/agent-tools.d.ts +66 -0
- package/dist/media/agent-tools.d.ts.map +1 -0
- package/dist/media/agent-tools.js +131 -0
- package/dist/media/agent-tools.js.map +1 -0
- package/dist/media/blob-gc-lock.d.ts +37 -0
- package/dist/media/blob-gc-lock.d.ts.map +1 -0
- package/dist/media/blob-gc-lock.js +55 -0
- package/dist/media/blob-gc-lock.js.map +1 -0
- package/dist/media/blob-gc.d.ts +246 -0
- package/dist/media/blob-gc.d.ts.map +1 -0
- package/dist/media/blob-gc.js +254 -0
- package/dist/media/blob-gc.js.map +1 -0
- package/dist/media/blob-key.d.ts +28 -0
- package/dist/media/blob-key.d.ts.map +1 -0
- package/dist/media/blob-key.js +11 -0
- package/dist/media/blob-key.js.map +1 -0
- package/dist/media/blob-store.fs.d.ts +23 -0
- package/dist/media/blob-store.fs.d.ts.map +1 -0
- package/dist/media/blob-store.fs.js +48 -0
- package/dist/media/blob-store.fs.js.map +1 -0
- package/dist/media/blob-store.memory.d.ts +22 -0
- package/dist/media/blob-store.memory.d.ts.map +1 -0
- package/dist/media/blob-store.memory.js +23 -0
- package/dist/media/blob-store.memory.js.map +1 -0
- package/dist/media/content-type-sniffer.d.ts +49 -0
- package/dist/media/content-type-sniffer.d.ts.map +1 -0
- package/dist/media/content-type-sniffer.js +141 -0
- package/dist/media/content-type-sniffer.js.map +1 -0
- package/dist/media/image-transformer.d.ts +45 -0
- package/dist/media/image-transformer.d.ts.map +1 -0
- package/dist/media/image-transformer.js +23 -0
- package/dist/media/image-transformer.js.map +1 -0
- package/dist/media/image-transformer.sharp.d.ts +26 -0
- package/dist/media/image-transformer.sharp.d.ts.map +1 -0
- package/dist/media/image-transformer.sharp.js +91 -0
- package/dist/media/image-transformer.sharp.js.map +1 -0
- package/dist/media/index.d.ts +43 -0
- package/dist/media/index.d.ts.map +1 -0
- package/dist/media/index.js +31 -0
- package/dist/media/index.js.map +1 -0
- package/dist/media/media-service.d.ts +244 -0
- package/dist/media/media-service.d.ts.map +1 -0
- package/dist/media/media-service.js +345 -0
- package/dist/media/media-service.js.map +1 -0
- package/dist/media/ports.d.ts +142 -0
- package/dist/media/ports.d.ts.map +1 -0
- package/dist/media/ports.js +2 -0
- package/dist/media/ports.js.map +1 -0
- package/dist/media/rendition-service.d.ts +66 -0
- package/dist/media/rendition-service.d.ts.map +1 -0
- package/dist/media/rendition-service.js +135 -0
- package/dist/media/rendition-service.js.map +1 -0
- package/dist/media/repo.memory.d.ts +107 -0
- package/dist/media/repo.memory.d.ts.map +1 -0
- package/dist/media/repo.memory.js +131 -0
- package/dist/media/repo.memory.js.map +1 -0
- package/dist/media/tool-registrations.d.ts +42 -0
- package/dist/media/tool-registrations.d.ts.map +1 -0
- package/dist/media/tool-registrations.js +121 -0
- package/dist/media/tool-registrations.js.map +1 -0
- package/dist/media/transform-lock.d.ts +36 -0
- package/dist/media/transform-lock.d.ts.map +1 -0
- package/dist/media/transform-lock.js +50 -0
- package/dist/media/transform-lock.js.map +1 -0
- package/dist/media/transform-registry.d.ts +103 -0
- package/dist/media/transform-registry.d.ts.map +1 -0
- package/dist/media/transform-registry.js +87 -0
- package/dist/media/transform-registry.js.map +1 -0
- package/dist/media/transform-types.d.ts +82 -0
- package/dist/media/transform-types.d.ts.map +1 -0
- package/dist/media/transform-types.js +47 -0
- package/dist/media/transform-types.js.map +1 -0
- package/dist/media/types.d.ts +150 -0
- package/dist/media/types.d.ts.map +1 -0
- package/dist/media/types.js +26 -0
- package/dist/media/types.js.map +1 -0
- package/dist/navigation/agent-tools.d.ts +90 -0
- package/dist/navigation/agent-tools.d.ts.map +1 -0
- package/dist/navigation/agent-tools.js +225 -0
- package/dist/navigation/agent-tools.js.map +1 -0
- package/dist/navigation/contracts.d.ts +98 -0
- package/dist/navigation/contracts.d.ts.map +1 -0
- package/dist/navigation/contracts.js +70 -0
- package/dist/navigation/contracts.js.map +1 -0
- package/dist/navigation/index.d.ts +39 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +30 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/navigation/menu-service.d.ts +256 -0
- package/dist/navigation/menu-service.d.ts.map +1 -0
- package/dist/navigation/menu-service.js +382 -0
- package/dist/navigation/menu-service.js.map +1 -0
- package/dist/navigation/ports.d.ts +147 -0
- package/dist/navigation/ports.d.ts.map +1 -0
- package/dist/navigation/ports.js +2 -0
- package/dist/navigation/ports.js.map +1 -0
- package/dist/navigation/read-model.d.ts +11 -0
- package/dist/navigation/read-model.d.ts.map +1 -0
- package/dist/navigation/read-model.js +27 -0
- package/dist/navigation/read-model.js.map +1 -0
- package/dist/navigation/reconcile.d.ts +57 -0
- package/dist/navigation/reconcile.d.ts.map +1 -0
- package/dist/navigation/reconcile.js +33 -0
- package/dist/navigation/reconcile.js.map +1 -0
- package/dist/navigation/repo.memory.d.ts +137 -0
- package/dist/navigation/repo.memory.d.ts.map +1 -0
- package/dist/navigation/repo.memory.js +95 -0
- package/dist/navigation/repo.memory.js.map +1 -0
- package/dist/navigation/resolver.d.ts +110 -0
- package/dist/navigation/resolver.d.ts.map +1 -0
- package/dist/navigation/resolver.js +131 -0
- package/dist/navigation/resolver.js.map +1 -0
- package/dist/navigation/tool-registrations.d.ts +43 -0
- package/dist/navigation/tool-registrations.d.ts.map +1 -0
- package/dist/navigation/tool-registrations.js +126 -0
- package/dist/navigation/tool-registrations.js.map +1 -0
- package/dist/navigation/types.d.ts +207 -0
- package/dist/navigation/types.d.ts.map +1 -0
- package/dist/navigation/types.js +14 -0
- package/dist/navigation/types.js.map +1 -0
- package/dist/presentation/index.d.ts +15 -0
- package/dist/presentation/index.d.ts.map +1 -0
- package/dist/presentation/index.js +15 -0
- package/dist/presentation/index.js.map +1 -0
- package/dist/presentation/presentation.d.ts +72 -0
- package/dist/presentation/presentation.d.ts.map +1 -0
- package/dist/presentation/presentation.js +51 -0
- package/dist/presentation/presentation.js.map +1 -0
- package/dist/presentation/repo.memory.d.ts +9 -0
- package/dist/presentation/repo.memory.d.ts.map +1 -0
- package/dist/presentation/repo.memory.js +21 -0
- package/dist/presentation/repo.memory.js.map +1 -0
- package/dist/server/index.d.ts +28 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +28 -0
- package/dist/server/index.js.map +1 -0
- package/dist/settings/agent-tools.d.ts +83 -0
- package/dist/settings/agent-tools.d.ts.map +1 -0
- package/dist/settings/agent-tools.js +200 -0
- package/dist/settings/agent-tools.js.map +1 -0
- package/dist/settings/agent-writable-preferences.d.ts +67 -0
- package/dist/settings/agent-writable-preferences.d.ts.map +1 -0
- package/dist/settings/agent-writable-preferences.js +144 -0
- package/dist/settings/agent-writable-preferences.js.map +1 -0
- package/dist/settings/change-feed.d.ts +74 -0
- package/dist/settings/change-feed.d.ts.map +1 -0
- package/dist/settings/change-feed.js +61 -0
- package/dist/settings/change-feed.js.map +1 -0
- package/dist/settings/definitions-dispatch.d.ts +51 -0
- package/dist/settings/definitions-dispatch.d.ts.map +1 -0
- package/dist/settings/definitions-dispatch.js +86 -0
- package/dist/settings/definitions-dispatch.js.map +1 -0
- package/dist/settings/dictionaries/index.d.ts +45 -0
- package/dist/settings/dictionaries/index.d.ts.map +1 -0
- package/dist/settings/dictionaries/index.js +69 -0
- package/dist/settings/dictionaries/index.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ar.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ar.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ar.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ar.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.bn.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.bn.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.bn.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.bn.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.de.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.de.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.de.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.de.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.es.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.es.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.es.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.es.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.fa.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.fa.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.fa.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.fa.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.fr.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.fr.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.fr.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.fr.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.hi.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.hi.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.hi.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.hi.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.hu.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.hu.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.hu.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.hu.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.id.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.id.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.id.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.id.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.it.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.it.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.it.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.it.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ja.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ja.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ja.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ja.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ko.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ko.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ko.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ko.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.pl.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.pl.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.pl.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.pl.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.pt-BR.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.pt-BR.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.pt-BR.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.pt-BR.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ru.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ru.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ru.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ru.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.th.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.th.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.th.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.th.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.tr.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.tr.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.tr.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.tr.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.uk.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.uk.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.uk.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.uk.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ur.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ur.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ur.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ur.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.zh-CN.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.zh-CN.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.zh-CN.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.zh-CN.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.zh-TW.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.zh-TW.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.zh-TW.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.zh-TW.js.map +1 -0
- package/dist/settings/ensure-definitions.d.ts +88 -0
- package/dist/settings/ensure-definitions.d.ts.map +1 -0
- package/dist/settings/ensure-definitions.js +91 -0
- package/dist/settings/ensure-definitions.js.map +1 -0
- package/dist/settings/errors.d.ts +36 -0
- package/dist/settings/errors.d.ts.map +1 -0
- package/dist/settings/errors.js +40 -0
- package/dist/settings/errors.js.map +1 -0
- package/dist/settings/index.d.ts +37 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +36 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/ports.d.ts +117 -0
- package/dist/settings/ports.d.ts.map +1 -0
- package/dist/settings/ports.js +2 -0
- package/dist/settings/ports.js.map +1 -0
- package/dist/settings/purge-service.d.ts +53 -0
- package/dist/settings/purge-service.d.ts.map +1 -0
- package/dist/settings/purge-service.js +105 -0
- package/dist/settings/purge-service.js.map +1 -0
- package/dist/settings/repo.memory.d.ts +119 -0
- package/dist/settings/repo.memory.d.ts.map +1 -0
- package/dist/settings/repo.memory.js +199 -0
- package/dist/settings/repo.memory.js.map +1 -0
- package/dist/settings/settings.d.ts +124 -0
- package/dist/settings/settings.d.ts.map +1 -0
- package/dist/settings/settings.js +238 -0
- package/dist/settings/settings.js.map +1 -0
- package/dist/settings/tool-registrations.d.ts +56 -0
- package/dist/settings/tool-registrations.d.ts.map +1 -0
- package/dist/settings/tool-registrations.js +240 -0
- package/dist/settings/tool-registrations.js.map +1 -0
- package/dist/settings/types.d.ts +125 -0
- package/dist/settings/types.d.ts.map +1 -0
- package/dist/settings/types.js +3 -0
- package/dist/settings/types.js.map +1 -0
- package/dist/settings/ui-tab-definitions.d.ts +41 -0
- package/dist/settings/ui-tab-definitions.d.ts.map +1 -0
- package/dist/settings/ui-tab-definitions.js +148 -0
- package/dist/settings/ui-tab-definitions.js.map +1 -0
- package/dist/settings/write-service.d.ts +314 -0
- package/dist/settings/write-service.d.ts.map +1 -0
- package/dist/settings/write-service.js +677 -0
- package/dist/settings/write-service.js.map +1 -0
- package/dist/taxonomy/agent-tools.d.ts +76 -0
- package/dist/taxonomy/agent-tools.d.ts.map +1 -0
- package/dist/taxonomy/agent-tools.js +178 -0
- package/dist/taxonomy/agent-tools.js.map +1 -0
- package/dist/taxonomy/content-lookup.d.ts +45 -0
- package/dist/taxonomy/content-lookup.d.ts.map +1 -0
- package/dist/taxonomy/content-lookup.js +9 -0
- package/dist/taxonomy/content-lookup.js.map +1 -0
- package/dist/taxonomy/index.d.ts +38 -0
- package/dist/taxonomy/index.d.ts.map +1 -0
- package/dist/taxonomy/index.js +38 -0
- package/dist/taxonomy/index.js.map +1 -0
- package/dist/taxonomy/list.d.ts +39 -0
- package/dist/taxonomy/list.d.ts.map +1 -0
- package/dist/taxonomy/list.js +19 -0
- package/dist/taxonomy/list.js.map +1 -0
- package/dist/taxonomy/merge-term.d.ts +94 -0
- package/dist/taxonomy/merge-term.d.ts.map +1 -0
- package/dist/taxonomy/merge-term.js +65 -0
- package/dist/taxonomy/merge-term.js.map +1 -0
- package/dist/taxonomy/repo.memory.d.ts +160 -0
- package/dist/taxonomy/repo.memory.d.ts.map +1 -0
- package/dist/taxonomy/repo.memory.js +171 -0
- package/dist/taxonomy/repo.memory.js.map +1 -0
- package/dist/taxonomy/validation-chain.d.ts +114 -0
- package/dist/taxonomy/validation-chain.d.ts.map +1 -0
- package/dist/taxonomy/validation-chain.js +152 -0
- package/dist/taxonomy/validation-chain.js.map +1 -0
- package/dist/taxonomy/write-service.d.ts +387 -0
- package/dist/taxonomy/write-service.d.ts.map +1 -0
- package/dist/taxonomy/write-service.js +350 -0
- package/dist/taxonomy/write-service.js.map +1 -0
- package/dist/workspace/agent-tools.d.ts +67 -0
- package/dist/workspace/agent-tools.d.ts.map +1 -0
- package/dist/workspace/agent-tools.js +103 -0
- package/dist/workspace/agent-tools.js.map +1 -0
- package/dist/workspace/create.d.ts +116 -0
- package/dist/workspace/create.d.ts.map +1 -0
- package/dist/workspace/create.js +69 -0
- package/dist/workspace/create.js.map +1 -0
- package/dist/workspace/delete.d.ts +50 -0
- package/dist/workspace/delete.d.ts.map +1 -0
- package/dist/workspace/delete.js +24 -0
- package/dist/workspace/delete.js.map +1 -0
- package/dist/workspace/index.d.ts +27 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +27 -0
- package/dist/workspace/index.js.map +1 -0
- package/dist/workspace/repo.memory.d.ts +34 -0
- package/dist/workspace/repo.memory.d.ts.map +1 -0
- package/dist/workspace/repo.memory.js +50 -0
- package/dist/workspace/repo.memory.js.map +1 -0
- package/dist/workspace/tool-registrations.d.ts +38 -0
- package/dist/workspace/tool-registrations.d.ts.map +1 -0
- package/dist/workspace/tool-registrations.js +71 -0
- package/dist/workspace/tool-registrations.js.map +1 -0
- package/dist/workspace/update.d.ts +52 -0
- package/dist/workspace/update.d.ts.map +1 -0
- package/dist/workspace/update.js +41 -0
- package/dist/workspace/update.js.map +1 -0
- package/package.json +149 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { UUID } from "../core/ports.js";
|
|
2
|
+
import type { PolicyPermissionRepoPort, PrincipalPolicyRepoPort, PrincipalRepoPort, PrincipalRoleRepoPort, RolePolicyRepoPort } from "./ports.js";
|
|
3
|
+
import type { PolicyPermissionRecord } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* @file `authorize()` — the RBAC evaluator (REQ-04).
|
|
6
|
+
*
|
|
7
|
+
* Purpose:
|
|
8
|
+
* Ordinary core function, deliberately NOT a port (one evaluator —
|
|
9
|
+
* "no PolicyPort"). The command gateway calls this before every
|
|
10
|
+
* mutation (REQ-05); it is deterministic and side-effect free given the
|
|
11
|
+
* repo snapshot (state.spec §4).
|
|
12
|
+
*
|
|
13
|
+
* How it relates to the project:
|
|
14
|
+
* - `command.ts`'s `executeCommand` calls a bound closure of this shape
|
|
15
|
+
* (typed there as `AuthorizeFn`, kept generic so `core/commands` never
|
|
16
|
+
* imports this feature-level library — see that file's header).
|
|
17
|
+
* - Route handlers call it directly for mutations that do not flow through
|
|
18
|
+
* the command gateway (this pass: `members` disable — see the handoff).
|
|
19
|
+
*
|
|
20
|
+
* Architectural role:
|
|
21
|
+
* Implements the matcher precedence in behavior.spec §1.1 exactly:
|
|
22
|
+
* disabled-principal short-circuit > owner wildcard > exact matching row >
|
|
23
|
+
* fail-closed default. Fail-closed extensibility: a non-null
|
|
24
|
+
* `constraintJson` is never treated as unconstrained, and a `resourceType`
|
|
25
|
+
* mismatch/absence is never treated as a global grant.
|
|
26
|
+
*/
|
|
27
|
+
/** The context an authorization decision is evaluated against (REQ-04). */
|
|
28
|
+
export interface AuthorizeContext {
|
|
29
|
+
workspaceId: UUID;
|
|
30
|
+
entityType?: string;
|
|
31
|
+
entityId?: UUID;
|
|
32
|
+
}
|
|
33
|
+
/** `authorize()`'s result — always fail-closed on `allowed: false` (INV-03). */
|
|
34
|
+
export interface AuthorizeResult {
|
|
35
|
+
allowed: boolean;
|
|
36
|
+
/** Machine-readable reason: `principal_disabled | no_grant | resource_scope_mismatch | unconstrained_deny | owner_wildcard | matched`. */
|
|
37
|
+
reason: string;
|
|
38
|
+
}
|
|
39
|
+
/** Repos `authorize()`/`resolveEffectivePermissions()` read. Not a port bag with alternate adapters — see file header. */
|
|
40
|
+
export interface AuthorizeDeps {
|
|
41
|
+
principals: PrincipalRepoPort;
|
|
42
|
+
principalRoles: PrincipalRoleRepoPort;
|
|
43
|
+
rolePolicies: RolePolicyRepoPort;
|
|
44
|
+
principalPolicies: PrincipalPolicyRepoPort;
|
|
45
|
+
policyPermissions: PolicyPermissionRepoPort;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve a principal's effective permission rows: the union of (a) its
|
|
49
|
+
* roles' policies' permissions and (b) policies attached directly via
|
|
50
|
+
* `principal_policies` (behavior.spec §1.2). Scoped to `workspaceId` by
|
|
51
|
+
* construction (every repo call below is workspace-scoped).
|
|
52
|
+
*
|
|
53
|
+
* @complexity O(r*p + d) round trips, r = roles held, p = policies per role,
|
|
54
|
+
* d = direct policy attachments — all expected small (a handful of rows per
|
|
55
|
+
* principal). No caller-unbounded collection is walked.
|
|
56
|
+
* @overallScore 100
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveEffectivePermissions(required: {
|
|
59
|
+
deps: AuthorizeDeps;
|
|
60
|
+
principalId: UUID;
|
|
61
|
+
workspaceId: UUID;
|
|
62
|
+
}): Promise<PolicyPermissionRecord[]>;
|
|
63
|
+
/**
|
|
64
|
+
* The RBAC decision (REQ-04). Fail-closed: `allowed` defaults to `false` and
|
|
65
|
+
* only ever flips to `true` on an explicit disabled-short-circuit-cleared,
|
|
66
|
+
* matching row.
|
|
67
|
+
*
|
|
68
|
+
* Precedence (behavior.spec §1.1, highest to lowest):
|
|
69
|
+
* 1. Disabled principal -> `false`, `principal_disabled` (overrides all grants).
|
|
70
|
+
* 2. An unconstrained owner `"*"` row -> `true`, `owner_wildcard`.
|
|
71
|
+
* 3. An exact matching row (permission + workspace + resource-scope + no
|
|
72
|
+
* constraint) -> `true`, `matched`.
|
|
73
|
+
* 4. Fail-closed default -> `false`, with the most specific diagnostic reason
|
|
74
|
+
* available among same-permission candidates (`unconstrained_deny` over
|
|
75
|
+
* `resource_scope_mismatch` over `no_grant` — an inferred, undocumented-but-
|
|
76
|
+
* reasonable tie-break; the spec only pins each reason in isolation, see
|
|
77
|
+
* AC-09/AC-14/EC-04).
|
|
78
|
+
*
|
|
79
|
+
* @complexity O(resolveEffectivePermissions) + O(k) local filtering, k = the
|
|
80
|
+
* principal's effective row count (small, bounded by grants a workspace
|
|
81
|
+
* administrator creates by hand).
|
|
82
|
+
* @overallScore 100
|
|
83
|
+
*/
|
|
84
|
+
export declare function authorize(required: {
|
|
85
|
+
deps: AuthorizeDeps;
|
|
86
|
+
principalId: UUID;
|
|
87
|
+
permission: string;
|
|
88
|
+
context: AuthorizeContext;
|
|
89
|
+
}): Promise<AuthorizeResult>;
|
|
90
|
+
//# sourceMappingURL=authorize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/identity/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,IAAI,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,IAAI,CAAC;CACjB;AAED,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,0IAA0I;IAC1I,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,0HAA0H;AAC1H,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,cAAc,EAAE,qBAAqB,CAAC;IACtC,YAAY,EAAE,kBAAkB,CAAC;IACjC,iBAAiB,EAAE,uBAAuB,CAAC;IAC3C,iBAAiB,EAAE,wBAAwB,CAAC;CAC7C;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAAC,QAAQ,EAAE;IAC1D,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,IAAI,CAAC;IAClB,WAAW,EAAE,IAAI,CAAC;CACnB,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CA2BpC;AAeD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE;IACxC,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,IAAI,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,gBAAgB,CAAC;CAC3B,GAAG,OAAO,CAAC,eAAe,CAAC,CAsC3B"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a principal's effective permission rows: the union of (a) its
|
|
3
|
+
* roles' policies' permissions and (b) policies attached directly via
|
|
4
|
+
* `principal_policies` (behavior.spec §1.2). Scoped to `workspaceId` by
|
|
5
|
+
* construction (every repo call below is workspace-scoped).
|
|
6
|
+
*
|
|
7
|
+
* @complexity O(r*p + d) round trips, r = roles held, p = policies per role,
|
|
8
|
+
* d = direct policy attachments — all expected small (a handful of rows per
|
|
9
|
+
* principal). No caller-unbounded collection is walked.
|
|
10
|
+
* @overallScore 100
|
|
11
|
+
*/
|
|
12
|
+
export async function resolveEffectivePermissions(required) {
|
|
13
|
+
const { deps, principalId, workspaceId } = required;
|
|
14
|
+
const roleLinks = await deps.principalRoles.listByPrincipalId({ workspaceId, principalId });
|
|
15
|
+
const rolePermissionGroups = await Promise.all(roleLinks.map(async (roleLink) => {
|
|
16
|
+
const rolePolicyLinks = await deps.rolePolicies.listByRoleId({
|
|
17
|
+
workspaceId,
|
|
18
|
+
roleId: roleLink.roleId,
|
|
19
|
+
});
|
|
20
|
+
const policyPermissionGroups = await Promise.all(rolePolicyLinks.map((rolePolicyLink) => deps.policyPermissions.listByPolicyId({ workspaceId, policyId: rolePolicyLink.policyId })));
|
|
21
|
+
return policyPermissionGroups.flat();
|
|
22
|
+
}));
|
|
23
|
+
const directLinks = await deps.principalPolicies.listByPrincipalId({ workspaceId, principalId });
|
|
24
|
+
const directPermissionGroups = await Promise.all(directLinks.map((directLink) => deps.policyPermissions.listByPolicyId({ workspaceId, policyId: directLink.policyId })));
|
|
25
|
+
return [...rolePermissionGroups.flat(), ...directPermissionGroups.flat()];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* True iff `row` is an exact, unconstrained-or-scope-matching grant of
|
|
29
|
+
* `permission` in `context` (state.spec §4 `matchesRow`). Assumes `row` has
|
|
30
|
+
* already passed the owner-wildcard check upstream — this never special-cases
|
|
31
|
+
* `"*"`.
|
|
32
|
+
*/
|
|
33
|
+
function matchesRow(row, permission, context) {
|
|
34
|
+
if (row.permission !== permission)
|
|
35
|
+
return false;
|
|
36
|
+
if (row.constraintJson != null)
|
|
37
|
+
return false;
|
|
38
|
+
if (row.resourceType != null && row.resourceType !== context.entityType)
|
|
39
|
+
return false;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The RBAC decision (REQ-04). Fail-closed: `allowed` defaults to `false` and
|
|
44
|
+
* only ever flips to `true` on an explicit disabled-short-circuit-cleared,
|
|
45
|
+
* matching row.
|
|
46
|
+
*
|
|
47
|
+
* Precedence (behavior.spec §1.1, highest to lowest):
|
|
48
|
+
* 1. Disabled principal -> `false`, `principal_disabled` (overrides all grants).
|
|
49
|
+
* 2. An unconstrained owner `"*"` row -> `true`, `owner_wildcard`.
|
|
50
|
+
* 3. An exact matching row (permission + workspace + resource-scope + no
|
|
51
|
+
* constraint) -> `true`, `matched`.
|
|
52
|
+
* 4. Fail-closed default -> `false`, with the most specific diagnostic reason
|
|
53
|
+
* available among same-permission candidates (`unconstrained_deny` over
|
|
54
|
+
* `resource_scope_mismatch` over `no_grant` — an inferred, undocumented-but-
|
|
55
|
+
* reasonable tie-break; the spec only pins each reason in isolation, see
|
|
56
|
+
* AC-09/AC-14/EC-04).
|
|
57
|
+
*
|
|
58
|
+
* @complexity O(resolveEffectivePermissions) + O(k) local filtering, k = the
|
|
59
|
+
* principal's effective row count (small, bounded by grants a workspace
|
|
60
|
+
* administrator creates by hand).
|
|
61
|
+
* @overallScore 100
|
|
62
|
+
*/
|
|
63
|
+
export async function authorize(required) {
|
|
64
|
+
const { deps, principalId, permission, context } = required;
|
|
65
|
+
const principal = await deps.principals.findById({ workspaceId: context.workspaceId, id: principalId });
|
|
66
|
+
if (!principal || principal.status === "disabled") {
|
|
67
|
+
return { allowed: false, reason: "principal_disabled" };
|
|
68
|
+
}
|
|
69
|
+
const effectiveRows = await resolveEffectivePermissions({
|
|
70
|
+
deps,
|
|
71
|
+
principalId,
|
|
72
|
+
workspaceId: context.workspaceId,
|
|
73
|
+
});
|
|
74
|
+
const hasUnconstrainedWildcard = effectiveRows.some((row) => row.permission === "*" && row.resourceType == null && row.constraintJson == null);
|
|
75
|
+
if (hasUnconstrainedWildcard) {
|
|
76
|
+
return { allowed: true, reason: "owner_wildcard" };
|
|
77
|
+
}
|
|
78
|
+
const candidates = effectiveRows.filter((row) => row.permission === permission);
|
|
79
|
+
if (candidates.length === 0) {
|
|
80
|
+
return { allowed: false, reason: "no_grant" };
|
|
81
|
+
}
|
|
82
|
+
const matched = candidates.some((row) => matchesRow(row, permission, context));
|
|
83
|
+
if (matched) {
|
|
84
|
+
return { allowed: true, reason: "matched" };
|
|
85
|
+
}
|
|
86
|
+
if (candidates.some((row) => row.constraintJson != null)) {
|
|
87
|
+
return { allowed: false, reason: "unconstrained_deny" };
|
|
88
|
+
}
|
|
89
|
+
if (candidates.some((row) => row.resourceType != null)) {
|
|
90
|
+
return { allowed: false, reason: "resource_scope_mismatch" };
|
|
91
|
+
}
|
|
92
|
+
return { allowed: false, reason: "no_grant" };
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=authorize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/identity/authorize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import type { UUID } from "../core/ports.js";
|
|
2
|
+
import { type AuthorizeDeps } from "./authorize.js";
|
|
3
|
+
import type { AuthServiceDeps } from "./auth-service.js";
|
|
4
|
+
import type { IdentityRepos } from "./ports.js";
|
|
5
|
+
import { type PolicyRecord, type PrincipalPolicyRecord, type PrincipalRecord, type PrincipalRoleRecord, type RoleRecord, type UserRecord } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* @file Human grant-writing transitions (state.spec.md §3): `CREATE_USER`,
|
|
8
|
+
* `CREATE_ROLE`, `CREATE_POLICY`, `ASSIGN_ROLE`, `ATTACH_POLICY`.
|
|
9
|
+
*
|
|
10
|
+
* Purpose:
|
|
11
|
+
* The only usable identity principal before this file was the seeded owner —
|
|
12
|
+
* there was no API path to create a second user or grant/change permissions.
|
|
13
|
+
* These five functions are that path, following `auth-service.ts`'s exact
|
|
14
|
+
* shape (`{ deps: AuthServiceDeps, input: {...} }`, one exported async
|
|
15
|
+
* function per transition, plain `Error` subclasses for control flow).
|
|
16
|
+
*
|
|
17
|
+
* Out of scope (deferred, see the dispatch directive): `ISSUE_API_KEY`,
|
|
18
|
+
* `CREATE_PRINCIPAL` (api_key/agent principal creation), agent/api_key
|
|
19
|
+
* delegation, `WRITE_POLICY_PERMISSION`, `DISABLE_PRINCIPAL`.
|
|
20
|
+
*
|
|
21
|
+
* Architectural role:
|
|
22
|
+
* Ordinary core functions, not ports (mirrors `auth-service.ts`'s reasoning —
|
|
23
|
+
* grant-writing logic has one implementation). Each function calls
|
|
24
|
+
* `authorize()`/`resolveEffectivePermissions()` from `authorize.ts` itself
|
|
25
|
+
* (rather than pushing the gate into the route layer, the way
|
|
26
|
+
* `members/disable.ts`'s route does) so the caller-permission gate and the
|
|
27
|
+
* INV-07 clamp are exercised directly by unit tests, no HTTP harness needed.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Assemble the `AuthorizeDeps` bag `authorize()`/`resolveEffectivePermissions()` expect from the
|
|
31
|
+
* flat `IdentityRepos` bag. Exported so `admin-crud-service.ts`'s new transitions
|
|
32
|
+
* (`ENABLE_PRINCIPAL`/`UPDATE_USER`/`RESET_USER_PASSWORD`/`UPDATE_ROLE`/`UPDATE_POLICY`/
|
|
33
|
+
* `DELETE_ROLE`/`DELETE_POLICY`/`WRITE_POLICY_PERMISSION`/`DISABLE_PRINCIPAL`) reuse the identical
|
|
34
|
+
* gate/clamp logic rather than duplicating it — same file-split reasoning `auth-service.ts` and
|
|
35
|
+
* `grant-service.ts` already use (one shared helper set, two transition files).
|
|
36
|
+
*/
|
|
37
|
+
export declare function authorizeDepsFrom(repos: IdentityRepos): AuthorizeDeps;
|
|
38
|
+
/**
|
|
39
|
+
* Fail-closed caller-permission gate shared by every transition in this file.
|
|
40
|
+
* Throws `IdentityForbiddenError` (403 `FORBIDDEN`) unless the caller holds
|
|
41
|
+
* at least one of `permissions` (an OR gate — `CREATE_USER` accepts either
|
|
42
|
+
* `user.manage` or `member.manage`, state.spec §3).
|
|
43
|
+
*
|
|
44
|
+
* @complexity O(p) `authorize()` calls, p = `permissions.length` (1 or 2 in
|
|
45
|
+
* every caller this pass) — each itself O(resolveEffectivePermissions), see
|
|
46
|
+
* that function's doc.
|
|
47
|
+
* @overallScore 100
|
|
48
|
+
*/
|
|
49
|
+
export declare function assertCallerHasAnyPermission(required: {
|
|
50
|
+
deps: AuthServiceDeps;
|
|
51
|
+
workspaceId: UUID;
|
|
52
|
+
callerPrincipalId: UUID;
|
|
53
|
+
permissions: readonly string[];
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* The INV-07 grant-authority clamp (feature.spec.md, state.spec §3
|
|
57
|
+
* `ASSIGN_ROLE`/`ATTACH_POLICY` rows): every permission in `conferredPermissions`
|
|
58
|
+
* must be a matching effective row the caller holds unconstrained
|
|
59
|
+
* (`resourceType`/`constraintJson` both null; owner's `*` qualifies for all).
|
|
60
|
+
* A permission held only conditionally (resource-scoped or constraint-bound)
|
|
61
|
+
* cannot be delegated. Throws `GrantExceedsIssuerError` (403
|
|
62
|
+
* `GRANT_EXCEEDS_ISSUER`) naming every offending permission, and writes no
|
|
63
|
+
* grant row (caller does the write only after this resolves).
|
|
64
|
+
*
|
|
65
|
+
* @complexity O(resolveEffectivePermissions) + O(k) local filtering, k =
|
|
66
|
+
* `conferredPermissions.length` (bounded by one role's/policy's permission
|
|
67
|
+
* rows — a handful, per `identity/INFO.md`'s scale assumptions).
|
|
68
|
+
* @overallScore 100
|
|
69
|
+
*/
|
|
70
|
+
export declare function assertGrantClamp(required: {
|
|
71
|
+
deps: AuthServiceDeps;
|
|
72
|
+
workspaceId: UUID;
|
|
73
|
+
callerPrincipalId: UUID;
|
|
74
|
+
conferredPermissions: readonly string[];
|
|
75
|
+
}): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* `CREATE_USER` (state.spec §3, REQ-01/MF-1). Atomically mints a NEW
|
|
78
|
+
* `kind='user'` principal and its `users` row — the `principalId` is always
|
|
79
|
+
* generated here, never caller-supplied, so this transition can never attach
|
|
80
|
+
* a credential to a pre-existing principal (the MF-1 privilege-escalation
|
|
81
|
+
* class: an earlier draft let an admin bind a password to the seeded owner
|
|
82
|
+
* principal and log in as owner). Gated by `user.manage` OR `member.manage`
|
|
83
|
+
* (admin onboarding, AC-22).
|
|
84
|
+
*
|
|
85
|
+
* "Atomically" here means structurally, not via a DB transaction — the
|
|
86
|
+
* in-memory adapters have no cross-repo transaction (same disclosed gap as
|
|
87
|
+
* `seed.ts`/`executeCommand`'s compensating-rollback path). The invariant
|
|
88
|
+
* that actually matters (no credential ever attaches to an existing
|
|
89
|
+
* principal) holds regardless, because `principalId` is generated inline and
|
|
90
|
+
* the password is hashed before either row is written, so a hashing failure
|
|
91
|
+
* leaves no orphan principal. A future SQLite adapter wraps both writes in
|
|
92
|
+
* one real transaction (port/adapter rule-of-two) without changing this contract.
|
|
93
|
+
*
|
|
94
|
+
* @complexity O(1) — one permission check, one username lookup, one hash,
|
|
95
|
+
* two saves.
|
|
96
|
+
* @overallScore 100
|
|
97
|
+
*/
|
|
98
|
+
export declare function createUser(required: {
|
|
99
|
+
deps: AuthServiceDeps;
|
|
100
|
+
input: {
|
|
101
|
+
workspaceId: UUID;
|
|
102
|
+
callerPrincipalId: UUID;
|
|
103
|
+
username: string;
|
|
104
|
+
email?: string | undefined;
|
|
105
|
+
password: string;
|
|
106
|
+
};
|
|
107
|
+
}): Promise<{
|
|
108
|
+
principal: PrincipalRecord;
|
|
109
|
+
user: UserRecord;
|
|
110
|
+
}>;
|
|
111
|
+
/**
|
|
112
|
+
* `CREATE_ROLE` (state.spec §3). Gated by `role.manage`. Always mints
|
|
113
|
+
* `isBuiltin=false` — built-ins are SEED-only and immutable (INV-06).
|
|
114
|
+
*
|
|
115
|
+
* Deviation from the state.spec §3 table (disclosed): that row lists
|
|
116
|
+
* `name`, `description?` jointly for `CREATE_ROLE`/`CREATE_POLICY`, but
|
|
117
|
+
* `RoleRecord` (types.ts, frozen before this task) has no `description`
|
|
118
|
+
* field — only `PolicyRecord` does. `createRole` therefore takes `name`
|
|
119
|
+
* only; `createPolicy` below takes both.
|
|
120
|
+
*
|
|
121
|
+
* @complexity O(1) — one permission check, one save.
|
|
122
|
+
* @overallScore 100
|
|
123
|
+
*/
|
|
124
|
+
export declare function createRole(required: {
|
|
125
|
+
deps: AuthServiceDeps;
|
|
126
|
+
input: {
|
|
127
|
+
workspaceId: UUID;
|
|
128
|
+
callerPrincipalId: UUID;
|
|
129
|
+
name: string;
|
|
130
|
+
};
|
|
131
|
+
}): Promise<{
|
|
132
|
+
role: RoleRecord;
|
|
133
|
+
}>;
|
|
134
|
+
/**
|
|
135
|
+
* `CREATE_POLICY` (state.spec §3). Gated by `role.manage`. Always mints
|
|
136
|
+
* `isBuiltin=false` and `isFrozen=false` — only the (out-of-scope this pass)
|
|
137
|
+
* `ISSUE_API_KEY` transition ever mints `isFrozen=true` policies.
|
|
138
|
+
*
|
|
139
|
+
* @complexity O(1) — one permission check, one save.
|
|
140
|
+
* @overallScore 100
|
|
141
|
+
*/
|
|
142
|
+
export declare function createPolicy(required: {
|
|
143
|
+
deps: AuthServiceDeps;
|
|
144
|
+
input: {
|
|
145
|
+
workspaceId: UUID;
|
|
146
|
+
callerPrincipalId: UUID;
|
|
147
|
+
name: string;
|
|
148
|
+
description?: string | undefined;
|
|
149
|
+
};
|
|
150
|
+
}): Promise<{
|
|
151
|
+
policy: PolicyRecord;
|
|
152
|
+
}>;
|
|
153
|
+
/**
|
|
154
|
+
* `ASSIGN_ROLE` (state.spec §3, REQ-02, AC-24/AC-25). Gated by `role.manage`;
|
|
155
|
+
* target must be a `kind='user'` principal (AC-25b); the INV-07 clamp must
|
|
156
|
+
* pass over every permission carried by the role's policies (AC-24) — so
|
|
157
|
+
* assigning the built-in `owner` role requires the caller to already hold
|
|
158
|
+
* the wildcard `*` (owner-only). No row is written on any rejection.
|
|
159
|
+
*
|
|
160
|
+
* @complexity O(resolveEffectivePermissions) + O(role's rolePolicy count)
|
|
161
|
+
* round trips to gather conferred permissions — both bounded by the small,
|
|
162
|
+
* hand-authored grant graph this system assumes (see `identity/INFO.md`).
|
|
163
|
+
* @overallScore 100
|
|
164
|
+
*/
|
|
165
|
+
export declare function assignRole(required: {
|
|
166
|
+
deps: AuthServiceDeps;
|
|
167
|
+
input: {
|
|
168
|
+
workspaceId: UUID;
|
|
169
|
+
callerPrincipalId: UUID;
|
|
170
|
+
principalId: UUID;
|
|
171
|
+
roleId: UUID;
|
|
172
|
+
};
|
|
173
|
+
}): Promise<{
|
|
174
|
+
assignment: PrincipalRoleRecord;
|
|
175
|
+
}>;
|
|
176
|
+
/**
|
|
177
|
+
* `ATTACH_POLICY` (state.spec §3, REQ-02, AC-24/AC-25). Gated by
|
|
178
|
+
* `role.manage`; target must be a `kind='user'` principal (AC-25b); the
|
|
179
|
+
* INV-07 clamp must pass over every permission the policy carries (AC-24) —
|
|
180
|
+
* attaching the built-in `owner` policy requires the caller to already hold
|
|
181
|
+
* `*` (owner-only). No row is written on any rejection.
|
|
182
|
+
*
|
|
183
|
+
* @complexity O(resolveEffectivePermissions) + O(policy's permission row
|
|
184
|
+
* count) — both bounded, see `assignRole`'s doc.
|
|
185
|
+
* @overallScore 100
|
|
186
|
+
*/
|
|
187
|
+
export declare function attachPolicy(required: {
|
|
188
|
+
deps: AuthServiceDeps;
|
|
189
|
+
input: {
|
|
190
|
+
workspaceId: UUID;
|
|
191
|
+
callerPrincipalId: UUID;
|
|
192
|
+
principalId: UUID;
|
|
193
|
+
policyId: UUID;
|
|
194
|
+
};
|
|
195
|
+
}): Promise<{
|
|
196
|
+
attachment: PrincipalPolicyRecord;
|
|
197
|
+
}>;
|
|
198
|
+
//# sourceMappingURL=grant-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant-service.d.ts","sourceRoot":"","sources":["../../src/identity/grant-service.ts"],"names":[],"mappings":"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"}
|