@jantstack/adonis-authz 2.4.0-alpha.1 → 2.4.0-alpha.3

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 (108) hide show
  1. package/README.md +299 -19
  2. package/build/commands/authz_relations_reconcile.d.ts +25 -1
  3. package/build/commands/authz_relations_reconcile.d.ts.map +1 -1
  4. package/build/commands/authz_relations_reconcile.js +94 -6
  5. package/build/commands/authz_relations_reconcile.js.map +1 -1
  6. package/build/index.d.ts +13 -2
  7. package/build/index.d.ts.map +1 -1
  8. package/build/index.js +15 -1
  9. package/build/index.js.map +1 -1
  10. package/build/providers/authz_provider.d.ts +6 -1
  11. package/build/providers/authz_provider.d.ts.map +1 -1
  12. package/build/providers/authz_provider.js +18 -2
  13. package/build/providers/authz_provider.js.map +1 -1
  14. package/build/src/define_config.d.ts +73 -1
  15. package/build/src/define_config.d.ts.map +1 -1
  16. package/build/src/define_config.js.map +1 -1
  17. package/build/src/drivers/database_driver.d.ts +53 -14
  18. package/build/src/drivers/database_driver.d.ts.map +1 -1
  19. package/build/src/drivers/database_driver.js +104 -32
  20. package/build/src/drivers/database_driver.js.map +1 -1
  21. package/build/src/drivers/database_relations_driver.d.ts +57 -9
  22. package/build/src/drivers/database_relations_driver.d.ts.map +1 -1
  23. package/build/src/drivers/database_relations_driver.js +344 -89
  24. package/build/src/drivers/database_relations_driver.js.map +1 -1
  25. package/build/src/drivers/openfga_driver.d.ts +17 -4
  26. package/build/src/drivers/openfga_driver.d.ts.map +1 -1
  27. package/build/src/drivers/openfga_driver.js +38 -3
  28. package/build/src/drivers/openfga_driver.js.map +1 -1
  29. package/build/src/drivers/openfga_facts.d.ts +15 -0
  30. package/build/src/drivers/openfga_facts.d.ts.map +1 -1
  31. package/build/src/drivers/openfga_facts.js +25 -2
  32. package/build/src/drivers/openfga_facts.js.map +1 -1
  33. package/build/src/drivers/openfga_relations_driver.d.ts +40 -6
  34. package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -1
  35. package/build/src/drivers/openfga_relations_driver.js +244 -44
  36. package/build/src/drivers/openfga_relations_driver.js.map +1 -1
  37. package/build/src/errors.d.ts +83 -4
  38. package/build/src/errors.d.ts.map +1 -1
  39. package/build/src/errors.js +139 -3
  40. package/build/src/errors.js.map +1 -1
  41. package/build/src/freeze.d.ts +37 -16
  42. package/build/src/freeze.d.ts.map +1 -1
  43. package/build/src/freeze.js +53 -8
  44. package/build/src/freeze.js.map +1 -1
  45. package/build/src/manager.d.ts +16 -1
  46. package/build/src/manager.d.ts.map +1 -1
  47. package/build/src/manager.js +116 -25
  48. package/build/src/manager.js.map +1 -1
  49. package/build/src/models/authz_assignment.d.ts +2 -2
  50. package/build/src/models/authz_assignment.d.ts.map +1 -1
  51. package/build/src/models/authz_deny.d.ts +2 -2
  52. package/build/src/models/authz_deny.d.ts.map +1 -1
  53. package/build/src/models/authz_permission.d.ts +2 -2
  54. package/build/src/models/authz_permission.d.ts.map +1 -1
  55. package/build/src/models/authz_role.d.ts +2 -2
  56. package/build/src/models/authz_role.d.ts.map +1 -1
  57. package/build/src/models/authz_role_permission.d.ts +2 -2
  58. package/build/src/models/authz_role_permission.d.ts.map +1 -1
  59. package/build/src/relation_partition_trigger.d.ts.map +1 -1
  60. package/build/src/relation_partition_trigger.js +11 -3
  61. package/build/src/relation_partition_trigger.js.map +1 -1
  62. package/build/src/relations/define_relations_config.d.ts +51 -0
  63. package/build/src/relations/define_relations_config.d.ts.map +1 -1
  64. package/build/src/relations/define_relations_config.js +68 -1
  65. package/build/src/relations/define_relations_config.js.map +1 -1
  66. package/build/src/relations/manager.d.ts +71 -6
  67. package/build/src/relations/manager.d.ts.map +1 -1
  68. package/build/src/relations/manager.js +301 -29
  69. package/build/src/relations/manager.js.map +1 -1
  70. package/build/src/relations/reconcile.d.ts +53 -4
  71. package/build/src/relations/reconcile.d.ts.map +1 -1
  72. package/build/src/relations/reconcile.js +92 -30
  73. package/build/src/relations/reconcile.js.map +1 -1
  74. package/build/src/scope_outbox.d.ts.map +1 -1
  75. package/build/src/scope_outbox.js +17 -10
  76. package/build/src/scope_outbox.js.map +1 -1
  77. package/build/src/shared/backend_guard.d.ts +28 -0
  78. package/build/src/shared/backend_guard.d.ts.map +1 -1
  79. package/build/src/shared/backend_guard.js +52 -0
  80. package/build/src/shared/backend_guard.js.map +1 -1
  81. package/build/src/shared/transaction_guard.d.ts +50 -0
  82. package/build/src/shared/transaction_guard.d.ts.map +1 -0
  83. package/build/src/shared/transaction_guard.js +60 -0
  84. package/build/src/shared/transaction_guard.js.map +1 -0
  85. package/build/src/testing/contract.d.ts +55 -4
  86. package/build/src/testing/contract.d.ts.map +1 -1
  87. package/build/src/testing/contract.js +240 -8
  88. package/build/src/testing/contract.js.map +1 -1
  89. package/build/src/testing/main.d.ts +4 -4
  90. package/build/src/testing/main.d.ts.map +1 -1
  91. package/build/src/testing/main.js +2 -2
  92. package/build/src/testing/main.js.map +1 -1
  93. package/build/src/testing/relations_contract.d.ts +23 -1
  94. package/build/src/testing/relations_contract.d.ts.map +1 -1
  95. package/build/src/testing/relations_contract.js +603 -19
  96. package/build/src/testing/relations_contract.js.map +1 -1
  97. package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -1
  98. package/build/src/testing/relations_reconcile_contract.js +49 -1
  99. package/build/src/testing/relations_reconcile_contract.js.map +1 -1
  100. package/build/src/traits/has_uuid.d.ts +2 -2
  101. package/build/src/traits/has_uuid.d.ts.map +1 -1
  102. package/build/src/types.d.ts +284 -16
  103. package/build/src/types.d.ts.map +1 -1
  104. package/build/src/types.js +4 -0
  105. package/build/src/types.js.map +1 -1
  106. package/build/stubs/config/authorization.stub +45 -1
  107. package/build/stubs/migration.stub +20 -10
  108. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAyB7D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAqC1D,OAAO,KAAK,EACV,mBAAmB,EAEnB,gBAAgB,EAGhB,WAAW,EACX,cAAc,EACd,WAAW,EACX,OAAO,EACP,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,SAAS,EAGT,iBAAiB,EACjB,cAAc,EAGd,gBAAgB,EAChB,eAAe,EAIf,kBAAkB,EAElB,gBAAgB,EAChB,QAAQ,EAER,qBAAqB,EACrB,SAAS,EACT,UAAU,EAEX,MAAM,YAAY,CAAA;AAuBnB;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAClC,oBAAoB,EAClB,WAAW,GACX,SAAS,GACT,cAAc,GACd,YAAY,GACZ,WAAW,GACX,gBAAgB,GAChB,OAAO,GACP,QAAQ,GACR,MAAM,GACN,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,sBAAsB,GACtB,eAAe,GACf,kBAAkB,GAClB,wBAAwB,GACxB,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,CACrB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAEhH;AAED,qGAAqG;AACrG,eAAO,MAAM,kBAAkB,OAAQ,CAAA;AACvC,eAAO,MAAM,uBAAuB,QAAS,CAAA;AAC7C;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,WAAa,CAAA;AACzC;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAA;AACtC,eAAO,MAAM,mBAAmB,QAAS,CAAA;AAGzC,gGAAgG;AAChG,eAAO,MAAM,uBAAuB,QAAS,CAAA;AAE7C,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAgBD,4FAA4F;AAC5F,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,UAAU,GAAG,SAAS,CAAA;IAC5B,8EAA8E;IAC9E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,KAAK,EAAE,MAAM,CAAA;CACd;AAUD;;;;;;;;GAQG;AACH,qBAAa,oBAAoB;;gBAwBnB,MAAM,EAAE,mBAAmB;IAkCvC;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,iBAAiB;IAmB9D;;;;;;;;;;;;;;OAcG;IACG,MAAM,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAyD5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACG,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,UAAU,CAAA;KAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IA4DjH;;;OAGG;IACG,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBpD;;;;OAIG;IACH,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,mGAAmG;IAC7F,YAAY,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAYlD;;;;;;;OAOG;IACG,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAuH3E,mDAAmD;IACnD,iBAAiB,IAAI,IAAI;IAiCzB;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM;0BAOW,QAAQ,UAAU,QAAQ,YAAY,qBAAqB,KAAG,OAAO,CAAC,IAAI,CAAC;QAiBnG;;;;;;;;;;;;WAYG;uBACkB,QAAQ,aAAa,QAAQ,YAAY,qBAAqB,KAAG,OAAO,CAAC,IAAI,CAAC;QAenG;;;;;;;;;;;;;;;;;;;;;;WAsBG;0BACqB,QAAQ,YAAY,qBAAqB,KAAG,OAAO,CAAC,IAAI,CAAC;MA6ClF;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;IACG,iBAAiB,CACrB,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GACrE,OAAO,CAAC,gBAAgB,CAAC;IAkJ5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;IACG,SAAS,CACb,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,gBAAgB,GACxD,OAAO,CAAC,eAAe,CAAC;IA4Z3B;;;;;OAKG;IACG,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IA8J5D,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrF,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAKtF;;;;;;;;OAQG;IACG,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA0BpG,2GAA2G;IACrG,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAKrE,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKxE,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKlE,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKpF,mHAAmH;IAC7G,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAM3E;;;;;;;OAOG;IACG,oBAAoB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiKnF;;;;;;;;;;;;;;;OAeG;IACG,gBAAgB,CACpB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,QAAQ,EACpB,IAAI,EAAE,cAAc,EACpB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,WAAW,CAAC;IAmGvB;;;;;;;;OAQG;IACG,gBAAgB,CACpB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,WAAW,CAAC;IA2FvB;;;;;;OAMG;IACG,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2FG;IACG,gBAAgB,CAAC,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC;QAC3F,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,WAAW,CAAC;YAAC,KAAK,EAAE,QAAQ,CAAC;YAAC,WAAW,EAAE,MAAM,EAAE,CAAC;YAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;YAAC,aAAa,EAAE,OAAO,GAAG,SAAS,CAAA;SAAE,CAAC,CAAA;QAClJ,MAAM,EAAE,cAAc,EAAE,CAAA;QACxB,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,cAAc,CAAC;YAAC,MAAM,EAAE,iBAAiB,CAAA;SAAE,CAAC,CAAA;QACnE,2FAA2F;QAC3F,SAAS,EAAE,OAAO,CAAA;QAClB,MAAM,EAAE,OAAO,CAAA;KAChB,CAAC;IAshBF;;;;;;OAMG;IACG,KAAK,CACT,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,QAAQ,EACf,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,YAAY,CAAC;IAyCxB;;;;;OAKG;IACG,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1G,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IASpG,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IASvH;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACG,gBAAgB,CACpB,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,gBAAgB,CAAC;IAoE5B;;;;;;;OAOG;IACG,sBAAsB,CAC1B,QAAQ,EAAE,eAAe,EAAE,EAC3B,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,QAAQ,EAAE,CAAC;CAmNvB"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import { v7 as uuidv7 } from 'uuid';
