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

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 (236) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +837 -51
  3. package/build/commands/authz_catalog_diff.d.ts +28 -0
  4. package/build/commands/authz_catalog_diff.d.ts.map +1 -0
  5. package/build/commands/authz_catalog_diff.js +67 -0
  6. package/build/commands/authz_catalog_diff.js.map +1 -0
  7. package/build/commands/authz_catalog_prune_orphans.d.ts +78 -0
  8. package/build/commands/authz_catalog_prune_orphans.d.ts.map +1 -0
  9. package/build/commands/authz_catalog_prune_orphans.js +136 -0
  10. package/build/commands/authz_catalog_prune_orphans.js.map +1 -0
  11. package/build/commands/authz_catalog_sync.d.ts +37 -0
  12. package/build/commands/authz_catalog_sync.d.ts.map +1 -0
  13. package/build/commands/authz_catalog_sync.js +81 -0
  14. package/build/commands/authz_catalog_sync.js.map +1 -0
  15. package/build/commands/authz_freeze.d.ts +44 -0
  16. package/build/commands/authz_freeze.d.ts.map +1 -0
  17. package/build/commands/authz_freeze.js +95 -0
  18. package/build/commands/authz_freeze.js.map +1 -0
  19. package/build/commands/authz_reconcile.d.ts +102 -0
  20. package/build/commands/authz_reconcile.d.ts.map +1 -0
  21. package/build/commands/authz_reconcile.js +294 -0
  22. package/build/commands/authz_reconcile.js.map +1 -0
  23. package/build/commands/authz_relations_reconcile.d.ts +73 -0
  24. package/build/commands/authz_relations_reconcile.d.ts.map +1 -0
  25. package/build/commands/authz_relations_reconcile.js +225 -0
  26. package/build/commands/authz_relations_reconcile.js.map +1 -0
  27. package/build/commands/authz_scopes_relay.d.ts +47 -0
  28. package/build/commands/authz_scopes_relay.d.ts.map +1 -0
  29. package/build/commands/authz_scopes_relay.js +141 -0
  30. package/build/commands/authz_scopes_relay.js.map +1 -0
  31. package/build/commands/authz_unfreeze.d.ts +37 -0
  32. package/build/commands/authz_unfreeze.d.ts.map +1 -0
  33. package/build/commands/authz_unfreeze.js +92 -0
  34. package/build/commands/authz_unfreeze.js.map +1 -0
  35. package/build/commands/main.d.ts +8 -1
  36. package/build/commands/main.d.ts.map +1 -1
  37. package/build/commands/main.js +8 -1
  38. package/build/commands/main.js.map +1 -1
  39. package/build/commands/openfga_provision.d.ts +46 -4
  40. package/build/commands/openfga_provision.d.ts.map +1 -1
  41. package/build/commands/openfga_provision.js +91 -7
  42. package/build/commands/openfga_provision.js.map +1 -1
  43. package/build/configure.d.ts +11 -0
  44. package/build/configure.d.ts.map +1 -1
  45. package/build/configure.js +37 -1
  46. package/build/configure.js.map +1 -1
  47. package/build/index.d.ts +75 -7
  48. package/build/index.d.ts.map +1 -1
  49. package/build/index.js +67 -5
  50. package/build/index.js.map +1 -1
  51. package/build/providers/authz_provider.d.ts +26 -2
  52. package/build/providers/authz_provider.d.ts.map +1 -1
  53. package/build/providers/authz_provider.js +48 -2
  54. package/build/providers/authz_provider.js.map +1 -1
  55. package/build/services/relations.d.ts +14 -0
  56. package/build/services/relations.d.ts.map +1 -0
  57. package/build/services/relations.js +17 -0
  58. package/build/services/relations.js.map +1 -0
  59. package/build/src/catalog/catalog.d.ts +289 -0
  60. package/build/src/catalog/catalog.d.ts.map +1 -0
  61. package/build/src/catalog/catalog.js +859 -0
  62. package/build/src/catalog/catalog.js.map +1 -0
  63. package/build/src/catalog/catalog_cache.d.ts +324 -0
  64. package/build/src/catalog/catalog_cache.d.ts.map +1 -0
  65. package/build/src/catalog/catalog_cache.js +666 -0
  66. package/build/src/catalog/catalog_cache.js.map +1 -0
  67. package/build/src/clock.d.ts +24 -0
  68. package/build/src/clock.d.ts.map +1 -0
  69. package/build/src/clock.js +7 -0
  70. package/build/src/clock.js.map +1 -0
  71. package/build/src/define_config.d.ts +201 -7
  72. package/build/src/define_config.d.ts.map +1 -1
  73. package/build/src/define_config.js.map +1 -1
  74. package/build/src/drivers/database_driver.d.ts +324 -15
  75. package/build/src/drivers/database_driver.d.ts.map +1 -1
  76. package/build/src/drivers/database_driver.js +1107 -128
  77. package/build/src/drivers/database_driver.js.map +1 -1
  78. package/build/src/drivers/database_relations_driver.d.ts +75 -0
  79. package/build/src/drivers/database_relations_driver.d.ts.map +1 -0
  80. package/build/src/drivers/database_relations_driver.js +450 -0
  81. package/build/src/drivers/database_relations_driver.js.map +1 -0
  82. package/build/src/drivers/openfga_driver.d.ts +963 -55
  83. package/build/src/drivers/openfga_driver.d.ts.map +1 -1
  84. package/build/src/drivers/openfga_driver.js +2693 -372
  85. package/build/src/drivers/openfga_driver.js.map +1 -1
  86. package/build/src/drivers/openfga_facts.d.ts +369 -0
  87. package/build/src/drivers/openfga_facts.d.ts.map +1 -0
  88. package/build/src/drivers/openfga_facts.js +813 -0
  89. package/build/src/drivers/openfga_facts.js.map +1 -0
  90. package/build/src/drivers/openfga_relations_driver.d.ts +120 -0
  91. package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -0
  92. package/build/src/drivers/openfga_relations_driver.js +466 -0
  93. package/build/src/drivers/openfga_relations_driver.js.map +1 -0
  94. package/build/src/errors.d.ts +586 -0
  95. package/build/src/errors.d.ts.map +1 -1
  96. package/build/src/errors.js +583 -0
  97. package/build/src/errors.js.map +1 -1
  98. package/build/src/expiry.d.ts +27 -0
  99. package/build/src/expiry.d.ts.map +1 -0
  100. package/build/src/expiry.js +50 -0
  101. package/build/src/expiry.js.map +1 -0
  102. package/build/src/freeze.d.ts +120 -0
  103. package/build/src/freeze.d.ts.map +1 -0
  104. package/build/src/freeze.js +172 -0
  105. package/build/src/freeze.js.map +1 -0
  106. package/build/src/hierarchical_resolver.d.ts +56 -0
  107. package/build/src/hierarchical_resolver.d.ts.map +1 -0
  108. package/build/src/hierarchical_resolver.js +87 -0
  109. package/build/src/hierarchical_resolver.js.map +1 -0
  110. package/build/src/{middleware → http}/app_access_middleware.d.ts +8 -6
  111. package/build/src/http/app_access_middleware.d.ts.map +1 -0
  112. package/build/src/{middleware → http}/app_access_middleware.js +10 -26
  113. package/build/src/http/app_access_middleware.js.map +1 -0
  114. package/build/src/http/resource_access_middleware.d.ts +105 -0
  115. package/build/src/http/resource_access_middleware.d.ts.map +1 -0
  116. package/build/src/http/resource_access_middleware.js +81 -0
  117. package/build/src/http/resource_access_middleware.js.map +1 -0
  118. package/build/src/identity.d.ts +228 -0
  119. package/build/src/identity.d.ts.map +1 -0
  120. package/build/src/identity.js +457 -0
  121. package/build/src/identity.js.map +1 -0
  122. package/build/src/manager.d.ts +536 -7
  123. package/build/src/manager.d.ts.map +1 -1
  124. package/build/src/manager.js +2676 -23
  125. package/build/src/manager.js.map +1 -1
  126. package/build/src/memoize_ancestors.d.ts +23 -0
  127. package/build/src/memoize_ancestors.d.ts.map +1 -0
  128. package/build/src/memoize_ancestors.js +42 -0
  129. package/build/src/memoize_ancestors.js.map +1 -0
  130. package/build/src/models/authz_assignment.d.ts +11 -11
  131. package/build/src/models/authz_assignment.d.ts.map +1 -1
  132. package/build/src/models/authz_deny.d.ts +11 -11
  133. package/build/src/models/authz_deny.d.ts.map +1 -1
  134. package/build/src/models/authz_permission.d.ts +17 -11
  135. package/build/src/models/authz_permission.d.ts.map +1 -1
  136. package/build/src/models/authz_permission.js +4 -0
  137. package/build/src/models/authz_permission.js.map +1 -1
  138. package/build/src/models/authz_role.d.ts +19 -12
  139. package/build/src/models/authz_role.d.ts.map +1 -1
  140. package/build/src/models/authz_role.js +6 -1
  141. package/build/src/models/authz_role.js.map +1 -1
  142. package/build/src/models/authz_role_permission.d.ts +11 -11
  143. package/build/src/models/authz_role_permission.d.ts.map +1 -1
  144. package/build/src/openfga.d.ts +29 -0
  145. package/build/src/openfga.d.ts.map +1 -0
  146. package/build/src/openfga.js +26 -0
  147. package/build/src/openfga.js.map +1 -0
  148. package/build/src/reconcile.d.ts +37 -0
  149. package/build/src/reconcile.d.ts.map +1 -0
  150. package/build/src/reconcile.js +69 -0
  151. package/build/src/reconcile.js.map +1 -0
  152. package/build/src/relation_partition_trigger.d.ts +8 -0
  153. package/build/src/relation_partition_trigger.d.ts.map +1 -0
  154. package/build/src/relation_partition_trigger.js +85 -0
  155. package/build/src/relation_partition_trigger.js.map +1 -0
  156. package/build/src/relations/define_relations_config.d.ts +58 -0
  157. package/build/src/relations/define_relations_config.d.ts.map +1 -0
  158. package/build/src/relations/define_relations_config.js +144 -0
  159. package/build/src/relations/define_relations_config.js.map +1 -0
  160. package/build/src/relations/manager.d.ts +38 -0
  161. package/build/src/relations/manager.d.ts.map +1 -0
  162. package/build/src/relations/manager.js +156 -0
  163. package/build/src/relations/manager.js.map +1 -0
  164. package/build/src/relations/reconcile.d.ts +62 -0
  165. package/build/src/relations/reconcile.d.ts.map +1 -0
  166. package/build/src/relations/reconcile.js +138 -0
  167. package/build/src/relations/reconcile.js.map +1 -0
  168. package/build/src/relations_config_store.d.ts +22 -0
  169. package/build/src/relations_config_store.d.ts.map +1 -0
  170. package/build/src/relations_config_store.js +74 -0
  171. package/build/src/relations_config_store.js.map +1 -0
  172. package/build/src/scope_outbox.d.ts +69 -0
  173. package/build/src/scope_outbox.d.ts.map +1 -0
  174. package/build/src/scope_outbox.js +291 -0
  175. package/build/src/scope_outbox.js.map +1 -0
  176. package/build/src/shared/backend_guard.d.ts +106 -0
  177. package/build/src/shared/backend_guard.d.ts.map +1 -0
  178. package/build/src/shared/backend_guard.js +246 -0
  179. package/build/src/shared/backend_guard.js.map +1 -0
  180. package/build/src/shared/sql_expiry.d.ts +53 -0
  181. package/build/src/shared/sql_expiry.d.ts.map +1 -0
  182. package/build/src/shared/sql_expiry.js +66 -0
  183. package/build/src/shared/sql_expiry.js.map +1 -0
  184. package/build/src/sql_descendants.d.ts +97 -0
  185. package/build/src/sql_descendants.d.ts.map +1 -0
  186. package/build/src/sql_descendants.js +203 -0
  187. package/build/src/sql_descendants.js.map +1 -0
  188. package/build/src/testing/contract.d.ts +212 -7
  189. package/build/src/testing/contract.d.ts.map +1 -1
  190. package/build/src/testing/contract.js +3449 -24
  191. package/build/src/testing/contract.js.map +1 -1
  192. package/build/src/testing/main.d.ts +10 -2
  193. package/build/src/testing/main.d.ts.map +1 -1
  194. package/build/src/testing/main.js +5 -1
  195. package/build/src/testing/main.js.map +1 -1
  196. package/build/src/testing/migration_contract.d.ts +284 -0
  197. package/build/src/testing/migration_contract.d.ts.map +1 -0
  198. package/build/src/testing/migration_contract.js +586 -0
  199. package/build/src/testing/migration_contract.js.map +1 -0
  200. package/build/src/testing/relations_contract.d.ts +51 -0
  201. package/build/src/testing/relations_contract.d.ts.map +1 -0
  202. package/build/src/testing/relations_contract.js +654 -0
  203. package/build/src/testing/relations_contract.js.map +1 -0
  204. package/build/src/testing/relations_reconcile_contract.d.ts +24 -0
  205. package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -0
  206. package/build/src/testing/relations_reconcile_contract.js +172 -0
  207. package/build/src/testing/relations_reconcile_contract.js.map +1 -0
  208. package/build/src/testing/scope_tree.d.ts +65 -0
  209. package/build/src/testing/scope_tree.d.ts.map +1 -0
  210. package/build/src/testing/scope_tree.js +145 -0
  211. package/build/src/testing/scope_tree.js.map +1 -0
  212. package/build/src/traits/authz_scopes.d.ts +30 -6
  213. package/build/src/traits/authz_scopes.d.ts.map +1 -1
  214. package/build/src/traits/authz_scopes.js +30 -18
  215. package/build/src/traits/authz_scopes.js.map +1 -1
  216. package/build/src/traits/has_uuid.d.ts +12 -12
  217. package/build/src/traits/has_uuid.d.ts.map +1 -1
  218. package/build/src/types.d.ts +1313 -28
  219. package/build/src/types.d.ts.map +1 -1
  220. package/build/src/types.js +20 -4
  221. package/build/src/types.js.map +1 -1
  222. package/build/stubs/config/app_acl.stub +4 -2
  223. package/build/stubs/config/authorization.stub +168 -14
  224. package/build/stubs/migration.stub +183 -13
  225. package/build/stubs/scopes_outbox_migration.stub +57 -0
  226. package/package.json +14 -7
  227. package/build/commands/openfga_import.d.ts +0 -28
  228. package/build/commands/openfga_import.d.ts.map +0 -1
  229. package/build/commands/openfga_import.js +0 -74
  230. package/build/commands/openfga_import.js.map +0 -1
  231. package/build/src/catalog.d.ts +0 -3
  232. package/build/src/catalog.d.ts.map +0 -1
  233. package/build/src/catalog.js +0 -103
  234. package/build/src/catalog.js.map +0 -1
  235. package/build/src/middleware/app_access_middleware.d.ts.map +0 -1
  236. package/build/src/middleware/app_access_middleware.js.map +0 -1
