@astram/identity 0.14.0 → 0.16.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.
Files changed (39) hide show
  1. package/dist/features/identity-feature.module.d.ts +7 -1
  2. package/dist/features/identity-feature.module.d.ts.map +1 -1
  3. package/dist/features/identity-feature.module.js +33 -1
  4. package/dist/features/org-bootstrap/run-org-bootstrap.d.ts +19 -0
  5. package/dist/features/org-bootstrap/run-org-bootstrap.d.ts.map +1 -1
  6. package/dist/features/org-bootstrap/run-org-bootstrap.js +96 -10
  7. package/dist/features/org-bootstrap/set-password-links.d.ts +14 -2
  8. package/dist/features/org-bootstrap/set-password-links.d.ts.map +1 -1
  9. package/dist/features/org-bootstrap/set-password-links.js +25 -4
  10. package/dist/features/user/invite-message.d.ts +8 -0
  11. package/dist/features/user/invite-message.d.ts.map +1 -0
  12. package/dist/features/user/invite-message.js +23 -0
  13. package/dist/features/user/invite.config.d.ts +15 -0
  14. package/dist/features/user/invite.config.d.ts.map +1 -0
  15. package/dist/features/user/invite.config.js +55 -0
  16. package/dist/features/user/invite.service.d.ts +62 -0
  17. package/dist/features/user/invite.service.d.ts.map +1 -0
  18. package/dist/features/user/invite.service.js +254 -0
  19. package/dist/features/user/invite.tokens.d.ts +11 -0
  20. package/dist/features/user/invite.tokens.d.ts.map +1 -0
  21. package/dist/features/user/invite.tokens.js +13 -0
  22. package/dist/features/user/user.controller.d.ts +12 -3
  23. package/dist/features/user/user.controller.d.ts.map +1 -1
  24. package/dist/features/user/user.controller.js +28 -2
  25. package/dist/features/user/user.service.d.ts +25 -7
  26. package/dist/features/user/user.service.d.ts.map +1 -1
  27. package/dist/features/user/user.service.js +53 -17
  28. package/dist/index.d.ts +7 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/user.object.d.ts.map +1 -1
  31. package/dist/user.object.js +3 -0
  32. package/migrations/1710000000102-CreateAuditChain.cjs +71 -0
  33. package/package.json +9 -4
  34. package/dist/features/org-bootstrap/org-bootstrap-runner.harness.d.ts +0 -259
  35. package/dist/features/org-bootstrap/org-bootstrap-runner.harness.d.ts.map +0 -1
  36. package/dist/features/org-bootstrap/org-bootstrap-runner.harness.js +0 -604
  37. package/dist/features/org-bootstrap/org-bootstrap-runner.mocks.d.ts +0 -24
  38. package/dist/features/org-bootstrap/org-bootstrap-runner.mocks.d.ts.map +0 -1
  39. package/dist/features/org-bootstrap/org-bootstrap-runner.mocks.js +0 -39