4
4
  import { assertCatalogUuid, assertIdentity, assertScope, assertScopeType, assertSubject, assertValidSlug, chainKeysFrom, normalizeRoleQuery, scopeFromKey, scopeKey, scopeSpellings, } from './identity.js';
5
5
  import { expiryChanged } from './expiry.js';
6
6
  import { randomBytes } from 'node:crypto';
7
- import { DEFAULT_FREEZE_LEASE_MS, acquireFreeze, freezeIsLive, freezeKindOf, readFreezeRow, releaseFreeze, renewFreeze, } from './freeze.js';
7
+ import { DEFAULT_FREEZE_LEASE_MS, acquireFreeze, freezeIsLive, freezeKindOf, readFreezeRow, assertNotFrozenRow, releaseFreeze, renewFreeze, } from './freeze.js';
8
8
  import { assertKnownScope, isAuthzError, resolveChain, rootOnlyResolver } from './shared/backend_guard.js';
9
9
  import { CatalogCache, GLOBAL_OWNER_KEY, invalidateAuthzCatalog, isRoleVisibleWith, readLocalRoles, withAuthzCatalogWrite } from './catalog/catalog_cache.js';
10
10
  import { assertAssignableAt } from './catalog/catalog.js';
@@ -196,10 +196,65 @@ export class AuthorizationManager {
196
196
  }
