@bevel-software/platform-core-backend 0.9.1 → 0.11.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/THIRD-PARTY-NOTICES.md +2 -2
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +16 -1
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +25 -0
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +45 -1
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core-config.d.ts +19 -1
- package/dist/core-config.d.ts.map +1 -1
- package/dist/core-config.js +44 -4
- package/dist/core-config.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +54 -28
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +129 -14
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +435 -66
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access-declarations.d.ts.map +1 -1
- package/dist/modules/access/access-declarations.js +5 -3
- package/dist/modules/access/access-declarations.js.map +1 -1
- package/dist/modules/access/access-mutation.service.d.ts +39 -6
- package/dist/modules/access/access-mutation.service.d.ts.map +1 -1
- package/dist/modules/access/access-mutation.service.js +78 -18
- package/dist/modules/access/access-mutation.service.js.map +1 -1
- package/dist/modules/access/access-splice.d.ts +31 -4
- package/dist/modules/access/access-splice.d.ts.map +1 -1
- package/dist/modules/access/access-splice.js +40 -16
- package/dist/modules/access/access-splice.js.map +1 -1
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +204 -82
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/access/admin-locked-commit.d.ts +134 -0
- package/dist/modules/access/admin-locked-commit.d.ts.map +1 -0
- package/dist/modules/access/admin-locked-commit.js +277 -0
- package/dist/modules/access/admin-locked-commit.js.map +1 -0
- package/dist/modules/access/admin-route-helpers.d.ts +32 -0
- package/dist/modules/access/admin-route-helpers.d.ts.map +1 -0
- package/dist/modules/access/admin-route-helpers.js +44 -0
- package/dist/modules/access/admin-route-helpers.js.map +1 -0
- package/dist/modules/access/capability-registry.d.ts +41 -0
- package/dist/modules/access/capability-registry.d.ts.map +1 -0
- package/dist/modules/access/capability-registry.js +46 -0
- package/dist/modules/access/capability-registry.js.map +1 -0
- package/dist/modules/access/directory-sync-bot.d.ts +13 -0
- package/dist/modules/access/directory-sync-bot.d.ts.map +1 -0
- package/dist/modules/access/directory-sync-bot.js +64 -0
- package/dist/modules/access/directory-sync-bot.js.map +1 -0
- package/dist/modules/access/group-files.d.ts +83 -0
- package/dist/modules/access/group-files.d.ts.map +1 -0
- package/dist/modules/access/group-files.js +167 -0
- package/dist/modules/access/group-files.js.map +1 -0
- package/dist/modules/access/groups-admin.routes.d.ts +19 -0
- package/dist/modules/access/groups-admin.routes.d.ts.map +1 -0
- package/dist/modules/access/groups-admin.routes.js +98 -0
- package/dist/modules/access/groups-admin.routes.js.map +1 -0
- package/dist/modules/access/groups-admin.service.d.ts +166 -0
- package/dist/modules/access/groups-admin.service.d.ts.map +1 -0
- package/dist/modules/access/groups-admin.service.js +442 -0
- package/dist/modules/access/groups-admin.service.js.map +1 -0
- package/dist/modules/access/groups-edit.d.ts +58 -0
- package/dist/modules/access/groups-edit.d.ts.map +1 -0
- package/dist/modules/access/groups-edit.js +162 -0
- package/dist/modules/access/groups-edit.js.map +1 -0
- package/dist/modules/access/reference-scan.d.ts +141 -0
- package/dist/modules/access/reference-scan.d.ts.map +1 -0
- package/dist/modules/access/reference-scan.js +440 -0
- package/dist/modules/access/reference-scan.js.map +1 -0
- package/dist/modules/access/roles-admin.service.d.ts +88 -119
- package/dist/modules/access/roles-admin.service.d.ts.map +1 -1
- package/dist/modules/access/roles-admin.service.js +230 -384
- package/dist/modules/access/roles-admin.service.js.map +1 -1
- package/dist/modules/access/roles-edit.d.ts +51 -25
- package/dist/modules/access/roles-edit.d.ts.map +1 -1
- package/dist/modules/access/roles-edit.js +133 -59
- package/dist/modules/access/roles-edit.js.map +1 -1
- package/dist/modules/access/synced-groups-committer.d.ts +28 -0
- package/dist/modules/access/synced-groups-committer.d.ts.map +1 -0
- package/dist/modules/access/synced-groups-committer.js +139 -0
- package/dist/modules/access/synced-groups-committer.js.map +1 -0
- package/dist/modules/access/synced-groups-writer.d.ts +78 -0
- package/dist/modules/access/synced-groups-writer.d.ts.map +1 -0
- package/dist/modules/access/synced-groups-writer.js +219 -0
- package/dist/modules/access/synced-groups-writer.js.map +1 -0
- package/dist/modules/database/core-schema.d.ts +17 -0
- package/dist/modules/database/core-schema.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +9 -0
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.d.ts +13 -2
- package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.js +61 -2
- package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
- package/dist/modules/mcp/mcp.routes.d.ts +9 -3
- package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.routes.js +126 -2
- package/dist/modules/mcp/mcp.routes.js.map +1 -1
- package/dist/modules/mcp/mcp.service.d.ts +14 -0
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.service.js +6 -1
- package/dist/modules/mcp/mcp.service.js.map +1 -1
- package/dist/modules/update-check/update-check.routes.d.ts +13 -0
- package/dist/modules/update-check/update-check.routes.d.ts.map +1 -0
- package/dist/modules/update-check/update-check.routes.js +21 -0
- package/dist/modules/update-check/update-check.routes.js.map +1 -0
- package/dist/modules/update-check/update-check.service.d.ts +57 -0
- package/dist/modules/update-check/update-check.service.d.ts.map +1 -0
- package/dist/modules/update-check/update-check.service.js +109 -0
- package/dist/modules/update-check/update-check.service.js.map +1 -0
- package/dist/modules/workflow/file-lock.service.d.ts +11 -1
- package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
- package/dist/modules/workflow/file-lock.service.js +15 -1
- package/dist/modules/workflow/file-lock.service.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +34 -11
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +173 -37
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/locking-filesystem.d.ts +4 -0
- package/dist/modules/workflow/locking-filesystem.d.ts.map +1 -1
- package/dist/modules/workflow/locking-filesystem.js +181 -28
- package/dist/modules/workflow/locking-filesystem.js.map +1 -1
- package/dist/modules/workflow/pending-commits.service.d.ts +10 -0
- package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
- package/dist/modules/workflow/pending-commits.service.js +19 -1
- package/dist/modules/workflow/pending-commits.service.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +17 -2
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +113 -19
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/version.d.ts +14 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +25 -0
- package/dist/version.js.map +1 -1
- package/kb-template/AGENTS.md +4 -1
- package/migrations/0004_file_lock_mode.sql +2 -0
- package/migrations/meta/0004_snapshot.json +1564 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +4 -4
- package/src/__tests__/core-config.domain.test.ts +92 -0
- package/src/core/create-core-server.ts +21 -0
- package/src/core/create-core-services.ts +82 -0
- package/src/core-config.ts +48 -4
- package/src/index.ts +10 -0
- package/src/modules/access/__tests__/access-control.service.test.ts +9 -3
- package/src/modules/access/__tests__/access-groups.test.ts +427 -0
- package/src/modules/access/__tests__/access-mutation.service.test.ts +171 -5
- package/src/modules/access/__tests__/access-splice.test.ts +65 -0
- package/src/modules/access/__tests__/access.routes.group-grant.test.ts +337 -0
- package/src/modules/access/__tests__/access.routes.revoke.test.ts +48 -0
- package/src/modules/access/__tests__/admin-locked-commit.test.ts +221 -0
- package/src/modules/access/__tests__/admin-route-helpers.test.ts +61 -0
- package/src/modules/access/__tests__/directory-sync-bot.test.ts +106 -0
- package/src/modules/access/__tests__/grant-sources.test.ts +67 -0
- package/src/modules/access/__tests__/groups-admin.service.test.ts +440 -0
- package/src/modules/access/__tests__/reference-scan.test.ts +288 -0
- package/src/modules/access/__tests__/roles-admin.service.test.ts +161 -83
- package/src/modules/access/__tests__/roles-capabilities.test.ts +325 -0
- package/src/modules/access/__tests__/roles-edit.test.ts +104 -28
- package/src/modules/access/__tests__/roles.routes.test.ts +63 -40
- package/src/modules/access/__tests__/synced-groups-committer.test.ts +238 -0
- package/src/modules/access/__tests__/synced-groups-writer.test.ts +249 -0
- package/src/modules/access/access-control.interface.ts +66 -32
- package/src/modules/access/access-control.service.ts +536 -73
- package/src/modules/access/access-declarations.ts +5 -2
- package/src/modules/access/access-mutation.service.ts +88 -14
- package/src/modules/access/access-splice.ts +55 -17
- package/src/modules/access/access.routes.ts +227 -93
- package/src/modules/access/admin-locked-commit.ts +331 -0
- package/src/modules/access/admin-route-helpers.ts +55 -0
- package/src/modules/access/capability-registry.ts +74 -0
- package/src/modules/access/directory-sync-bot.ts +76 -0
- package/src/modules/access/group-files.ts +212 -0
- package/src/modules/access/groups-admin.routes.ts +113 -0
- package/src/modules/access/groups-admin.service.ts +551 -0
- package/src/modules/access/groups-edit.ts +187 -0
- package/src/modules/access/reference-scan.ts +513 -0
- package/src/modules/access/roles-admin.service.ts +290 -418
- package/src/modules/access/roles-edit.ts +134 -61
- package/src/modules/access/synced-groups-committer.ts +177 -0
- package/src/modules/access/synced-groups-writer.ts +303 -0
- package/src/modules/database/core-schema.ts +9 -0
- package/src/modules/mcp/__tests__/mcp-auth.middleware.test.ts +116 -0
- package/src/modules/mcp/__tests__/mcp.e2e.test.ts +3 -1
- package/src/modules/mcp/__tests__/mcp.routes.delete.test.ts +6 -1
- package/src/modules/mcp/__tests__/mcp.routes.local-token.test.ts +301 -0
- package/src/modules/mcp/mcp-auth.middleware.ts +61 -1
- package/src/modules/mcp/mcp.routes.ts +137 -2
- package/src/modules/mcp/mcp.service.ts +6 -1
- package/src/modules/update-check/__tests__/update-check.routes.test.ts +69 -0
- package/src/modules/update-check/__tests__/update-check.service.test.ts +170 -0
- package/src/modules/update-check/update-check.routes.ts +28 -0
- package/src/modules/update-check/update-check.service.ts +130 -0
- package/src/modules/workflow/__tests__/locking-filesystem.test.ts +336 -0
- package/src/modules/workflow/__tests__/preserve-roles-yaml.test.ts +1 -1
- package/src/modules/workflow/__tests__/workflow.service.commitFileWhileLocked.test.ts +32 -0
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +13 -2
- package/src/modules/workflow/__tests__/workflow.service.releaseLock.test.ts +139 -1
- package/src/modules/workflow/file-lock.service.ts +15 -0
- package/src/modules/workflow/git/__tests__/git.service.accessGating.test.ts +0 -1
- package/src/modules/workflow/git/__tests__/git.service.commitChanges.test.ts +132 -0
- package/src/modules/workflow/git/__tests__/git.service.deleteBranch.test.ts +0 -1
- package/src/modules/workflow/git/__tests__/pull-request.service.test.ts +0 -1
- package/src/modules/workflow/git/git.service.ts +182 -35
- package/src/modules/workflow/locking-filesystem.ts +188 -26
- package/src/modules/workflow/pending-commits.service.ts +27 -1
- package/src/modules/workflow/review-workflow/__tests__/approval-states.test.ts +0 -1
- package/src/modules/workflow/review-workflow/__tests__/cancel-pr.test.ts +0 -1
- package/src/modules/workflow/workflow.service.ts +140 -20
- package/src/version.ts +28 -0
|
@@ -1,41 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Admin Roles & Members service —
|
|
2
|
+
* Admin Roles & Members service — MEMBERSHIP editing on the default-branch
|
|
3
|
+
* `roles.yaml`.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Roles are APP-DEFINED capabilities (see `capability-registry.ts`): the
|
|
6
|
+
* product decides which roles exist; users can never create, rename, or
|
|
7
|
+
* delete one — those editors are gone. What remains admin-editable is
|
|
8
|
+
* MEMBERSHIP: adding/removing individual emails and assigning/unassigning
|
|
9
|
+
* groups (`group:<canonical>` members), on capability roles and on LEGACY
|
|
10
|
+
* people-set roles alike (pre-split roles keep resolving and stay editable;
|
|
11
|
+
* `convertRoleToGroup` is their migration path).
|
|
12
|
+
*
|
|
13
|
+
* It is the primary in-app writer of `roles.yaml` (the groups admin also
|
|
14
|
+
* rewrites its `group:` refs on group rename/delete, through the same shared
|
|
15
|
+
* validated pipeline), and it is built around one non-negotiable safety
|
|
16
|
+
* property:
|
|
8
17
|
*
|
|
9
18
|
* roles.yaml has NO admin-rescue (canWrite('roles.yaml') is a pure isAdmin
|
|
10
19
|
* check) and loadModel HARD-THROWS on a parse failure (which isAdmin swallows
|
|
11
20
|
* into false for EVERYONE). So a single malformed write = a permanent,
|
|
12
21
|
* app-wide, in-app-unrecoverable admin lockout. Every mutation therefore runs
|
|
13
22
|
* the candidate text through the resolver's OWN parser (validateRolesYaml)
|
|
14
|
-
* before a byte hits disk; on any error it writes nothing.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* Single-file ops (create/delete role, add/remove member) — `runEdit`:
|
|
19
|
-
* pre-check roles.yaml isn't locked → RolesAdminError 409
|
|
20
|
-
* read CURRENT roles.yaml → parse → edit-in-memory → re-emit candidate
|
|
21
|
-
* validateRolesYaml(candidate) → RolesAdminError 422, write nothing
|
|
22
|
-
* LockingFilesystem.writeFile(roles.yaml) ← acquire → write → release;
|
|
23
|
-
* release IS the commit + push (default per-file summary), so the commit
|
|
24
|
-
* lands a beat after the write — same pipeline the human editor + agent
|
|
25
|
-
* use. The HTTP roster reads the (synchronously written) working tree.
|
|
23
|
+
* before a byte hits disk; on any error it writes nothing. That parser also
|
|
24
|
+
* carries the Admin invariant — at least one DIRECT email member, group
|
|
25
|
+
* references alone are never enough — so no write path can land a
|
|
26
|
+
* directory-dependent Admin.
|
|
26
27
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* LockingFilesystem.writeFiles(roles.yaml + refs) ← acquires every path's
|
|
33
|
-
* lock, commits the curated set as ONE change (via the workflow service's
|
|
34
|
-
* commitChanges), then releases without a per-file commit.
|
|
35
|
-
*
|
|
36
|
-
* All reads and writes target the DEFAULT branch — the file admin status itself
|
|
37
|
-
* derives from. Editing any other branch's copy would show a roster that
|
|
38
|
-
* doesn't match who is actually an admin.
|
|
28
|
+
* Lock/commit plumbing is the SHARED `AdminLockedCommits` helper (one
|
|
29
|
+
* implementation for this service and the groups admin — the twins diverged
|
|
30
|
+
* once into a real bug). Reference scanning is the SHARED
|
|
31
|
+
* `KbReferenceScanner` (cached, so roster mutations don't rerun the full-KB
|
|
32
|
+
* sweep the GET pays for).
|
|
39
33
|
*/
|
|
40
34
|
import type { WorkflowEventBus } from '../workflow/event-bus.js';
|
|
41
35
|
import type { AuthUser, IWorkspaceService, IWorkflowService } from '@bevel-software/platform-shared';
|
|
@@ -49,12 +43,27 @@ export declare class RolesAdminError extends WorkflowDomainError {
|
|
|
49
43
|
export interface RoleRosterEntry {
|
|
50
44
|
canonical: string;
|
|
51
45
|
displayName: string;
|
|
46
|
+
/** Individual member EMAILS (group assignments are split into `groups`). */
|
|
52
47
|
members: string[];
|
|
48
|
+
/** Canonical names of groups this role is assigned to (`group:` members). */
|
|
49
|
+
groups: string[];
|
|
53
50
|
isAdmin: boolean;
|
|
54
51
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
52
|
+
* Registry metadata when this is a CAPABILITY role (Admin today); null for
|
|
53
|
+
* a legacy pre-split people-set role, which the UI flags with a
|
|
54
|
+
* convert-to-group action.
|
|
55
|
+
*/
|
|
56
|
+
capability: {
|
|
57
|
+
description: string;
|
|
58
|
+
groupAssignable: boolean;
|
|
59
|
+
} | null;
|
|
60
|
+
/**
|
|
61
|
+
* Every access rule referencing this ROLE — folder `access.md` AND node
|
|
62
|
+
* frontmatter. `role/<name>` hits always count; a BARE-token hit counts
|
|
63
|
+
* only when no group shadows the name (bare tokens resolve group-first, so
|
|
64
|
+
* a shadowed bare grant is the GROUP's reference, listed on the groups
|
|
65
|
+
* roster instead). Sound: this is the SAME scan the group rename/delete
|
|
66
|
+
* rewrites use.
|
|
58
67
|
*/
|
|
59
68
|
referencedBy: {
|
|
60
69
|
path: string;
|
|
@@ -94,6 +103,10 @@ export declare class RolesAdminService {
|
|
|
94
103
|
* recovery exists to escape.
|
|
95
104
|
*/
|
|
96
105
|
private readonly recoveryAdmins;
|
|
106
|
+
/** Shared lock/commit plumbing — see module doc. */
|
|
107
|
+
private readonly locked;
|
|
108
|
+
/** Shared cached reference scanner — see module doc. */
|
|
109
|
+
private readonly references;
|
|
97
110
|
constructor(workspaceService: IWorkspaceService, workflowService: IWorkflowService, accessControl: IAccessControl, kbDirName: string,
|
|
98
111
|
/**
|
|
99
112
|
* The branch whose roles.yaml is authoritative for admin status, read
|
|
@@ -131,29 +144,13 @@ export declare class RolesAdminService {
|
|
|
131
144
|
private emitWrites;
|
|
132
145
|
/** Ensure the authoritative clone exists, then return its workspace id. */
|
|
133
146
|
private ensureWorkspace;
|
|
134
|
-
private repoDir;
|
|
135
|
-
/**
|
|
136
|
-
* A lock-aware filesystem scoped to `actor` — writes auto-commit + push as the
|
|
137
|
-
* actor on release, through the same pipeline as the human editor and agent.
|
|
138
|
-
* Built per-op because the lock context captures the acting user.
|
|
139
|
-
*/
|
|
140
|
-
private lockingFsForActor;
|
|
141
147
|
/**
|
|
142
148
|
* Fail fast with a friendly 409 if roles.yaml is already locked by someone
|
|
143
|
-
* else. The actual lock is taken by the
|
|
144
|
-
*
|
|
145
|
-
*
|
|
149
|
+
* else. The actual lock is taken by the write that follows; this only
|
|
150
|
+
* preserves the explicit "being edited by X" contract (the raw contention
|
|
151
|
+
* error is status-less and would surface as 500).
|
|
146
152
|
*/
|
|
147
153
|
private assertRolesUnlocked;
|
|
148
|
-
/**
|
|
149
|
-
* Run a lock-aware filesystem write, mapping its status-less contention error
|
|
150
|
-
* ("Skipped editing … — locked by …") to the friendly 409. {@link
|
|
151
|
-
* assertRolesUnlocked} pre-checks the common case (and names the holder), but
|
|
152
|
-
* it's a TOCTOU check — another admin can grab the lock between it and the
|
|
153
|
-
* actual acquire inside the write. This catches that race so contention always
|
|
154
|
-
* surfaces as a 409, never an unhandled 500.
|
|
155
|
-
*/
|
|
156
|
-
private mapLockContention;
|
|
157
154
|
private readRolesYaml;
|
|
158
155
|
/** The roster: every role on the default branch with members + references. */
|
|
159
156
|
getRoster(): Promise<RoleRosterEntry[]>;
|
|
@@ -184,85 +181,57 @@ export declare class RolesAdminService {
|
|
|
184
181
|
* through precisely when the file is broken.
|
|
185
182
|
*/
|
|
186
183
|
recover(actor: AuthUser): Promise<RoleRosterEntry[]>;
|
|
187
|
-
createRole(actor: AuthUser, displayName: string): Promise<RoleRosterEntry[]>;
|
|
188
|
-
deleteRole(actor: AuthUser, canonical: string): Promise<RoleRosterEntry[]>;
|
|
189
184
|
addMember(actor: AuthUser, canonical: string, email: string): Promise<RoleRosterEntry[]>;
|
|
190
185
|
/**
|
|
191
|
-
* Remove a member. Refuses to
|
|
192
|
-
*
|
|
193
|
-
*
|
|
186
|
+
* Remove a member. Refuses to remove the Admin role's LAST DIRECT EMAIL
|
|
187
|
+
* (422) — the kept invariant: whatever groups Admin references, at least
|
|
188
|
+
* one directory-independent email member must remain, or a broken IdP
|
|
189
|
+
* connection becomes an admin lockout. Removing the caller's OWN last
|
|
190
|
+
* Admin membership requires `confirm` (409 otherwise) — no silent
|
|
191
|
+
* self-lockout, since admin status is read live from this file.
|
|
194
192
|
*/
|
|
195
193
|
removeMember(actor: AuthUser, canonical: string, email: string, confirm: boolean): Promise<RoleRosterEntry[]>;
|
|
196
194
|
/**
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
195
|
+
* Assign a role to a group — Admin included (the parse-time invariant keeps
|
|
196
|
+
* at least one direct email on Admin, so a group ref can never be its only
|
|
197
|
+
* membership).
|
|
198
|
+
*
|
|
199
|
+
* The ref must name a group the ACTIVE source knows: mergeGroupsIntoRoles
|
|
200
|
+
* ignores an unknown ref with only a log warning, so a typo here would be
|
|
201
|
+
* accepted and then silently grant the role to nobody. The check is
|
|
202
|
+
* BEST-EFFORT validation, not a race-free guarantee: the manual group
|
|
203
|
+
* file's lock is held across validate + write (so a concurrent groups-page
|
|
204
|
+
* deletion/rename can't invalidate the ref mid-flight), but the IdP sync
|
|
205
|
+
* writer commits through its own lock — a provisioning push can retire the
|
|
206
|
+
* group between this check and the next sync. That is fine by design: a
|
|
207
|
+
* dangling ref resolves to nothing, with a resolver warning naming it.
|
|
208
|
+
*/
|
|
209
|
+
assignGroup(actor: AuthUser, canonical: string, groupName: string): Promise<RoleRosterEntry[]>;
|
|
210
|
+
unassignGroup(actor: AuthUser, canonical: string, groupName: string): Promise<RoleRosterEntry[]>;
|
|
211
|
+
/**
|
|
212
|
+
* Convert a LEGACY people-set role into a manual group — the migration the
|
|
213
|
+
* roles/groups split defines: "Product" was never a capability, it was a
|
|
214
|
+
* team. Atomic two-file move (roles.yaml loses the role, groups.yaml gains
|
|
215
|
+
* the group with the same members) in ONE commit; grant references keep
|
|
216
|
+
* working untouched because the NAME does not change.
|
|
217
|
+
*
|
|
218
|
+
* Refusals: capability roles (they ARE roles — Admin included), roles with
|
|
219
|
+
* group assignments (unwind those first: a group containing a group is
|
|
220
|
+
* nesting), IdP mode (groups are managed in the identity provider — this
|
|
221
|
+
* would write a retired file), and a groups.yaml name collision.
|
|
203
222
|
*/
|
|
204
|
-
|
|
223
|
+
convertRoleToGroup(actor: AuthUser, canonical: string): Promise<RoleRosterEntry[]>;
|
|
205
224
|
/** Map a RolesEditError to a RolesAdminError (preserving status). */
|
|
206
225
|
private guardEdit;
|
|
207
226
|
private assertLoadable;
|
|
208
227
|
/**
|
|
209
|
-
* Single-file roles.yaml mutation
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
* to `actor`), the same pipeline the human editor and agent use. So unlike the
|
|
215
|
-
* rename's synchronous atomic commit, the git commit here lands on release
|
|
216
|
-
* (a beat after the write); the HTTP response reads the working tree, which is
|
|
217
|
-
* already on disk, so the returned roster is correct.
|
|
228
|
+
* Single-file roles.yaml mutation under the shared file-lock/commit helper.
|
|
229
|
+
* `pre` produces the candidate (and may throw RolesAdminError for invariant
|
|
230
|
+
* violations before any write). Skips on a no-op. Every candidate passes
|
|
231
|
+
* the resolver's own parser (assertLoadable) plus the pre-disk validator
|
|
232
|
+
* before a byte lands.
|
|
218
233
|
*/
|
|
219
234
|
private runEdit;
|
|
220
|
-
|
|
221
|
-
* Find every genuine role reference to `oldCanonical` across folder access.md
|
|
222
|
-
* AND node frontmatter, and rewrite each to `newDisplayName`. Reference-aware:
|
|
223
|
-
* a line is rewritten ONLY if it PARSES as a role entry whose canonical name
|
|
224
|
-
* == oldCanonical. Prose, comments, `Name <email>` user entries, other keys,
|
|
225
|
-
* and substrings never match. Returns the repo-relative writes to commit.
|
|
226
|
-
*/
|
|
227
|
-
private rewriteRoleReferences;
|
|
228
|
-
/**
|
|
229
|
-
* Repo-relative paths of every file that could carry a role reference: all
|
|
230
|
-
* `access.md` files plus every `.md` node (its own frontmatter). Sourced from
|
|
231
|
-
* the workspace file tree (which already skips `.git` and honours
|
|
232
|
-
* `.bevelignore`), filtered to `.md` under the KB dir and returned bare
|
|
233
|
-
* repo-relative. (`roles.yaml` isn't `.md`, so it's excluded; the rename
|
|
234
|
-
* commits it separately.) Under save=share the working tree matches the
|
|
235
|
-
* committed set, so this is the same candidate list git-tracking would give.
|
|
236
|
-
*/
|
|
237
|
-
private collectCandidateFiles;
|
|
238
|
-
/**
|
|
239
|
-
* Sound scan of EVERY `.md` (folder `access.md` + node frontmatter)
|
|
240
|
-
* for genuine role references, indexed by canonical role name. Shares the
|
|
241
|
-
* candidate set and the config-region role-entry parse with the rename
|
|
242
|
-
* rewrite (`findRoleRefsInText` / `rewriteRoleTokensInText`), so the delete
|
|
243
|
-
* warning and the rename rewrite see the SAME references — the warning can no
|
|
244
|
-
* longer undercount frontmatter the rename would touch. A file we cannot read
|
|
245
|
-
* is skipped (this is an advisory read, not the atomic write path): missing a
|
|
246
|
-
* reference here only weakens the warning, it cannot drop access.
|
|
247
|
-
*/
|
|
248
|
-
private scanRoleReferences;
|
|
235
|
+
private runEditLocked;
|
|
249
236
|
}
|
|
250
|
-
/** Every genuine role reference in `text`'s config region, as {role, verb}. */
|
|
251
|
-
export declare function findRoleRefsInText(text: string, isMarkdown?: boolean): {
|
|
252
|
-
role: string;
|
|
253
|
-
verb: string;
|
|
254
|
-
}[];
|
|
255
|
-
/**
|
|
256
|
-
* Rewrite every CONFIG-REGION line that PARSES as a role reference whose
|
|
257
|
-
* canonical name == `oldCanonical`, replacing the role token with
|
|
258
|
-
* `newDisplayName` (preserving any leading `deny ` and indentation). Only the
|
|
259
|
-
* frontmatter block of a markdown file is touched — the body is left
|
|
260
|
-
* byte-for-byte intact, so a prose line like `- Sales` is never corrupted.
|
|
261
|
-
* Lines that don't parse as a matching role entry (user entries, other keys,
|
|
262
|
-
* substrings) are also untouched. Exported for test.
|
|
263
|
-
*
|
|
264
|
-
* `isMarkdown` (default true) marks files that carry a markdown body below the
|
|
265
|
-
* frontmatter; pass false only for a pure-config file with no body.
|
|
266
|
-
*/
|
|
267
|
-
export declare function rewriteRoleTokensInText(text: string, oldCanonical: string, newDisplayName: string, isMarkdown?: boolean): string;
|
|
268
237
|
//# sourceMappingURL=roles-admin.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roles-admin.service.d.ts","sourceRoot":"","sources":["../../../src/modules/access/roles-admin.service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"roles-admin.service.d.ts","sourceRoot":"","sources":["../../../src/modules/access/roles-admin.service.ts"],"names":[],"mappings":"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"}
|