@astram/guard 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 (99) hide show
  1. package/dist/auth/auth.module.d.ts +8 -1
  2. package/dist/auth/auth.module.d.ts.map +1 -1
  3. package/dist/auth/auth.module.js +76 -31
  4. package/dist/authentication/mariadb-api-key-store.d.ts +10 -1
  5. package/dist/authentication/mariadb-api-key-store.d.ts.map +1 -1
  6. package/dist/authentication/mariadb-api-key-store.js +20 -10
  7. package/dist/authentication/mariadb-credential-resolver.d.ts +8 -1
  8. package/dist/authentication/mariadb-credential-resolver.d.ts.map +1 -1
  9. package/dist/authentication/mariadb-credential-resolver.js +15 -5
  10. package/dist/authentication/mariadb-credential-writer.d.ts +6 -1
  11. package/dist/authentication/mariadb-credential-writer.d.ts.map +1 -1
  12. package/dist/authentication/mariadb-credential-writer.js +9 -3
  13. package/dist/authentication/mariadb-email-address-changer.d.ts +10 -1
  14. package/dist/authentication/mariadb-email-address-changer.d.ts.map +1 -1
  15. package/dist/authentication/mariadb-email-address-changer.js +22 -9
  16. package/dist/authentication/mariadb-email-change-token-store.d.ts +8 -1
  17. package/dist/authentication/mariadb-email-change-token-store.d.ts.map +1 -1
  18. package/dist/authentication/mariadb-email-change-token-store.js +18 -9
  19. package/dist/authentication/mariadb-mfa-device-store.d.ts +6 -1
  20. package/dist/authentication/mariadb-mfa-device-store.d.ts.map +1 -1
  21. package/dist/authentication/mariadb-mfa-device-store.js +22 -13
  22. package/dist/authentication/mariadb-profile-resolver.d.ts +6 -1
  23. package/dist/authentication/mariadb-profile-resolver.d.ts.map +1 -1
  24. package/dist/authentication/mariadb-profile-resolver.js +12 -6
  25. package/dist/authentication/mariadb-profile-writer.d.ts +6 -1
  26. package/dist/authentication/mariadb-profile-writer.d.ts.map +1 -1
  27. package/dist/authentication/mariadb-profile-writer.js +11 -4
  28. package/dist/authentication/mariadb-recovery-code-store.d.ts +6 -1
  29. package/dist/authentication/mariadb-recovery-code-store.d.ts.map +1 -1
  30. package/dist/authentication/mariadb-recovery-code-store.js +11 -5
  31. package/dist/authentication/mariadb-reset-token-store.d.ts +6 -1
  32. package/dist/authentication/mariadb-reset-token-store.d.ts.map +1 -1
  33. package/dist/authentication/mariadb-reset-token-store.js +11 -5
  34. package/dist/authentication/mariadb-session-sweeper.d.ts +6 -1
  35. package/dist/authentication/mariadb-session-sweeper.d.ts.map +1 -1
  36. package/dist/authentication/mariadb-session-sweeper.js +11 -5
  37. package/dist/authz/cross-tenant-grant-writer.d.ts.map +1 -1
  38. package/dist/authz/cross-tenant-grant-writer.js +4 -3
  39. package/dist/authz/list-scope-sql.d.ts +10 -2
  40. package/dist/authz/list-scope-sql.d.ts.map +1 -1
  41. package/dist/authz/list-scope-sql.js +4 -4
  42. package/dist/authz/mariadb-cross-tenant-grant-adapter.d.ts.map +1 -1
  43. package/dist/authz/mariadb-cross-tenant-grant-adapter.js +4 -3
  44. package/dist/authz/mariadb-list-scope-adapter.d.ts.map +1 -1
  45. package/dist/authz/mariadb-list-scope-adapter.js +4 -3
  46. package/dist/authz/mariadb-policy-store.d.ts.map +1 -1
  47. package/dist/authz/mariadb-policy-store.js +4 -3
  48. package/dist/authz/mariadb-record-rule-adapter.d.ts.map +1 -1
  49. package/dist/authz/mariadb-record-rule-adapter.js +4 -3
  50. package/dist/authz/mariadb-record-share-adapter.d.ts.map +1 -1
  51. package/dist/authz/mariadb-record-share-adapter.js +4 -3
  52. package/dist/authz/record-share-cascade.d.ts.map +1 -1
  53. package/dist/authz/record-share-cascade.js +4 -3
  54. package/dist/authz/record-share-writer.d.ts.map +1 -1
  55. package/dist/authz/record-share-writer.js +4 -3
  56. package/dist/authz/wire-record-authorization.d.ts +8 -0
  57. package/dist/authz/wire-record-authorization.d.ts.map +1 -1
  58. package/dist/authz/wire-record-authorization.js +14 -6
  59. package/dist/boot/boot-sequence.d.ts +10 -0
  60. package/dist/boot/boot-sequence.d.ts.map +1 -1
  61. package/dist/boot/boot-sequence.js +47 -3
  62. package/dist/boot/migration-ledger-check.d.ts +94 -0
  63. package/dist/boot/migration-ledger-check.d.ts.map +1 -0
  64. package/dist/boot/migration-ledger-check.js +280 -0
  65. package/dist/boot/single-layout-probe.d.ts +66 -0
  66. package/dist/boot/single-layout-probe.d.ts.map +1 -0
  67. package/dist/boot/single-layout-probe.js +334 -0
  68. package/dist/config/app-config.d.ts +46 -3
  69. package/dist/config/app-config.d.ts.map +1 -1
  70. package/dist/config/app-config.js +90 -11
  71. package/dist/config/config.module.d.ts +7 -0
  72. package/dist/config/config.module.d.ts.map +1 -1
  73. package/dist/config/config.module.js +8 -1
  74. package/dist/config/framework-schema-names.d.ts +29 -0
  75. package/dist/config/framework-schema-names.d.ts.map +1 -0
  76. package/dist/config/framework-schema-names.js +41 -0
  77. package/dist/identity/permission-facts.adapter.d.ts +7 -1
  78. package/dist/identity/permission-facts.adapter.d.ts.map +1 -1
  79. package/dist/identity/permission-facts.adapter.js +15 -6
  80. package/dist/index.d.ts +5 -2
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +18 -2
  83. package/dist/module/shield.module.d.ts.map +1 -1
  84. package/dist/module/shield.module.js +43 -7
  85. package/dist/session/mariadb-session-record-store.d.ts +8 -1
  86. package/dist/session/mariadb-session-record-store.d.ts.map +1 -1
  87. package/dist/session/mariadb-session-record-store.js +23 -13
  88. package/dist/session/session-restriction-store.d.ts +8 -1
  89. package/dist/session/session-restriction-store.d.ts.map +1 -1
  90. package/dist/session/session-restriction-store.js +15 -5
  91. package/migrations/1710000000006-CreateAuthzSchema.cjs +15 -4
  92. package/migrations/1710000000007-ExtendPermissionAndRolePermission.cjs +11 -3
  93. package/migrations/1710000000008-CreateAccessBundleTables.cjs +14 -4
  94. package/migrations/1710000000009-CreateRecordPermissionRule.cjs +15 -4
  95. package/migrations/1710000000014-CreateRecordShare.cjs +15 -4
  96. package/migrations/1710000000015-CreateScopeClosure.cjs +14 -4
  97. package/migrations/1710000000016-AlterCompanyParentFkRestrict.cjs +20 -9
  98. package/migrations/1710000000017-CreateServiceAccountKey.cjs +14 -4
  99. package/package.json +3 -3