197
197
  driver = driver.withClock(clock);
198
198
  }
199
+ this.#assertTransactionalWritesRequired(driver);
199
200
  this.#assertScopeDriftGuarded(driver);
200
201
  this.#driver = driver;
201
202
  return driver;
202
203
  }
204
+ /**
205
+ * **Puerta 2 de `{ transaction }`** (L-2, opt-in): con
206
+ * `requireTransactionalWrites: true` el driver activo tiene que declarar
207
+ * `transactionalWrites: true` o el manager falla AL RESOLVERLO — antes de
208
+ * cachearlo, así que toda lectura, toda escritura y `driver()` fallan igual:
209
+ * el despliegue no arranca. Es la forma honesta de «fallar al construirse»:
210
+ * el roadmap lo pedía incondicional y eso haría `openfga` inconstruible en
211
+ * cualquier app que solo lo tenga registrado (y el driver se resuelve
212
+ * perezosamente y por nombre, así que al construir no se sabe si alguien
213
+ * pasará `{ transaction }`). Quien quiera fallar al arrancar, lo pide.
214
+ */
215
+ #assertTransactionalWritesRequired(driver) {
216
+ if (this.#config.requireTransactionalWrites !== true)
217
+ return;
218
+ if (driver.capabilities?.transactionalWrites === true)
219
+ return;
220
+ throw new AuthorizationConfigError(`config.requireTransactionalWrites está en true y el driver '${this.#config.default}' declara ` +
221
+ `transactionalWrites: ${driver.capabilities ? String(driver.capabilities.transactionalWrites) : 'nada (sin capabilities)'}: ` +
222
+ `no puede inscribir grant/revoke/deny/removeDeny en la transacción del consumidor («los dos o ninguno»), así ` +
223
+ `que el manager no se resuelve. Usa un driver que la declare (database) o quita requireTransactionalWrites.`);
224
+ }
225
+ /**
226
+ * **Puerta 1 de `{ transaction }`** (L-2, siempre activa): una escritura de
227
+ * HECHOS con `{ transaction }` a un driver que no declara
228
+ * `transactionalWrites: true` es 500 `E_AUTHZ_UNSUPPORTED` nombrando driver
229
+ * y operación, ANTES de la barrera, de la identidad y del driver (cero
230
+ * llamadas). Nunca se ignora, nunca un `logger.warn`: aceptarla y no
231
+ * cumplirla sería publicar con nuestra firma la fuga del cruce 4 · S5.
232
+ * `scopes.*` NO pasa por aquí: su `transaction` ENCOLA (encolar ≠ escribir).
233
+ */
234
+ async #assertTransactionalWrite(options, operation) {
235
+ if (options?.transaction === undefined || options.transaction === null)
236
+ return;
237
+ const driver = await this.driver();
238
+ if (driver.capabilities?.transactionalWrites === true)
239
+ return;
240
+ throw UnsupportedOperationError.transactional(operation, this.#config.default, 'roles');
241
+ }
242
+ /**
243
+ * La marca del evento de una escritura inscrita en la transacción del
244
+ * llamante (L-3): `onWrite` se dispara cuando el DRIVER vuelve, y en ese
245
+ * momento la fila existe solo dentro de esa transacción — es un hecho si y
246
+ * solo si el llamante confirma, cosa que el paquete nunca ve. Quien audita
247
+ * lo necesita para no registrar como firme lo que un rollback deshace.
248
+ */
249
+ #transactional(options) {
250
+ return options?.transaction === undefined || options.transaction === null ? {} : { transactional: true };
251
+ }
252
+ /** La API de delegación no admite `{ transaction }` (§1.4 del veredicto `{trx}`): 500 antes de tocar nada. */
253
+ #assertNoTransaction(options, operation) {
254
+ if (options?.transaction === undefined || options.transaction === null)
255
+ return;
256
+ throw UnsupportedOperationError.transactionalCatalog(operation);
257
+ }
203
258
  /**
204
259
  * **El gate de deriva del árbol, en el MANAGER** (3b-2e · E3; cierra el
205
260
  * agujero que declaró el 3b-2d).
@@ -366,10 +421,16 @@ export class AuthorizationManager {
366
421
  * A1.1/A1.3): si este manager ya sostiene el freeze, la ventana interior
367
422
  * no toma otro ni lo levanta al salir — la exterior sigue en pie.
368
423
  */
