@bevel-software/platform-core-backend 0.10.0 → 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/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +12 -1
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +22 -0
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +34 -1
- package/dist/core/create-core-services.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/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 +165 -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/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 +3 -3
- package/src/core/create-core-server.ts +13 -0
- package/src/core/create-core-services.ts +68 -0
- 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/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 +174 -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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WorkspaceService } from '../workspace/workspace.service.js';
|
|
2
|
-
import type { IAccessControl, AccessTargetKind, GrantPrincipal, GrantSources } from './access-control.interface.js';
|
|
2
|
+
import type { IAccessControl, AccessTargetKind, GrantPrincipal, GrantSources, ResolvedPrincipal } from './access-control.interface.js';
|
|
3
|
+
import { type GroupsIndex } from './group-files.js';
|
|
3
4
|
export declare const ADMIN_CANONICAL = "admin";
|
|
4
5
|
/**
|
|
5
6
|
* Verbs the resolver understands in an `access.md` frontmatter. Each verb
|
|
@@ -38,6 +39,24 @@ export declare const EVERYONE_DISPLAY = "Everyone";
|
|
|
38
39
|
export declare function sourceVerbsFor(verb: Verb): Verb[];
|
|
39
40
|
export declare const RESERVED_ROLE_NAMES: Set<string>;
|
|
40
41
|
export declare const DENY_PREFIX = "deny ";
|
|
42
|
+
/**
|
|
43
|
+
* Member-entry prefix in roles.yaml that references a GROUP instead of an
|
|
44
|
+
* email: `- group:Engineering`. Explicit on purpose — membership kind is
|
|
45
|
+
* never guessed from string shape. Valid on EVERY role including Admin, with
|
|
46
|
+
* one kept invariant (see `parseRolesYaml`): Admin must always retain at
|
|
47
|
+
* least one direct email member, so a misconfigured or unreachable directory
|
|
48
|
+
* can never leave the deployment without a rescuable admin.
|
|
49
|
+
*/
|
|
50
|
+
export declare const GROUP_REF_PREFIX = "group:";
|
|
51
|
+
/**
|
|
52
|
+
* Explicit ROLE token prefix in access.md entries: `role/<Name>` resolves to
|
|
53
|
+
* the roles.yaml role only, never a group. A BARE name resolves GROUP-FIRST
|
|
54
|
+
* and falls back to the role — so `role/` is the escape hatch when a group
|
|
55
|
+
* shares the role's name. The prefix is reserved in the group name-safety
|
|
56
|
+
* rules (a group may never be named `role/...`), and every role is also
|
|
57
|
+
* registered in the principal index under its `role/<canonical>` alias.
|
|
58
|
+
*/
|
|
59
|
+
export declare const ROLE_TOKEN_PREFIX = "role/";
|
|
41
60
|
export declare const USER_REF_REGEX: RegExp;
|
|
42
61
|
export declare const EMAIL_REGEX: RegExp;
|
|
43
62
|
export interface RoleEntry {
|
|
@@ -66,10 +85,34 @@ export interface AccessFile {
|
|
|
66
85
|
entries: Record<Verb, ParsedEntry[]>;
|
|
67
86
|
}
|
|
68
87
|
export declare function isAccessMdPath(p: string): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Extensions of node files whose OWN `---` frontmatter can carry access verbs
|
|
90
|
+
* the resolver enforces (`readOwnEntries` → `parseOwnAccessEntries`). The
|
|
91
|
+
* SINGLE source of truth for every surface that enumerates candidate files —
|
|
92
|
+
* the access-declarations scan and the shared `KbReferenceScanner` (which
|
|
93
|
+
* must scan/rewrite the same set, or a rename strands a live `.tool`
|
|
94
|
+
* frontmatter grant). `access.md` is covered by `.md`.
|
|
95
|
+
*/
|
|
96
|
+
export declare const ACCESS_FRONTMATTER_EXTENSIONS: readonly [".md", ".tool"];
|
|
97
|
+
/** True when `p` is a file the resolver reads access frontmatter from. */
|
|
98
|
+
export declare function hasAccessFrontmatterExtension(p: string): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* The PRINCIPAL index — canonical name → member emails. Despite the name it
|
|
101
|
+
* holds both kinds of named principal after `mergeGroupsIntoRoles` runs:
|
|
102
|
+
* roles.yaml roles (`kind: 'role'`, the default) and the active group file's
|
|
103
|
+
* groups (`kind: 'group'`). Grant resolution treats them identically — a
|
|
104
|
+
* grant names a principal, the principal has member emails — which is what
|
|
105
|
+
* lets the whole closeness-first resolver work on groups without changes.
|
|
106
|
+
*
|
|
107
|
+
* `groupRefs` carries a role's `group:<Name>` member entries between parse
|
|
108
|
+
* and merge; the merge expands them into `emails`/`byEmail`.
|
|
109
|
+
*/
|
|
69
110
|
interface RolesIndex {
|
|
70
111
|
byCanonical: Map<string, {
|
|
71
112
|
displayName: string;
|
|
72
113
|
emails: Set<string>;
|
|
114
|
+
groupRefs?: Set<string>;
|
|
115
|
+
kind?: 'role' | 'group';
|
|
73
116
|
}>;
|
|
74
117
|
byEmail: Map<string, Set<string>>;
|
|
75
118
|
}
|
|
@@ -84,7 +127,17 @@ interface YamlErr {
|
|
|
84
127
|
ok: false;
|
|
85
128
|
error: string;
|
|
86
129
|
}
|
|
87
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Strip a trailing `# comment` the way the YAML-subset tokeniser reads a
|
|
132
|
+
* line: a `#` at the start (after only whitespace) or preceded by whitespace
|
|
133
|
+
* begins a comment. Exported so the reference scanner matches tokens against
|
|
134
|
+
* the SAME comment rule the resolver parses with (a `- GTM Team # sales`
|
|
135
|
+
* entry is the token `GTM Team`, never `GTM Team # sales`).
|
|
136
|
+
*/
|
|
137
|
+
export declare function stripComment(line: string): string;
|
|
138
|
+
export declare function parseYamlSubset(text: string, opts?: {
|
|
139
|
+
tolerateEmptyKeys?: boolean;
|
|
140
|
+
}): YamlOk | YamlErr;
|
|
88
141
|
export declare function extractFrontmatter(text: string): {
|
|
89
142
|
ok: true;
|
|
90
143
|
frontmatter: string;
|
|
@@ -110,6 +163,61 @@ export declare function parseRolesYaml(text: string): {
|
|
|
110
163
|
ok: false;
|
|
111
164
|
errors: string[];
|
|
112
165
|
};
|
|
166
|
+
/**
|
|
167
|
+
* Merge the active group source into the principal index and expand role →
|
|
168
|
+
* group assignments. Mutates `index` in place; returns human-readable
|
|
169
|
+
* warnings (callers log them — nothing here ever throws, because group
|
|
170
|
+
* problems must degrade, not brick access resolution).
|
|
171
|
+
*
|
|
172
|
+
* Rules (the grant-grammar precedence):
|
|
173
|
+
* - Every role is ALSO registered under its explicit `role/<canonical>`
|
|
174
|
+
* alias — the token that always resolves to the role.
|
|
175
|
+
* - A BARE name resolves GROUP-FIRST: when a group's canonical name
|
|
176
|
+
* collides with a role's, the bare key resolves to the GROUP (warned);
|
|
177
|
+
* the role stays reachable via `role/<canonical>`.
|
|
178
|
+
* - Role `group:<Name>` refs — Admin's included — expand against the
|
|
179
|
+
* merged groups; an unknown ref contributes nothing (warned).
|
|
180
|
+
* - `byEmail` is rebuilt so each member holds exactly the tokens that
|
|
181
|
+
* resolve to a principal they belong to (bare + `role/` alias for roles,
|
|
182
|
+
* bare for groups).
|
|
183
|
+
*/
|
|
184
|
+
export declare function mergeGroupsIntoRoles(index: RolesIndex, groups: GroupsIndex, sourceFile: string): string[];
|
|
185
|
+
/**
|
|
186
|
+
* Health of the ACTIVE groups source as of the last load. `ok: false` means
|
|
187
|
+
* the source EXISTS but could not be read or parsed — groups contribute
|
|
188
|
+
* nothing, bare grant tokens fall through to roles, and group-backed denies
|
|
189
|
+
* drop (the owner's explicit degrade-loudly decision, NOT fail-closed). The
|
|
190
|
+
* marker is carried on the loaded model and surfaced by the groups admin
|
|
191
|
+
* endpoints so the Groups page can banner it.
|
|
192
|
+
*/
|
|
193
|
+
export type GroupsHealth = {
|
|
194
|
+
ok: true;
|
|
195
|
+
} | {
|
|
196
|
+
ok: false;
|
|
197
|
+
file: string;
|
|
198
|
+
reason: string;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Load the ACTIVE group source through `read` (working tree or at-ref — the
|
|
202
|
+
* caller supplies the reader, so both model loaders share one mode rule):
|
|
203
|
+
* `synced-groups.yaml` existing → IdP mode (groups.yaml ignored entirely,
|
|
204
|
+
* even when the synced file is empty or malformed — falling back would
|
|
205
|
+
* resurrect retired manual groups); otherwise `groups.yaml` → manual mode.
|
|
206
|
+
*
|
|
207
|
+
* `read` returns null for a genuinely-absent file and may THROW for any other
|
|
208
|
+
* failure. Only ENOENT/ENOTDIR count as absent (the caller may also whitelist
|
|
209
|
+
* them into null); every other read error — notably a non-absence error on
|
|
210
|
+
* `synced-groups.yaml` — is treated as a BROKEN source: no groups, no
|
|
211
|
+
* fallback to the manual file (falling back would resurrect retired groups),
|
|
212
|
+
* and an `ok: false` health marker. Structural parse failures degrade the
|
|
213
|
+
* same way; this function never throws.
|
|
214
|
+
*/
|
|
215
|
+
export declare function loadActiveGroups(read: (filename: string) => Promise<string | null>): Promise<{
|
|
216
|
+
groups: GroupsIndex;
|
|
217
|
+
sourceFile: string;
|
|
218
|
+
warnings: string[];
|
|
219
|
+
health: GroupsHealth;
|
|
220
|
+
}>;
|
|
113
221
|
/**
|
|
114
222
|
* Does an `access.md` body declare access rules — i.e. is the file in the NEW
|
|
115
223
|
* (body-governs-the-folder) format?
|
|
@@ -252,16 +360,6 @@ export declare class AccessControlService implements IAccessControl {
|
|
|
252
360
|
ok: false;
|
|
253
361
|
errors: string[];
|
|
254
362
|
};
|
|
255
|
-
/**
|
|
256
|
-
* Advisory scan of folder `access.md` files for references to a role (by
|
|
257
|
-
* canonical name). See `IAccessControl.referencesToRole` — undercounts node
|
|
258
|
-
* frontmatter by design; powers the delete warning only, never the rename
|
|
259
|
-
* gate.
|
|
260
|
-
*/
|
|
261
|
-
referencesToRole(workspaceId: string, canonicalRole: string): Promise<{
|
|
262
|
-
path: string;
|
|
263
|
-
verb: string;
|
|
264
|
-
}[]>;
|
|
265
363
|
canWrite(workspaceId: string, userEmail: string, relativePath: string): Promise<boolean>;
|
|
266
364
|
canRead(workspaceId: string, userEmail: string, relativePath: string): Promise<boolean>;
|
|
267
365
|
canReadBatch(workspaceId: string, userEmail: string, relativePaths: string[]): Promise<Map<string, boolean>>;
|
|
@@ -270,6 +368,7 @@ export declare class AccessControlService implements IAccessControl {
|
|
|
270
368
|
canOwnerBatch(workspaceId: string, userEmail: string, relativePaths: string[]): Promise<Map<string, boolean>>;
|
|
271
369
|
canOwner(workspaceId: string, userEmail: string, relativePath: string): Promise<boolean>;
|
|
272
370
|
eligibleOwners(workspaceId: string, relativePath: string): Promise<{
|
|
371
|
+
principals: ResolvedPrincipal[];
|
|
273
372
|
roles: string[];
|
|
274
373
|
users: {
|
|
275
374
|
name: string;
|
|
@@ -277,6 +376,7 @@ export declare class AccessControlService implements IAccessControl {
|
|
|
277
376
|
}[];
|
|
278
377
|
}>;
|
|
279
378
|
eligibleWriters(workspaceId: string, relativePath: string): Promise<{
|
|
379
|
+
principals: ResolvedPrincipal[];
|
|
280
380
|
roles: string[];
|
|
281
381
|
users: {
|
|
282
382
|
name: string;
|
|
@@ -285,6 +385,7 @@ export declare class AccessControlService implements IAccessControl {
|
|
|
285
385
|
}>;
|
|
286
386
|
eligibleReaders(workspaceId: string, relativePath: string): Promise<{
|
|
287
387
|
restricted: boolean;
|
|
388
|
+
principals: ResolvedPrincipal[];
|
|
288
389
|
roles: string[];
|
|
289
390
|
users: {
|
|
290
391
|
name: string;
|
|
@@ -292,6 +393,7 @@ export declare class AccessControlService implements IAccessControl {
|
|
|
292
393
|
}[];
|
|
293
394
|
}>;
|
|
294
395
|
eligibleDownloaders(workspaceId: string, relativePath: string): Promise<{
|
|
396
|
+
principals: ResolvedPrincipal[];
|
|
295
397
|
roles: string[];
|
|
296
398
|
users: {
|
|
297
399
|
name: string;
|
|
@@ -306,9 +408,12 @@ export declare class AccessControlService implements IAccessControl {
|
|
|
306
408
|
name: string;
|
|
307
409
|
email: string;
|
|
308
410
|
}>>;
|
|
309
|
-
grantSources(workspaceId: string, kind: AccessTargetKind, relativePath: string, principal: GrantPrincipal
|
|
411
|
+
grantSources(workspaceId: string, kind: AccessTargetKind, relativePath: string, principal: GrantPrincipal, opts?: {
|
|
412
|
+
tokenMatch?: 'exact' | 'name';
|
|
413
|
+
}): Promise<GrantSources>;
|
|
310
414
|
kbPrincipals(workspaceId: string): Promise<{
|
|
311
|
-
|
|
415
|
+
roles: string[];
|
|
416
|
+
groups: string[];
|
|
312
417
|
people: {
|
|
313
418
|
name: string;
|
|
314
419
|
email: string;
|
|
@@ -318,6 +423,16 @@ export declare class AccessControlService implements IAccessControl {
|
|
|
318
423
|
email: string;
|
|
319
424
|
displayName: string;
|
|
320
425
|
} | null>;
|
|
426
|
+
/**
|
|
427
|
+
* `synced-groups.yaml` is MACHINE-OWNED: regenerated wholesale from the
|
|
428
|
+
* directory mirror and committed by the directory-sync bot. The bot is its
|
|
429
|
+
* ONLY writer — role/grant resolution never applies to it. That cuts both
|
|
430
|
+
* ways: the bot needs no role to write it (it isn't in roles.yaml, and on a
|
|
431
|
+
* protected branch nothing else would make it eligible), and no HUMAN can
|
|
432
|
+
* hand-edit it through the app (an edit would be silently overwritten by
|
|
433
|
+
* the next provisioning push anyway).
|
|
434
|
+
*/
|
|
435
|
+
private machineOwnedWriteRule;
|
|
321
436
|
canWriteAtRef(workspaceId: string, ref: string, userEmail: string, relativePath: string): Promise<boolean | null>;
|
|
322
437
|
canReadAtRef(workspaceId: string, ref: string, userEmail: string, relativePath: string): Promise<boolean | null>;
|
|
323
438
|
canWriteBatchAtRef(workspaceId: string, ref: string, userEmail: string, relativePaths: string[]): Promise<Map<string, boolean> | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-control.service.d.ts","sourceRoot":"","sources":["../../../src/modules/access/access-control.service.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EAEd,YAAY,
|
|
1
|
+
{"version":3,"file":"access-control.service.d.ts","sourceRoot":"","sources":["../../../src/modules/access/access-control.service.ts"],"names":[],"mappings":"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"}
|