@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 @@
1
+ {"version":3,"file":"openfga_facts.js","sourceRoot":"","sources":["../../../src/drivers/openfga_facts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ import type { RelObject, RelSubject, RelationObjectsPage, RelationSubjectsPage, RelationPage, RelationTuplePage, RelationsDriver, RelationsDriverCapabilities, RelationWriteOptions, ScopeRef } from '../types.js';
2
+ import type { HolderTypeMap } from './openfga_driver.js';
3
+ import type { RelationsConfig } from '../relations/define_relations_config.js';
4
+ export declare const DEFAULT_TIMEOUT_MS = 5000;
5
+ export interface OpenFgaRelationsDriverOptions {
6
+ apiUrl: string;
7
+ storeId: string;
8
+ /** Pin del model FUSIONADO; si se omite, FGA usa el último del store. */
9
+ modelId?: string;
10
+ /** Holders del consumidor: morph name → tipo FGA. El MISMO mapa del driver de roles. */
11
+ holderTypes: HolderTypeMap;
12
+ /** Deadline de cada llamada en ms (default 5000): vencido ⇒ 503. */
13
+ timeoutMs?: number;
14
+ /** Consistencia pedida al servidor (default `higher_consistency`, como el driver de roles). */
15
+ consistency?: 'higher_consistency' | 'minimize_latency';
16
+ /**
17
+ * El tope de `ListObjects` del servidor (`OPENFGA_LIST_OBJECTS_MAX_RESULTS`).
18
+ * Default 1000 (el default de OpenFGA). Cuando `listObjects` recibe `>= este`
19
+ * resultados, señala `truncated: true`. Ponlo igual que el del servidor.
20
+ */
21
+ listObjectsMaxResults?: number;
22
+ /** Dónde avisar de tuplas del store que el driver no puede parsear. */
23
+ logger?: {
24
+ warn(message: string): void;
25
+ };
26
+ }
27
+ export declare class OpenFgaRelationsDriver implements RelationsDriver {
28
+ #private;
29
+ /**
30
+ * Lo que declara (cada valor tiene su cara en `runRelationsDriverContract`):
31
+ * - `singleCheckRelations: true`: `check` es UN solo `Check` (el modelo
32
+ * resuelve includes + usersets del lado del servidor).
33
+ * - `listObjectsInherited: false`: `list*` no abren el subárbol de
34
+ * particiones (invariante 7); `ListObjects` sí resuelve la derivación del
35
+ * modelo (includes/usersets), que es «directos + derivados», no herencia
36
+ * de scopes.
37
+ * - `usersetSubjects: true`: `listSubjects` (`Read`) trae los usersets
38
+ * directos (`group#member`) junto con los holders.
39
+ * - `membersOfNative: false`: la membresía TRANSITIVA sería `ListUsers`, que
40
+ * trunca al tope del servidor; se declara 500 `E_AUTHZ_UNSUPPORTED`, jamás
41
+ * un userset enumerado a medias (par de `purgeRole` de la 3b).
42
+ * - `enumerateRelations: true` (4-5): es ORIGEN de `authz:reconcile` de
43
+ * relaciones — lee el store ENTERO (`Read({})`, la única forma de ver todo
44
+ * sin filtro por user u objeto: un `Read` por tipo-solo sin user es un 400)
45
+ * y devuelve SOLO las tuplas de relación de la partición (tipo declarado o
46
+ * `group`), descartando las de `facts` (scope/role/role_binding).
47
+ * - `listObjectsTruncation: true`: `ListObjects` trunca al tope del servidor
48
+ * y este driver lo SEÑALA (medido contra el `:8103` de tope 3).
49
+ */
50
+ readonly capabilities: RelationsDriverCapabilities;
51
+ private readonly client;
52
+ readonly diagnostics: {
53
+ unparseableTuples: number;
54
+ };
55
+ constructor(config: RelationsConfig, options: OpenFgaRelationsDriverOptions);
56
+ relate(subject: RelSubject, relation: string, object: RelObject, partition: ScopeRef, _options?: RelationWriteOptions): Promise<void>;
57
+ unrelate(subject: RelSubject, relation: string, object: RelObject, partition: ScopeRef, _options?: RelationWriteOptions): Promise<void>;
58
+ /** `check` = UN solo `Check` (el modelo resuelve includes + usersets). */
59
+ check(subject: RelSubject, relation: string, object: RelObject, partition: ScopeRef): Promise<boolean>;
60
+ /**
61
+ * `listObjects` = `ListObjects` (resuelve includes + usersets del lado del
62
+ * servidor) + FILTRO por partición + señal de TRUNCADO. `ListObjects` corta
63
+ * al tope del servidor sin `continuation_token` ni bandera, así que el
64
+ * truncado se detecta comparando el número de resultados CRUDOS con el tope
65
+ * configurado (`listObjectsMaxResults`): `>= tope` ⇒ no se puede prometer la
66
+ * lista completa ⇒ `truncated: true`. El filtro por partición se aplica
67
+ * DESPUÉS (los ids llevan la partición), así que en un store con varias
68
+ * particiones el tope se consume entre todas — otra razón para señalar el
69
+ * truncado y no callar (documentado en el README).
70
+ */
71
+ listObjects(subject: RelSubject, relation: string, objectType: string, partition: ScopeRef, _page?: RelationPage): Promise<RelationObjectsPage>;
72
+ /**
73
+ * `listSubjects` = `Read` por `(object, relation)` — hechos DIRECTOS del
74
+ * relation EXACTO (invariante 7): ni transitivo (eso es `membersOf`) ni
75
+ * derivado por includes. `usersetSubjects: true` ⇒ los usersets
76
+ * (`group#member`) salen junto con los holders.
77
+ */
78
+ listSubjects(relation: string, object: RelObject, partition: ScopeRef, _page?: RelationPage): Promise<RelationSubjectsPage>;
79
+ /**
80
+ * **`membersOf` ⇒ 500 `E_AUTHZ_UNSUPPORTED`** (cara `whenFalse`): la
81
+ * membresía TRANSITIVA de un grupo sería `ListUsers`, que trunca al tope del
82
+ * servidor sin señal fiable. No hay userset transitivo enumerable aquí; se
83
+ * dice con 500 nombrándolo, jamás un userset a medias. Es el análogo del par
84
+ * `purgeRole` de la 3b. (El método existe en el prototipo para que el manager
85
+ * lo despache, pero la capacidad `membersOfNative: false` lo corta antes.)
86
+ */
87
+ membersOf(): Promise<RelationSubjectsPage>;
88
+ /**
89
+ * **`enumerateRelations` — el ORIGEN de `authz:reconcile` de relaciones**
90
+ * (4-5). Lee el store ENTERO (`Read({})`) —la única forma de ver todo sin un
91
+ * filtro por `user` u `object`, que un `Read` por tipo-solo sin user
92
+ * rechazaría con 400— y devuelve SOLO las tuplas de relación de la partición
93
+ * pedida: tipo `group` o un tipo declarado en la config, DESCARTANDO las de
94
+ * `facts` (`scope`/`role`/`role_binding`, que no llevan la partición en el id
95
+ * con la forma `<key>|<uuid>` de relaciones —o cuyo tipo no está declarado—).
96
+ *
97
+ * `truncated`/paginación: `enumerateRelations` agota el `Read` (exhaustivo,
98
+ * como `listSubjects`/`purge*`), así que devuelve TODO en una página sin
99
+ * cursor —el reconcile itera hasta que no hay cursor—. Es el ORIGEN de una
100
+ * migración: una tupla que no llegara aquí desaparecería sin rastro.
101
+ */
102
+ enumerateRelations(partition: ScopeRef, _page?: RelationPage): Promise<RelationTuplePage>;
103
+ /**
104
+ * Borra TODAS las tuplas del objeto (cualquier relación) y demuestra cero.
105
+ * Barre las DOS ortografías del uuid de partición (🟡2, paridad con
106
+ * `database`): un motor que funda `aaa…` con `aaa-…` dejaría la fila del
107
+ * alias concediendo tras una purga «exitosa». Si tras borrar quedan tuplas
108
+ * ⇒ 500 `E_AUTHZ_PURGE_INCOMPLETE`.
109
+ */
110
+ purgeObject(object: RelObject, partition: ScopeRef): Promise<void>;
111
+ /**
112
+ * Borra TODAS las tuplas cuyo SUJETO es este subject en la partición, en
113
+ * cualquier tipo de objeto declarado, y demuestra cero. `Read` exige un
114
+ * filtro de objeto (un `Read` solo por `user` es un 400 del servidor), así
115
+ * que se recorre cada tipo declarado (`group` + los del consumidor) con
116
+ * `Read({ user, object: '<type>:' })`.
117
+ */
118
+ purgeSubject(subject: RelSubject, partition: ScopeRef): Promise<void>;
119
+ }
120
+ //# sourceMappingURL=openfga_relations_driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openfga_relations_driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/openfga_relations_driver.ts"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EAEZ,iBAAiB,EACjB,eAAe,EACf,2BAA2B,EAC3B,oBAAoB,EACpB,QAAQ,EAET,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAA;AAE9E,eAAO,MAAM,kBAAkB,OAAQ,CAAA;AAgCvC,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wFAAwF;IACxF,WAAW,EAAE,aAAa,CAAA;IAC1B,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+FAA+F;IAC/F,WAAW,CAAC,EAAE,oBAAoB,GAAG,kBAAkB,CAAA;IACvD;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,uEAAuE;IACvE,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CACzC;AAED,qBAAa,sBAAuB,YAAW,eAAe;;IAC5D;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,YAAY,EAAE,2BAA2B,CAOhD;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IASvC,QAAQ,CAAC,WAAW;;MAA2B;gBAEnC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,6BAA6B;IA+GrE,MAAM,CACV,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,IAAI,CAAC;IAYV,QAAQ,CACZ,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,IAAI,CAAC;IAahB,0EAA0E;IACpE,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAW5G;;;;;;;;;;OAUG;IACG,WAAW,CACf,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,QAAQ,EACnB,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,mBAAmB,CAAC;IAuB/B;;;;;OAKG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,QAAQ,EACnB,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,oBAAoB,CAAC;IAchC;;;;;;;OAOG;IACG,SAAS,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAYhD;;;;;;;;;;;;;OAaG;IACG,kBAAkB,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA6B/F;;;;;;OAMG;IACG,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxE;;;;;;OAMG;IACG,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CA+G5E"}
@@ -0,0 +1,466 @@
1
+ /**
2
+ * Driver `openfga` del puerto `RelationsDriver` — ReBAC sobre el MISMO store y
3
+ * `modelId` que el driver `facts` de roles (Fase 4, lote 4-4).
4
+ *
5
+ * Store COMPARTIDO (decisión del dueño / juez §2): las relaciones ReBAC viven
6
+ * en el modelo FUSIONADO (`facts` + `group` + los tipos de objeto del
7
+ * consumidor), así que `relate`/`unrelate` son `Write`/delete de tuplas del
8
+ * mismo store, `check` es UN solo `Check` (el modelo resuelve includes +
9
+ * usersets del lado del servidor) y `list*` van por `ListObjects`/`Read`.
10
+ *
11
+ * **La partición va en el ID del objeto y del userset**, no en el modelo:
12
+ * `document:<scopeKey(partition)>|<uuid>`, `group:<scopeKey(partition)>|<uuid>#member`.
13
+ * El cruce de particiones se corta por comparación de string —aquí NO hay
14
+ * trigger como en `database`, así que F-05 (en el manager) + la comparación de
15
+ * string son la ÚNICA defensa de tenant—. El id lleva DOS `|` cuando la
16
+ * partición es un scope no-raíz (`document:unit|<partUuid>|<objUuid>`), así que
17
+ * el parseo es CANÓNICO desde la DERECHA (⚪5, el mismo cuidado que
18
+ * `parseBindingId`): partición = todo menos el ÚLTIMO segmento; el id del
19
+ * objeto es el último y no contiene `|`.
20
+ *
21
+ * **La frontera del 🔴 (F-05) NO vive aquí**: la cierra el `RelationsManager`
22
+ * ANTES de tocar el driver (un `object.type` no declarado ⇒ 422) junto con ⚪4
23
+ * (un tipo reservado no se puede declarar). Si a este driver se le llama en
24
+ * DIRECTO con `object.type: 'role_binding'` (la salida `manager.driver()`, de
25
+ * plataforma), compondría el id de un binding real y escalaría — por eso el
26
+ * caso-exploit del auditor se cierra en el manager, y el runner publica el
27
+ * caso para que un driver de terceros que no lo cumpla NO pase el contrato.
28
+ *
29
+ * Pureza: vive detrás del subpath `@jantstack/adonis-authz/openfga`
30
+ * (`src/openfga.ts`), como el driver `facts` de roles: es lo único que puede
31
+ * tocar `@openfga/sdk` (peer opcional). La abstracción no filtra: ningún error
32
+ * del SDK escapa (todo va por `#guard`, que clasifica a 503/timeout).
33
+ */
34
+ import { OpenFgaClient, ConsistencyPreference, ClientWriteRequestOnMissingDeletes, ClientWriteRequestOnDuplicateWrites, } from '@openfga/sdk';
35
+ import { AuthorizationBackendError, AuthorizationBackendTimeoutError, InvalidIdentityError, PurgeIncompleteError, UnsupportedOperationError, } from '../errors.js';
36
+ import { assertScope, assertSubject, assertRelationId, scopeKey, scopeSpellings } from '../identity.js';
37
+ import { isRelUserset } from '../types.js';
38
+ import { assertFgaObjectId, FACTS_GROUP_TYPE } from './openfga_facts.js';
39
+ export const DEFAULT_TIMEOUT_MS = 5_000;
40
+ /** Tope de operaciones por `Write` en FGA (`exceeded_entity_limit` a partir de 100). */
41
+ const WRITE_BATCH_SIZE = 100;
42
+ /** Tamaño de página de `Read` (máximo del servidor). */
43
+ const READ_PAGE_SIZE = 100;
44
+ /**
45
+ * Cota de páginas de una enumeración por `Read`. Un `continuation_token` que
46
+ * no avanza (servidor roto, proxy, caché) sería un bucle que ningún deadline
47
+ * corta (el deadline es por llamada). Mismo patrón que el driver de roles.
48
+ */
49
+ const MAX_READ_PAGES = 10_000;
50
+ /**
51
+ * El tope de `ListObjects` del servidor por defecto (`OPENFGA_LIST_OBJECTS_MAX_RESULTS`).
52
+ * `ListObjects` NO devuelve señal de truncado ni `continuation_token`: corta al
53
+ * tope y calla. La única forma honesta de detectar el corte es comparar el
54
+ * número de resultados con el tope CONFIGURADO del servidor —de ahí la opción
55
+ * `listObjectsMaxResults`—: si vuelven `>= tope`, no se puede prometer que la
56
+ * lista esté completa ⇒ `truncated: true` (lección S16/L0.7: nunca una lista
57
+ * parcial MUDA). Ponerlo por debajo del tope real del servidor daría un
58
+ * truncado FALSO (el servidor devolvió todo); por encima, se perdería el corte.
59
+ */
60
+ const DEFAULT_LIST_OBJECTS_MAX = 1_000;
61
+ /** Ignora duplicados: las tuplas de relación no llevan condición (idénticas por construcción). */
62
+ const IGNORE_DUPLICATE_WRITES = {
63
+ conflict: { onDuplicateWrites: ClientWriteRequestOnDuplicateWrites.Ignore },
64
+ };
65
+ /** Ignora deletes de tuplas ya ausentes (re-unrelate no-op seguro, invariante 6). */
66
+ const IGNORE_MISSING_DELETES = {
67
+ conflict: { onMissingDeletes: ClientWriteRequestOnMissingDeletes.Ignore },
68
+ };
69
+ export class OpenFgaRelationsDriver {
70
+ /**
71
+ * Lo que declara (cada valor tiene su cara en `runRelationsDriverContract`):
72
+ * - `singleCheckRelations: true`: `check` es UN solo `Check` (el modelo
73
+ * resuelve includes + usersets del lado del servidor).
74
+ * - `listObjectsInherited: false`: `list*` no abren el subárbol de
75
+ * particiones (invariante 7); `ListObjects` sí resuelve la derivación del
76
+ * modelo (includes/usersets), que es «directos + derivados», no herencia
77
+ * de scopes.
78
+ * - `usersetSubjects: true`: `listSubjects` (`Read`) trae los usersets
79
+ * directos (`group#member`) junto con los holders.
80
+ * - `membersOfNative: false`: la membresía TRANSITIVA sería `ListUsers`, que
81
+ * trunca al tope del servidor; se declara 500 `E_AUTHZ_UNSUPPORTED`, jamás
82
+ * un userset enumerado a medias (par de `purgeRole` de la 3b).
83
+ * - `enumerateRelations: true` (4-5): es ORIGEN de `authz:reconcile` de
84
+ * relaciones — lee el store ENTERO (`Read({})`, la única forma de ver todo
85
+ * sin filtro por user u objeto: un `Read` por tipo-solo sin user es un 400)
86
+ * y devuelve SOLO las tuplas de relación de la partición (tipo declarado o
87
+ * `group`), descartando las de `facts` (scope/role/role_binding).
88
+ * - `listObjectsTruncation: true`: `ListObjects` trunca al tope del servidor
89
+ * y este driver lo SEÑALA (medido contra el `:8103` de tope 3).
90
+ */
91
+ capabilities = Object.freeze({
92
+ singleCheckRelations: true,
93
+ listObjectsInherited: false,
94
+ usersetSubjects: true,
95
+ membersOfNative: false,
96
+ enumerateRelations: true,
97
+ listObjectsTruncation: true,
98
+ });
99
+ client;
100
+ #config;
101
+ #holderTypes;
102
+ #fgaToMorph;
103
+ #timeoutMs;
104
+ #consistency;
105
+ #listObjectsMax;
106
+ #logger;
107
+ diagnostics = { unparseableTuples: 0 };
108
+ constructor(config, options) {
109
+ this.#config = config;
110
+ this.#holderTypes = options.holderTypes;
111
+ this.#fgaToMorph = Object.fromEntries(Object.entries(options.holderTypes).map(([morph, fga]) => [fga, morph]));
112
+ this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
113
+ this.#consistency =
114
+ options.consistency === 'minimize_latency'
115
+ ? ConsistencyPreference.MinimizeLatency
116
+ : ConsistencyPreference.HigherConsistency;
117
+ this.#listObjectsMax = options.listObjectsMaxResults ?? DEFAULT_LIST_OBJECTS_MAX;
118
+ this.#logger = options.logger ?? console;
119
+ this.client = new OpenFgaClient({
120
+ apiUrl: options.apiUrl,
121
+ storeId: options.storeId,
122
+ authorizationModelId: options.modelId,
123
+ baseOptions: { timeout: this.#timeoutMs },
124
+ retryParams: { maxRetry: 0 },
125
+ });
126
+ }
127
+ /* ── Clasificación de fallos (la abstracción no filtra) ─────────────────── */
128
+ async #guard(operation, fn) {
129
+ try {
130
+ return await fn();
131
+ }
132
+ catch (error) {
133
+ // Un error del paquete (422/500 ya clasificado) se propaga tal cual.
134
+ if (error instanceof InvalidIdentityError || error instanceof PurgeIncompleteError)
135
+ throw error;
136
+ if (isTimeoutLike(error)) {
137
+ throw new AuthorizationBackendTimeoutError('openfga-relations', operation, this.#timeoutMs, error);
138
+ }
139
+ throw new AuthorizationBackendError('openfga-relations', operation, error);
140
+ }
141
+ }
142
+ /* ── Composición y parseo de ids (⚪5: partición por string en el id) ────── */
143
+ /** `<type>:<scopeKey(partition)>|<objectUuid>`. */
144
+ #objectId(objectType, partitionKey, objectUuid) {
145
+ // R-16 (defensa en profundidad, paridad con `database`): el `object.id` con
146
+ // la gramática estricta ANTES de componer. Un `|`/`#`/`:`/espacio dentro se
147
+ // escribía (solo se medía la longitud) y luego se perdía en el parseo por
148
+ // el último `|` —invisible en enumeración y `reconcile`—. `manager.driver()`
149
+ // salta el manager, así que el driver aplica la MISMA regla que él.
150
+ assertRelationId(`el id del objeto '${objectType}'`, objectUuid);
151
+ const id = `${objectType}:${partitionKey}|${objectUuid}`;
152
+ assertFgaObjectId(objectType, id);
153
+ return id;
154
+ }
155
+ /**
156
+ * El `user` FGA de un sujeto: holder ⇒ `<fgaType>:<uuid>`; userset ⇒
157
+ * `<type>:<scopeKey(partition)>|<objUuid>#<relation>`. El userset comparte la
158
+ * partición de la tupla (el manager lo exige).
159
+ */
160
+ #subjectUser(subject, partitionKey) {
161
+ if (isRelUserset(subject)) {
162
+ const object = this.#objectId(subject.object.type, partitionKey, subject.object.id);
163
+ return `${object}#${subject.relation}`;
164
+ }
165
+ const fgaType = this.#holderTypes[subject.type];
166
+ if (!fgaType) {
167
+ throw new InvalidIdentityError(`Holder type '${subject.type}' no está en holderTypes del driver openfga de relaciones ` +
168
+ `(declarados: ${Object.keys(this.#holderTypes).join(', ') || 'ninguno'}).`);
169
+ }
170
+ return `${fgaType}:${subject.uuid}`;
171
+ }
172
+ /**
173
+ * **Parseo CANÓNICO del id de un objeto de relación** (⚪5): a partir de
174
+ * `<type>:<scopeKey>|<objUuid>`, separa `type` (antes del primer `:`),
175
+ * `partitionKey` (todo menos el ÚLTIMO segmento tras el `:`) y `objectUuid`
176
+ * (el último segmento, que no contiene `|`). Es el MISMO parseo-desde-la-
177
+ * derecha que `parseBindingId`: `lastIndexOf('|')` corta el objeto de la
178
+ * clave de partición (que tiene 1 parte `app` o 2 `<tipo>|<uuid>`). `null` si
179
+ * el id no tiene la forma que este driver escribe.
180
+ */
181
+ #parseObjectId(fullId) {
182
+ const colon = fullId.indexOf(':');
183
+ if (colon <= 0)
184
+ return null;
185
+ const type = fullId.slice(0, colon);
186
+ const rest = fullId.slice(colon + 1);
187
+ const cut = rest.lastIndexOf('|');
188
+ if (cut < 0)
189
+ return null;
190
+ const partitionKey = rest.slice(0, cut);
191
+ const objectUuid = rest.slice(cut + 1);
192
+ if (!partitionKey || !objectUuid)
193
+ return null;
194
+ return { type, partitionKey, objectUuid };
195
+ }
196
+ /** Un `user` del store de vuelta a `RelSubject`: userset (`…#rel`) o holder (`<fga>:<uuid>`). */
197
+ #userToSubject(user) {
198
+ const hash = user.indexOf('#');
199
+ if (hash >= 0) {
200
+ const parsed = this.#parseObjectId(user.slice(0, hash));
201
+ const relation = user.slice(hash + 1);
202
+ if (!parsed || !relation)
203
+ return null;
204
+ return { object: { type: parsed.type, id: parsed.objectUuid }, relation };
205
+ }
206
+ const colon = user.indexOf(':');
207
+ if (colon <= 0)
208
+ return null;
209
+ const morph = this.#fgaToMorph[user.slice(0, colon)];
210
+ const uuid = user.slice(colon + 1);
211
+ if (!morph || !uuid || uuid === '*' || uuid.includes('|'))
212
+ return null;
213
+ return { type: morph, uuid };
214
+ }
215
+ /* ── Escrituras ─────────────────────────────────────────────────────────── */
216
+ async relate(subject, relation, object, partition, _options) {
217
+ assertScope(partition);
218
+ const partitionKey = scopeKey(partition);
219
+ const objectId = this.#objectId(object.type, partitionKey, object.id);
220
+ const user = this.#subjectUser(subject, partitionKey);
221
+ await this.#guard('relate', () =>
222
+ // Idempotente (invariante 6): un `Write` de una tupla que ya está es un
223
+ // duplicado idéntico (sin condición), así que se ignora.
224
+ this.client.write({ writes: [{ user, relation, object: objectId }] }, IGNORE_DUPLICATE_WRITES));
225
+ }
226
+ async unrelate(subject, relation, object, partition, _options) {
227
+ assertScope(partition);
228
+ const partitionKey = scopeKey(partition);
229
+ const objectId = this.#objectId(object.type, partitionKey, object.id);
230
+ const user = this.#subjectUser(subject, partitionKey);
231
+ await this.#guard('unrelate', () =>
232
+ // Re-unrelate no-op seguro: borrar una tupla ausente se ignora.
233
+ this.client.write({ deletes: [{ user, relation, object: objectId }] }, IGNORE_MISSING_DELETES));
234
+ }
235
+ /* ── Lecturas ───────────────────────────────────────────────────────────── */
236
+ /** `check` = UN solo `Check` (el modelo resuelve includes + usersets). */
237
+ async check(subject, relation, object, partition) {
238
+ assertScope(partition);
239
+ const partitionKey = scopeKey(partition);
240
+ const objectId = this.#objectId(object.type, partitionKey, object.id);
241
+ const user = this.#subjectUser(subject, partitionKey);
242
+ const response = await this.#guard('check', () => this.client.check({ user, relation, object: objectId }, { consistency: this.#consistency }));
243
+ return response.allowed === true;
244
+ }
245
+ /**
246
+ * `listObjects` = `ListObjects` (resuelve includes + usersets del lado del
247
+ * servidor) + FILTRO por partición + señal de TRUNCADO. `ListObjects` corta
248
+ * al tope del servidor sin `continuation_token` ni bandera, así que el
249
+ * truncado se detecta comparando el número de resultados CRUDOS con el tope
250
+ * configurado (`listObjectsMaxResults`): `>= tope` ⇒ no se puede prometer la
251
+ * lista completa ⇒ `truncated: true`. El filtro por partición se aplica
252
+ * DESPUÉS (los ids llevan la partición), así que en un store con varias
253
+ * particiones el tope se consume entre todas — otra razón para señalar el
254
+ * truncado y no callar (documentado en el README).
255
+ */
256
+ async listObjects(subject, relation, objectType, partition, _page) {
257
+ assertScope(partition);
258
+ const partitionKey = scopeKey(partition);
259
+ const user = this.#subjectUser(subject, partitionKey);
260
+ const response = await this.#guard('listObjects', () => this.client.listObjects({ user, relation, type: objectType }, { consistency: this.#consistency }));
261
+ const raw = response.objects ?? [];
262
+ const truncated = raw.length >= this.#listObjectsMax;
263
+ const objects = [];
264
+ for (const full of raw) {
265
+ const parsed = this.#parseObjectId(full);
266
+ if (!parsed || parsed.type !== objectType) {
267
+ this.#warnUnparseable('listObjects', full);
268
+ continue;
269
+ }
270
+ if (parsed.partitionKey !== partitionKey)
271
+ continue; // otra partición: no cruza
272
+ objects.push({ type: objectType, id: parsed.objectUuid });
273
+ }
274
+ objects.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
275
+ return truncated ? { objects, truncated: true } : { objects };
276
+ }
277
+ /**
278
+ * `listSubjects` = `Read` por `(object, relation)` — hechos DIRECTOS del
279
+ * relation EXACTO (invariante 7): ni transitivo (eso es `membersOf`) ni
280
+ * derivado por includes. `usersetSubjects: true` ⇒ los usersets
281
+ * (`group#member`) salen junto con los holders.
282
+ */
283
+ async listSubjects(relation, object, partition, _page) {
284
+ assertScope(partition);
285
+ const partitionKey = scopeKey(partition);
286
+ const objectId = this.#objectId(object.type, partitionKey, object.id);
287
+ const tuples = await this.#readAll('listSubjects', { object: objectId, relation });
288
+ const subjects = [];
289
+ for (const t of tuples) {
290
+ const subject = this.#userToSubject(t.user);
291
+ if (subject)
292
+ subjects.push(subject);
293
+ else
294
+ this.#warnUnparseable('listSubjects', t.user);
295
+ }
296
+ return { subjects };
297
+ }
298
+ /**
299
+ * **`membersOf` ⇒ 500 `E_AUTHZ_UNSUPPORTED`** (cara `whenFalse`): la
300
+ * membresía TRANSITIVA de un grupo sería `ListUsers`, que trunca al tope del
301
+ * servidor sin señal fiable. No hay userset transitivo enumerable aquí; se
302
+ * dice con 500 nombrándolo, jamás un userset a medias. Es el análogo del par
303
+ * `purgeRole` de la 3b. (El método existe en el prototipo para que el manager
304
+ * lo despache, pero la capacidad `membersOfNative: false` lo corta antes.)
305
+ */
306
+ async membersOf() {
307
+ throw new UnsupportedOperationError('membersOf', 'la membresía transitiva de un grupo', 'openfga', `En 'openfga' la transitiva sería 'ListUsers', que trunca al tope del servidor sin señal fiable. ` +
308
+ `Usa el driver 'database' (CTE recursiva) o 'listSubjects' para los hechos directos.`);
309
+ }
310
+ /* ── ORIGEN de reconcile (4-5): las tuplas de relación de la partición ──── */
311
+ /**
312
+ * **`enumerateRelations` — el ORIGEN de `authz:reconcile` de relaciones**
313
+ * (4-5). Lee el store ENTERO (`Read({})`) —la única forma de ver todo sin un
314
+ * filtro por `user` u `object`, que un `Read` por tipo-solo sin user
315
+ * rechazaría con 400— y devuelve SOLO las tuplas de relación de la partición
316
+ * pedida: tipo `group` o un tipo declarado en la config, DESCARTANDO las de
317
+ * `facts` (`scope`/`role`/`role_binding`, que no llevan la partición en el id
318
+ * con la forma `<key>|<uuid>` de relaciones —o cuyo tipo no está declarado—).
319
+ *
320
+ * `truncated`/paginación: `enumerateRelations` agota el `Read` (exhaustivo,
321
+ * como `listSubjects`/`purge*`), así que devuelve TODO en una página sin
322
+ * cursor —el reconcile itera hasta que no hay cursor—. Es el ORIGEN de una
323
+ * migración: una tupla que no llegara aquí desaparecería sin rastro.
324
+ */
325
+ async enumerateRelations(partition, _page) {
326
+ assertScope(partition);
327
+ const partitionKey = scopeKey(partition);
328
+ const relationTypes = new Set([FACTS_GROUP_TYPE, ...this.#config.objectTypes.map((t) => t.type)]);
329
+ const all = await this.#readAll('enumerateRelations', {});
330
+ const tuples = [];
331
+ for (const key of all) {
332
+ const parsed = this.#parseObjectId(key.object);
333
+ // No es una tupla de relación (facts: scope/role/role_binding, o un tipo
334
+ // no declarado): no la migra este puerto.
335
+ if (!parsed || !relationTypes.has(parsed.type))
336
+ continue;
337
+ if (parsed.partitionKey !== partitionKey)
338
+ continue; // otra partición: no cruza
339
+ const subject = this.#userToSubject(key.user);
340
+ if (!subject) {
341
+ this.#warnUnparseable('enumerateRelations', key.user);
342
+ continue;
343
+ }
344
+ tuples.push({
345
+ subject,
346
+ relation: key.relation,
347
+ object: { type: parsed.type, id: parsed.objectUuid },
348
+ partition,
349
+ });
350
+ }
351
+ return { tuples };
352
+ }
353
+ /* ── Purga (invariante 11): borra y DEMUESTRA cero, o lanza ─────────────── */
354
+ /**
355
+ * Borra TODAS las tuplas del objeto (cualquier relación) y demuestra cero.
356
+ * Barre las DOS ortografías del uuid de partición (🟡2, paridad con
357
+ * `database`): un motor que funda `aaa…` con `aaa-…` dejaría la fila del
358
+ * alias concediendo tras una purga «exitosa». Si tras borrar quedan tuplas
359
+ * ⇒ 500 `E_AUTHZ_PURGE_INCOMPLETE`.
360
+ */
361
+ async purgeObject(object, partition) {
362
+ assertScope(partition);
363
+ const objectIds = this.#partitionSpellings(partition).map((key) => this.#objectId(object.type, key, object.id));
364
+ for (const objectId of objectIds) {
365
+ await this.#purgeByFilter('purgeObject', { object: objectId }, `objeto ${objectId}`);
366
+ }
367
+ }
368
+ /**
369
+ * Borra TODAS las tuplas cuyo SUJETO es este subject en la partición, en
370
+ * cualquier tipo de objeto declarado, y demuestra cero. `Read` exige un
371
+ * filtro de objeto (un `Read` solo por `user` es un 400 del servidor), así
372
+ * que se recorre cada tipo declarado (`group` + los del consumidor) con
373
+ * `Read({ user, object: '<type>:' })`.
374
+ */
375
+ async purgeSubject(subject, partition) {
376
+ assertScope(partition);
377
+ if (!isRelUserset(subject))
378
+ assertSubject(subject);
379
+ const partitionKeys = this.#partitionSpellings(partition);
380
+ const types = [FACTS_GROUP_TYPE, ...this.#config.objectTypes.map((t) => t.type)];
381
+ for (const partitionKey of partitionKeys) {
382
+ const user = this.#subjectUser(subject, partitionKey);
383
+ for (const type of types) {
384
+ await this.#purgeByFilter('purgeSubject', { user, object: `${type}:` }, `sujeto ${user} en '${type}'`);
385
+ }
386
+ }
387
+ }
388
+ /** Lee por filtro, borra en lotes, y RE-LEE para demostrar cero (o lanza). */
389
+ async #purgeByFilter(operation, filter, what) {
390
+ const keys = await this.#readAll(operation, filter);
391
+ for (let i = 0; i < keys.length; i += WRITE_BATCH_SIZE) {
392
+ await this.#guard(operation, () => this.client.deleteTuples(keys.slice(i, i + WRITE_BATCH_SIZE).map((k) => ({ user: k.user, relation: k.relation, object: k.object })), IGNORE_MISSING_DELETES));
393
+ }
394
+ if (keys.length === 0)
395
+ return;
396
+ // Demostración de cero: re-lee tras borrar (invariante 11).
397
+ const residue = await this.#readAll(operation, filter);
398
+ if (residue.length > 0) {
399
+ throw new PurgeIncompleteError(`${operation}: quedan ${residue.length} tuplas de ${what} tras el borrado ` +
400
+ `(${residue.slice(0, 3).map((k) => `${k.user}#${k.relation}@${k.object}`).join('; ')}). ` +
401
+ `No se confirma la purga.`);
402
+ }
403
+ }
404
+ /* ── Helpers ────────────────────────────────────────────────────────────── */
405
+ /** Las dos ortografías del uuid de partición, como claves de scope (🟡2). */
406
+ #partitionSpellings(partition) {
407
+ return [...new Set(scopeSpellings(partition).map((s) => scopeKey(s)))];
408
+ }
409
+ /**
410
+ * TODAS las tuplas que casan con el filtro, paginando `Read` hasta agotar el
411
+ * `continuation_token`. `Read` no tiene tope de resultados (a diferencia de
412
+ * `ListObjects`), así que es exhaustivo — por eso las purgas y `listSubjects`
413
+ * van por aquí, no por `ListObjects`.
414
+ */
415
+ async #readAll(operation, filter) {
416
+ const keys = [];
417
+ let continuationToken;
418
+ const seenTokens = new Set();
419
+ let pages = 0;
420
+ do {
421
+ const response = await this.#guard(operation, () => this.client.read(filter, {
422
+ pageSize: READ_PAGE_SIZE,
423
+ continuationToken,
424
+ consistency: this.#consistency,
425
+ }));
426
+ pages += 1;
427
+ for (const tuple of response.tuples ?? []) {
428
+ const key = tuple?.key;
429
+ if (!key?.user || !key?.relation || !key?.object) {
430
+ this.#warnUnparseable(operation, JSON.stringify(key ?? null));
431
+ continue;
432
+ }
433
+ keys.push({ user: key.user, relation: key.relation, object: key.object });
434
+ }
435
+ continuationToken = response.continuation_token || undefined;
436
+ if (continuationToken) {
437
+ if (seenTokens.has(continuationToken)) {
438
+ throw new AuthorizationBackendError('openfga-relations', operation, new Error(`el continuation_token se repite (página ${pages}); el servidor no avanza`));
439
+ }
440
+ if (pages >= MAX_READ_PAGES) {
441
+ throw new AuthorizationBackendError('openfga-relations', operation, new Error(`más de ${MAX_READ_PAGES} páginas sin agotar el Read`));
442
+ }
443
+ seenTokens.add(continuationToken);
444
+ }
445
+ } while (continuationToken);
446
+ return keys;
447
+ }
448
+ #warnUnparseable(operation, detail) {
449
+ this.diagnostics.unparseableTuples += 1;
450
+ this.#logger.warn(`authz(openfga-relations): tupla no parseable en ${operation} (${detail}); ` +
451
+ `se ignora en la enumeración (total: ${this.diagnostics.unparseableTuples})`);
452
+ }
453
+ }
454
+ /** ¿El error huele a timeout de red/axios? (mismo criterio que el driver de roles). */
455
+ function isTimeoutLike(error) {
456
+ let current = error;
457
+ for (let depth = 0; current && depth < 6; depth++) {
458
+ const code = String(current.code ?? '');
459
+ if (code === 'ECONNABORTED' || code === 'ETIMEDOUT' || /timeout/i.test(String(current.message ?? ''))) {
460
+ return true;
461
+ }
462
+ current = current.cause;
463
+ }
464
+ return false;
465
+ }
466
+ //# sourceMappingURL=openfga_relations_driver.js.map