369
- async withFrozenWrites(reason, fn) {
370
- const context = await this.#durableFreezeContext(reason, 'platform', { operatorAsContext: false });
424
+ async withFrozenWrites(reason, fn, options = {}) {
425
+ // L-1 · J1: una pasada que quiera correr DENTRO de la ventana del
426
+ // operador (el cutover) y publicar su `lapsed` —`authz:relations:reconcile`,
427
+ // que vive fuera de este manager— pide `kind: 'reconcile'` y
428
+ // `operatorAsContext: true`, lo mismo que hace `reconcile` de roles.
429
+ const context = await this.#durableFreezeContext(reason, options.kind ?? 'platform', {
430
+ operatorAsContext: options.operatorAsContext === true,
431
+ });
371
432
  try {
372
- return await fn();
433
+ return await fn({ fence: context.fence, leaseMs: context.leaseMs, lapsed: context.lapsed });
373
434
  }
374
435
  finally {
375
436
  await context.release();
@@ -454,25 +515,23 @@ export class AuthorizationManager {
454
515
  * freeze, y con `catalogRevalidate: { everyMs }` la fila del memo ni se
455
516
  * lee.
456
517
  */
457
- async #assertNotFrozen(operation, transaction) {
518
+ async #assertNotFrozen(operation) {
458
519
  const root = this.#root();
459
520
  const held = root.#heldFreeze;
460
521
  if (held) {
461
522
  throw new AuthorizationFrozenError(`${operation}: el motor de autorización está congelado (${held.reason}) y no acepta escrituras. ` +
462
523
  `Las lecturas siguen funcionando; reintenta esta escritura cuando la operación termine.`);
463
524
  }
464
- // Si la escritura llegó con la TRANSACCIÓN del consumidor, la fila se lee
465
- // por ella: exigir una segunda conexión con la suya abierta interbloquea
466
- // un pool de 1 (SQLite `:memory:`). El precio va declarado en freeze.ts.
467
- const client = transaction && typeof transaction.from === 'function'
468
- ? transaction
469
- : undefined;
470
- const row = await readFreezeRow({ driver: this.#config.default, client });
471
- if (!freezeIsLive(row, root.#wallMs()))
472
- return;
473
- const lift = freezeKindOf(row.holder) === 'operator' ? ' (la levanta authz:unfreeze)' : '';
474
- throw new AuthorizationFrozenError(`${operation}: el motor de autorización está congelado (${row.reason})${lift} y no acepta escrituras. ` +
475
- `Las lecturas siguen funcionando; reintenta esta escritura cuando la ventana termine.`);
525
+ // La fila se lee SIEMPRE por la conexión del motor (L-1 · 🟠 8). Hasta
526
+ // L-1 se leía por la transacción del consumidor si la escritura llegaba
527
+ // con una —«para no interbloquear un pool de 1»—, y eso era el agujero:
528
+ // la barrera la decidía el snapshot del llamante (medido en SQLite, MySQL
529
+ // y PG). Con pool 1 el precio es un 503 con deadline, no un bypass.
530
+ await assertNotFrozenRow(operation, {
531
+ driver: this.#config.default,
532
+ nowMs: root.#wallMs(),
533
+ timeoutMs: this.#config.freezeTimeoutMs,
534
+ });
476
535
  }
477
536
  /** Solo tests: fuerza re-resolución del driver. */
478
537
  clearCachedDriver() {
@@ -1163,7 +1222,10 @@ export class AuthorizationManager {
1163
1222
  * `{}` si no hay actor: el evento no inventa autores).
1164
1223
  */
1165
1224
  async #writeOptions(options, operation) {
1166
- await this.#assertNotFrozen(operation, options?.transaction);
1225
+ // Sin cast sobre `transaction` (L-1 · 🟠 8): la barrera no lee nada del
1226
+ // llamante, y `transaction` solo lo consumen los tipos que lo declaran
1227
+ // (`ScopeTreeWriteOptions`, para ENCOLAR — nunca para decidir).
1228
+ await this.#assertNotFrozen(operation);
1167
1229
  if (options?.actor !== undefined)
1168
1230
  assertSubject(options.actor);
1169
1231
  if (this.#config.requireActor === true && !options?.actor) {
@@ -1594,6 +1656,7 @@ export class AuthorizationManager {
1594
1656
  * Devuelve el rol y notifica `role_defined`.
1595
1657
  */
1596
1658
  async defineScopedRole(actor, ownerScope, spec, options) {
1659
+ this.#assertNoTransaction(options, 'defineScopedRole');
1597
1660
  const who = await this.#requireActor(actor, 'defineScopedRole');
1598
1661
  this.#assertOwnerScope(ownerScope, 'defineScopedRole');
1599
1662
  const parsed = this.#parseScopedRoleSpec(spec);
@@ -1693,6 +1756,7 @@ export class AuthorizationManager {
1693
1756
  * escribe ni notifica (idempotente). Notifica `role_updated`.
1694
1757
  */
1695
1758
  async updateScopedRole(actor, roleUuid, changes, options) {
1759
+ this.#assertNoTransaction(options, 'updateScopedRole');
1696
1760
  const who = await this.#requireActor(actor, 'updateScopedRole');
1697
1761
  assertCatalogUuid('rol', roleUuid);
1698
1762
  const parsed = this.#parseScopedRoleChanges(changes);
@@ -1786,6 +1850,7 @@ export class AuthorizationManager {
1786
1850
  * su owner. Notifica `role_purged`. No necesita `listDenies`.
1787
1851
  */
1788
1852
  async deleteScopedRole(actor, roleUuid, options) {
1853
+ this.#assertNoTransaction(options, 'deleteScopedRole');
1789
1854
  const who = await this.#requireActor(actor, 'deleteScopedRole');
1790
1855
  assertCatalogUuid('rol', roleUuid);
1791
1856
  const driver = await this.driver();
@@ -2397,13 +2462,15 @@ export class AuthorizationManager {
2397
2462
  * `E_AUTHZ_AMBIGUOUS_ROLE`, nunca «el más cercano gana»).
2398
2463
  */
2399
2464
  async grant(subject, role, scope, options) {
2465
+ await this.#assertTransactionalWrite(options, 'grant');
2400
2466
  const actor = await this.#writeOptions(options, 'grant');
2401
2467
  assertIdentity({ subject, role, scope, expiresAt: options?.expiresAt });
2402
2468
  await this.#assertWithin(scope, options, 'grant');
2403
2469
  // 3E · Q7: el evento lleva el rol RESUELTO (uuid + slug + nivel + owner),
2404
2470
  // no la pregunta cruda. Solo se resuelve si hay hook que lo vaya a leer.
2405
2471
  const roles = await this.#resolvedRoles(role, scope, 'grant');
2406
- const outcome = (await this.#write({ action: 'granted', subject, scope, roles, expiresAt: options?.expiresAt ?? null, ...actor }, async () => (await this.driver()).grant(subject, role, scope, options))) ??
2472
+ const transactional = this.#transactional(options);
2473
+ const outcome = (await this.#write({ action: 'granted', subject, scope, roles, expiresAt: options?.expiresAt ?? null, ...actor, ...transactional }, async () => (await this.driver()).grant(subject, role, scope, options))) ??
2407
2474
  // Un driver de terceros que aún devuelva `void`: la firma promete un
2408
2475
  // `GrantOutcome` y no miente (E1). Sin lectura previa no hay caducidad
2409
2476
  // anterior que contar: es lo que pidió el llamante, y `existed: false`.
@@ -2419,6 +2486,7 @@ export class AuthorizationManager {
2419
2486
  expiresAt: outcome.expiresAt,
2420
2487
  previousExpiresAt: outcome.previousExpiresAt,
2421
2488
  ...actor,
2489
+ ...transactional,
2422
2490
  });
2423
2491
  }
2424
2492
  else {
@@ -2429,6 +2497,7 @@ export class AuthorizationManager {
2429
2497
  roles,
2430
2498
  expiresAt: outcome.expiresAt,
2431
2499
  ...actor,
2500
+ ...transactional,
2432
2501
  });
2433
2502
  }
2434
2503
  return outcome;
@@ -2440,27 +2509,38 @@ export class AuthorizationManager {
2440
2509
  * rol.
2441
2510
  */
2442
2511
  async revoke(subject, role, scope, options) {
2512
+ await this.#assertTransactionalWrite(options, 'revoke');
2443
2513
  const actor = await this.#writeOptions(options, 'revoke');
2444
2514
  assertIdentity({ subject, role, scope });
2445
2515
  await this.#assertWithin(scope, options, 'revoke');
2446
- const event = { action: 'revoked', subject, scope, roles: await this.#resolvedRoles(role, scope, 'revoke'), ...actor };
2447
- await this.#write(event, async () => (await this.driver()).revoke(subject, role, scope));
2516
+ const event = {
2517
+ action: 'revoked',
2518
+ subject,
2519
+ scope,
2520
+ roles: await this.#resolvedRoles(role, scope, 'revoke'),
2521
+ ...actor,
2522
+ ...this.#transactional(options),
2523
+ };
2524
+ // L-2: las opciones viajan al driver (`transaction`, si la puerta la dejó pasar) — como en `grant`.
2525
+ await this.#write(event, async () => (await this.driver()).revoke(subject, role, scope, options));
2448
2526
  await this.#notify(event);
2449
2527
  }
2450
2528
  async deny(subject, permission, scope, options) {
2529
+ await this.#assertTransactionalWrite(options, 'deny');
2451
2530
  const actor = await this.#writeOptions(options, 'deny');
2452
2531
  assertIdentity({ subject, permission, scope });
2453
2532
  await this.#assertWithin(scope, options, 'deny');
2454
- const event = { action: 'denied', subject, scope, permission, ...actor };
2455
- await this.#write(event, async () => (await this.driver()).deny(subject, permission, scope));
2533
+ const event = { action: 'denied', subject, scope, permission, ...actor, ...this.#transactional(options) };
2534
+ await this.#write(event, async () => (await this.driver()).deny(subject, permission, scope, options));
2456
2535
  await this.#notify(event);
2457
2536
  }
2458
2537
  async removeDeny(subject, permission, scope, options) {
2538
+ await this.#assertTransactionalWrite(options, 'removeDeny');
2459
2539
  const actor = await this.#writeOptions(options, 'removeDeny');
2460
2540
  assertIdentity({ subject, permission, scope });
2461
2541
  await this.#assertWithin(scope, options, 'removeDeny');
2462
- const event = { action: 'deny_removed', subject, scope, permission, ...actor };
2463
- await this.#write(event, async () => (await this.driver()).removeDeny(subject, permission, scope));
2542
+ const event = { action: 'deny_removed', subject, scope, permission, ...actor, ...this.#transactional(options) };
2543
+ await this.#write(event, async () => (await this.driver()).removeDeny(subject, permission, scope, options));
2464
2544
  await this.#notify(event);
2465
2545
  }
2466
2546
  /**
@@ -2711,6 +2791,17 @@ export class AuthorizationManager {
2711
2791
  * `indeterminate: true`, para que quien audita registre "puede haber
2712
2792
  * ocurrido" en vez de nada. Cualquier otro fallo (422, conexión rechazada)
2713
2793
  * significa que la escritura no ocurrió y se propaga sin evento.
2794
+ *
2795
+ * **Dentro de la transacción del llamante (L-3) el deadline sigue siendo
2796
+ * `indeterminate: true`**, y el evento lleva además `transactional: true`.
2797
+ * El auditor del panel `{trx}` (🟡 12) objetó que ahí «el rollback la
2798
+ * determina»; pero lo que determina el rollback lo determina el LLAMANTE
2799
+ * y el paquete no lo ve: en el instante del 503 la sentencia puede haber
2800
+ * aterrizado en la transacción (SQLite no cancela; en PG la transacción
2801
+ * queda abortada y ya no puede confirmar; en MySQL la sentencia se mata y
2802
+ * la transacción sigue viva) y el llamante puede confirmar o no. Lo
2803
+ * honesto es el mismo «no lo sé» de siempre más la marca de que la última
2804
+ * palabra es su commit. Medido por motor en `database_transaction.spec.ts`.
2714
2805
  */
2715
2806
  async #write(event, fn) {
2716
2807
  try {