@@ -0,0 +1,450 @@
1
+ /**
2
+ * Driver `database` del puerto `RelationsDriver` — ReBAC sobre SQL propio
3
+ * (Fase 4, lote 4-3).
4
+ *
5
+ * Los hechos de relación viven en la tabla `authz_relations` (una fila por
6
+ * tupla, INSERT/DELETE-ONLY, decisión (c) del dueño): NO hay `expires_at` y no
7
+ * hay «renovar = delete+insert» (la caducidad de relaciones —R-15— quedó FUERA
8
+ * de la 2.4, default del dueño). La resolución de `check`/`membersOf`/
9
+ * `listObjects` —includes de un nivel y usersets de grupos anidados— es una
10
+ * **CTE recursiva por dialecto** (mismo patrón que `sql_descendants.ts`), y el
11
+ * cruce de particiones lo defiende, además, el trigger `relationPartitionTrigger`
12
+ * (defensa en profundidad para el escritor «a mano»; el corte primario es la
13
+ * columna `partition_key` en cada consulta).
14
+ *
15
+ * Pureza: este módulo vive en `drivers/` y NO importa `openfga` (regla 3 de
16
+ * `check_purity.mjs`) ni el `manager`. Consume solo el puerto (`../types.js`),
17
+ * los errores, la gramática compartida (`../identity.js`), el guard SQL y el
18
+ * TIPO de la config de relaciones (`../relations/define_relations_config.js`).
19
+ */
20
+ import db from '@adonisjs/lucid/services/db';
21
+ import { v7 as uuidv7 } from 'uuid';
22
+ import { InvalidIdentityError, UnsupportedDialectError } from '../errors.js';
23
+ import { assertScope, assertSubject, scopeKey, scopeSpellings } from '../identity.js';
24
+ import { relationPartitionTrigger, relationPartitionTriggerDrops } from '../relation_partition_trigger.js';
25
+ import { systemClock } from '../clock.js';
26
+ import { guardSql } from '../shared/backend_guard.js';
27
+ import { isRelUserset } from '../types.js';
28
+ const DEFAULT_TIMEOUT_MS = 5_000;
29
+ const RELATIONS_TABLE = 'authz_relations';
30
+ /** Longitud máxima del id de un objeto/holder de relación (columna `varchar(64)`). */
31
+ const RELATION_ID_MAX = 64;
32
+ /** El tipo BUILT-IN portador de usersets (declarado por el generador, no por el consumidor). */
33
+ const GROUP_TYPE = 'group';
34
+ const GROUP_MEMBER = 'member';
35
+ /** Tamaño de página por defecto y tope de `enumerateRelations` (origen de reconcile). */
36
+ const DEFAULT_ENUMERATE_LIMIT = 100;
37
+ const MAX_ENUMERATE_LIMIT = 1_000;
38
+ /** Formato de id de relación: minúsculas, dígitos y `._-`; sin separadores del store. */
39
+ const RELATION_ID_FORMAT = /^[a-z0-9_.-]+$/;
40
+ const DIALECTS = {
41
+ postgres: { quote: '"', text: (e) => `CAST(${e} AS varchar(64))`, hint: '' },
42
+ sqlite3: { quote: '"', text: (e) => `CAST(${e} AS text)`, hint: '' },
43
+ 'better-sqlite3': { quote: '"', text: (e) => `CAST(${e} AS text)`, hint: '' },
44
+ mysql: { quote: '`', text: (e) => `CAST(${e} AS CHAR(64))`, hint: '/*+ SET_VAR(cte_max_recursion_depth = 50000) */ ' },
45
+ mysql2: { quote: '`', text: (e) => `CAST(${e} AS CHAR(64))`, hint: '/*+ SET_VAR(cte_max_recursion_depth = 50000) */ ' },
46
+ };
47
+ // La DDL del trigger de partición vive en el módulo PURO
48
+ // `../relation_partition_trigger.js` (sin dependencia del servicio `db`, para
49
+ // que lo importe también el espejo del esquema, cargado antes de bootear la
50
+ // app). Se re-exporta aquí por comodidad del consumidor del driver.
51
+ export { relationPartitionTrigger, relationPartitionTriggerDrops };
52
+ /**
53
+ * El driver `database` de relaciones. Toda consulta pasa por `guardSql`: un
54
+ * fallo del cliente SQL sale como `AuthorizationBackendError` (503), nunca como
55
+ * el error crudo de knex (invariante 5).
56
+ */
57
+ export class DatabaseRelationsDriver {
58
+ /**
59
+ * Lo que declara (cada valor tiene su cara en `runRelationsDriverContract`):
60
+ * - `singleCheckRelations`: `check` es UNA consulta (la CTE resuelve includes
61
+ * + usersets anidados en un round-trip).
62
+ * - `listObjectsInherited: false`: los `list*` no abren un subárbol (invariante 7).
63
+ * - `usersetSubjects`: `listSubjects` incluye los usersets directos (`group#member`).
64
+ * - `membersOfNative`: la membresía TRANSITIVA la resuelve la CTE recursiva.
65
+ * - `enumerateRelations: true` (4-5): es ORIGEN de `authz:reconcile` de
66
+ * relaciones — enumera los hechos DIRECTOS de la partición (`authz_relations`),
67
+ * paginados por la PK, sin filtrar ni derivar (invariante 7 + higiene de
68
+ * reconcile): la caña la ve el destino tal cual la escribió el origen.
69
+ * - `listObjectsTruncation: false`: sin tope de servidor, `listObjects` es exhaustiva.
70
+ */
71
+ capabilities = Object.freeze({
72
+ singleCheckRelations: true,
73
+ listObjectsInherited: false,
74
+ usersetSubjects: true,
75
+ membersOfNative: true,
76
+ enumerateRelations: true,
77
+ listObjectsTruncation: false,
78
+ });
79
+ #config;
80
+ #connectionName;
81
+ #timeoutMs;
82
+ #now;
83
+ /** Inyectable para probar el dialecto ajeno sin servidor. */
84
+ #database;
85
+ constructor(config, options = {}, database = db) {
86
+ this.#config = config;
87
+ this.#connectionName = options.connection;
88
+ this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
89
+ this.#now = options.now ?? systemClock;
90
+ this.#database = database;
91
+ }
92
+ /* ── Infraestructura ──────────────────────────────────────────────────── */
93
+ #connection() {
94
+ return this.#database.connection(this.#connectionName);
95
+ }
96
+ #dialectMeta() {
97
+ const connection = this.#connection();
98
+ const name = connection?.dialect?.name ?? connection?.client?.driverName ?? 'desconocido';
99
+ const meta = DIALECTS[name];
100
+ if (!meta) {
101
+ throw new UnsupportedDialectError(`DatabaseRelationsDriver: dialecto '${name}' sin observación en la suite ` +
102
+ `(hoy: PostgreSQL, MySQL 8 y SQLite). La CTE recursiva del check no se declara igual en dos ` +
103
+ `motores; impleméntala a mano para este motor.`);
104
+ }
105
+ return meta;
106
+ }
107
+ #sql(operation, fn) {
108
+ return guardSql('database-relations', operation, this.#timeoutMs, fn);
109
+ }
110
+ #raw(operation, text, bindings) {
111
+ return this.#sql(operation, () => this.#connection().rawQuery(text, bindings));
112
+ }
113
+ /* ── Validación de identidad (defensa en profundidad) ─────────────────── */
114
+ /** El objeto es `{ type, id }` bien formado (el `type` ya pasó F-05 en el manager). */
115
+ #assertObject(object) {
116
+ if (!object || typeof object !== 'object') {
117
+ throw new InvalidIdentityError(`Objeto de relación inválido: llegó ${typeof object}`);
118
+ }
119
+ this.#assertId('el tipo de objeto', object.type, RELATION_ID_MAX);
120
+ this.#assertId(`el id del objeto '${object.type}'`, object.id, RELATION_ID_MAX);
121
+ }
122
+ #assertId(kind, value, max) {
123
+ if (typeof value !== 'string' || value.length === 0 || value.length > max || !RELATION_ID_FORMAT.test(value)) {
124
+ throw new InvalidIdentityError(`${kind} inválido: se esperaba una cadena de 1-${max} caracteres en minúsculas, dígitos y '._-' ` +
125
+ `(llegó ${JSON.stringify(value)})`);
126
+ }
127
+ }
128
+ /** Valida el sujeto (holder o userset) y devuelve sus columnas. */
129
+ #subjectColumns(subject, partitionKey) {
130
+ if (isRelUserset(subject)) {
131
+ this.#assertObject(subject.object);
132
+ this.#assertId(`la relación del userset '${subject.object.type}'`, subject.relation, RELATION_ID_MAX);
133
+ // El userset comparte la partición de la tupla (el manager así lo exige);
134
+ // se materializa en `subject_partition` para que el trigger lo defienda.
135
+ return { type: subject.object.type, uuid: subject.object.id, relation: subject.relation, partition: partitionKey };
136
+ }
137
+ assertSubject(subject);
138
+ return { type: subject.type, uuid: subject.uuid, relation: null, partition: null };
139
+ }
140
+ /* ── Expansión de includes (un nivel, hacia ABAJO desde la relación) ──── */
141
+ #expandDown(objectType, relation) {
142
+ const out = new Set([relation]);
143
+ const type = this.#config.objectTypes.find((t) => t.type === objectType);
144
+ const queue = [relation];
145
+ while (queue.length) {
146
+ const current = queue.pop();
147
+ const def = type?.relations.find((r) => r.name === current);
148
+ for (const inc of def?.includes ?? []) {
149
+ if (!out.has(inc)) {
150
+ out.add(inc);
151
+ queue.push(inc);
152
+ }
153
+ }
154
+ }
155
+ return [...out];
156
+ }
157
+ /* ── Escrituras ───────────────────────────────────────────────────────── */
158
+ async relate(subject, relation, object, partition, _options) {
159
+ assertScope(partition);
160
+ this.#assertObject(object);
161
+ this.#assertId(`la relación de '${object.type}'`, relation, RELATION_ID_MAX);
162
+ const partitionKey = scopeKey(partition);
163
+ const s = this.#subjectColumns(subject, partitionKey);
164
+ // Transacción INTERNA: la atomicidad trigger+insert (el trigger corre en el
165
+ // mismo INSERT; el check-then-insert idempotente va dentro de la misma
166
+ // transacción). `{trx}` NO se expone en el puerto (decisión (b), diferido).
167
+ await this.#sql('relate', () => this.#connection().transaction(async (trx) => {
168
+ const existing = await trx
169
+ .from(RELATIONS_TABLE)
170
+ .where('partition_key', partitionKey)
171
+ .where('object_type', object.type)
172
+ .where('object_uuid', object.id)
173
+ .where('relation', relation)
174
+ .where('subject_type', s.type)
175
+ .where('subject_uuid', s.uuid)
176
+ .where((b) => (s.relation === null ? b.whereNull('subject_relation') : b.where('subject_relation', s.relation)))
177
+ .limit(1);
178
+ if (existing.length > 0)
179
+ return; // idempotente (invariante 6): no duplica.
180
+ await trx.table(RELATIONS_TABLE).insert({
181
+ uuid: uuidv7(),
182
+ partition_key: partitionKey,
183
+ object_type: object.type,
184
+ object_uuid: object.id,
185
+ relation,
186
+ subject_type: s.type,
187
+ subject_uuid: s.uuid,
188
+ subject_relation: s.relation,
189
+ subject_partition: s.partition,
190
+ created_at: this.#now(),
191
+ });
192
+ }));
193
+ }
194
+ async unrelate(subject, relation, object, partition, _options) {
195
+ assertScope(partition);
196
+ this.#assertObject(object);
197
+ this.#assertId(`la relación de '${object.type}'`, relation, RELATION_ID_MAX);
198
+ const partitionKey = scopeKey(partition);
199
+ const s = this.#subjectColumns(subject, partitionKey);
200
+ await this.#sql('unrelate', () => this.#connection()
201
+ .from(RELATIONS_TABLE)
202
+ .where('partition_key', partitionKey)
203
+ .where('object_type', object.type)
204
+ .where('object_uuid', object.id)
205
+ .where('relation', relation)
206
+ .where('subject_type', s.type)
207
+ .where('subject_uuid', s.uuid)
208
+ .where((b) => (s.relation === null ? b.whereNull('subject_relation') : b.where('subject_relation', s.relation)))
209
+ .delete());
210
+ }
211
+ /* ── Lecturas ─────────────────────────────────────────────────────────── */
212
+ async check(subject, relation, object, partition) {
213
+ assertScope(partition);
214
+ this.#assertObject(object);
215
+ const partitionKey = scopeKey(partition);
216
+ const s = this.#subjectColumns(subject, partitionKey);
217
+ const relations = this.#expandDown(object.type, relation);
218
+ const meta = this.#dialectMeta();
219
+ const q = (name) => `${meta.quote}${name}${meta.quote}`;
220
+ const { cte, bindings: cteBindings } = this.#principalCte(meta, q, s, partitionKey);
221
+ const relPlaceholders = relations.map(() => '?').join(', ');
222
+ const sql = cte +
223
+ ` SELECT ${meta.hint}1 FROM ${q(RELATIONS_TABLE)} r ` +
224
+ `JOIN principal p ON r.${q('subject_type')} = p.p_type AND r.${q('subject_uuid')} = p.p_uuid ` +
225
+ `AND COALESCE(r.${q('subject_relation')}, '') = p.p_rel ` +
226
+ `WHERE r.${q('partition_key')} = ? AND r.${q('object_type')} = ? AND r.${q('object_uuid')} = ? ` +
227
+ `AND r.${q('relation')} IN (${relPlaceholders}) LIMIT 1`;
228
+ const bindings = [...cteBindings, partitionKey, object.type, object.id, ...relations];
229
+ const rows = rowsOf(await this.#raw('check', sql, bindings));
230
+ return rows.length > 0;
231
+ }
232
+ async listObjects(subject, relation, objectType, partition, _page) {
233
+ assertScope(partition);
234
+ this.#assertId('el tipo de objeto', objectType, RELATION_ID_MAX);
235
+ const partitionKey = scopeKey(partition);
236
+ const s = this.#subjectColumns(subject, partitionKey);
237
+ const relations = this.#expandDown(objectType, relation);
238
+ const meta = this.#dialectMeta();
239
+ const q = (name) => `${meta.quote}${name}${meta.quote}`;
240
+ const { cte, bindings: cteBindings } = this.#principalCte(meta, q, s, partitionKey);
241
+ const relPlaceholders = relations.map(() => '?').join(', ');
242
+ const sql = cte +
243
+ ` SELECT ${meta.hint}DISTINCT r.${q('object_uuid')} AS ${q('object_uuid')} FROM ${q(RELATIONS_TABLE)} r ` +
244
+ `JOIN principal p ON r.${q('subject_type')} = p.p_type AND r.${q('subject_uuid')} = p.p_uuid ` +
245
+ `AND COALESCE(r.${q('subject_relation')}, '') = p.p_rel ` +
246
+ `WHERE r.${q('partition_key')} = ? AND r.${q('object_type')} = ? ` +
247
+ `AND r.${q('relation')} IN (${relPlaceholders})`;
248
+ const bindings = [...cteBindings, partitionKey, objectType, ...relations];
249
+ const rows = rowsOf(await this.#raw('listObjects', sql, bindings));
250
+ const objects = rows
251
+ .map((row) => ({ type: objectType, id: String(row.object_uuid) }))
252
+ .sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
253
+ return { objects };
254
+ }
255
+ async listSubjects(relation, object, partition, _page) {
256
+ assertScope(partition);
257
+ this.#assertObject(object);
258
+ const partitionKey = scopeKey(partition);
259
+ // DIRECTOS del relation EXACTO (invariante 7): ni transitivo (eso es
260
+ // `membersOf`) ni derivado por includes. `usersetSubjects: true` ⇒ los
261
+ // usersets (`group#member`) salen junto con los holders.
262
+ const rows = await this.#sql('listSubjects', () => this.#connection()
263
+ .from(RELATIONS_TABLE)
264
+ .where('partition_key', partitionKey)
265
+ .where('object_type', object.type)
266
+ .where('object_uuid', object.id)
267
+ .where('relation', relation)
268
+ .select('subject_type', 'subject_uuid', 'subject_relation'));
269
+ const subjects = rows.map((row) => this.#rowToSubject(row));
270
+ return { subjects };
271
+ }
272
+ /**
273
+ * Membresía TRANSITIVA de un objeto-grupo: todos los HOLDERS que son `member`
274
+ * directa o a través de grupos anidados (usersets `group#member`). CTE
275
+ * recursiva hacia ABAJO por los usersets. DISTINTA de `listSubjects` (hechos
276
+ * directos): en un grupo con `member(g1#member, g2)`, `membersOf(g2)` trae a
277
+ * los holders de g1 y `listSubjects(member, g2)` solo el userset `g1#member`.
278
+ */
279
+ async membersOf(object, relation, partition, _page) {
280
+ assertScope(partition);
281
+ this.#assertObject(object);
282
+ const partitionKey = scopeKey(partition);
283
+ const relations = this.#expandDown(object.type, relation);
284
+ const meta = this.#dialectMeta();
285
+ const q = (name) => `${meta.quote}${name}${meta.quote}`;
286
+ const relPlaceholders = relations.map(() => '?').join(', ');
287
+ // `grp`: los grupos alcanzables por usersets desde (object, RS) —directos y
288
+ // anidados—. Ancla de UN solo SELECT (MySQL no mezcla UNION ALL con la
289
+ // recursión): los usersets directos del objeto para cualquier rel de RS.
290
+ const sql = `WITH RECURSIVE grp(g_uuid) AS ( ` +
291
+ `SELECT r.${q('subject_uuid')} FROM ${q(RELATIONS_TABLE)} r ` +
292
+ `WHERE r.${q('partition_key')} = ? AND r.${q('object_type')} = ? AND r.${q('object_uuid')} = ? ` +
293
+ `AND r.${q('relation')} IN (${relPlaceholders}) AND r.${q('subject_type')} = '${GROUP_TYPE}' ` +
294
+ `AND r.${q('subject_relation')} = '${GROUP_MEMBER}' ` +
295
+ `UNION ` +
296
+ `SELECT r.${q('subject_uuid')} FROM ${q(RELATIONS_TABLE)} r ` +
297
+ `JOIN grp ON r.${q('object_uuid')} = grp.g_uuid ` +
298
+ `WHERE r.${q('partition_key')} = ? AND r.${q('object_type')} = '${GROUP_TYPE}' ` +
299
+ `AND r.${q('relation')} = '${GROUP_MEMBER}' AND r.${q('subject_type')} = '${GROUP_TYPE}' ` +
300
+ `AND r.${q('subject_relation')} = '${GROUP_MEMBER}' ` +
301
+ `) ` +
302
+ // Holders directos del objeto para RS, UNION holders directos de cualquier grupo de `grp`.
303
+ `SELECT ${meta.hint}${q('subject_type')} AS ${q('subject_type')}, ${q('subject_uuid')} AS ${q('subject_uuid')} ` +
304
+ `FROM ${q(RELATIONS_TABLE)} r ` +
305
+ `WHERE r.${q('partition_key')} = ? AND r.${q('object_type')} = ? AND r.${q('object_uuid')} = ? ` +
306
+ `AND r.${q('relation')} IN (${relPlaceholders}) AND r.${q('subject_relation')} IS NULL ` +
307
+ `UNION ` +
308
+ `SELECT r.${q('subject_type')}, r.${q('subject_uuid')} FROM ${q(RELATIONS_TABLE)} r ` +
309
+ `JOIN grp ON r.${q('object_uuid')} = grp.g_uuid ` +
310
+ `WHERE r.${q('partition_key')} = ? AND r.${q('object_type')} = '${GROUP_TYPE}' ` +
311
+ `AND r.${q('relation')} = '${GROUP_MEMBER}' AND r.${q('subject_relation')} IS NULL`;
312
+ const bindings = [
313
+ // grp ancla
314
+ partitionKey, object.type, object.id, ...relations,
315
+ // grp recursiva
316
+ partitionKey,
317
+ // holders directos del objeto
318
+ partitionKey, object.type, object.id, ...relations,
319
+ // holders de los grupos
320
+ partitionKey,
321
+ ];
322
+ const rows = rowsOf(await this.#raw('membersOf', sql, bindings));
323
+ const subjects = rows.map((row) => ({ type: String(row.subject_type), uuid: String(row.subject_uuid) }));
324
+ return { subjects };
325
+ }
326
+ /* ── Purga (invariante 11): el DELETE demuestra el cero ───────────────── */
327
+ async purgeObject(object, partition) {
328
+ assertScope(partition);
329
+ this.#assertObject(object);
330
+ const partitionKeys = this.#partitionSpellings(partition);
331
+ await this.#sql('purgeObject', () => this.#connection()
332
+ .from(RELATIONS_TABLE)
333
+ .whereIn('partition_key', partitionKeys)
334
+ .where('object_type', object.type)
335
+ .where('object_uuid', object.id)
336
+ .delete());
337
+ }
338
+ async purgeSubject(subject, partition) {
339
+ assertScope(partition);
340
+ const partitionKeys = this.#partitionSpellings(partition);
341
+ const s = this.#subjectColumns(subject, scopeKey(partition));
342
+ await this.#sql('purgeSubject', () => this.#connection()
343
+ .from(RELATIONS_TABLE)
344
+ .whereIn('partition_key', partitionKeys)
345
+ .where('subject_type', s.type)
346
+ .where('subject_uuid', s.uuid)
347
+ .where((b) => (s.relation === null ? b.whereNull('subject_relation') : b.where('subject_relation', s.relation)))
348
+ .delete());
349
+ }
350
+ /* ── ORIGEN de reconcile (4-5): enumera los hechos directos ───────────── */
351
+ /**
352
+ * **`enumerateRelations` — el ORIGEN de `authz:reconcile` de relaciones**
353
+ * (4-5). Devuelve los hechos DIRECTOS de la partición (`authz_relations`),
354
+ * paginados por la PK (`uuid`, cursor que AVANZA), sin derivar por
355
+ * includes/usersets (el modelo del destino lo recompone): el destino recibe
356
+ * los hechos tal cual y decide qué escribe (invariante 7 + la higiene de
357
+ * reconcile — una caducada tendría que LLEGAR; aquí no hay caducidad, R-15
358
+ * quedó fuera). Barre las DOS ortografías del uuid de partición (🟡2,
359
+ * coherente con `purge*`): un origen que las funde no puede dejar hechos del
360
+ * alias sin migrar.
361
+ *
362
+ * **Filtra por TIPOS DECLARADOS** (⚪3, paridad con `openfga`): el driver
363
+ * `openfga` descarta de su enumeración todo `object_type` que no sea `group`
364
+ * ni un tipo de `defineRelationsConfig`; el de `database` NO lo hacía y
365
+ * devolvía TODA fila. Como `reconcileRelations` escribe `to.relate(...)`
366
+ * DIRECTO (salta el manager/F-05), una fila `object_type='role_binding'`
367
+ * sembrada a mano habría migrado al store compartido y reabierto la escalada.
368
+ * Con el filtro ambos drivers censan lo mismo y el chokepoint no deja residuo
369
+ * por el camino de reconcile.
370
+ */
371
+ async enumerateRelations(partition, page) {
372
+ assertScope(partition);
373
+ const partitionKeys = this.#partitionSpellings(partition);
374
+ const declaredTypes = [GROUP_TYPE, ...this.#config.objectTypes.map((t) => t.type)];
375
+ const limit = Math.max(1, Math.min(page?.limit ?? DEFAULT_ENUMERATE_LIMIT, MAX_ENUMERATE_LIMIT));
376
+ const after = page?.after;
377
+ const rows = await this.#sql('enumerateRelations', () => {
378
+ let q = this.#connection()
379
+ .from(RELATIONS_TABLE)
380
+ .whereIn('partition_key', partitionKeys)
381
+ .whereIn('object_type', declaredTypes)
382
+ .orderBy('uuid', 'asc')
383
+ .limit(limit + 1);
384
+ if (after)
385
+ q = q.where('uuid', '>', after);
386
+ return q.select('uuid', 'object_type', 'object_uuid', 'relation', 'subject_type', 'subject_uuid', 'subject_relation');
387
+ });
388
+ const hasMore = rows.length > limit;
389
+ const pageRows = hasMore ? rows.slice(0, limit) : rows;
390
+ const tuples = pageRows.map((row) => ({
391
+ subject: this.#rowToSubject(row),
392
+ relation: String(row.relation),
393
+ object: { type: String(row.object_type), id: String(row.object_uuid) },
394
+ // La partición canónica pedida: el barrido de ortografías ya la unificó.
395
+ partition,
396
+ }));
397
+ const cursor = hasMore ? String(pageRows[pageRows.length - 1].uuid) : undefined;
398
+ return cursor ? { tuples, cursor } : { tuples };
399
+ }
400
+ /* ── Helpers privados ─────────────────────────────────────────────────── */
401
+ /**
402
+ * **Barre AMBAS ortografías del uuid de partición** (🟡2 del auditor,
403
+ * paridad con el fix del lote 3b-2h): un motor que funde `aaa…` con `aaa-…`
404
+ * (tipo `uuid` de PG, collation `*_ci`) haría del `DELETE` un no-op sobre el
405
+ * alias y la fila real seguiría concediendo. `scopeSpellings` da la del
406
+ * llamante Y la canónica de la que puede ser alias; se convierten a clave.
407
+ */
408
+ #partitionSpellings(partition) {
409
+ const keys = scopeSpellings(partition).map((s) => scopeKey(s));
410
+ return [...new Set(keys)];
411
+ }
412
+ /**
413
+ * La CTE `principal`: el conjunto de identidades `(p_type, p_uuid, p_rel)` que
414
+ * el SUJETO «es» —él mismo (holder ⇒ `p_rel = ''`; userset ⇒ su relación) más
415
+ * cada `group#member` del que es miembro, transitivamente (grupos anidados)—.
416
+ * Un `check`/`listObjects` casa un hecho directo del objeto contra cualquiera
417
+ * de esas identidades. Devuelve el `WITH RECURSIVE …` (sin el SELECT final) y
418
+ * sus bindings.
419
+ */
420
+ #principalCte(meta, q, s, partitionKey) {
421
+ const baseRel = s.relation ?? '';
422
+ const cte = `WITH RECURSIVE principal(p_type, p_uuid, p_rel) AS ( ` +
423
+ `SELECT ${meta.text('?')}, ${meta.text('?')}, ${meta.text('?')} ` +
424
+ `UNION ` +
425
+ `SELECT ${meta.text(`'${GROUP_TYPE}'`)}, r.${q('object_uuid')}, ${meta.text(`'${GROUP_MEMBER}'`)} ` +
426
+ `FROM ${q(RELATIONS_TABLE)} r ` +
427
+ `JOIN principal p ON r.${q('subject_type')} = p.p_type AND r.${q('subject_uuid')} = p.p_uuid ` +
428
+ `AND COALESCE(r.${q('subject_relation')}, '') = p.p_rel ` +
429
+ `WHERE r.${q('partition_key')} = ? AND r.${q('object_type')} = '${GROUP_TYPE}' ` +
430
+ `AND r.${q('relation')} = '${GROUP_MEMBER}' )`;
431
+ return { cte, bindings: [s.type, s.uuid, baseRel, partitionKey] };
432
+ }
433
+ #rowToSubject(row) {
434
+ if (row.subject_relation === null || row.subject_relation === undefined) {
435
+ return { type: String(row.subject_type), uuid: String(row.subject_uuid) };
436
+ }
437
+ return { object: { type: String(row.subject_type), id: String(row.subject_uuid) }, relation: String(row.subject_relation) };
438
+ }
439
+ }
440
+ /**
441
+ * Forma del resultado crudo por cliente: pg `{ rows }`, sqlite `rows[]`,
442
+ * mysql2 `[rows[], fields[]]` (2.5 · J3).
443
+ */
444
+ function rowsOf(result) {
445
+ if (Array.isArray(result)) {
446
+ return result.length === 2 && Array.isArray(result[0]) && Array.isArray(result[1]) ? result[0] : result;
447
+ }
448
+ return result?.rows ?? [];
449
+ }
450
+ //# sourceMappingURL=database_relations_driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database_relations_driver.js","sourceRoot":"","sources":["../../../src/drivers/database_relations_driver.ts"],"names":[],"mappings":"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"}