@@ -1,26 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MariaDbSessionRestrictionStore = void 0;
4
+ const framework_schema_names_js_1 = require("../config/framework-schema-names.js");
4
5
  /** MariaDB `ER_NO_SUCH_TABLE`. */
5
6
  const ER_NO_SUCH_TABLE = 1146;
6
7
  class MariaDbSessionRestrictionStore {
7
8
  pool;
8
- constructor(pool) {
9
+ /** `<identity>`.`session`. */
10
+ sessionTable;
11
+ /** `<app>`.`users`. */
12
+ usersTable;
13
+ constructor(pool,
14
+ /** Framework database names; absent ⇒ resolved from `SHIELD_DB_NAMESPACE` here, once. */
15
+ schemas) {
9
16
  this.pool = pool;
17
+ const s = (0, framework_schema_names_js_1.schemaNamesAtConstruction)(schemas);
18
+ this.sessionTable = (0, framework_schema_names_js_1.qualifiedTableName)(s.identity, 'session');
19
+ this.usersTable = (0, framework_schema_names_js_1.qualifiedTableName)(s.app, 'users');
10
20
  }
11
21
  async markMustReenroll(sessionId) {
12
- await this.pool.query('UPDATE `shield_identity`.`session` SET s_must_reenroll = 1 WHERE s_session_id = ?', [sessionId]);
22
+ await this.pool.query(`UPDATE ${this.sessionTable} SET s_must_reenroll = 1 WHERE s_session_id = ?`, [sessionId]);
13
23
  }
14
24
  async clearMustReenroll(sessionId) {
15
- await this.pool.query('UPDATE `shield_identity`.`session` SET s_must_reenroll = 0 WHERE s_session_id = ?', [sessionId]);
25
+ await this.pool.query(`UPDATE ${this.sessionTable} SET s_must_reenroll = 0 WHERE s_session_id = ?`, [sessionId]);
16
26
  }
17
27
  async rebuildFacts(sessionId, principalId) {
18
- const rows = (await this.pool.query('SELECT s_must_reenroll FROM `shield_identity`.`session` WHERE s_session_id = ? LIMIT 1', [sessionId]));
28
+ const rows = (await this.pool.query(`SELECT s_must_reenroll FROM ${this.sessionTable} WHERE s_session_id = ? LIMIT 1`, [sessionId]));
19
29
  // No row → treat as restricted (the caller also re-reads the session and refuses a missing one).
20
30
  const mustReenroll = rows[0] === undefined || Number(rows[0].s_must_reenroll) !== 0;
21
31
  let accountActive = true;
22
32
  try {
23
- const users = (await this.pool.query('SELECT u_status FROM `shield_app`.`users` WHERE u_uuid = ? LIMIT 1', [principalId]));
33
+ const users = (await this.pool.query(`SELECT u_status FROM ${this.usersTable} WHERE u_uuid = ? LIMIT 1`, [principalId]));
24
34
  if (users[0] !== undefined)
25
35
  accountActive = users[0].u_status === 'active';
26
36
  }
@@ -10,10 +10,19 @@
10
10
  * Idempotent (CREATE TABLE IF NOT EXISTS). No hard-coded UUIDs. Run by the DDL account.
11
11
  */
12
12
 
13
- const SCHEMA = 'shield_authz';
13
+ const { frameworkSchemasForMigration } = require('@astram/core');
14
+
15
+ // Database names come from `ctx.schemas` (SHIELD_DB_NAMESPACE, ADR-0037); under an older
16
+ // @astram/migrate without it, the default names apply only while the namespace is unset.
17
+ // replacesChecksums: every checksum this file had in a published release (git release tags), so
18
+ // an existing ledger row is accepted and updated, not reported as drift (ADR-0037).
19
+ const replacesChecksums = ['48b8c9616c73a05ad030cfbfeb8b9e447d74f59804dbd7d3d26850df16d9e07e'];
20
+
14
21
  const TS = 'TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP';
15
22
 
16
- async function up({ query }) {
23
+ async function up(ctx) {
24
+ const { query } = ctx;
25
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
17
26
  await query(`CREATE SCHEMA IF NOT EXISTS \`${SCHEMA}\` DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
18
27
 
19
28
  // permission — the grantable key catalog (perm_key is the stable identity).
@@ -44,10 +53,12 @@ async function up({ query }) {
44
53
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
45
54
  }
46
55
 
47
- async function down({ query }) {
56
+ async function down(ctx) {
57
+ const { query } = ctx;
58
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
48
59
  await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`role_permission\``);
49
60
  await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`authz_permission_version\``);
50
61
  await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`permission\``);
51
62
  }
52
63
 
53
- module.exports = { up, down };
64
+ module.exports = { up, down, replacesChecksums };
@@ -20,9 +20,17 @@
20
20
  * Run by the DDL account.
21
21
  */
22
22
 
23
- const SCHEMA = 'shield_authz';
23
+ const { frameworkSchemasForMigration } = require('@astram/core');
24
24
 
25
- async function up({ query }) {
25
+ // Database names come from `ctx.schemas` (SHIELD_DB_NAMESPACE, ADR-0037); under an older
26
+ // @astram/migrate without it, the default names apply only while the namespace is unset.
27
+ // replacesChecksums: every checksum this file had in a published release (git release tags), so
28
+ // an existing ledger row is accepted and updated, not reported as drift (ADR-0037).
29
+ const replacesChecksums = ['7c6733f7acb8dfc8ddc32d79aa3e19df1a424802d87e2a18c2b109a7a0b07f5d'];
30
+
31
+ async function up(ctx) {
32
+ const { query } = ctx;
33
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
26
34
  // permission — add the catalog columns astram3's MariaDbCatalogStore contract expects.
27
35
  await query(
28
36
  `ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_uuid VARCHAR(36) NULL`
@@ -63,4 +71,4 @@ async function down() {
63
71
  // reviewed follow-up migration — not an automatic DROP COLUMN in `down()`.
64
72
  }
65
73
 
66
- module.exports = { up, down };
74
+ module.exports = { up, down, replacesChecksums };
@@ -14,9 +14,17 @@
14
14
  * Idempotent (CREATE TABLE IF NOT EXISTS). Structural (no tenant gate). Run by the DDL account.
15
15
  */
16
16
 
17
- const SCHEMA = 'shield_authz';
17
+ const { frameworkSchemasForMigration } = require('@astram/core');
18
18
 
19
- async function up({ query }) {
19
+ // Database names come from `ctx.schemas` (SHIELD_DB_NAMESPACE, ADR-0037); under an older
20
+ // @astram/migrate without it, the default names apply only while the namespace is unset.
21
+ // replacesChecksums: every checksum this file had in a published release (git release tags), so
22
+ // an existing ledger row is accepted and updated, not reported as drift (ADR-0037).
23
+ const replacesChecksums = ['7537d160c1ce7890e2ddb29333fd48ca4a13c3d191af85e8bff601d41245488f'];
24
+
25
+ async function up(ctx) {
26
+ const { query } = ctx;
27
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
20
28
  await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`access_bundle\` (
21
29
  ab_uuid CHAR(36) NOT NULL,
22
30
  ab_key VARCHAR(120) NOT NULL,
@@ -40,10 +48,12 @@ async function up({ query }) {
40
48
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
41
49
  }
42
50
 
43
- async function down({ query }) {
51
+ async function down(ctx) {
52
+ const { query } = ctx;
53
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
44
54
  // FK order: drop the child (access_bundle_permission) before the parent (access_bundle).
45
55
  await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`access_bundle_permission\``);
46
56
  await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`access_bundle\``);
47
57
  }
48
58
 
49
- module.exports = { up, down };
59
+ module.exports = { up, down, replacesChecksums };
@@ -25,10 +25,19 @@
25
25
  * drops the table. Run by the DDL account.
26
26
  */
27
27
 
28
- const SCHEMA = 'shield_authz';
28
+ const { frameworkSchemasForMigration } = require('@astram/core');
29
+
30
+ // Database names come from `ctx.schemas` (SHIELD_DB_NAMESPACE, ADR-0037); under an older
31
+ // @astram/migrate without it, the default names apply only while the namespace is unset.
32
+ // replacesChecksums: every checksum this file had in a published release (git release tags), so
33
+ // an existing ledger row is accepted and updated, not reported as drift (ADR-0037).
34
+ const replacesChecksums = ['0e28b8f4682dea265dbd399d153f29c3f42c80e826dbe8bc5cbd3319fbdc4db3'];
35
+
29
36
  const TS = 'TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP';
30
37
 
31
- async function up({ query }) {
38
+ async function up(ctx) {
39
+ const { query } = ctx;
40
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
32
41
  await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`record_permission_rule\` (
33
42
  rpr_uuid VARCHAR(36) NOT NULL,
34
43
  rpr_policy_uuid VARCHAR(36) NULL, -- groups a guided policy's AND-composed condition-rows; NULL = legacy/unconditional single-row rule
@@ -49,8 +58,10 @@ async function up({ query }) {
49
58
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
50
59
  }
51
60
 
52
- async function down({ query }) {
61
+ async function down(ctx) {
62
+ const { query } = ctx;
63
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
53
64
  await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`record_permission_rule\``);
54
65
  }
55
66
 
56
- module.exports = { up, down };
67
+ module.exports = { up, down, replacesChecksums };
@@ -19,10 +19,19 @@
19
19
  * account. No FK to `record_permission_rule` — the two tables are independent.
20
20
  */
21
21
 
22
- const SCHEMA = 'shield_authz';
22
+ const { frameworkSchemasForMigration } = require('@astram/core');
23
+
24
+ // Database names come from `ctx.schemas` (SHIELD_DB_NAMESPACE, ADR-0037); under an older
25
+ // @astram/migrate without it, the default names apply only while the namespace is unset.
26
+ // replacesChecksums: every checksum this file had in a published release (git release tags), so
27
+ // an existing ledger row is accepted and updated, not reported as drift (ADR-0037).
28
+ const replacesChecksums = ['434236fcd1ef4c73a419674ebd757ce889a25c39744acb4db365a93c5230a844'];
29
+
23
30
  const TS = 'TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP';
24
31
 
25
- async function up({ query }) {
32
+ async function up(ctx) {
33
+ const { query } = ctx;
34
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
26
35
  await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`record_share\` (
27
36
  rs_uuid VARCHAR(36) NOT NULL,
28
37
  rs_tenant_uuid VARCHAR(36) NOT NULL, -- the tenant the shared record belongs to
@@ -42,8 +51,10 @@ async function up({ query }) {
42
51
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
43
52
  }
44
53
 
45
- async function down({ query }) {
54
+ async function down(ctx) {
55
+ const { query } = ctx;
56
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
46
57
  await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`record_share\``);
47
58
  }
48
59
 
49
- module.exports = { up, down };
60
+ module.exports = { up, down, replacesChecksums };
@@ -27,9 +27,17 @@
27
27
  * the Application schema).
28
28
  */
29
29
 
30
- const SCHEMA = 'shield_authz';
30
+ const { frameworkSchemasForMigration } = require('@astram/core');
31
31
 
32
- async function up({ query }) {
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
+ // replacesChecksums: every checksum this file had in a published release (git release tags), so
35
+ // an existing ledger row is accepted and updated, not reported as drift (ADR-0037).
36
+ const replacesChecksums = ['91be11b8677118a50f8a786c967cc2643ab4d5db48b5847acb57560634ab4591'];
37
+
38
+ async function up(ctx) {
39
+ const { query } = ctx;
40
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
33
41
  await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`scope_closure\` (
34
42
  ancestor_uuid VARCHAR(36) NOT NULL, -- a node (company) in the hierarchy
35
43
  descendant_uuid VARCHAR(36) NOT NULL, -- a node at or below the ancestor (self = depth 0)
@@ -39,8 +47,10 @@ async function up({ query }) {
39
47
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
40
48
  }
41
49
 
42
- async function down({ query }) {
50
+ async function down(ctx) {
51
+ const { query } = ctx;
52
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
43
53
  await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`scope_closure\``);
44
54
  }
45
55
 
46
- module.exports = { up, down };
56
+ module.exports = { up, down, replacesChecksums };
@@ -21,14 +21,21 @@
21
21
  * timestamp); `...016` sorts strictly after `...001`, so `companies` + its FK already exist.
22
22
  */
23
23
 
24
- const SCHEMA = 'shield_app';
24
+ const { frameworkSchemasForMigration } = require('@astram/core');
25
+
26
+ // Database names come from `ctx.schemas` (SHIELD_DB_NAMESPACE, ADR-0037); under an older
27
+ // @astram/migrate without it, the default names apply only while the namespace is unset.
28
+ // replacesChecksums: every checksum this file had in a published release (git release tags), so
29
+ // an existing ledger row is accepted and updated, not reported as drift (ADR-0037).
30
+ const replacesChecksums = ['4af1a570fa1e9d161bcac25087866baf1a3783e88df06db40f0a91be4ee590b4'];
31
+
25
32
  const TABLE = 'companies';
26
33
  const FK = 'FK_companies_parent';
27
34
  const COL = 'c_parent_uuid';
28
35
  const PK = 'c_uuid';
29
36
 
30
37
  /** True if a FK constraint of this name exists on the table (idempotency guard). */
31
- async function fkExists(query) {
38
+ async function fkExists(query, SCHEMA) {
32
39
  const rows = await query(
33
40
  `SELECT 1
34
41
  FROM information_schema.TABLE_CONSTRAINTS
@@ -42,15 +49,17 @@ async function fkExists(query) {
42
49
  return Array.isArray(rows) && rows.length > 0;
43
50
  }
44
51
 
45
- async function dropFkIfPresent(query) {
46
- if (await fkExists(query)) {
52
+ async function dropFkIfPresent(query, SCHEMA) {
53
+ if (await fkExists(query, SCHEMA)) {
47
54
  await query(`ALTER TABLE \`${SCHEMA}\`.\`${TABLE}\` DROP FOREIGN KEY \`${FK}\``);
48
55
  }
49
56
  }
50
57
 
51
- async function up({ query }) {
58
+ async function up(ctx) {
59
+ const { query } = ctx;
60
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).app;
52
61
  // Drop the existing SET NULL FK (if present), re-add it as RESTRICT.
53
- await dropFkIfPresent(query);
62
+ await dropFkIfPresent(query, SCHEMA);
54
63
  await query(
55
64
  `ALTER TABLE \`${SCHEMA}\`.\`${TABLE}\`
56
65
  ADD CONSTRAINT \`${FK}\` FOREIGN KEY (\`${COL}\`)
@@ -58,9 +67,11 @@ async function up({ query }) {
58
67
  );
59
68
  }
60
69
 
61
- async function down({ query }) {
70
+ async function down(ctx) {
71
+ const { query } = ctx;
72
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).app;
62
73
  // Restore the original SET NULL behavior.
63
- await dropFkIfPresent(query);
74
+ await dropFkIfPresent(query, SCHEMA);
64
75
  await query(
65
76
  `ALTER TABLE \`${SCHEMA}\`.\`${TABLE}\`
66
77
  ADD CONSTRAINT \`${FK}\` FOREIGN KEY (\`${COL}\`)
@@ -68,4 +79,4 @@ async function down({ query }) {
68
79
  );
69
80
  }
70
81
 
71
- module.exports = { up, down };
82
+ module.exports = { up, down, replacesChecksums };
@@ -15,9 +15,17 @@
15
15
  * `down` drops the table. Run by the DDL account.
16
16
  */
17
17
 
18
- const SCHEMA = 'shield_authz';
18
+ const { frameworkSchemasForMigration } = require('@astram/core');
19
19
 
20
- async function up({ query }) {
20
+ // Database names come from `ctx.schemas` (SHIELD_DB_NAMESPACE, ADR-0037); under an older
21
+ // @astram/migrate without it, the default names apply only while the namespace is unset.
22
+ // replacesChecksums: every checksum this file had in a published release (git release tags), so
23
+ // an existing ledger row is accepted and updated, not reported as drift (ADR-0037).
24
+ const replacesChecksums = ['8c591ca61982f183ba26fb2ce6df2f56068333713654ca1b1e27a70d5e6101e2'];
25
+
26
+ async function up(ctx) {
27
+ const { query } = ctx;
28
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
21
29
  await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`service_account_key\` (
22
30
  sak_account_id VARCHAR(36) NOT NULL, -- the <accountId> inside the ask_ key (= service_account.sa_id)
23
31
  sak_version INT NOT NULL, -- monotonic per account; rotation bumps it
@@ -34,8 +42,10 @@ async function up({ query }) {
34
42
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
35
43
  }
36
44
 
37
- async function down({ query }) {
45
+ async function down(ctx) {
46
+ const { query } = ctx;
47
+ const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
38
48
  await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`service_account_key\``);
39
49
  }
40
50
 
41
- module.exports = { up, down };
51
+ module.exports = { up, down, replacesChecksums };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astram/guard",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "license": "MIT",
5
5
  "description": "Astram framework — the enforcement guard + real-world adapters (the 'hands'). One global deny-by-default gate every request passes through (ADR-0002), classification decorators, boot-pool assertion (ADR-0018), the forRoot() registration seam, and the DB/Redis/crypto adapters that connect the sealed core to a real backend. Depends on @astram/core (ADR-0003, ADR-0023).",
6
6
  "type": "commonjs",
@@ -36,8 +36,8 @@
36
36
  "argon2": "^0.41.1",
37
37
  "ioredis": "^5.4.1",
38
38
  "mariadb": "^3.5.4",
39
- "@astram/core": "1.6.0",
40
- "@astram/engine": "0.7.0"
39
+ "@astram/core": "1.8.0",
40
+ "@astram/engine": "0.9.0"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@nestjs/common": "^11",