@astram/identity 0.12.0 → 0.14.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/features/authz/grant-admin.service.d.ts +1 -1
- package/dist/features/authz/grant-admin.service.d.ts.map +1 -1
- package/dist/features/authz/grant-admin.service.js +8 -0
- package/dist/features/authz/grant-ceiling.d.ts +11 -3
- package/dist/features/authz/grant-ceiling.d.ts.map +1 -1
- package/dist/features/authz/grant-ceiling.js +20 -3
- package/dist/features/authz/record-authorization.d.ts +9 -1
- package/dist/features/authz/record-authorization.d.ts.map +1 -1
- package/dist/features/authz/record-authorization.js +24 -3
- package/dist/features/company/company-hierarchy.service.d.ts +6 -0
- package/dist/features/company/company-hierarchy.service.d.ts.map +1 -1
- package/dist/features/company/company-hierarchy.service.js +19 -0
- package/dist/features/identity-feature.module.d.ts +7 -1
- package/dist/features/identity-feature.module.d.ts.map +1 -1
- package/dist/features/identity-feature.module.js +25 -5
- package/dist/features/membership/membership.service.d.ts +9 -0
- package/dist/features/membership/membership.service.d.ts.map +1 -1
- package/dist/features/membership/membership.service.js +40 -0
- package/dist/features/membership/posting.service.d.ts +18 -0
- package/dist/features/membership/posting.service.d.ts.map +1 -1
- package/dist/features/membership/posting.service.js +85 -27
- package/dist/features/org-bootstrap/org-bootstrap-error.d.ts +20 -0
- package/dist/features/org-bootstrap/org-bootstrap-error.d.ts.map +1 -0
- package/dist/features/org-bootstrap/org-bootstrap-error.js +24 -0
- package/dist/features/org-bootstrap/org-bootstrap-file.d.ts +58 -0
- package/dist/features/org-bootstrap/org-bootstrap-file.d.ts.map +1 -0
- package/dist/features/org-bootstrap/org-bootstrap-file.js +323 -0
- package/dist/features/org-bootstrap/org-bootstrap-plan.d.ts +79 -0
- package/dist/features/org-bootstrap/org-bootstrap-plan.d.ts.map +1 -0
- package/dist/features/org-bootstrap/org-bootstrap-plan.js +288 -0
- package/dist/features/org-bootstrap/org-bootstrap-runner.harness.d.ts +259 -0
- package/dist/features/org-bootstrap/org-bootstrap-runner.harness.d.ts.map +1 -0
- package/dist/features/org-bootstrap/org-bootstrap-runner.harness.js +604 -0
- package/dist/features/org-bootstrap/org-bootstrap-runner.mocks.d.ts +24 -0
- package/dist/features/org-bootstrap/org-bootstrap-runner.mocks.d.ts.map +1 -0
- package/dist/features/org-bootstrap/org-bootstrap-runner.mocks.js +39 -0
- package/dist/features/org-bootstrap/org-bootstrap.manifest.d.ts +19 -0
- package/dist/features/org-bootstrap/org-bootstrap.manifest.d.ts.map +1 -0
- package/dist/features/org-bootstrap/org-bootstrap.manifest.js +30 -0
- package/dist/features/org-bootstrap/org-bootstrap.tokens.d.ts +8 -0
- package/dist/features/org-bootstrap/org-bootstrap.tokens.d.ts.map +1 -0
- package/dist/features/org-bootstrap/org-bootstrap.tokens.js +10 -0
- package/dist/features/org-bootstrap/org-names.d.ts +12 -0
- package/dist/features/org-bootstrap/org-names.d.ts.map +1 -0
- package/dist/features/org-bootstrap/org-names.js +26 -0
- package/dist/features/org-bootstrap/org-state.reader.d.ts +15 -0
- package/dist/features/org-bootstrap/org-state.reader.d.ts.map +1 -0
- package/dist/features/org-bootstrap/org-state.reader.js +225 -0
- package/dist/features/org-bootstrap/root-password-source.d.ts +9 -0
- package/dist/features/org-bootstrap/root-password-source.d.ts.map +1 -0
- package/dist/features/org-bootstrap/root-password-source.js +57 -0
- package/dist/features/org-bootstrap/run-org-bootstrap.d.ts +42 -0
- package/dist/features/org-bootstrap/run-org-bootstrap.d.ts.map +1 -0
- package/dist/features/org-bootstrap/run-org-bootstrap.js +688 -0
- package/dist/features/org-bootstrap/set-password-links.d.ts +30 -0
- package/dist/features/org-bootstrap/set-password-links.d.ts.map +1 -0
- package/dist/features/org-bootstrap/set-password-links.js +55 -0
- package/dist/features/org-structure/org-catalog.service.d.ts +13 -0
- package/dist/features/org-structure/org-catalog.service.d.ts.map +1 -1
- package/dist/features/org-structure/org-catalog.service.js +40 -0
- package/dist/features/role/role-owner-transition.d.ts +17 -0
- package/dist/features/role/role-owner-transition.d.ts.map +1 -0
- package/dist/features/role/role-owner-transition.js +23 -0
- package/dist/features/role/role.controller.d.ts +1 -1
- package/dist/features/role/role.controller.d.ts.map +1 -1
- package/dist/features/role/role.controller.js +6 -4
- package/dist/features/role/role.service.d.ts +8 -2
- package/dist/features/role/role.service.d.ts.map +1 -1
- package/dist/features/role/role.service.js +13 -3
- package/dist/features/user/credential-provisioner.token.d.ts +8 -0
- package/dist/features/user/credential-provisioner.token.d.ts.map +1 -0
- package/dist/features/user/credential-provisioner.token.js +10 -0
- package/dist/features/user/user.controller.d.ts +1 -3
- package/dist/features/user/user.controller.d.ts.map +1 -1
- package/dist/features/user/user.controller.js +2 -2
- package/dist/features/user/user.service.d.ts +28 -5
- package/dist/features/user/user.service.d.ts.map +1 -1
- package/dist/features/user/user.service.js +45 -12
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +3 -1
- package/dist/role.object.d.ts +1 -0
- package/dist/role.object.d.ts.map +1 -1
- package/dist/role.object.js +8 -0
- package/migrations/1710000000101-AddRoleOwnerCompany.cjs +98 -0
- package/package.json +4 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Pool } from 'mariadb';
|
|
2
2
|
import type { Principal } from '@astram/core';
|
|
3
|
-
import type
|
|
3
|
+
import { type AuditPort } from '@astram/engine';
|
|
4
4
|
import { PermissionVersionBumper } from './permission-version.bumper.js';
|
|
5
5
|
import { AccessBundleStore } from './access-bundle-store.js';
|
|
6
6
|
import { GrantCeiling } from './grant-ceiling.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grant-admin.service.d.ts","sourceRoot":"","sources":["../../../src/features/authz/grant-admin.service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"grant-admin.service.d.ts","sourceRoot":"","sources":["../../../src/features/authz/grant-admin.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GrantAdminService = exports.BadKeyError = void 0;
|
|
4
4
|
const core_1 = require("@astram/core");
|
|
5
|
+
const engine_1 = require("@astram/engine");
|
|
5
6
|
const access_bundle_store_js_1 = require("./access-bundle-store.js");
|
|
6
7
|
const db_permission_facts_adapter_js_1 = require("./db-permission-facts.adapter.js");
|
|
7
8
|
const grant_ceiling_js_1 = require("./grant-ceiling.js");
|
|
@@ -216,6 +217,12 @@ class GrantAdminService {
|
|
|
216
217
|
return [labelOf(rowTenant)];
|
|
217
218
|
return actor.isRoot === true ? tenants.map(labelOf) : [];
|
|
218
219
|
};
|
|
220
|
+
// G-009 R6: a grantor bound to a declared operation (org bootstrap) is attributed in the row;
|
|
221
|
+
// an unbound grantor adds nothing, so today's attributes stay byte-identical.
|
|
222
|
+
const op = (0, engine_1.operationOf)(actor);
|
|
223
|
+
const operationAttributes = !op
|
|
224
|
+
? {}
|
|
225
|
+
: { operation: op.operationKey, step: op.stepKey, onBehalfOf: op.onBehalfOf };
|
|
219
226
|
const occurredAtMs = Date.now();
|
|
220
227
|
for (const tenantId of new Set([actor.tenantId, ...tenants])) {
|
|
221
228
|
const tenantNames = tenantsFor(tenantId);
|
|
@@ -231,6 +238,7 @@ class GrantAdminService {
|
|
|
231
238
|
keys: [...keys],
|
|
232
239
|
tenants: tenantNames,
|
|
233
240
|
...extra,
|
|
241
|
+
...operationAttributes,
|
|
234
242
|
},
|
|
235
243
|
}, query);
|
|
236
244
|
}
|
|
@@ -20,6 +20,14 @@ import { type IdentitySchemaNames } from '../../schema.js';
|
|
|
20
20
|
export declare class GrantCeilingError extends Error {
|
|
21
21
|
constructor(key: string, message?: string);
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* The org-bootstrap exception (G-009 AC-7): `operationRoleIds` is the allow-set the runner computed
|
|
25
|
+
* from the file's roles for the company. It relaxes a role check ONLY for a principal bound (engine
|
|
26
|
+
* WeakMap binding, unforgeable) to `shield:org-bootstrap`, and only when EVERY id of the call is in the set.
|
|
27
|
+
*/
|
|
28
|
+
export interface OperationRoleOptions {
|
|
29
|
+
readonly operationRoleIds?: readonly string[];
|
|
30
|
+
}
|
|
23
31
|
/** The actor's reachable subtree: the session's cached closure, else the self node (non-widening). */
|
|
24
32
|
export declare function subtreeOf(actor: Principal): readonly string[];
|
|
25
33
|
/**
|
|
@@ -89,7 +97,7 @@ export declare class GrantCeiling {
|
|
|
89
97
|
* A role holding nothing assigns nothing and passes; a role key the registry does not know
|
|
90
98
|
* counts as not held (Phase 8 #4). Root bypasses. Store outage → 503.
|
|
91
99
|
*/
|
|
92
|
-
assertCanAssignRoles(actor: Principal, roleIds: readonly string[]): Promise<void>;
|
|
100
|
+
assertCanAssignRoles(actor: Principal, roleIds: readonly string[], opts?: OperationRoleOptions): Promise<void>;
|
|
93
101
|
/**
|
|
94
102
|
* The first of a TARGET's raw keys (a role's `role_permission` rows) the actor does not cover,
|
|
95
103
|
* or `undefined` when all are covered. Phase 8 #4: judged per RAW key with `coversKey`, so a key
|
|
@@ -166,12 +174,12 @@ export declare class GrantCeiling {
|
|
|
166
174
|
* role not bound in the subtree is "not found" for the actor (no existence leak); a role also
|
|
167
175
|
* used outside (a shared role) is root-only. Root bypasses.
|
|
168
176
|
*/
|
|
169
|
-
assertRoleAdministrable(actor: Principal, roleUuid: string): Promise<void>;
|
|
177
|
+
assertRoleAdministrable(actor: Principal, roleUuid: string, opts?: OperationRoleOptions): Promise<void>;
|
|
170
178
|
/**
|
|
171
179
|
* Assert the actor may POST someone to the role (#11): the role is bound within the actor's
|
|
172
180
|
* subtree or not bound at all — never a role also used outside it (a shared role's assignment
|
|
173
181
|
* would widen another tenant's role). Pair with {@link assertCanAssignRoles}. Root bypasses.
|
|
174
182
|
*/
|
|
175
|
-
assertRoleAssignable(actor: Principal, roleUuid: string): Promise<void>;
|
|
183
|
+
assertRoleAssignable(actor: Principal, roleUuid: string, opts?: OperationRoleOptions): Promise<void>;
|
|
176
184
|
}
|
|
177
185
|
//# sourceMappingURL=grant-ceiling.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grant-ceiling.d.ts","sourceRoot":"","sources":["../../../src/features/authz/grant-ceiling.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"grant-ceiling.d.ts","sourceRoot":"","sources":["../../../src/features/authz/grant-ceiling.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,8 @@ exports.GrantCeiling = exports.GrantCeilingError = void 0;
|
|
|
4
4
|
exports.subtreeOf = subtreeOf;
|
|
5
5
|
exports.coversKey = coversKey;
|
|
6
6
|
const core_1 = require("@astram/core");
|
|
7
|
+
const engine_1 = require("@astram/engine");
|
|
8
|
+
const org_bootstrap_manifest_js_1 = require("../org-bootstrap/org-bootstrap.manifest.js");
|
|
7
9
|
const http_js_1 = require("../shared/http.js");
|
|
8
10
|
const db_permission_facts_adapter_js_1 = require("./db-permission-facts.adapter.js");
|
|
9
11
|
const role_binding_js_1 = require("./role-binding.js");
|
|
@@ -18,6 +20,15 @@ class GrantCeilingError extends Error {
|
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
exports.GrantCeilingError = GrantCeilingError;
|
|
23
|
+
function operationCovers(actor, roleIds, opts) {
|
|
24
|
+
const allowed = opts?.operationRoleIds;
|
|
25
|
+
if (allowed === undefined || allowed.length === 0 || roleIds.length === 0)
|
|
26
|
+
return false;
|
|
27
|
+
if ((0, engine_1.operationOf)(actor)?.operationKey !== org_bootstrap_manifest_js_1.ORG_BOOTSTRAP_OPERATION)
|
|
28
|
+
return false;
|
|
29
|
+
const set = new Set(allowed);
|
|
30
|
+
return roleIds.every((id) => set.has(id));
|
|
31
|
+
}
|
|
21
32
|
/** The actor's reachable subtree: the session's cached closure, else the self node (non-widening). */
|
|
22
33
|
function subtreeOf(actor) {
|
|
23
34
|
return actor.scopeSubtreeNodeIds?.length ? actor.scopeSubtreeNodeIds : [actor.tenantId];
|
|
@@ -160,9 +171,11 @@ class GrantCeiling {
|
|
|
160
171
|
* A role holding nothing assigns nothing and passes; a role key the registry does not know
|
|
161
172
|
* counts as not held (Phase 8 #4). Root bypasses. Store outage → 503.
|
|
162
173
|
*/
|
|
163
|
-
async assertCanAssignRoles(actor, roleIds) {
|
|
174
|
+
async assertCanAssignRoles(actor, roleIds, opts) {
|
|
164
175
|
if (actor.isRoot === true)
|
|
165
176
|
return;
|
|
177
|
+
if (operationCovers(actor, roleIds, opts))
|
|
178
|
+
return;
|
|
166
179
|
const ids = [...new Set(roleIds)];
|
|
167
180
|
if (ids.length === 0)
|
|
168
181
|
return;
|
|
@@ -372,9 +385,11 @@ class GrantCeiling {
|
|
|
372
385
|
* role not bound in the subtree is "not found" for the actor (no existence leak); a role also
|
|
373
386
|
* used outside (a shared role) is root-only. Root bypasses.
|
|
374
387
|
*/
|
|
375
|
-
async assertRoleAdministrable(actor, roleUuid) {
|
|
388
|
+
async assertRoleAdministrable(actor, roleUuid, opts) {
|
|
376
389
|
if (actor.isRoot === true)
|
|
377
390
|
return;
|
|
391
|
+
if (operationCovers(actor, [roleUuid], opts))
|
|
392
|
+
return;
|
|
378
393
|
GrantCeiling.checkAdministrable(await this.roleBinding(actor, roleUuid));
|
|
379
394
|
}
|
|
380
395
|
/**
|
|
@@ -382,9 +397,11 @@ class GrantCeiling {
|
|
|
382
397
|
* subtree or not bound at all — never a role also used outside it (a shared role's assignment
|
|
383
398
|
* would widen another tenant's role). Pair with {@link assertCanAssignRoles}. Root bypasses.
|
|
384
399
|
*/
|
|
385
|
-
async assertRoleAssignable(actor, roleUuid) {
|
|
400
|
+
async assertRoleAssignable(actor, roleUuid, opts) {
|
|
386
401
|
if (actor.isRoot === true)
|
|
387
402
|
return;
|
|
403
|
+
if (operationCovers(actor, [roleUuid], opts))
|
|
404
|
+
return;
|
|
388
405
|
GrantCeiling.checkAssignable(await this.roleBinding(actor, roleUuid));
|
|
389
406
|
}
|
|
390
407
|
}
|
|
@@ -16,6 +16,14 @@ import type { FrameworkSchemas } from '@astram/core';
|
|
|
16
16
|
import { type RecordAuthorizationInputs } from '@astram/guard';
|
|
17
17
|
import type { ObjectTypeInput } from '@astram/engine';
|
|
18
18
|
import type { IdentitySchemaNames } from '../../schema.js';
|
|
19
|
+
/**
|
|
20
|
+
* A pool-size variable: unset or blank gives `undefined`; otherwise plain digits, a positive safe
|
|
21
|
+
* integer, or it throws naming the variable (never the value). The single-layout pool budget in
|
|
22
|
+
* `@astram/guard` (`loadPoolBudget`) applies the same rule, so the budget counts the pools that open.
|
|
23
|
+
*/
|
|
24
|
+
export declare function strictPoolSize(raw: string | undefined, name: string): number | undefined;
|
|
25
|
+
/** The authz pool cap: `APP_AUTHZ_POOL_MAX` (strict), else 4. */
|
|
26
|
+
export declare function authzPoolLimit(env?: NodeJS.ProcessEnv): number;
|
|
19
27
|
/**
|
|
20
28
|
* A lean `mariadb` pool for the authz grant-reads (built from `APP_DB_*` env via guard's
|
|
21
29
|
* `loadDbConfig`). Kept small — these are pre-gate coarse-grant reads, not the main CRUD pool.
|
|
@@ -33,7 +41,7 @@ export declare function createIdentityAuthzPool(schemas?: FrameworkSchemas): Poo
|
|
|
33
41
|
* - `registry` — bridged from `identityObjects` PLUS the consumer's `extraObjects` (their
|
|
34
42
|
* `<module>:<type>:<action>` keys project into a principal's grants at gate 5; without them a
|
|
35
43
|
* consumer type is `resource_not_registered`),
|
|
36
|
-
* - `operationManifest` —
|
|
44
|
+
* - `operationManifest` — the `shield:org-bootstrap` steps (G-009); no other delegated operation.
|
|
37
45
|
*/
|
|
38
46
|
export declare function buildRecordAuthorizationInputs(pool: Pool, extraObjects?: readonly ObjectTypeInput[],
|
|
39
47
|
/** Resolved framework names for the facts adapter (absent ⇒ from the namespace, once). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-authorization.d.ts","sourceRoot":"","sources":["../../../src/features/authz/record-authorization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAgB,EAAE,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"record-authorization.d.ts","sourceRoot":"","sources":["../../../src/features/authz/record-authorization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAgB,EAAE,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMxF;AAED,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE3E;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAaxE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,IAAI,EACV,YAAY,GAAE,SAAS,eAAe,EAAO;AAC7C,0FAA0F;AAC1F,OAAO,CAAC,EAAE,mBAAmB,GAC5B,yBAAyB,CAS3B"}
|
|
@@ -3,6 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.strictPoolSize = strictPoolSize;
|
|
7
|
+
exports.authzPoolLimit = authzPoolLimit;
|
|
6
8
|
exports.createIdentityAuthzPool = createIdentityAuthzPool;
|
|
7
9
|
exports.buildRecordAuthorizationInputs = buildRecordAuthorizationInputs;
|
|
8
10
|
/**
|
|
@@ -20,9 +22,28 @@ exports.buildRecordAuthorizationInputs = buildRecordAuthorizationInputs;
|
|
|
20
22
|
*/
|
|
21
23
|
const mariadb_1 = __importDefault(require("mariadb"));
|
|
22
24
|
const guard_1 = require("@astram/guard");
|
|
25
|
+
const org_bootstrap_manifest_js_1 = require("../org-bootstrap/org-bootstrap.manifest.js");
|
|
23
26
|
const objects_js_1 = require("../../objects.js");
|
|
24
27
|
const db_permission_facts_adapter_js_1 = require("./db-permission-facts.adapter.js");
|
|
25
28
|
const session_facts_reader_js_1 = require("./session-facts.reader.js");
|
|
29
|
+
/**
|
|
30
|
+
* A pool-size variable: unset or blank gives `undefined`; otherwise plain digits, a positive safe
|
|
31
|
+
* integer, or it throws naming the variable (never the value). The single-layout pool budget in
|
|
32
|
+
* `@astram/guard` (`loadPoolBudget`) applies the same rule, so the budget counts the pools that open.
|
|
33
|
+
*/
|
|
34
|
+
function strictPoolSize(raw, name) {
|
|
35
|
+
if (raw === undefined || raw.trim() === '')
|
|
36
|
+
return undefined;
|
|
37
|
+
const t = raw.trim();
|
|
38
|
+
const n = /^[0-9]+$/.test(t) ? Number(t) : Number.NaN;
|
|
39
|
+
if (!Number.isSafeInteger(n) || n < 1)
|
|
40
|
+
throw new Error(`${name} must be a positive integer`);
|
|
41
|
+
return n;
|
|
42
|
+
}
|
|
43
|
+
/** The authz pool cap: `APP_AUTHZ_POOL_MAX` (strict), else 4. */
|
|
44
|
+
function authzPoolLimit(env = process.env) {
|
|
45
|
+
return strictPoolSize(env.APP_AUTHZ_POOL_MAX, 'APP_AUTHZ_POOL_MAX') ?? 4;
|
|
46
|
+
}
|
|
26
47
|
/**
|
|
27
48
|
* A lean `mariadb` pool for the authz grant-reads (built from `APP_DB_*` env via guard's
|
|
28
49
|
* `loadDbConfig`). Kept small — these are pre-gate coarse-grant reads, not the main CRUD pool.
|
|
@@ -39,7 +60,7 @@ function createIdentityAuthzPool(schemas) {
|
|
|
39
60
|
user: db.user,
|
|
40
61
|
password: db.password,
|
|
41
62
|
database: db.database,
|
|
42
|
-
connectionLimit:
|
|
63
|
+
connectionLimit: authzPoolLimit(process.env),
|
|
43
64
|
// Phase 16: APP_DB_TLS / APP_DB_TLS_CA (production accounts are REQUIRE SSL).
|
|
44
65
|
...(ssl ? { ssl } : {}),
|
|
45
66
|
});
|
|
@@ -53,7 +74,7 @@ function createIdentityAuthzPool(schemas) {
|
|
|
53
74
|
* - `registry` — bridged from `identityObjects` PLUS the consumer's `extraObjects` (their
|
|
54
75
|
* `<module>:<type>:<action>` keys project into a principal's grants at gate 5; without them a
|
|
55
76
|
* consumer type is `resource_not_registered`),
|
|
56
|
-
* - `operationManifest` —
|
|
77
|
+
* - `operationManifest` — the `shield:org-bootstrap` steps (G-009); no other delegated operation.
|
|
57
78
|
*/
|
|
58
79
|
function buildRecordAuthorizationInputs(pool, extraObjects = [],
|
|
59
80
|
/** Resolved framework names for the facts adapter (absent ⇒ from the namespace, once). */
|
|
@@ -64,6 +85,6 @@ schemas) {
|
|
|
64
85
|
permissionFacts: new db_permission_facts_adapter_js_1.DbPermissionFactsAdapter(pool, registry, undefined, schemas),
|
|
65
86
|
sessionFacts: new session_facts_reader_js_1.AlsSessionFactsReader(),
|
|
66
87
|
registry,
|
|
67
|
-
operationManifest:
|
|
88
|
+
operationManifest: org_bootstrap_manifest_js_1.ORG_BOOTSTRAP_MANIFEST,
|
|
68
89
|
};
|
|
69
90
|
}
|
|
@@ -115,6 +115,12 @@ export declare class CompanyHierarchyService {
|
|
|
115
115
|
* Every change is audited on this transaction (names; ids only in structured attributes).
|
|
116
116
|
*/
|
|
117
117
|
private retireDependents;
|
|
118
|
+
/**
|
|
119
|
+
* Step 5 of {@link retireDependents} (G-009 T14, SPEC §5 v4): the roles the company owns become
|
|
120
|
+
* shared. Each owner is cleared through the audited `transitionRoleOwner` seam on the delete's
|
|
121
|
+
* connection (the FK's SET NULL would do it silently, without an audit row).
|
|
122
|
+
*/
|
|
123
|
+
private clearRoleOwners;
|
|
118
124
|
/** Step 4 of {@link retireDependents}: revoke and audit the grants naming the company. */
|
|
119
125
|
private revokeGrantsNaming;
|
|
120
126
|
/** Lock the company, then require dominance over each of its members (see `remove`). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"company-hierarchy.service.d.ts","sourceRoot":"","sources":["../../../src/features/company/company-hierarchy.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAkB,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"company-hierarchy.service.d.ts","sourceRoot":"","sources":["../../../src/features/company/company-hierarchy.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAkB,MAAM,mCAAmC,CAAC;AASxF,OAAO,EAA2B,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,6FAA6F;AAC7F,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnE;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,8BAA8B,CAC5B,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,aAAa,CAAC;QACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;QAChD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;KACrC,CAAC,GACD,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAqCD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAElD;AAED,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAPP,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,mBAAmB;IAC7C,2FAA2F;IAC1E,OAAO,EAAE,eAAe,EACxB,KAAK,CAAC,EAAE,SAAS,YAAA,EACjB,GAAG,GAAE,MAAM,MAAiB;IAC7C,mFAAmF;IAClE,OAAO,GAAE,mBAA+C;IAG3E,yDAAyD;IACzD,OAAO,CAAC,OAAO;IAIf;;;;;OAKG;YACW,UAAU;IAQxB,uDAAuD;YACzC,KAAK;YAUL,WAAW;IAqBzB,iGAAiG;IAC3F,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAoD3F;;;;;;;;;;;;;;;;;OAiBG;IACG,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB/D;;;;;;;;;;;;;;;;;;;;;;;OAuBG;YACW,gBAAgB;IAmF9B;;;;OAIG;YACW,eAAe;IA6B7B,0FAA0F;YAC5E,kBAAkB;IAmDhC,wFAAwF;YAC1E,sBAAsB;IAgCpC,wFAAwF;IAClF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGhD"}
|
|
@@ -6,6 +6,7 @@ const http_js_1 = require("../shared/http.js");
|
|
|
6
6
|
const grant_ceiling_js_1 = require("../authz/grant-ceiling.js");
|
|
7
7
|
const lock_service_accounts_js_1 = require("../service-account/lock-service-accounts.js");
|
|
8
8
|
const identity_errors_js_1 = require("../shared/identity-errors.js");
|
|
9
|
+
const role_owner_transition_js_1 = require("../role/role-owner-transition.js");
|
|
9
10
|
const schema_js_1 = require("../../schema.js");
|
|
10
11
|
/** A JSON-array column (the driver returns an array OR a string) → its string items; else []. */
|
|
11
12
|
function jsonIdArray(v) {
|
|
@@ -233,8 +234,26 @@ class CompanyHierarchyService {
|
|
|
233
234
|
});
|
|
234
235
|
}
|
|
235
236
|
await this.revokeGrantsNaming(conn, actor, nodeUuid, companyName);
|
|
237
|
+
await this.clearRoleOwners(conn, actor, nodeUuid, companyName);
|
|
236
238
|
return [...touched];
|
|
237
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Step 5 of {@link retireDependents} (G-009 T14, SPEC §5 v4): the roles the company owns become
|
|
242
|
+
* shared. Each owner is cleared through the audited `transitionRoleOwner` seam on the delete's
|
|
243
|
+
* connection (the FK's SET NULL would do it silently, without an audit row).
|
|
244
|
+
*/
|
|
245
|
+
async clearRoleOwners(conn, actor, nodeUuid, companyName) {
|
|
246
|
+
const owned = (await conn.query(`SELECT r_uuid, r_name FROM \`${this.schemas.app}\`.\`roles\` WHERE r_owner_company_uuid = ? ORDER BY r_uuid FOR UPDATE`, [nodeUuid]));
|
|
247
|
+
for (const role of owned) {
|
|
248
|
+
await (0, role_owner_transition_js_1.transitionRoleOwner)((sql, params) => conn.query(sql, params), role.r_uuid, nodeUuid, null, (action, attributes, query) => this.recordAudit({ query }, actor, action, {
|
|
249
|
+
eventType: 'role',
|
|
250
|
+
...attributes,
|
|
251
|
+
role: role.r_name,
|
|
252
|
+
company: companyName,
|
|
253
|
+
reason: 'company_deleted',
|
|
254
|
+
}), this.schemas);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
238
257
|
/** Step 4 of {@link retireDependents}: revoke and audit the grants naming the company. */
|
|
239
258
|
async revokeGrantsNaming(conn, actor, nodeUuid, companyName) {
|
|
240
259
|
const grants = (await conn.query(`SELECT ctg_uuid, ctg_owning_tenant_uuid, ctg_grantee_tenant_uuid, ctg_grantee_kind,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { type FrameworkSchemas } from '@astram/core';
|
|
3
|
-
import { type ObjectTypeInput } from '@astram/engine';
|
|
3
|
+
import { type EngineDbConfig, type ObjectTypeInput } from '@astram/engine';
|
|
4
4
|
/**
|
|
5
5
|
* The boot check behind {@link IDENTITY_DECISION_AUTHORITY_CHECK}: with this module wired, the
|
|
6
6
|
* request path must decide with the authority guard built from this module's inputs. A missing
|
|
@@ -30,6 +30,12 @@ export declare function assertFrameworkDatabaseAgrees(identityDatabase: string,
|
|
|
30
30
|
readonly database?: string;
|
|
31
31
|
};
|
|
32
32
|
} | null | undefined): true;
|
|
33
|
+
/**
|
|
34
|
+
* Map guard's DbConfig → the engine's EngineDbConfig (adds the pool cap the engine needs). The
|
|
35
|
+
* database and default user follow `schemas` (the names `forRoot` resolved or was given); an
|
|
36
|
+
* explicit `APP_DB_USER` / `APP_DB_NAME` still wins (QA P2-5).
|
|
37
|
+
*/
|
|
38
|
+
export declare function engineDbFromEnv(schemas: FrameworkSchemas, env?: NodeJS.ProcessEnv): EngineDbConfig;
|
|
33
39
|
/**
|
|
34
40
|
* IdentityFeatureModule — the framework-owned identity FEATURE surface (company/user/role CRUD;
|
|
35
41
|
* more in later phases) as thin controllers over the engine's RecordsService. The CONSUMER imports
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-feature.module.d.ts","sourceRoot":"","sources":["../../src/features/identity-feature.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,cAAc,CAAC;AACtB,OAAO,
|
|
1
|
+
{"version":3,"file":"identity-feature.module.d.ts","sourceRoot":"","sources":["../../src/features/identity-feature.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,cAAc,CAAC;AACtB,OAAO,EAYL,KAAK,cAAc,EAGnB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AA+GxB;;;;;;GAMG;AACH,wBAAgB,0CAA0C,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAUnF;AAKD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,GACzC,IAAI,CAwBN;AAKD;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,gBAAgB,EAAE,MAAM,EACxB,WAAW,EAAE;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GAC/E,IAAI,CAQN;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,gBAAgB,EACzB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,cAAc,CAqBhB;AAED;;;;;;;;;;GAUG;AACH,qBACa,qBAAqB;IAChC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,OAAO,CAAC,EACb,OAAO,EACP,YAAiB,EACjB,OAAO,EAAE,YAAY,GACtB,GAAE;QACD,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC5B,YAAY,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;QAC1C,OAAO,CAAC,EAAE,gBAAgB,CAAC;KACvB,GAAG,aAAa;CAqkBvB"}
|
|
@@ -11,11 +11,13 @@ exports.IdentityFeatureModule = void 0;
|
|
|
11
11
|
exports.assertRequestPathUsesIdentityAuthorization = assertRequestPathUsesIdentityAuthorization;
|
|
12
12
|
exports.assertFrameworkSchemasAgree = assertFrameworkSchemasAgree;
|
|
13
13
|
exports.assertFrameworkDatabaseAgrees = assertFrameworkDatabaseAgrees;
|
|
14
|
+
exports.engineDbFromEnv = engineDbFromEnv;
|
|
14
15
|
const common_1 = require("@nestjs/common");
|
|
15
16
|
const core_1 = require("@nestjs/core");
|
|
16
17
|
const core_2 = require("@astram/core");
|
|
17
18
|
const engine_1 = require("@astram/engine");
|
|
18
19
|
const guard_1 = require("@astram/guard");
|
|
20
|
+
const internal_1 = require("@astram/guard/internal");
|
|
19
21
|
const objects_js_1 = require("../objects.js");
|
|
20
22
|
const index_js_1 = require("./access/index.js");
|
|
21
23
|
const company_service_js_1 = require("./company/company.service.js");
|
|
@@ -25,7 +27,9 @@ const role_service_js_1 = require("./role/role.service.js");
|
|
|
25
27
|
const role_controller_js_1 = require("./role/role.controller.js");
|
|
26
28
|
const user_service_js_1 = require("./user/user.service.js");
|
|
27
29
|
const email_address_changer_token_js_1 = require("./user/email-address-changer.token.js");
|
|
30
|
+
const credential_provisioner_token_js_1 = require("./user/credential-provisioner.token.js");
|
|
28
31
|
const framework_schemas_token_js_1 = require("./framework-schemas.token.js");
|
|
32
|
+
const org_bootstrap_tokens_js_1 = require("./org-bootstrap/org-bootstrap.tokens.js");
|
|
29
33
|
const user_controller_js_1 = require("./user/user.controller.js");
|
|
30
34
|
const membership_controller_js_1 = require("./membership/membership.controller.js");
|
|
31
35
|
const membership_service_js_1 = require("./membership/membership.service.js");
|
|
@@ -107,7 +111,7 @@ const IDENTITY_FRAMEWORK_SCHEMAS_CHECK = Symbol('IDENTITY_FRAMEWORK_SCHEMAS_CHEC
|
|
|
107
111
|
* Throws (fail closed) with the namespaces and names only.
|
|
108
112
|
*/
|
|
109
113
|
function assertFrameworkSchemasAgree(identity, guard) {
|
|
110
|
-
const names = (s) => `namespace=${s.namespace} app=${s.app} identity=${s.identity} authz=${s.authz} audit=${s.audit}`;
|
|
114
|
+
const names = (s) => `namespace=${s.namespace} app=${s.app} identity=${s.identity} authz=${s.authz} audit=${s.audit} layout=${s.layout ?? 'four'}`;
|
|
111
115
|
if (guard === undefined || guard === null) {
|
|
112
116
|
if (identity.isDefault)
|
|
113
117
|
return true;
|
|
@@ -117,7 +121,8 @@ function assertFrameworkSchemasAgree(identity, guard) {
|
|
|
117
121
|
const same = identity.app === guard.app &&
|
|
118
122
|
identity.identity === guard.identity &&
|
|
119
123
|
identity.authz === guard.authz &&
|
|
120
|
-
identity.audit === guard.audit
|
|
124
|
+
identity.audit === guard.audit &&
|
|
125
|
+
(identity.layout ?? 'four') === (guard.layout ?? 'four');
|
|
121
126
|
if (!same) {
|
|
122
127
|
throw new Error(`IdentityFeatureModule: framework database names disagree — identity ${names(identity)}; ` +
|
|
123
128
|
`guard ${names(guard)}. Pass the same names (or none) to ShieldModule and ` +
|
|
@@ -147,8 +152,13 @@ function assertFrameworkDatabaseAgrees(identityDatabase, guardConfig) {
|
|
|
147
152
|
* database and default user follow `schemas` (the names `forRoot` resolved or was given); an
|
|
148
153
|
* explicit `APP_DB_USER` / `APP_DB_NAME` still wins (QA P2-5).
|
|
149
154
|
*/
|
|
150
|
-
function engineDbFromEnv(schemas) {
|
|
151
|
-
const db = (0, guard_1.loadDbConfig)(
|
|
155
|
+
function engineDbFromEnv(schemas, env = process.env) {
|
|
156
|
+
const db = (0, guard_1.loadDbConfig)(env, schemas);
|
|
157
|
+
// POOL_MAX_ENGINE, else APP_DB_MAX_CONNECTIONS, else 10; a set but invalid value throws naming
|
|
158
|
+
// the variable. Guard's single-layout pool budget parses these the same way.
|
|
159
|
+
const connectionLimit = (0, record_authorization_js_1.strictPoolSize)(env.POOL_MAX_ENGINE, 'POOL_MAX_ENGINE') ??
|
|
160
|
+
(0, record_authorization_js_1.strictPoolSize)(env.APP_DB_MAX_CONNECTIONS, 'APP_DB_MAX_CONNECTIONS') ??
|
|
161
|
+
10;
|
|
152
162
|
const ssl = (0, guard_1.mariadbSslOption)(db.tls);
|
|
153
163
|
return {
|
|
154
164
|
host: db.host,
|
|
@@ -158,7 +168,7 @@ function engineDbFromEnv(schemas) {
|
|
|
158
168
|
database: db.database,
|
|
159
169
|
// The engine's runtime CRUD pool cap. A conservative default; the app can raise it later via
|
|
160
170
|
// an explicit EngineModule.forRoot if it needs more. (ADR-0018 budget lives app-side.)
|
|
161
|
-
connectionLimit
|
|
171
|
+
connectionLimit,
|
|
162
172
|
// Phase 16: APP_DB_TLS / APP_DB_TLS_CA (production accounts are REQUIRE SSL).
|
|
163
173
|
...(ssl ? { ssl } : {}),
|
|
164
174
|
};
|
|
@@ -196,6 +206,8 @@ let IdentityFeatureModule = IdentityFeatureModule_1 = class IdentityFeatureModul
|
|
|
196
206
|
* differ from guard's `FRAMEWORK_SCHEMAS`. Never read per request.
|
|
197
207
|
*/
|
|
198
208
|
static forRoot({ rootIds, extraObjects = [], schemas: givenSchemas, } = {}) {
|
|
209
|
+
// G-009 N4: a reserved operation principal is never a root, whatever variable `rootIds` came from.
|
|
210
|
+
(0, guard_1.assertNoReservedRootId)(rootIds);
|
|
199
211
|
// The framework database names, resolved ONCE (boot) for every SQL path built below.
|
|
200
212
|
// Caller-supplied names are checked before any SQL is built (fail closed, Shield #1).
|
|
201
213
|
const schemas = givenSchemas !== undefined
|
|
@@ -578,9 +590,17 @@ let IdentityFeatureModule = IdentityFeatureModule_1 = class IdentityFeatureModul
|
|
|
578
590
|
provide: email_address_changer_token_js_1.IDENTITY_EMAIL_ADDRESS_CHANGER,
|
|
579
591
|
useValue: new guard_1.MariaDbEmailAddressChanger(authzPool, Date.now, schemas),
|
|
580
592
|
},
|
|
593
|
+
// G-009 T7 (OD-6): the locked-credential writer UserService runs on the create transaction.
|
|
594
|
+
{
|
|
595
|
+
provide: credential_provisioner_token_js_1.IDENTITY_CREDENTIAL_PROVISIONER,
|
|
596
|
+
useValue: new internal_1.MariaDbCredentialProvisioner(authzPool, Date.now, schemas),
|
|
597
|
+
},
|
|
581
598
|
// The same resolved names for identity services Nest constructs (UserService's
|
|
582
599
|
// email-change audit sink), never a second env read.
|
|
583
600
|
{ provide: framework_schemas_token_js_1.IDENTITY_FRAMEWORK_SCHEMAS, useValue: schemas },
|
|
601
|
+
// G-009 T10: the ONE shared authz pool, for the org bootstrap runner (named lock, state reads,
|
|
602
|
+
// claim and root-flag writes). Not exported; the runner reads it with `app.get({ strict: false })`.
|
|
603
|
+
{ provide: org_bootstrap_tokens_js_1.IDENTITY_AUTHZ_POOL, useValue: authzPool },
|
|
584
604
|
// ADR-0035 (GAPS #6): attach the guard's Redis permission-version cache to the ONE shared
|
|
585
605
|
// bumper, so every committed bump (postings, grants, hierarchy) is published to Redis,
|
|
586
606
|
// where gate 5 reads it. Provided by the auth surface under `auth: true` (through the
|
|
@@ -41,6 +41,15 @@ export declare class MembershipService {
|
|
|
41
41
|
* swallowed here). `createdBy` is stamped server-side (actorId-trusted).
|
|
42
42
|
*/
|
|
43
43
|
addMembership(actor: Principal, userUuid: string, companyUuid: string): Promise<RecordId>;
|
|
44
|
+
/**
|
|
45
|
+
* Add an ACTIVE membership for `(userUuid, companyUuid)` in one create (G-009 R4): a brand-new
|
|
46
|
+
* membership has no other active card to displace, so no create-then-activate pair. A
|
|
47
|
+
* membership for that pair already existing is an `IdentityConflictError`, from the pre-check
|
|
48
|
+
* and from the `(cm_user_uuid, cm_company_uuid)` unique index (the pre-check read is SQL-scoped
|
|
49
|
+
* and can miss a row for an operation-bound principal); the driver message is never echoed.
|
|
50
|
+
* Bumps the company's tenant. The reach checks of `addMembership` apply unchanged.
|
|
51
|
+
*/
|
|
52
|
+
addActiveMembership(actor: Principal, userUuid: string, companyUuid: string): Promise<RecordId>;
|
|
44
53
|
/** List a user's membership cards (tenant-scoped by the pipe). */
|
|
45
54
|
listMemberships(userUuid: string): Promise<readonly RecordView[]>;
|
|
46
55
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"membership.service.d.ts","sourceRoot":"","sources":["../../../src/features/membership/membership.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAwB,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE1F,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"membership.service.d.ts","sourceRoot":"","sources":["../../../src/features/membership/membership.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAwB,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE1F,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AASzD,qBACa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAGxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAQxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAXZ,OAAO,EAAE,cAAc,EAGvB,OAAO,EAAE,YAAY,EAQrB,WAAW,CAAC,GAAE,kBAAkB,GAAG,IAAI,aAAA;IAG1D;;;;OAIG;YACW,WAAW;IAQzB;;;;;;OAMG;YACW,WAAW;IAYzB;;;;;;OAMG;IACG,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAkB/F;;;;;;;OAOG;IACG,mBAAmB,CACvB,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,QAAQ,CAAC;IAwBpB,kEAAkE;IAC5D,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAKvE;;;;;;;;;;;;;;;;;OAiBG;IACG,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC1F;;;;OAIG;IACG,gBAAgB,CACpB,KAAK,EAAE,SAAS,EAChB,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC,IAAI,CAAC;IAchB;;;OAGG;IACG,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAYhF"}
|
|
@@ -30,6 +30,13 @@ const engine_1 = require("@astram/engine");
|
|
|
30
30
|
const posting_version_bump_js_1 = require("./posting-version-bump.js");
|
|
31
31
|
const identity_errors_js_1 = require("../shared/identity-errors.js");
|
|
32
32
|
const grant_ceiling_js_1 = require("../authz/grant-ceiling.js");
|
|
33
|
+
/** A driver duplicate-key error (errno 1062), recognised by errno/code only, never its message. */
|
|
34
|
+
function isDuplicateKey(err) {
|
|
35
|
+
if (typeof err !== 'object' || err === null)
|
|
36
|
+
return false;
|
|
37
|
+
const e = err;
|
|
38
|
+
return e.errno === 1062 || e.code === 'ER_DUP_ENTRY';
|
|
39
|
+
}
|
|
33
40
|
let MembershipService = class MembershipService {
|
|
34
41
|
records;
|
|
35
42
|
ceiling;
|
|
@@ -101,6 +108,39 @@ let MembershipService = class MembershipService {
|
|
|
101
108
|
fields: { userUuid, companyUuid, isActive: false, status: 'active' },
|
|
102
109
|
});
|
|
103
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Add an ACTIVE membership for `(userUuid, companyUuid)` in one create (G-009 R4): a brand-new
|
|
113
|
+
* membership has no other active card to displace, so no create-then-activate pair. A
|
|
114
|
+
* membership for that pair already existing is an `IdentityConflictError`, from the pre-check
|
|
115
|
+
* and from the `(cm_user_uuid, cm_company_uuid)` unique index (the pre-check read is SQL-scoped
|
|
116
|
+
* and can miss a row for an operation-bound principal); the driver message is never echoed.
|
|
117
|
+
* Bumps the company's tenant. The reach checks of `addMembership` apply unchanged.
|
|
118
|
+
*/
|
|
119
|
+
async addActiveMembership(actor, userUuid, companyUuid) {
|
|
120
|
+
if (actor.isRoot !== true) {
|
|
121
|
+
const user = await this.records.get('user', userUuid);
|
|
122
|
+
if (user === null)
|
|
123
|
+
throw new identity_errors_js_1.IdentityNotFoundError('User not found.');
|
|
124
|
+
}
|
|
125
|
+
const existing = await this.records.list('company_membership', { where: { userUuid } });
|
|
126
|
+
if (existing.rows.some((m) => m.fields?.companyUuid === companyUuid)) {
|
|
127
|
+
throw new identity_errors_js_1.IdentityConflictError('That user already has a membership in this company.');
|
|
128
|
+
}
|
|
129
|
+
let id;
|
|
130
|
+
try {
|
|
131
|
+
id = await this.records.create('company_membership', {
|
|
132
|
+
fields: { userUuid, companyUuid, isActive: true, status: 'active' },
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (isDuplicateKey(err)) {
|
|
137
|
+
throw new identity_errors_js_1.IdentityConflictError('That user already has a membership in this company.');
|
|
138
|
+
}
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
await this.bumpTenants([companyUuid]);
|
|
142
|
+
return id;
|
|
143
|
+
}
|
|
104
144
|
/** List a user's membership cards (tenant-scoped by the pipe). */
|
|
105
145
|
async listMemberships(userUuid) {
|
|
106
146
|
const page = await this.records.list('company_membership', { where: { userUuid } });
|
|
@@ -53,5 +53,23 @@ export declare class PostingService {
|
|
|
53
53
|
* runs BEFORE any write; the writes run in one transaction (see the file header).
|
|
54
54
|
*/
|
|
55
55
|
replacePostings(actor: Principal, membershipUuid: string, desired: readonly PostingInput[]): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Add postings to a membership WITHOUT touching the rest of its set (G-009 R4/R5): only tuples
|
|
58
|
+
* (role|department|branch) not already present are created; nothing is updated or deleted. The
|
|
59
|
+
* pre-checks, the in-transaction lock + re-check, the atomicity and the version bump are those
|
|
60
|
+
* of `replacePostings` (shared helpers). `opts.operationRoleIds` is forwarded to the ceiling
|
|
61
|
+
* calls (the org-bootstrap operation's declared roles). An inactive membership is refused.
|
|
62
|
+
*/
|
|
63
|
+
addPostings(actor: Principal, membershipUuid: string, toAdd: readonly PostingInput[], opts?: {
|
|
64
|
+
operationRoleIds?: ReadonlySet<string> | readonly string[];
|
|
65
|
+
}): Promise<void>;
|
|
66
|
+
private assertEveryRole;
|
|
67
|
+
/** The membership through the subtree read wall (404 when out of reach) and its company. */
|
|
68
|
+
private reachMembership;
|
|
69
|
+
/** Authority for ADDED postings (binding rule, ceiling, org units); returns the distinct roles. */
|
|
70
|
+
private assertMayAdd;
|
|
71
|
+
/** Lock each added role row on the transaction, then re-run the binding rule (review F2). */
|
|
72
|
+
private lockAndRecheck;
|
|
73
|
+
private bumpTenant;
|
|
56
74
|
}
|
|
57
75
|
//# sourceMappingURL=posting.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"posting.service.d.ts","sourceRoot":"","sources":["../../../src/features/membership/posting.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAwB,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC1F,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"posting.service.d.ts","sourceRoot":"","sources":["../../../src/features/membership/posting.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAwB,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC1F,OAAO,EAAE,YAAY,EAA6B,MAAM,2BAA2B,CAAC;AAOpF;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACzC;AA0ED,qBACa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAGxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAKxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;gBARZ,OAAO,EAAE,cAAc,EAGvB,OAAO,EAAE,YAAY,EAKrB,WAAW,CAAC,GAAE,kBAAkB,GAAG,IAAI,aAAA;IAG1D,gEAAgE;IAC1D,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAK1E;;;;;OAKG;IACG,eAAe,CACnB,KAAK,EAAE,SAAS,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,SAAS,YAAY,EAAE,GAC/B,OAAO,CAAC,IAAI,CAAC;IAyEhB;;;;;;OAMG;IACG,WAAW,CACf,KAAK,EAAE,SAAS,EAChB,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,IAAI,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,MAAM,EAAE,CAAA;KAAE,GACpE,OAAO,CAAC,IAAI,CAAC;IA2ChB,OAAO,CAAC,eAAe;IAQvB,4FAA4F;YAC9E,eAAe;IAY7B,mGAAmG;YACrF,YAAY;IAqB1B,6FAA6F;YAC/E,cAAc;YAYd,UAAU;CAkBzB"}
|