@jini-ai/user-management 0.2.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/CHANGELOG.md +77 -0
- package/LICENSE +201 -0
- package/README.md +104 -0
- package/dist/admin/adapters/http.d.ts +29 -0
- package/dist/admin/adapters/http.js +69 -0
- package/dist/admin/adapters/memory.d.ts +61 -0
- package/dist/admin/adapters/memory.js +217 -0
- package/dist/admin/auth.module.d.ts +30 -0
- package/dist/admin/auth.module.js +12 -0
- package/dist/admin/conformance/index.d.ts +56 -0
- package/dist/admin/conformance/index.js +156 -0
- package/dist/admin/controllers/auth.controller.d.ts +23 -0
- package/dist/admin/controllers/auth.controller.js +33 -0
- package/dist/admin/controllers/controller-store.d.ts +18 -0
- package/dist/admin/controllers/controller-store.js +23 -0
- package/dist/admin/controllers/members.controller.d.ts +33 -0
- package/dist/admin/controllers/members.controller.js +119 -0
- package/dist/admin/controllers/roles.controller.d.ts +47 -0
- package/dist/admin/controllers/roles.controller.js +282 -0
- package/dist/admin/controllers/users.controller.d.ts +53 -0
- package/dist/admin/controllers/users.controller.js +220 -0
- package/dist/admin/index.d.ts +21 -0
- package/dist/admin/index.js +15 -0
- package/dist/admin/members.module.d.ts +34 -0
- package/dist/admin/members.module.js +13 -0
- package/dist/admin/messages.en.d.ts +37 -0
- package/dist/admin/messages.en.js +21 -0
- package/dist/admin/models.d.ts +133 -0
- package/dist/admin/models.js +2 -0
- package/dist/admin/people.rules.d.ts +29 -0
- package/dist/admin/people.rules.js +51 -0
- package/dist/admin/ports.d.ts +187 -0
- package/dist/admin/ports.js +17 -0
- package/dist/admin/react/components/DestructiveDialog.d.ts +5 -0
- package/dist/admin/react/components/DestructiveDialog.js +6 -0
- package/dist/admin/react/components/MemberRow.d.ts +5 -0
- package/dist/admin/react/components/MemberRow.js +8 -0
- package/dist/admin/react/components/MembersConfirmation.d.ts +2 -0
- package/dist/admin/react/components/MembersConfirmation.js +8 -0
- package/dist/admin/react/components/PermissionPanel.d.ts +5 -0
- package/dist/admin/react/components/PermissionPanel.js +9 -0
- package/dist/admin/react/components/PolicyRow.d.ts +5 -0
- package/dist/admin/react/components/PolicyRow.js +11 -0
- package/dist/admin/react/components/RoleRow.d.ts +5 -0
- package/dist/admin/react/components/RoleRow.js +10 -0
- package/dist/admin/react/components/UserRow.d.ts +5 -0
- package/dist/admin/react/components/UserRow.js +8 -0
- package/dist/admin/react/components/UsersConfirmation.d.ts +3 -0
- package/dist/admin/react/components/UsersConfirmation.js +9 -0
- package/dist/admin/react/hooks/AuthBinding.hooks.d.ts +39 -0
- package/dist/admin/react/hooks/AuthBinding.hooks.js +21 -0
- package/dist/admin/react/hooks/LoginPage.hooks.d.ts +54 -0
- package/dist/admin/react/hooks/LoginPage.hooks.js +23 -0
- package/dist/admin/react/hooks/MembersBinding.hooks.d.ts +35 -0
- package/dist/admin/react/hooks/MembersBinding.hooks.js +21 -0
- package/dist/admin/react/hooks/MembersPage.hooks.d.ts +99 -0
- package/dist/admin/react/hooks/MembersPage.hooks.js +38 -0
- package/dist/admin/react/hooks/PeopleController.hooks.d.ts +18 -0
- package/dist/admin/react/hooks/PeopleController.hooks.js +20 -0
- package/dist/admin/react/hooks/PermissionPanel.hooks.d.ts +30 -0
- package/dist/admin/react/hooks/PermissionPanel.hooks.js +15 -0
- package/dist/admin/react/hooks/PoliciesTab.hooks.d.ts +47 -0
- package/dist/admin/react/hooks/PoliciesTab.hooks.js +26 -0
- package/dist/admin/react/hooks/RolesBinding.hooks.d.ts +39 -0
- package/dist/admin/react/hooks/RolesBinding.hooks.js +23 -0
- package/dist/admin/react/hooks/RolesController.hooks.d.ts +43 -0
- package/dist/admin/react/hooks/RolesController.hooks.js +25 -0
- package/dist/admin/react/hooks/RolesPage.hooks.d.ts +105 -0
- package/dist/admin/react/hooks/RolesPage.hooks.js +33 -0
- package/dist/admin/react/hooks/RolesTab.hooks.d.ts +35 -0
- package/dist/admin/react/hooks/RolesTab.hooks.js +19 -0
- package/dist/admin/react/hooks/UsersBinding.hooks.d.ts +36 -0
- package/dist/admin/react/hooks/UsersBinding.hooks.js +21 -0
- package/dist/admin/react/hooks/UsersPage.hooks.d.ts +106 -0
- package/dist/admin/react/hooks/UsersPage.hooks.js +22 -0
- package/dist/admin/react/hooks/UsersTab.hooks.d.ts +101 -0
- package/dist/admin/react/hooks/UsersTab.hooks.js +53 -0
- package/dist/admin/react/index.d.ts +203 -0
- package/dist/admin/react/index.js +32 -0
- package/dist/admin/react/pages/LoginPage.d.ts +3 -0
- package/dist/admin/react/pages/LoginPage.js +13 -0
- package/dist/admin/react/pages/MembersPage.d.ts +3 -0
- package/dist/admin/react/pages/MembersPage.js +19 -0
- package/dist/admin/react/pages/RolesPage.d.ts +3 -0
- package/dist/admin/react/pages/RolesPage.js +19 -0
- package/dist/admin/react/pages/UsersPage.d.ts +3 -0
- package/dist/admin/react/pages/UsersPage.js +19 -0
- package/dist/admin/react/tabs/AuthTab.d.ts +4 -0
- package/dist/admin/react/tabs/AuthTab.js +8 -0
- package/dist/admin/react/tabs/MembersTab.d.ts +4 -0
- package/dist/admin/react/tabs/MembersTab.js +9 -0
- package/dist/admin/react/tabs/PoliciesTab.d.ts +4 -0
- package/dist/admin/react/tabs/PoliciesTab.js +9 -0
- package/dist/admin/react/tabs/RolesTab.d.ts +4 -0
- package/dist/admin/react/tabs/RolesTab.js +9 -0
- package/dist/admin/react/tabs/UsersTab.d.ts +4 -0
- package/dist/admin/react/tabs/UsersTab.js +9 -0
- package/dist/admin/roles.module.d.ts +48 -0
- package/dist/admin/roles.module.js +15 -0
- package/dist/admin/rules.d.ts +32 -0
- package/dist/admin/rules.js +32 -0
- package/dist/admin/users.module.d.ts +39 -0
- package/dist/admin/users.module.js +14 -0
- package/dist/core/builtin-permissions.d.ts +10 -0
- package/dist/core/builtin-permissions.js +402 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +9 -0
- package/dist/core/permissions.d.ts +40 -0
- package/dist/core/permissions.js +52 -0
- package/dist/core/ports.d.ts +237 -0
- package/dist/core/ports.js +2 -0
- package/dist/core/runtime-ports.d.ts +8 -0
- package/dist/core/runtime-ports.js +2 -0
- package/dist/core/types.d.ts +224 -0
- package/dist/core/types.js +93 -0
- package/dist/react/auth/Login.d.ts +9 -0
- package/dist/react/auth/Login.js +8 -0
- package/dist/react/auth/hooks/use-login.hooks.d.ts +22 -0
- package/dist/react/auth/hooks/use-login.hooks.js +24 -0
- package/dist/react/errors.d.ts +10 -0
- package/dist/react/errors.js +13 -0
- package/dist/react/index.d.ts +18 -0
- package/dist/react/index.js +9 -0
- package/dist/react/members/Members.d.ts +6 -0
- package/dist/react/members/Members.js +38 -0
- package/dist/react/members/hooks/use-members.hooks.d.ts +32 -0
- package/dist/react/members/hooks/use-members.hooks.js +120 -0
- package/dist/react/members/rules.d.ts +26 -0
- package/dist/react/members/rules.js +35 -0
- package/dist/react/models.d.ts +50 -0
- package/dist/react/models.js +2 -0
- package/dist/react/ports.d.ts +157 -0
- package/dist/react/ports.js +2 -0
- package/dist/react/roles/Roles.d.ts +100 -0
- package/dist/react/roles/Roles.hooks.d.ts +17 -0
- package/dist/react/roles/Roles.hooks.js +40 -0
- package/dist/react/roles/Roles.js +150 -0
- package/dist/react/roles/hooks/use-roles.hooks.d.ts +80 -0
- package/dist/react/roles/hooks/use-roles.hooks.js +303 -0
- package/dist/react/roles/rules.d.ts +35 -0
- package/dist/react/roles/rules.js +31 -0
- package/dist/react/roles/text.d.ts +27 -0
- package/dist/react/roles/text.js +13 -0
- package/dist/react/testing.d.ts +51 -0
- package/dist/react/testing.js +275 -0
- package/dist/react/users/Users.d.ts +72 -0
- package/dist/react/users/Users.js +129 -0
- package/dist/react/users/hooks/use-reset-password-fields.hooks.d.ts +16 -0
- package/dist/react/users/hooks/use-reset-password-fields.hooks.js +21 -0
- package/dist/react/users/hooks/use-users.hooks.d.ts +77 -0
- package/dist/react/users/hooks/use-users.hooks.js +286 -0
- package/dist/react/users/rules.d.ts +33 -0
- package/dist/react/users/rules.js +61 -0
- package/dist/server/admin-crud-service.d.ts +295 -0
- package/dist/server/admin-crud-service.js +561 -0
- package/dist/server/agent-tool-input.d.ts +58 -0
- package/dist/server/agent-tool-input.js +158 -0
- package/dist/server/agent-tool-registrations.d.ts +51 -0
- package/dist/server/agent-tool-registrations.js +417 -0
- package/dist/server/agent-tools.d.ts +88 -0
- package/dist/server/agent-tools.js +229 -0
- package/dist/server/auth-service.d.ts +107 -0
- package/dist/server/auth-service.js +170 -0
- package/dist/server/authorize.d.ts +92 -0
- package/dist/server/authorize.js +96 -0
- package/dist/server/grant-service.d.ts +219 -0
- package/dist/server/grant-service.js +419 -0
- package/dist/server/hasher.d.ts +64 -0
- package/dist/server/hasher.js +53 -0
- package/dist/server/identity-transaction.d.ts +9 -0
- package/dist/server/identity-transaction.js +8 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.js +20 -0
- package/dist/server/messages.d.ts +7 -0
- package/dist/server/messages.js +5 -0
- package/dist/server/password-policy.d.ts +59 -0
- package/dist/server/password-policy.js +66 -0
- package/dist/server/permission-migrations.d.ts +84 -0
- package/dist/server/permission-migrations.js +77 -0
- package/dist/server/repo.memory-transactions.d.ts +16 -0
- package/dist/server/repo.memory-transactions.js +79 -0
- package/dist/server/repo.memory.d.ts +186 -0
- package/dist/server/repo.memory.js +230 -0
- package/dist/server/seed.d.ts +56 -0
- package/dist/server/seed.js +435 -0
- package/dist/server/session-tokens.d.ts +10 -0
- package/dist/server/session-tokens.js +12 -0
- package/dist/server/username.d.ts +14 -0
- package/dist/server/username.js +14 -0
- package/package.json +144 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
export const BUILTIN_PERMISSIONS = [
|
|
2
|
+
...[
|
|
3
|
+
{ id: "content.read", owner: "core", description: "Read content entries." },
|
|
4
|
+
{ id: "content.write", owner: "core", description: "Create and edit content entries." },
|
|
5
|
+
{ id: "content.publish", owner: "core", description: "Publish/unpublish content entries." },
|
|
6
|
+
{ id: "content.delete", owner: "core", description: "Delete content entries." },
|
|
7
|
+
{
|
|
8
|
+
id: "media.write",
|
|
9
|
+
owner: "core",
|
|
10
|
+
description: "DEPRECATED — superseded by the flat media.* permission " +
|
|
11
|
+
"set registered below. Retained (not deleted) — see the media.* registration block's own " +
|
|
12
|
+
"comment and docs/decisions/permission-catalog-migration.md for the same migration contract " +
|
|
13
|
+
"this repo's other permission renames (navigation.manage, integration.manage) have used. " +
|
|
14
|
+
"Do not register a new dependency on this string.",
|
|
15
|
+
},
|
|
16
|
+
{ id: "theme.set", owner: "core", description: "Change the active theme/presentation settings." },
|
|
17
|
+
{
|
|
18
|
+
id: "theme.edit",
|
|
19
|
+
owner: "core",
|
|
20
|
+
description: "Create and edit the source files inside a theme package (templates, tokens, styles, manifest). " +
|
|
21
|
+
"Distinct from theme.set, which only chooses among already-validated themes: editing a theme's " +
|
|
22
|
+
"files can take that theme to status:'invalid', degrading its pages to the built-in fallback " +
|
|
23
|
+
"body until corrected. Granted to admin (and owner via '*'), not to editor.",
|
|
24
|
+
},
|
|
25
|
+
{ id: "plugin.read", owner: "core", description: "List installed plugins and their state." },
|
|
26
|
+
{ id: "plugin.enable", owner: "core", description: "Enable a plugin." },
|
|
27
|
+
{ id: "plugin.disable", owner: "core", description: "Disable a plugin." },
|
|
28
|
+
{ id: "changeset.read", owner: "core", description: "Read the change-set audit trail." },
|
|
29
|
+
{ id: "changeset.revert", owner: "core", description: "Revert an applied change set." },
|
|
30
|
+
{ id: "member.manage", owner: "core", description: "Manage front-end members and subscriptions." },
|
|
31
|
+
{ id: "user.manage", owner: "core", description: "Create/disable operator users and principals." },
|
|
32
|
+
{ id: "role.manage", owner: "core", description: "Manage roles, policies, and grants." },
|
|
33
|
+
{
|
|
34
|
+
id: "settings.write",
|
|
35
|
+
owner: "core",
|
|
36
|
+
description: "DEPRECATED — superseded by the fine-grained settings.* catalog below. Retained until the data migration that maps existing grants to settings.workspace.write + settings.definitions.manage completes and is verified; do not reuse this string for anything else afterward. See docs/decisions/permission-catalog-migration.md for the migration's completion criteria.",
|
|
37
|
+
},
|
|
38
|
+
{ id: "apikey.manage", owner: "core", description: "Issue and revoke API keys." },
|
|
39
|
+
// settings.* catalog (core-only subset).
|
|
40
|
+
{ id: "settings.global.write", owner: "settings", description: "Set/clear a setting's global-layer value." },
|
|
41
|
+
{
|
|
42
|
+
id: "settings.workspace.write",
|
|
43
|
+
owner: "settings",
|
|
44
|
+
description: "Set/clear a setting's workspace-layer value.",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "settings.user.self.write",
|
|
48
|
+
owner: "settings",
|
|
49
|
+
description: "Set/clear a setting's own user-layer value.",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "settings.user.write",
|
|
53
|
+
owner: "settings",
|
|
54
|
+
description: "Set/clear another principal's user-layer value.",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "settings.user.read",
|
|
58
|
+
owner: "settings",
|
|
59
|
+
description: "Read another principal's user-layer value. The read-side counterpart of settings.user.write — " +
|
|
60
|
+
"gates the ?principalId= cross-principal path on the settings read routes (get-raw/get-effective), " +
|
|
61
|
+
"which previously had no read permission of its own and borrowed settings.user.write.",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "settings.definitions.manage",
|
|
65
|
+
owner: "settings",
|
|
66
|
+
description: "Register/rename/retype/deprecate/tombstone setting definitions; also gates the purge service and authorizes the background coerce repair job.",
|
|
67
|
+
},
|
|
68
|
+
{ id: "settings.reset.global", owner: "settings", description: "Reset a namespace's global-layer values to defaults." },
|
|
69
|
+
{
|
|
70
|
+
id: "settings.reset.workspace",
|
|
71
|
+
owner: "settings",
|
|
72
|
+
description: "Reset a namespace's workspace-layer values to defaults.",
|
|
73
|
+
},
|
|
74
|
+
{ id: "settings.reset.user", owner: "settings", description: "Reset a namespace's user-layer values to defaults." },
|
|
75
|
+
{ id: "settings.read", owner: "settings", description: "Read effective setting values (getEffective)." },
|
|
76
|
+
{
|
|
77
|
+
id: "settings.read.raw",
|
|
78
|
+
owner: "settings",
|
|
79
|
+
description: "Read per-layer raw setting values. Reserved for a future API surface.",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "settings.read.revisions",
|
|
83
|
+
owner: "settings",
|
|
84
|
+
description: "Read the setting_revisions ledger. Reserved for a future API surface.",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: "settings.read.definitions",
|
|
88
|
+
owner: "settings",
|
|
89
|
+
description: "List setting definitions grouped by namespace.",
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
{
|
|
93
|
+
id: "navigation.manage",
|
|
94
|
+
owner: "navigation",
|
|
95
|
+
description: "DEPRECATED — superseded by the admin.menus.* catalog below. " +
|
|
96
|
+
"Retained (not deleted) until the Point of No Return: a persistent identity store shipping " +
|
|
97
|
+
"plus a real deprecation window with observed zero reliance on this string, gated on " +
|
|
98
|
+
"authorize()-decision logging existing first to measure that. See " +
|
|
99
|
+
"docs/decisions/permission-catalog-migration.md. Do not register a new dependency on this string.",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: "admin.menus.read",
|
|
103
|
+
// Action grants separate force-purge from ordinary edits. Keep these spellings aligned with
|
|
104
|
+
// the navigation capability contract; a catalog entry and its enforcing gate must agree.
|
|
105
|
+
owner: "navigation",
|
|
106
|
+
description: "Read menus and their location bindings.",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: "admin.menus.create",
|
|
110
|
+
owner: "navigation",
|
|
111
|
+
description: "Create a new menu.",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: "admin.menus.update",
|
|
115
|
+
owner: "navigation",
|
|
116
|
+
description: "Replace a menu's item tree.",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: "admin.menus.delete",
|
|
120
|
+
owner: "navigation",
|
|
121
|
+
description: "Trash a menu, and attempt an ordinary (non-forced) hard purge.",
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: "admin.menus.delete.force",
|
|
125
|
+
owner: "navigation",
|
|
126
|
+
description: "Force-purge a menu past the dangling-location-binding guard — split from " +
|
|
127
|
+
"admin.menus.delete so force-purge is not reachable with only the ordinary delete grant.",
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
id: "admin.menus.assign",
|
|
131
|
+
owner: "navigation",
|
|
132
|
+
description: "Assign (or reassign) a menu to a theme location.",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: "admin.menus.manage",
|
|
136
|
+
owner: "navigation",
|
|
137
|
+
description: "Umbrella grant covering every admin.menus.* action (mirrors owner-tier convenience grants).",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: "integration.manage",
|
|
141
|
+
owner: "integrations",
|
|
142
|
+
description: "DEPRECATED — superseded by admin.integrations.manage below, " +
|
|
143
|
+
"mirroring the navigation.manage -> admin.menus.* precedent. Retained (not " +
|
|
144
|
+
"deleted) — see admin.integrations.manage's own comment and " +
|
|
145
|
+
"docs/decisions/permission-catalog-migration.md for the same migration contract " +
|
|
146
|
+
"this repo's other permission renames have used.",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: "admin.integrations.manage",
|
|
150
|
+
// One umbrella grant preserves the existing domain authority; a rename alone must not invent
|
|
151
|
+
// a finer read/write split that would narrow operators' stored grants.
|
|
152
|
+
owner: "integrations",
|
|
153
|
+
description: "Create, update, pause, and delete webhook subscriptions; read delivery logs.",
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: "admin.seo.manage",
|
|
157
|
+
// One umbrella covers reads and writes because this domain has no self-versus-other boundary
|
|
158
|
+
// requiring an independently privileged read capability.
|
|
159
|
+
owner: "seo",
|
|
160
|
+
description: "Read and write per-entry SEO overrides, site-level SEO settings, and the sitemap cache.",
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
id: "admin.assistant.manage",
|
|
164
|
+
// Reading and changing the visitor-facing assistant's master switch share one authority.
|
|
165
|
+
// Access to an operator assistant is separate: authentication and each tool's own gate own it.
|
|
166
|
+
owner: "assistant",
|
|
167
|
+
description: "Read and change the visitor-facing AI assistant's settings, including its master on/off switch.",
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: "analytics.read",
|
|
171
|
+
// This explicit read grant closes a formerly ungated recent-hits surface; knowing an operator
|
|
172
|
+
// is authenticated is insufficient authority to disclose analytics records.
|
|
173
|
+
owner: "analytics",
|
|
174
|
+
description: "Read recent ingested analytics hits.",
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: "admin.redirects.manage",
|
|
178
|
+
// Mixed naming conventions are compatibility data. Normalizing this spelling to match older
|
|
179
|
+
// flat domain grants would invalidate existing policy rows without a grant migration.
|
|
180
|
+
owner: "redirects",
|
|
181
|
+
description: "Create, update, tombstone, import, and read hit stats for redirect rules.",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: "admin.forms.manage",
|
|
185
|
+
// Form definitions and submission content carry different trust: submissions contain visitor
|
|
186
|
+
// PII, so managing a form must not implicitly grant access to read or delete its submissions.
|
|
187
|
+
owner: "forms",
|
|
188
|
+
description: "Create, update, and disable/enable form definitions.",
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: "admin.forms.submissions.read",
|
|
192
|
+
owner: "forms",
|
|
193
|
+
description: "List and view form submissions.",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
id: "admin.forms.submissions.delete",
|
|
197
|
+
owner: "forms",
|
|
198
|
+
description: "Permanently delete a form submission.",
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
id: "admin.newsletter.read",
|
|
202
|
+
// Publish the domain's full vocabulary, including reserved settings/umbrella grants, so later
|
|
203
|
+
// endpoints can use existing capability names without another catalog change.
|
|
204
|
+
owner: "newsletter",
|
|
205
|
+
description: "List and read newsletter campaigns, lists, and the send log.",
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: "admin.newsletter.campaign.compose",
|
|
209
|
+
owner: "newsletter",
|
|
210
|
+
description: "Create/edit/cancel a newsletter campaign in draft or scheduled state.",
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: "admin.newsletter.campaign.schedule",
|
|
214
|
+
owner: "newsletter",
|
|
215
|
+
description: "Schedule a draft newsletter campaign to send at a future time.",
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
id: "admin.newsletter.campaign.send",
|
|
219
|
+
owner: "newsletter",
|
|
220
|
+
description: "Send, pause, or resume a newsletter campaign — real outbound mail.",
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
id: "admin.newsletter.campaign.send_test",
|
|
224
|
+
owner: "newsletter",
|
|
225
|
+
description: "Send a test copy of a newsletter campaign to a small address list.",
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
id: "admin.newsletter.list.manage",
|
|
229
|
+
owner: "newsletter",
|
|
230
|
+
description: "Create and archive newsletter subscriber lists.",
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
id: "admin.newsletter.subscriber.read",
|
|
234
|
+
owner: "newsletter",
|
|
235
|
+
description: "Read newsletter subscriptions and the per-campaign send log.",
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
id: "admin.newsletter.subscriber.manage",
|
|
239
|
+
owner: "newsletter",
|
|
240
|
+
description: "Add, import, remove newsletter subscriptions, and resend confirmation emails.",
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
id: "admin.newsletter.settings.manage",
|
|
244
|
+
owner: "newsletter",
|
|
245
|
+
description: "Reserved for a future API surface (no route uses this yet).",
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
id: "admin.newsletter.manage",
|
|
249
|
+
owner: "newsletter",
|
|
250
|
+
description: "Umbrella newsletter permission. Reserved for a future API surface (no route uses this yet).",
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: "storage.read",
|
|
254
|
+
owner: "database",
|
|
255
|
+
description: "DEPRECATED — superseded by database.read below, " +
|
|
256
|
+
"mirroring this catalog's integration.manage -> admin.integrations.manage precedent. Retained " +
|
|
257
|
+
"(not deleted) — see database.read's own comment and " +
|
|
258
|
+
"docs/decisions/permission-catalog-migration.md for the same migration contract " +
|
|
259
|
+
"this repo's other permission renames have used.",
|
|
260
|
+
},
|
|
261
|
+
{ id: "database.read", owner: "database", description: "Read the Database Timeline, schema drift status, and restore points." },
|
|
262
|
+
// "Database" distinguishes schema/history operations from media or blob storage. Keep old storage
|
|
263
|
+
// spellings registered and add replacement grants through migration rather than locking out users.
|
|
264
|
+
{ id: "system.read", owner: "server", description: "Read boot/readiness module lifecycle status." },
|
|
265
|
+
{
|
|
266
|
+
id: "storage.migrate",
|
|
267
|
+
owner: "database",
|
|
268
|
+
description: "DEPRECATED — superseded by database.migrate below, " +
|
|
269
|
+
"mirroring this catalog's integration.manage -> admin.integrations.manage precedent. Retained " +
|
|
270
|
+
"(not deleted) — see database.migrate's own comment and " +
|
|
271
|
+
"docs/decisions/permission-catalog-migration.md for the same migration contract " +
|
|
272
|
+
"this repo's other permission renames have used.",
|
|
273
|
+
},
|
|
274
|
+
{ id: "database.migrate", owner: "database", description: "Plan, confirm, and execute a forward schema migration." },
|
|
275
|
+
{ id: "backup.read", owner: "recovery", description: "Read restore points and the workspace's restore capability." },
|
|
276
|
+
{ id: "backup.create", owner: "recovery", description: "Mint a restore point independent of any migration." },
|
|
277
|
+
{ id: "backup.restore", owner: "recovery", description: "Confirm and execute a restore to a prior restore point." },
|
|
278
|
+
{ id: "comments.read", owner: "comments", description: "Read comments and the moderation queue." },
|
|
279
|
+
{ id: "comments.moderate", owner: "comments", description: "Approve, mark spam, or restore a comment." },
|
|
280
|
+
{ id: "comments.reply", owner: "comments", description: "Post an operator reply to a comment thread." },
|
|
281
|
+
{ id: "comments.delete", owner: "comments", description: "Trash a comment (soft delete, recoverable)." },
|
|
282
|
+
{ id: "comments.delete.force", owner: "comments", description: "Purge a comment permanently (hard delete, not recoverable)." },
|
|
283
|
+
{ id: "comments.submit", owner: "comments", description: "Reserved for a future member-only submission gate; the anonymous path is ingress-governed, not authorize()-gated." },
|
|
284
|
+
{ id: "comments.configure", owner: "comments", description: "Change Comments settings (moderation defaults, spam threshold, depth cap)." },
|
|
285
|
+
{
|
|
286
|
+
id: "admin.collections.read",
|
|
287
|
+
// Owner-wildcard access can hide missing catalog entries: runtime authorization can succeed
|
|
288
|
+
// even when catalog validation cannot recognize the same permission. Register every gate.
|
|
289
|
+
owner: "content-types",
|
|
290
|
+
description: "List Collections content types and their entries.",
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
id: "admin.collections.manage",
|
|
294
|
+
owner: "content-types",
|
|
295
|
+
description: "Create/edit content types and entries; deprecate/reactivate/tombstone a content type; publish/unpublish an entry.",
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
id: "admin.taxonomy.manage",
|
|
299
|
+
owner: "taxonomy",
|
|
300
|
+
description: "Read and write taxonomies, terms, and term assignments (one permission for this whole domain, no .read/.write split).",
|
|
301
|
+
},
|
|
302
|
+
{ id: "media.read", owner: "media", description: "List and read media assets." },
|
|
303
|
+
{ id: "media.upload", owner: "media", description: "Upload a new media asset." },
|
|
304
|
+
{ id: "media.update", owner: "media", description: "Edit a media asset's metadata (title/alt/caption/credit)." },
|
|
305
|
+
{ id: "media.delete", owner: "media", description: "Trash (soft-delete) a media asset." },
|
|
306
|
+
{
|
|
307
|
+
id: "media.delete.force",
|
|
308
|
+
owner: "media",
|
|
309
|
+
description: "Permanently purge a trashed media asset, past the still-referenced guard.",
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
id: "media.download_original",
|
|
313
|
+
owner: "media",
|
|
314
|
+
description: "Mint a short-TTL signed URL to download a media asset's original bytes. Reserved for a future API surface — no route uses this yet.",
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
id: "media.upload_svg",
|
|
318
|
+
owner: "media",
|
|
319
|
+
description: "Upload an SVG asset (sanitized at ingest, served origin-isolated).",
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
id: "media.manage",
|
|
323
|
+
owner: "media",
|
|
324
|
+
description: "Umbrella grant covering every media.* action (mirrors owner-tier convenience grants like admin.menus.manage).",
|
|
325
|
+
},
|
|
326
|
+
{ id: "widgets.read", owner: "widgets", description: "Read widget instances, widget_area regions, and their revision history." },
|
|
327
|
+
// Placement affects the live site and requires more trust than editing an off-site configuration;
|
|
328
|
+
// likewise, irreversible force-purge is a separate capability from recoverable deletion.
|
|
329
|
+
{ id: "widgets.create", owner: "widgets", description: "Create a new widget instance." },
|
|
330
|
+
{ id: "widgets.update", owner: "widgets", description: "Update an existing widget instance's config." },
|
|
331
|
+
{
|
|
332
|
+
id: "widgets.place",
|
|
333
|
+
owner: "widgets",
|
|
334
|
+
description: "Bind/reorder/disable a widget in a region's widget_area, or insert/remove/reorder a widgetEmbed node.",
|
|
335
|
+
},
|
|
336
|
+
{ id: "widgets.delete", owner: "widgets", description: "Trash a widget instance." },
|
|
337
|
+
{
|
|
338
|
+
id: "widgets.delete.force",
|
|
339
|
+
owner: "widgets",
|
|
340
|
+
description: "Force-purge a widget instance past the still-referenced guard, flagging any resulting dangling references.",
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
id: "workspace.manage",
|
|
344
|
+
// Renaming or deleting a workspace has a larger blast radius than editing a setting value;
|
|
345
|
+
// a distinct grant lets hosts authorize and audit those operations independently.
|
|
346
|
+
owner: "workspace",
|
|
347
|
+
description: "List/view/rename/delete the workspace.",
|
|
348
|
+
}
|
|
349
|
+
];
|
|
350
|
+
export const BUILTIN_PERMISSION_MIGRATIONS = [
|
|
351
|
+
// A seed that already has its owner normally skips rebuilding built-in grants. Changing a fresh
|
|
352
|
+
// seed's permission list therefore cannot repair existing installations: migrations add missing
|
|
353
|
+
// replacement grants without removing old ones, so permission renames/splits do not cause lockout.
|
|
354
|
+
{
|
|
355
|
+
from: "settings.user.write",
|
|
356
|
+
// This is an implication, not deprecation: a principal trusted to overwrite another user's
|
|
357
|
+
// settings is already trusted to read them. The write permission remains live after fan-out.
|
|
358
|
+
to: ["settings.user.read"],
|
|
359
|
+
reason: "Internal audit F2 remediation (2026-07-29): the cross-principal settings read path was gated on " +
|
|
360
|
+
"settings.user.write for lack of a read-side permission. settings.user.read now gates it; every " +
|
|
361
|
+
"existing write-holder gains the explicit read grant so no operator loses a shipped capability. " +
|
|
362
|
+
"Unlike this file's other pairs, `from` is not deprecated — it stays live for writes.",
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
from: "navigation.manage",
|
|
366
|
+
to: [
|
|
367
|
+
"admin.menus.read",
|
|
368
|
+
"admin.menus.create",
|
|
369
|
+
"admin.menus.update",
|
|
370
|
+
"admin.menus.delete",
|
|
371
|
+
"admin.menus.delete.force",
|
|
372
|
+
"admin.menus.assign",
|
|
373
|
+
],
|
|
374
|
+
reason: "navigation.manage split into per-action admin.menus.* strings; " +
|
|
375
|
+
"every policy holding the old flat permission must not be silently narrowed by the split.",
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
from: "integration.manage",
|
|
379
|
+
to: ["admin.integrations.manage"],
|
|
380
|
+
reason: "integration.manage renamed to admin.integrations.manage; every " +
|
|
381
|
+
"policy holding the old flat permission must not be silently locked out by the rename.",
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
from: "storage.read",
|
|
385
|
+
to: ["database.read"],
|
|
386
|
+
reason: "Naming-correction: storage.read renamed to database.read; every " +
|
|
387
|
+
"policy holding the old flat permission must not be silently locked out by the rename.",
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
from: "storage.migrate",
|
|
391
|
+
to: ["database.migrate"],
|
|
392
|
+
reason: "Naming-correction: storage.migrate renamed to database.migrate; every " +
|
|
393
|
+
"policy holding the old flat permission must not be silently locked out by the rename.",
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
from: "media.write",
|
|
397
|
+
to: ["media.read", "media.upload", "media.update", "media.delete", "media.delete.force", "media.download_original", "media.upload_svg"],
|
|
398
|
+
reason: "media.write replaced by the flat media.* permission set; " +
|
|
399
|
+
"every policy holding the old flat permission must not be silently narrowed by the split.",
|
|
400
|
+
}
|
|
401
|
+
];
|
|
402
|
+
//# sourceMappingURL=builtin-permissions.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Universal identity records, errors, ports, and permission vocabulary. */
|
|
2
|
+
// Consumers use this public entry for universal contracts rather than deep imports. Keeping the
|
|
3
|
+
// concrete hasher behind the server entry prevents a native binary from becoming a prerequisite
|
|
4
|
+
// for importing identity types or permission vocabulary; PasswordHasherPort is the shared contract.
|
|
5
|
+
export * from "./types.js";
|
|
6
|
+
export * from "./ports.js";
|
|
7
|
+
export * from "./runtime-ports.js";
|
|
8
|
+
export * from "./permissions.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** One entry in the registered permission catalog. */
|
|
2
|
+
export interface PermissionDescriptor {
|
|
3
|
+
/** Dotted permission string, e.g. `"content.write"`. */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Registering module, e.g. `"core"` or a feature name. */
|
|
6
|
+
owner: string;
|
|
7
|
+
description: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Code-side registry backing catalog validation and
|
|
11
|
+
* enumeration. `"*"` (the owner wildcard) is deliberately not a
|
|
12
|
+
* catalog entry — it is a distinct, built-in-only grant shape checked by
|
|
13
|
+
* `authorize`/seed, never a registrable permission string.
|
|
14
|
+
*
|
|
15
|
+
* @complexity O(1) amortized per lookup (Map-backed); O(n) to list all.
|
|
16
|
+
* @overallScore 100
|
|
17
|
+
* See docs/decisions/DR-001-identity-and-session-boundary.md.
|
|
18
|
+
*/
|
|
19
|
+
declare class PermissionCatalog {
|
|
20
|
+
private readonly byId;
|
|
21
|
+
constructor(initial: readonly PermissionDescriptor[]);
|
|
22
|
+
/** Idempotent: re-registering the same `id` (e.g. on a warm reload) is a no-op overwrite. */
|
|
23
|
+
register(descriptor: PermissionDescriptor): void;
|
|
24
|
+
has({ id }: {
|
|
25
|
+
id: string;
|
|
26
|
+
}): boolean;
|
|
27
|
+
list(_required: Record<string, never>): PermissionDescriptor[];
|
|
28
|
+
}
|
|
29
|
+
/** Module-singleton catalog — core's base vocabulary, extended by feature registration. */
|
|
30
|
+
export declare const permissionCatalog: PermissionCatalog;
|
|
31
|
+
/** Register an additional permission at feature startup. See docs/decisions/DR-001-identity-and-session-boundary.md. */
|
|
32
|
+
export declare function registerPermission(descriptor: PermissionDescriptor): void;
|
|
33
|
+
/** Enumerate the full registered catalog ( core capability; CLI wiring is N/A, see file header). See docs/decisions/DR-001-identity-and-session-boundary.md. */
|
|
34
|
+
export declare function listPermissions(_required: Record<string, never>): PermissionDescriptor[];
|
|
35
|
+
/** Whether `id` is a recognized catalog permission. `"*"` is intentionally excluded (see class doc). */
|
|
36
|
+
export declare function isKnownPermission({ id }: {
|
|
37
|
+
id: string;
|
|
38
|
+
}): boolean;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** A catalog initialized from explicit data; safe with sideEffects: false. */
|
|
2
|
+
// Authorization vocabulary is code-owned rather than a database enum; hosts extend it at startup.
|
|
3
|
+
// Keep built-ins reachable through this explicit initialization. Relying on an unreferenced module's
|
|
4
|
+
// registration side effects would let a production bundler remove the catalog while Node still
|
|
5
|
+
// worked, leaving catalog validation empty only in the bundled deployment.
|
|
6
|
+
import { IdentityValidationError } from './types.js';
|
|
7
|
+
import { BUILTIN_PERMISSIONS } from './builtin-permissions.js';
|
|
8
|
+
/**
|
|
9
|
+
* Code-side registry backing catalog validation and
|
|
10
|
+
* enumeration. `"*"` (the owner wildcard) is deliberately not a
|
|
11
|
+
* catalog entry — it is a distinct, built-in-only grant shape checked by
|
|
12
|
+
* `authorize`/seed, never a registrable permission string.
|
|
13
|
+
*
|
|
14
|
+
* @complexity O(1) amortized per lookup (Map-backed); O(n) to list all.
|
|
15
|
+
* @overallScore 100
|
|
16
|
+
* See docs/decisions/DR-001-identity-and-session-boundary.md.
|
|
17
|
+
*/
|
|
18
|
+
class PermissionCatalog {
|
|
19
|
+
byId = new Map();
|
|
20
|
+
constructor(initial) {
|
|
21
|
+
for (const descriptor of initial)
|
|
22
|
+
this.register(descriptor);
|
|
23
|
+
}
|
|
24
|
+
/** Idempotent: re-registering the same `id` (e.g. on a warm reload) is a no-op overwrite. */
|
|
25
|
+
register(descriptor) {
|
|
26
|
+
if (descriptor.id === "*") {
|
|
27
|
+
throw new IdentityValidationError({ message: "the owner wildcard cannot be registered as a permission" });
|
|
28
|
+
}
|
|
29
|
+
this.byId.set(descriptor.id, descriptor);
|
|
30
|
+
}
|
|
31
|
+
has({ id }) {
|
|
32
|
+
return this.byId.has(id);
|
|
33
|
+
}
|
|
34
|
+
list(_required) {
|
|
35
|
+
return [...this.byId.values()];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Module-singleton catalog — core's base vocabulary, extended by feature registration. */
|
|
39
|
+
export const permissionCatalog = new PermissionCatalog(BUILTIN_PERMISSIONS);
|
|
40
|
+
/** Register an additional permission at feature startup. See docs/decisions/DR-001-identity-and-session-boundary.md. */
|
|
41
|
+
export function registerPermission(descriptor) {
|
|
42
|
+
permissionCatalog.register(descriptor);
|
|
43
|
+
}
|
|
44
|
+
/** Enumerate the full registered catalog ( core capability; CLI wiring is N/A, see file header). See docs/decisions/DR-001-identity-and-session-boundary.md. */
|
|
45
|
+
export function listPermissions(_required) {
|
|
46
|
+
return permissionCatalog.list({});
|
|
47
|
+
}
|
|
48
|
+
/** Whether `id` is a recognized catalog permission. `"*"` is intentionally excluded (see class doc). */
|
|
49
|
+
export function isKnownPermission({ id }) {
|
|
50
|
+
return permissionCatalog.has({ id });
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=permissions.js.map
|