@@ -54,6 +54,9 @@ exports.User = User = __decorate([
54
54
  // capped root, the identity administrator, may list/read AND create/update/delete users). Uniform
55
55
  // across all actions (read reclassified control 2026-07-16), so plane is per-type.
56
56
  access: { plane: 'control', system: true },
57
+ // G-010 R11 (ADR-0038): `invite` (`identity:user:invite`, POST /identity/users/:uuid/invite) next
58
+ // to CRUD. Roles holding `identity:*` or `identity:user:*` gain it on upgrade; exact keys do not.
59
+ actions: ['invite'],
57
60
  // Read-scope wall (ADR-0027, Task 4.1): a user has no company column (they belong to many
58
61
  // companies via `company_membership`) — a user is in-scope iff they have a membership in
59
62
  // the caller's reachable subtree. A multi-tenant user correctly appears for each subtree
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Framework audit migration — the durable hash chain over `audit_log` (audit-chain-store SPEC §4.A,
3
+ * §4.B; Layer 9 reopened, STATUS G3). Both tables live in the audit database (`<ns>_audit`, default
4
+ * `shield_audit`), created by 1710000000010; this migration owns only the two tables.
5
+ * `audit_log` is NOT altered.
6
+ *
7
+ * `audit_chain` — one row per sealed `audit_log` row: per-tenant dense `ac_sequence` from 0, the
8
+ * row's content hash, the previous entry hash (`GENESIS` or the prior `ac_entry_hash`) and its own
9
+ * entry hash. `ac_occurred_at_ms` is an unhashed copy of `al_occurred_at_ms` (sealer window, prune
10
+ * prefix; `audit:verify` checks it); `ac_sealed_at_ms` is the sealer clock. PK (tenant, sequence) is
11
+ * the Layer-9 unique key; UNIQUE `ac_al_uuid` seals a row at most once; `idx_ac_occurred` serves the
12
+ * sealer's window start.
13
+ *
14
+ * `audit_chain_checkpoint` — one row per pruned batch (written only by `prune_audit`): the last
15
+ * pruned sequence and its entry hash, so verification can anchor after a prune.
16
+ *
17
+ * Collation: every tenant and uuid column is `utf8mb4_nopad_bin` (binary AND no pad), so `T1`, `t1`
18
+ * and `T1 ` are three tenants, exactly as in Node and `verifyChain`. Never `utf8mb4_bin` (PAD SPACE).
19
+ * Hash and run-id columns are `ascii_bin`. The table default collation is also `utf8mb4_nopad_bin`,
20
+ * so a character column added later without an explicit COLLATE keeps exact-byte semantics instead
21
+ * of silently folding case or trailing spaces. Comparisons against `audit_log`
22
+ * (`utf8mb4_unicode_ci`) must write `COLLATE utf8mb4_nopad_bin` on the `audit_log` side.
23
+ *
24
+ * Append-only: no code path UPDATEs or DELETEs these tables except `prune_audit` (definer).
25
+ * Idempotent (CREATE TABLE IF NOT EXISTS); `down` drops both (DROP TABLE IF EXISTS). No FK to
26
+ * `audit_log` (prune deletes rows in both under its own rules; a chain row whose `audit_log` row is
27
+ * gone is evidence for `audit:verify`). No seed, no hard-coded ids.
28
+ */
29
+
30
+ const { frameworkSchemasForMigration } = require('@astram/core');
31
+
32
+ // Database names come from `ctx.schemas` (SHIELD_DB_NAMESPACE, ADR-0037); under an older
33
+ // @astram/migrate without it, the default names apply only while the namespace is unset.
34
+
35
+ async function up(ctx) {
36
+ const { query } = ctx;
37
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).audit;
38
+
39
+ await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`audit_chain\` (
40
+ ac_tenant_id VARCHAR(64) COLLATE utf8mb4_nopad_bin NOT NULL,
41
+ ac_sequence BIGINT UNSIGNED NOT NULL,
42
+ ac_al_uuid VARCHAR(36) COLLATE utf8mb4_nopad_bin NOT NULL,
43
+ ac_content_hash CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
44
+ ac_prev_hash VARCHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
45
+ ac_entry_hash CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
46
+ ac_occurred_at_ms BIGINT NOT NULL,
47
+ ac_sealed_at_ms BIGINT NOT NULL,
48
+ PRIMARY KEY (ac_tenant_id, ac_sequence),
49
+ UNIQUE KEY uq_ac_al_uuid (ac_al_uuid),
50
+ INDEX idx_ac_occurred (ac_occurred_at_ms)
51
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_nopad_bin`);
52
+
53
+ await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`audit_chain_checkpoint\` (
54
+ acc_tenant_id VARCHAR(64) COLLATE utf8mb4_nopad_bin NOT NULL,
55
+ acc_sequence BIGINT UNSIGNED NOT NULL,
56
+ acc_entry_hash CHAR(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
57
+ acc_pruned_at_ms BIGINT NOT NULL,
58
+ acc_run_id VARCHAR(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
59
+ acc_acknowledged_sequence BIGINT UNSIGNED NULL,
60
+ PRIMARY KEY (acc_tenant_id, acc_sequence)
61
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_nopad_bin`);
62
+ }
63
+
64
+ async function down(ctx) {
65
+ const { query } = ctx;
66
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).audit;
67
+ await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`audit_chain_checkpoint\``);
68
+ await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`audit_chain\``);
69
+ }
70
+
71
+ module.exports = { up, down };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astram/identity",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "license": "MIT",
5
5
  "description": "Astram framework — the framework-owned identity + tenancy model. Hosts the identity @ObjectType classes (user, company, membership, posting), framework-authored identity migrations, and the identity resolver. Top of the dependency graph: depends on @astram/engine (for @ObjectType/@Field decorators) + @astram/guard / @astram/core (for the auth ports).",
6
6
  "type": "commonjs",
@@ -36,9 +36,9 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "mariadb": "^3.5.4",
39
- "@astram/core": "1.8.0",
40
- "@astram/engine": "0.10.0",
41
- "@astram/guard": "0.17.0"
39
+ "@astram/core": "1.10.0",
40
+ "@astram/engine": "0.10.2",
41
+ "@astram/guard": "0.19.0"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "@nestjs/common": "^11",
@@ -61,6 +61,11 @@
61
61
  "unplugin-swc": "^1.5.1",
62
62
  "vitest": "^2.1.8"
63
63
  },
