@astram/guard 0.4.0 → 0.5.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 (64) hide show
  1. package/dist/auth/auth.module.d.ts +6 -0
  2. package/dist/auth/auth.module.d.ts.map +1 -1
  3. package/dist/auth/auth.module.js +106 -15
  4. package/dist/auth/tokens.d.ts +9 -0
  5. package/dist/auth/tokens.d.ts.map +1 -1
  6. package/dist/auth/tokens.js +10 -1
  7. package/dist/authentication/log-email-sender.d.ts +13 -0
  8. package/dist/authentication/log-email-sender.d.ts.map +1 -0
  9. package/dist/authentication/log-email-sender.js +13 -0
  10. package/dist/authentication/mariadb-credential-writer.d.ts +16 -0
  11. package/dist/authentication/mariadb-credential-writer.d.ts.map +1 -0
  12. package/dist/authentication/mariadb-credential-writer.js +19 -0
  13. package/dist/authentication/mariadb-mfa-device-store.d.ts +16 -0
  14. package/dist/authentication/mariadb-mfa-device-store.d.ts.map +1 -0
  15. package/dist/authentication/mariadb-mfa-device-store.js +99 -0
  16. package/dist/authentication/mariadb-or-totp-verifier.d.ts +31 -0
  17. package/dist/authentication/mariadb-or-totp-verifier.d.ts.map +1 -0
  18. package/dist/authentication/mariadb-or-totp-verifier.js +48 -0
  19. package/dist/authentication/mariadb-profile-resolver.d.ts +24 -0
  20. package/dist/authentication/mariadb-profile-resolver.d.ts.map +1 -0
  21. package/dist/authentication/mariadb-profile-resolver.js +54 -0
  22. package/dist/authentication/mariadb-profile-writer.d.ts +18 -0
  23. package/dist/authentication/mariadb-profile-writer.d.ts.map +1 -0
  24. package/dist/authentication/mariadb-profile-writer.js +36 -0
  25. package/dist/authentication/mariadb-recovery-code-store.d.ts +47 -0
  26. package/dist/authentication/mariadb-recovery-code-store.d.ts.map +1 -0
  27. package/dist/authentication/mariadb-recovery-code-store.js +53 -0
  28. package/dist/authentication/mariadb-reset-token-store.d.ts +26 -0
  29. package/dist/authentication/mariadb-reset-token-store.d.ts.map +1 -0
  30. package/dist/authentication/mariadb-reset-token-store.js +43 -0
  31. package/dist/authentication/mariadb-session-sweeper.d.ts +33 -0
  32. package/dist/authentication/mariadb-session-sweeper.d.ts.map +1 -0
  33. package/dist/authentication/mariadb-session-sweeper.js +60 -0
  34. package/dist/config/app-config.d.ts +5 -7
  35. package/dist/config/app-config.d.ts.map +1 -1
  36. package/dist/config/app-config.js +24 -57
  37. package/dist/identity/auth-facts.controller.d.ts +24 -0
  38. package/dist/identity/auth-facts.controller.d.ts.map +1 -0
  39. package/dist/identity/auth-facts.controller.js +106 -0
  40. package/dist/identity/identity-actions.d.ts +22 -0
  41. package/dist/identity/identity-actions.d.ts.map +1 -0
  42. package/dist/identity/identity-actions.js +32 -0
  43. package/dist/identity/module-registry.bridge.d.ts +4 -0
  44. package/dist/identity/module-registry.bridge.d.ts.map +1 -0
  45. package/dist/identity/module-registry.bridge.js +43 -0
  46. package/dist/identity/permission-facts.adapter.d.ts +47 -0
  47. package/dist/identity/permission-facts.adapter.d.ts.map +1 -0
  48. package/dist/identity/permission-facts.adapter.js +108 -0
  49. package/dist/index.d.ts +3 -0
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +20 -2
  52. package/dist/migrations-dir.d.ts +2 -0
  53. package/dist/migrations-dir.d.ts.map +1 -0
  54. package/dist/migrations-dir.js +13 -0
  55. package/dist/module/shield-tokens.d.ts +6 -1
  56. package/dist/module/shield-tokens.d.ts.map +1 -1
  57. package/dist/module/shield-tokens.js +7 -1
  58. package/dist/module/shield.module.d.ts +17 -0
  59. package/dist/module/shield.module.d.ts.map +1 -1
  60. package/dist/module/shield.module.js +12 -0
  61. package/migrations/1710000000006-CreateAuthzSchema.cjs +53 -0
  62. package/migrations/1710000000007-ExtendPermissionAndRolePermission.cjs +66 -0
  63. package/migrations/1710000000008-CreateAccessBundleTables.cjs +49 -0
  64. package/package.json +5 -3
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Framework authz migration — the shield_authz backing tables (empty until now):
3
+ * permission — grantable permission-key catalog.
4
+ * role_permission — role→permission grants (exact OR wildcard key strings).
5
+ * authz_permission_version — per-tenant permission-version counter (ADR-0011 freshness).
6
+ *
7
+ * shield_authz is @astram/guard's OWN schema (its decision adapters read it). Shipped here
8
+ * (not @astram/identity) to keep the package boundary: identity owns the org model, guard owns
9
+ * authz. Literal column names (NOT in the @astram/identity object registry — no reflectObjectType).
10
+ * Idempotent (CREATE TABLE IF NOT EXISTS). No hard-coded UUIDs. Run by the DDL account.
11
+ */
12
+
13
+ const SCHEMA = 'shield_authz';
14
+ const TS = 'TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP';
15
+
16
+ async function up({ query }) {
17
+ await query(`CREATE SCHEMA IF NOT EXISTS \`${SCHEMA}\` DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
18
+
19
+ // permission — the grantable key catalog (perm_key is the stable identity).
20
+ await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`permission\` (
21
+ perm_key VARCHAR(191) NOT NULL,
22
+ perm_description VARCHAR(255) NULL,
23
+ perm_created_at ${TS},
24
+ PRIMARY KEY (perm_key)
25
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
26
+
27
+ // role_permission — role→permission grants (exact or wildcard key strings).
28
+ await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`role_permission\` (
29
+ rp_uuid VARCHAR(36) NOT NULL,
30
+ rp_role_uuid VARCHAR(36) NOT NULL,
31
+ rp_perm_key VARCHAR(191) NOT NULL,
32
+ rp_created_by VARCHAR(36) NULL,
33
+ rp_created_at ${TS},
34
+ PRIMARY KEY (rp_uuid),
35
+ UNIQUE KEY uq_role_perm (rp_role_uuid, rp_perm_key),
36
+ INDEX idx_rp_role (rp_role_uuid)
37
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
38
+
39
+ // authz_permission_version — per-tenant version counter (ADR-0011 freshness).
40
+ await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`authz_permission_version\` (
41
+ apv_tenant_uuid VARCHAR(36) NOT NULL,
42
+ apv_version BIGINT NOT NULL DEFAULT 0,
43
+ PRIMARY KEY (apv_tenant_uuid)
44
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
45
+ }
46
+
47
+ async function down({ query }) {
48
+ await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`role_permission\``);
49
+ await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`authz_permission_version\``);
50
+ await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`permission\``);
51
+ }
52
+
53
+ module.exports = { up, down };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Framework authz migration — extends the shield_authz.permission catalog + role_permission
3
+ * grant rows to the full column set the grant-admin service (Phase 4) needs.
4
+ *
5
+ * The framework's `1710000000006-CreateAuthzSchema` created `permission` with only
6
+ * (perm_key, perm_description, perm_created_at) and `role_permission` with
7
+ * (rp_uuid, rp_role_uuid, rp_perm_key, rp_created_by, rp_created_at). This migration is
8
+ * ADDITIVE — it never touches those existing columns — and brings `permission` up to
9
+ * astram3's catalog shape (perm_uuid/module/type_key/action/label/tier + perm_status for the
10
+ * MariaDbCatalogStore contract) and adds `rp_granted_by`/`rp_granted_at` to `role_permission`
11
+ * (the grant-admin service's own attribution columns, alongside the pre-existing rp_created_*).
12
+ *
13
+ * Idempotent: every ADD is `ADD COLUMN IF NOT EXISTS` (MariaDB-supported), so this is a clean
14
+ * no-op against a DB that already has these columns (e.g. astram4's live DB). `perm_uuid` is
15
+ * added as a plain nullable column — NOT a new primary key — since `permission` already has a
16
+ * populated PK (perm_key) and changing the PK of an existing table is out of scope here; the
17
+ * reconciler backfills perm_uuid + the other NOT NULL DEFAULT '' text columns with real values.
18
+ *
19
+ * Literal column names (NOT in the @astram/identity object registry — no reflectObjectType).
20
+ * Run by the DDL account.
21
+ */
22
+
23
+ const SCHEMA = 'shield_authz';
24
+
25
+ async function up({ query }) {
26
+ // permission — add the catalog columns astram3's MariaDbCatalogStore contract expects.
27
+ await query(
28
+ `ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_uuid VARCHAR(36) NULL`
29
+ );
30
+ await query(
31
+ `ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_module VARCHAR(64) NOT NULL DEFAULT ''`
32
+ );
33
+ await query(
34
+ `ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_type_key VARCHAR(64) NOT NULL DEFAULT ''`
35
+ );
36
+ await query(
37
+ `ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_action VARCHAR(64) NOT NULL DEFAULT ''`
38
+ );
39
+ await query(
40
+ `ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_label VARCHAR(191) NOT NULL DEFAULT ''`
41
+ );
42
+ await query(
43
+ `ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_tier VARCHAR(32) NOT NULL DEFAULT 'gated'`
44
+ );
45
+ await query(
46
+ `ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_status VARCHAR(16) NOT NULL DEFAULT 'active'`
47
+ );
48
+
49
+ // role_permission — add the grant-admin service's attribution columns (additive; rp_created_*
50
+ // from 006 stays untouched).
51
+ await query(
52
+ `ALTER TABLE \`${SCHEMA}\`.\`role_permission\` ADD COLUMN IF NOT EXISTS rp_granted_by CHAR(36) NULL`
53
+ );
54
+ await query(
55
+ `ALTER TABLE \`${SCHEMA}\`.\`role_permission\` ADD COLUMN IF NOT EXISTS rp_granted_at TIMESTAMP NULL`
56
+ );
57
+ }
58
+
59
+ async function down() {
60
+ // Documented NO-OP: dropping columns here would drop live catalog/grant-attribution data
61
+ // (perm_module/type_key/action/label/tier/status, rp_granted_by/rp_granted_at) with no safe
62
+ // way to reconstruct it. Reversal of this migration, if ever needed, must be a deliberate,
63
+ // reviewed follow-up migration — not an automatic DROP COLUMN in `down()`.
64
+ }
65
+
66
+ module.exports = { up, down };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Framework authz migration — the access-bundle backing tables in shield_authz:
3
+ * access_bundle — developer-declared, admin-grantable named permission bundles
4
+ * (reconciled from @AccessBundle specs, never seeded here)
5
+ * access_bundle_permission — bundle→atomic-key resolution rows
6
+ *
7
+ * A bundle expands to its atomic `role_permission` keys at grant time; these tables hold only
8
+ * the catalog (the declared bundles + their key sets). No seed rows, no hard-coded UUIDs —
9
+ * bundles are reconciled at boot from the collected declarations.
10
+ *
11
+ * Ported from astram3 `server/migrations/1720000000018-CreateAccessBundleTables.js` (read-only
12
+ * reference — column set, keys, and FK match exactly).
13
+ *
14
+ * Idempotent (CREATE TABLE IF NOT EXISTS). Structural (no tenant gate). Run by the DDL account.
15
+ */
16
+
17
+ const SCHEMA = 'shield_authz';
18
+
19
+ async function up({ query }) {
20
+ await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`access_bundle\` (
21
+ ab_uuid CHAR(36) NOT NULL,
22
+ ab_key VARCHAR(120) NOT NULL,
23
+ ab_module VARCHAR(60) NOT NULL,
24
+ ab_label VARCHAR(200) NOT NULL,
25
+ ab_description VARCHAR(500) NULL,
26
+ ab_status VARCHAR(16) NOT NULL DEFAULT 'active',
27
+ PRIMARY KEY (ab_uuid),
28
+ UNIQUE KEY UQ_access_bundle_module_key (ab_module, ab_key)
29
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
30
+
31
+ await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`access_bundle_permission\` (
32
+ abp_uuid CHAR(36) NOT NULL,
33
+ abp_bundle_uuid CHAR(36) NOT NULL,
34
+ abp_perm_key VARCHAR(200) NOT NULL,
35
+ PRIMARY KEY (abp_uuid),
36
+ UNIQUE KEY UQ_abp_bundle_key (abp_bundle_uuid, abp_perm_key),
37
+ CONSTRAINT FK_access_bundle_permission_bundle
38
+ FOREIGN KEY (abp_bundle_uuid) REFERENCES \`${SCHEMA}\`.\`access_bundle\` (ab_uuid)
39
+ ON DELETE CASCADE
40
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
41
+ }
42
+
43
+ async function down({ query }) {
44
+ // FK order: drop the child (access_bundle_permission) before the parent (access_bundle).
45
+ await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`access_bundle_permission\``);
46
+ await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`access_bundle\``);
47
+ }
48
+
49
+ module.exports = { up, down };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astram/guard",
3
- "version": "0.4.0",
3
+ "version": "0.5.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",
@@ -13,7 +13,8 @@
13
13
  }
14
14
  },
15
15
  "files": [
16
- "dist"
16
+ "dist",
17
+ "migrations"
17
18
  ],
18
19
  "sideEffects": false,
19
20
  "publishConfig": {
@@ -23,7 +24,8 @@
23
24
  "argon2": "^0.41.1",
24
25
  "ioredis": "^5.4.1",
25
26
  "mariadb": "^3.4.0",
26
- "@astram/core": "1.0.0"
27
+ "@astram/core": "1.0.0",
28
+ "@astram/engine": "0.1.3"
27
29
  },
28
30
  "peerDependencies": {
29
31
  "@nestjs/common": "^11",