64
+ "repository": {
65
+ "type": "git",
66
+ "url": "git+https://github.com/ASTRAM-2-0/astram-framework.git",
67
+ "directory": "packages/identity"
68
+ },
64
69
  "scripts": {
65
70
  "build": "tsc -p tsconfig.build.json",
66
71
  "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
@@ -1,259 +0,0 @@
1
- import type { Principal } from '@astram/core';
2
- import { current } from './org-bootstrap-runner.mocks.js';
3
- import type { OrgState } from './org-bootstrap-plan.js';
4
- export declare const SCHEMAS: {
5
- readonly namespace: "zzns";
6
- readonly app: "zzns_app";
7
- readonly identity: "zzns_identity";
8
- readonly authz: "zzns_authz";
9
- readonly audit: "zzns_audit";
10
- readonly isDefault: false;
11
- };
12
- export declare const PW = "Zq-root-pass-1";
13
- export declare const OPERATOR = "op.person@example.test";
14
- export declare const BASE = "https://app.example.test/reset-password";
15
- export declare const DEFAULT_DEV_BASE = "http://localhost:5173/reset-password";
16
- export declare const LOCK_NAME = "astram_org_bootstrap:zzns_app";
17
- export declare const ROOT_PW_VAR = "ASTRAM_BOOTSTRAP_ROOT_PASSWORD_ZROOT";
18
- /** Env of a development/test run that would pass every refusal. */
19
- export declare const TEST_ENV: Record<string, string>;
20
- /** Env of a production run; the root password must be secret-ref resolved (the spec adds ROOT_PW_VAR to its hoisted secretRefs set). */
21
- export declare const PROD_ENV: Record<string, string>;
22
- /** Fresh-database file: 1 root, 2 companies, 1 dept, 1 branch, 3 roles, 3 non-root users. */
23
- export declare const FILE_MAIN: {
24
- version: number;
25
- roots: {
26
- username: string;
27
- email: string;
28
- homeCompany: string;
29
- }[];
30
- tenants: {
31
- name: string;
32
- departments: string[];
33
- branches: string[];
34
- roles: {
35
- name: string;
36
- permissions: string[];
37
- }[];
38
- users: ({
39
- username: string;
40
- email: string;
41
- postings: {
42
- role: string;
43
- department: string;
44
- branch: string;
45
- }[];
46
- } | {
47
- username: string;
48
- email: string;
49
- postings?: never;
50
- })[];
51
- children: {
52
- name: string;
53
- roles: {
54
- name: string;
55
- permissions: never[];
56
- }[];
57
- users: {
58
- username: string;
59
- email: string;
60
- postings: {
61
- role: string;
62
- }[];
63
- }[];
64
- }[];
65
- }[];
66
- };
67
- /** Two tenants: used to prove `operationRoleIds` never reach across tenants. */
68
- export declare const FILE_TWO_TENANTS: {
69
- version: number;
70
- roots: {
71
- username: string;
72
- email: string;
73
- homeCompany: string;
74
- }[];
75
- tenants: {
76
- name: string;
77
- roles: {
78
- name: string;
79
- permissions: never[];
80
- }[];
81
- users: {
82
- username: string;
83
- email: string;
84
- postings: {
85
- role: string;
86
- }[];
87
- }[];
88
- }[];
89
- };
90
- /** One tenant already holding everything: the state below makes every entry `unchanged`. */
91
- export declare const FILE_MINI: {
92
- version: number;
93
- roots: {
94
- username: string;
95
- email: string;
96
- homeCompany: string;
97
- }[];
98
- tenants: {
99
- name: string;
100
- roles: {
101
- name: string;
102
- permissions: string[];
103
- }[];
104
- users: {
105
- username: string;
106
- email: string;
107
- postings: {
108
- role: string;
109
- }[];
110
- }[];
111
- }[];
112
- };
113
- /** A tenant with one user whose membership does not exist yet (for the "existing user" cases). */
114
- export declare const FILE_DAVE: {
115
- version: number;
116
- roots: {
117
- username: string;
118
- email: string;
119
- homeCompany: string;
120
- }[];
121
- tenants: {
122
- name: string;
123
- roles: {
124
- name: string;
125
- permissions: never[];
126
- }[];
127
- users: {
128
- username: string;
129
- email: string;
130
- postings: {
131
- role: string;
132
- }[];
133
- }[];
134
- }[];
135
- };
136
- export declare const emptyState: () => OrgState;
137
- type Cred = 'none' | 'locked' | 'usable';
138
- /** The state that makes FILE_MINI entirely `unchanged`, alice's credential as given. */
139
- export declare function stateMini(aliceCredential?: Cred): OrgState;
140
- export interface Call {
141
- seq: number;
142
- service: string;
143
- method: string;
144
- args: unknown[];
145
- /** The principal registered on the resolve context (request-scoped services), if any. */
146
- principal: Principal | undefined;
147
- /** The bootstrap principal passed as an explicit argument, if any. */
148
- actor: Principal | undefined;
149
- }
150
- export interface Query {
151
- conn: string;
152
- sql: string;
153
- params: unknown[];
154
- }
155
- export type Row = Record<string, unknown>;
156
- export interface World {
157
- app: FakeApp;
158
- state: OrgState;
159
- out: string[];
160
- outFn: (line: string) => void;
161
- events: string[];
162
- calls: Call[];
163
- queries: Query[];
164
- transitions: unknown[][];
165
- issued: {
166
- principalId: string;
167
- hash: string;
168
- expiresAtMs: number;
169
- }[];
170
- invalidated: string[];
171
- provisionedLocked: {
172
- principalId: string;
173
- hint: string;
174
- tenantId: string;
175
- }[];
176
- provisionedPassword: {
177
- principalId: string;
178
- hint: string;
179
- tenantId: string;
180
- password: string;
181
- }[];
182
- conns: FakeConn[];
183
- readerCalls: number;
184
- lockMode: 'acquired' | 'busy';
185
- failOn: ((service: string, method: string, args: unknown[]) => Error | undefined) | undefined;
186
- failTransition: Error | undefined;
187
- /** Throws for a matching statement (e.g. the audit INSERT), on whichever connection runs it. */
188
- failQuery: ((connId: string, sql: string, params: unknown[]) => Error | undefined) | undefined;
189
- /** Whether a posting outside the file's tenants holds the role being claimed (R1-8 re-check). */
190
- roleHeldOutside: boolean;
191
- id: (kind: string, name: string) => string;
192
- tables: Record<string, Row[]>;
193
- }
194
- export interface FakeConn {
195
- id: string;
196
- released: boolean;
197
- log: string[];
198
- query: (sql: string, params?: unknown[]) => Promise<unknown>;
199
- beginTransaction: () => Promise<void>;
200
- commit: () => Promise<void>;
201
- rollback: () => Promise<void>;
202
- release: () => Promise<void>;
203
- end: () => Promise<void>;
204
- }
205
- export { current };
206
- export declare class FakeApp {
207
- private readonly singletons;
208
- private readonly scoped;
209
- initCalls: number;
210
- readonly requests: Map<object, {
211
- principal?: Principal;
212
- }>;
213
- readonly resolved: {
214
- token: unknown;
215
- principal: Principal | undefined;
216
- }[];
217
- constructor(singletons: Map<unknown, unknown>, scoped: Map<unknown, (principal: Principal | undefined) => object>);
218
- init(): Promise<this>;
219
- get(token: unknown, _options?: unknown): unknown;
220
- registerRequestByContextId(request: {
221
- principal?: Principal;
222
- }, contextId: object): void;
223
- resolve(token: unknown, contextId: object, _options?: unknown): Promise<unknown>;
224
- }
225
- export interface WorldOptions {
226
- /** `IDENTITY_AUTHZ_POOL`, imported from `./org-bootstrap.tokens.js` by the spec. */
227
- poolToken: unknown;
228
- /** false = IdentityFeatureModule is not wired: `app.get` / `app.resolve` find nothing. */
229
- wired?: boolean;
230
- state?: OrgState;
231
- tables?: Record<string, Row[]>;
232
- lockMode?: 'acquired' | 'busy';
233
- memberships?: {
234
- id: string;
235
- userUuid: string;
236
- companyUuid: string;
237
- }[];
238
- failOn?: World['failOn'];
239
- }
240
- export declare function makeWorld(options: WorldOptions): World;
241
- export declare const sha256: (s: string) => string;
242
- export declare const isWriteCall: (c: Call) => boolean;
243
- export declare const writeCalls: (w: World) => Call[];
244
- export declare const callsOf: (w: World, service: string, method: string) => Call[];
245
- /** Every non-audit write the runner could make is absent. Lock and SELECT traffic is allowed. */
246
- export declare function noWritesAtAll(w: World): string[];
247
- /** Lock discipline: every GET_LOCK ran on a dedicated connection and was released on that one. */
248
- export declare function lockProblems(w: World): string[];
249
- /** Everything the run said or stored that must never carry a secret. Provisioner args excluded. */
250
- export declare function visibleText(w: World, extra?: unknown[]): string;
251
- /** The raw token of the link printed for `username` (a line with the name and `<base>?token=<hex>`). */
252
- export declare function linkFor(w: World, username: string): {
253
- raw: string;
254
- line: string;
255
- } | undefined;
256
- export declare const linkLines: (w: World) => string[];
257
- /** The audit rows (INSERTs into audit_log) naming `action`, from any connection. */
258
- export declare const auditRowsFor: (w: World, action: string) => Query[];
259
- //# sourceMappingURL=org-bootstrap-runner.harness.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"org-bootstrap-runner.harness.d.ts","sourceRoot":"","sources":["../../../src/features/org-bootstrap/org-bootstrap-runner.harness.ts"],"names":[],"mappings":"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"}