@jantstack/adonis-authz 1.1.0 → 2.0.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 (132) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +417 -58
  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_sync.d.ts +20 -0
  8. package/build/commands/authz_catalog_sync.d.ts.map +1 -0
  9. package/build/commands/authz_catalog_sync.js +58 -0
  10. package/build/commands/authz_catalog_sync.js.map +1 -0
  11. package/build/commands/main.d.ts +2 -0
  12. package/build/commands/main.d.ts.map +1 -1
  13. package/build/commands/main.js +2 -0
  14. package/build/commands/main.js.map +1 -1
  15. package/build/commands/openfga_import.d.ts +8 -2
  16. package/build/commands/openfga_import.d.ts.map +1 -1
  17. package/build/commands/openfga_import.js +29 -6
  18. package/build/commands/openfga_import.js.map +1 -1
  19. package/build/commands/openfga_provision.d.ts.map +1 -1
  20. package/build/commands/openfga_provision.js +2 -1
  21. package/build/commands/openfga_provision.js.map +1 -1
  22. package/build/index.d.ts +45 -6
  23. package/build/index.d.ts.map +1 -1
  24. package/build/index.js +37 -4
  25. package/build/index.js.map +1 -1
  26. package/build/src/catalog.d.ts +249 -2
  27. package/build/src/catalog.d.ts.map +1 -1
  28. package/build/src/catalog.js +709 -59
  29. package/build/src/catalog.js.map +1 -1
  30. package/build/src/catalog_cache.d.ts +300 -0
  31. package/build/src/catalog_cache.d.ts.map +1 -0
  32. package/build/src/catalog_cache.js +656 -0
  33. package/build/src/catalog_cache.js.map +1 -0
  34. package/build/src/clock.d.ts +24 -0
  35. package/build/src/clock.d.ts.map +1 -0
  36. package/build/src/clock.js +7 -0
  37. package/build/src/clock.js.map +1 -0
  38. package/build/src/define_config.d.ts +102 -6
  39. package/build/src/define_config.d.ts.map +1 -1
  40. package/build/src/define_config.js.map +1 -1
  41. package/build/src/drivers/backend_guard.d.ts +92 -0
  42. package/build/src/drivers/backend_guard.d.ts.map +1 -0
  43. package/build/src/drivers/backend_guard.js +221 -0
  44. package/build/src/drivers/backend_guard.js.map +1 -0
  45. package/build/src/drivers/database_driver.d.ts +242 -15
  46. package/build/src/drivers/database_driver.d.ts.map +1 -1
  47. package/build/src/drivers/database_driver.js +692 -127
  48. package/build/src/drivers/database_driver.js.map +1 -1
  49. package/build/src/drivers/openfga_driver.d.ts +341 -27
  50. package/build/src/drivers/openfga_driver.d.ts.map +1 -1
  51. package/build/src/drivers/openfga_driver.js +1020 -271
  52. package/build/src/drivers/openfga_driver.js.map +1 -1
  53. package/build/src/drivers/sql_expiry.d.ts +53 -0
  54. package/build/src/drivers/sql_expiry.d.ts.map +1 -0
  55. package/build/src/drivers/sql_expiry.js +66 -0
  56. package/build/src/drivers/sql_expiry.js.map +1 -0
  57. package/build/src/errors.d.ts +333 -0
  58. package/build/src/errors.d.ts.map +1 -1
  59. package/build/src/errors.js +352 -0
  60. package/build/src/errors.js.map +1 -1
  61. package/build/src/expiry.d.ts +27 -0
  62. package/build/src/expiry.d.ts.map +1 -0
  63. package/build/src/expiry.js +50 -0
  64. package/build/src/expiry.js.map +1 -0
  65. package/build/src/hierarchical_resolver.d.ts +56 -0
  66. package/build/src/hierarchical_resolver.d.ts.map +1 -0
  67. package/build/src/hierarchical_resolver.js +87 -0
  68. package/build/src/hierarchical_resolver.js.map +1 -0
  69. package/build/src/identity.d.ts +155 -0
  70. package/build/src/identity.d.ts.map +1 -0
  71. package/build/src/identity.js +359 -0
  72. package/build/src/identity.js.map +1 -0
  73. package/build/src/manager.d.ts +225 -7
  74. package/build/src/manager.d.ts.map +1 -1
  75. package/build/src/manager.js +1670 -23
  76. package/build/src/manager.js.map +1 -1
  77. package/build/src/memoize_ancestors.d.ts +23 -0
  78. package/build/src/memoize_ancestors.d.ts.map +1 -0
  79. package/build/src/memoize_ancestors.js +42 -0
  80. package/build/src/memoize_ancestors.js.map +1 -0
  81. package/build/src/middleware/app_access_middleware.d.ts +8 -6
  82. package/build/src/middleware/app_access_middleware.d.ts.map +1 -1
  83. package/build/src/middleware/app_access_middleware.js +10 -26
  84. package/build/src/middleware/app_access_middleware.js.map +1 -1
  85. package/build/src/models/authz_assignment.d.ts +5 -5
  86. package/build/src/models/authz_assignment.d.ts.map +1 -1
  87. package/build/src/models/authz_deny.d.ts +5 -5
  88. package/build/src/models/authz_deny.d.ts.map +1 -1
  89. package/build/src/models/authz_permission.d.ts +11 -5
  90. package/build/src/models/authz_permission.d.ts.map +1 -1
  91. package/build/src/models/authz_permission.js +4 -0
  92. package/build/src/models/authz_permission.js.map +1 -1
  93. package/build/src/models/authz_role.d.ts +13 -6
  94. package/build/src/models/authz_role.d.ts.map +1 -1
  95. package/build/src/models/authz_role.js +6 -1
  96. package/build/src/models/authz_role.js.map +1 -1
  97. package/build/src/models/authz_role_permission.d.ts +5 -5
  98. package/build/src/models/authz_role_permission.d.ts.map +1 -1
  99. package/build/src/openfga.d.ts +13 -0
  100. package/build/src/openfga.d.ts.map +1 -0
  101. package/build/src/openfga.js +12 -0
  102. package/build/src/openfga.js.map +1 -0
  103. package/build/src/sql_descendants.d.ts +51 -0
  104. package/build/src/sql_descendants.d.ts.map +1 -0
  105. package/build/src/sql_descendants.js +129 -0
  106. package/build/src/sql_descendants.js.map +1 -0
  107. package/build/src/testing/contract.d.ts +138 -7
  108. package/build/src/testing/contract.d.ts.map +1 -1
  109. package/build/src/testing/contract.js +2946 -24
  110. package/build/src/testing/contract.js.map +1 -1
  111. package/build/src/testing/main.d.ts +4 -2
  112. package/build/src/testing/main.d.ts.map +1 -1
  113. package/build/src/testing/main.js +2 -1
  114. package/build/src/testing/main.js.map +1 -1
  115. package/build/src/testing/scope_tree.d.ts +65 -0
  116. package/build/src/testing/scope_tree.d.ts.map +1 -0
  117. package/build/src/testing/scope_tree.js +145 -0
  118. package/build/src/testing/scope_tree.js.map +1 -0
  119. package/build/src/traits/authz_scopes.d.ts +30 -6
  120. package/build/src/traits/authz_scopes.d.ts.map +1 -1
  121. package/build/src/traits/authz_scopes.js +30 -18
  122. package/build/src/traits/authz_scopes.js.map +1 -1
  123. package/build/src/traits/has_uuid.d.ts +5 -5
  124. package/build/src/traits/has_uuid.d.ts.map +1 -1
  125. package/build/src/types.d.ts +530 -28
  126. package/build/src/types.d.ts.map +1 -1
  127. package/build/src/types.js +10 -4
  128. package/build/src/types.js.map +1 -1
  129. package/build/stubs/config/app_acl.stub +4 -2
  130. package/build/stubs/config/authorization.stub +66 -12
  131. package/build/stubs/migration.stub +57 -13
  132. package/package.json +11 -6
@@ -1,5 +1,10 @@
1
- import type { AuthorizationDriver, GrantOptions, ScopeRef, ScopeType, SubjectRef } from '../types.js';
2
- import type { ScopeAncestorsResolver } from '../types.js';
1
+ import db from '@adonisjs/lucid/services/db';
2
+ import type { AuthorizationDriver, CatalogRoleRef, DenyRef, GrantOptions, GrantOutcome, NormalizedRoleQuery, RoleQuery, ScopeRef, ScopeType, SubjectRef } from '../types.js';
3
+ import type { ScopeChainResolver } from '../types.js';
4
+ import { CatalogCache } from '../catalog_cache.js';
5
+ import type { CatalogRevalidate, CatalogRole, CatalogView } from '../catalog_cache.js';
6
+ import type { Clock } from '../clock.js';
7
+ export type QueryBuilder = ReturnType<typeof db.from>;
3
8
  /**
4
9
  * UUID centinela para el scope 'app' en las columnas scope_uuid (NOT NULL):
5
10
  * permite que el unique de assignments/denies cubra también el nivel app
@@ -7,6 +12,120 @@ import type { ScopeAncestorsResolver } from '../types.js';
7
12
  * de ESTE driver — la API pública sigue usando uuid null para app.
8
13
  */
9
14
  export declare const APP_SCOPE_DB_UUID = "00000000-0000-0000-0000-000000000000";
15
+ /**
16
+ * El rol `(slug, scopeType)` que existe en el scope cuya cadena empieza por
17
+ * `chainKeys`, o 422: `E_AUTHZ_ROLE_NOT_VISIBLE` si hay roles con ese nombre
18
+ * pero todos son locales a otro contenedor; `E_AUTHZ_UNKNOWN_ROLE` si no hay
19
+ * ninguno. Compartido por ambos drivers (3B · B2).
20
+ */
21
+ export declare function visibleRoleOrFail(catalog: CatalogView, slug: string, scope: ScopeRef, chainKeys: readonly string[]): CatalogRole;
22
+ /**
23
+ * EL rol al que apunta un `RoleQuery` en un scope concreto (3D · M1), para
24
+ * las rutas que direccionan un rol exacto (`grant`, `listSubjects`):
25
+ *
26
+ * - `{ uuid }`: resolución EXACTA, sin ambigüedad posible. Fuera del
27
+ * catálogo ⇒ 422 `E_AUTHZ_UNKNOWN_ROLE`; declarado para otro nivel o con
28
+ * el owner fuera de la cadena ⇒ 422 `E_AUTHZ_ROLE_NOT_VISIBLE` (no existe
29
+ * AQUÍ, que es lo mismo que decía la ruta por slug).
30
+ * - slug (con nivel opcional): `visibleRoleOrFail`, que ahora falla cerrado
31
+ * si hay más de un homónimo visible (422 `E_AUTHZ_AMBIGUOUS_ROLE`).
32
+ *
33
+ * Compartido por ambos drivers.
34
+ */
35
+ export declare function resolveRoleQuery(catalog: CatalogView, role: RoleQuery, scope: ScopeRef, chainKeys: readonly string[]): CatalogRole;
36
+ /**
37
+ * EL rol al que apunta un `RoleQuery` en un scope, para el camino de LECTURA
38
+ * (`listSubjects`): `null` si el catálogo no declara ninguno que exista ahí
39
+ * (invariante 5: desconocido no lanza). La AMBIGÜEDAD sí lanza (3D · M1):
40
+ * elegir uno de dos homónimos era enumerar los holders del otro tenant.
41
+ */
42
+ export declare function visibleRoleFor(catalog: CatalogView, query: NormalizedRoleQuery, scope: ScopeRef, chainKeys: readonly string[]): CatalogRole | null;
43
+ /**
44
+ * Los roles a los que un `RoleQuery` puede referirse en un scope, para
45
+ * `revoke` (3D · M1): por uuid, ESE rol (422 si el catálogo no lo declara);
46
+ * por slug, TODOS los homónimos `(slug, nivel)` — quitar nunca concede y el
47
+ * scope puede no existir ya para el árbol (D8), así que no se resuelve la
48
+ * ambigüedad: se quitan todos. 422 `E_AUTHZ_UNKNOWN_ROLE` si no hay ninguno.
49
+ */
50
+ export declare function rolesToRevoke(catalog: CatalogView, role: RoleQuery, scope: ScopeRef): CatalogRole[];
51
+ /**
52
+ * Los niveles de la cadena donde una asignación de ESE rol contaría, para
53
+ * `hasRole` (3D · M1): los scopes del tipo del rol desde los que el rol es
54
+ * visible por owner. `null` = el catálogo no declara nada que responda (la
55
+ * membresía es `false`, nunca un throw: invariante 5).
56
+ */
57
+ export declare function hasRoleTargets(catalog: CatalogView, role: RoleQuery, chain: ScopeRef[]): Array<{
58
+ scope: ScopeRef;
59
+ roleUuid: string;
60
+ }>;
61
+ /**
62
+ * Control de COMPOSICIÓN en la escritura (3B · B5, defensa en profundidad):
63
+ * un rol de nivel L que lleve un permiso cuyo `assignableAt` no incluye L no
64
+ * se asigna (422 `E_AUTHZ_ROLE_NOT_ASSIGNABLE_AT`). El sync y
65
+ * `defineScopedRole` ya lo rechazan al componer; aquí se cierra el vínculo
66
+ * escrito a mano. `authorize` NUNCA lo mira: lo ya asignado sigue
67
+ * concediendo (invariante 1).
68
+ */
69
+ export declare function assertRoleAssignableAt(catalog: CatalogView, role: CatalogRole): void;
70
+ /**
71
+ * EL rol de un uuid, si EXISTE en un scope de nivel `scopeType` cuya cadena
72
+ * tiene esas claves: declarado para ese nivel (D5/L0.6) y global o con el
73
+ * owner en la cadena desde ahí (3B · B2). `null` si no. Es la regla de
74
+ * visibilidad por uuid, en UN sitio (3D · N5): la usan `listRoles`,
75
+ * `rolesInChain`, `listRoleScopes`/`listScopes` (`visibleAt`) en `database`
76
+ * y `declaredRole` en `openfga`.
77
+ */
78
+ export declare function declaredRoleAt(catalog: CatalogView, roleUuid: string, scopeType: ScopeType, chainKeys: readonly string[]): CatalogRole | null;
79
+ /**
80
+ * Filtro (scope_type, scope_uuid) ∈ scopes (centinela para el nivel app).
81
+ *
82
+ * Con `scopes` VACÍO no hay filtro que construir, y "sin filtro" en SQL es
83
+ * "todas las filas": la consulta de denies sobre-bloquearía (cerrado) pero la
84
+ * de asignaciones concedería en CUALQUIER scope (abierto) — L0.1. Hoy ningún
85
+ * call-site pasa un conjunto vacío (la cadena siempre contiene el scope), pero
86
+ * `descendantsOf`/`authorizedScopes` (Fase 2) lo harán alcanzable:
87
+ * - lectura ⇒ `null`: nada puede coincidir, el llamante responde vacío/false
88
+ * SIN ejecutar la consulta;
89
+ * - escritura ⇒ 500: escribir "en ningún scope" es un bug de programación.
90
+ * Exportada (no método privado) para poder fijarlo con un test.
91
+ */
92
+ export declare function whereScopeIn(query: QueryBuilder, column: string, scopes: ScopeRef[], intent: 'write'): QueryBuilder;
93
+ export declare function whereScopeIn(query: QueryBuilder, column: string, scopes: ScopeRef[], intent: 'read'): QueryBuilder | null;
94
+ export interface DatabaseDriverOptions {
95
+ /** Jerarquía del consumidor: la cadena canónica de cada scope (ver `ScopeChainResolver`). */
96
+ resolveChain?: ScopeChainResolver;
97
+ /**
98
+ * Deadline de cada consulta SQL en ms (default 5000). Vencido ⇒ 503
99
+ * `E_AUTHZ_BACKEND_TIMEOUT`. Sin deadline, una base saturada convertía cada
100
+ * request autorizada en un socket retenido para siempre (L0.13).
101
+ */
102
+ timeoutMs?: number;
103
+ /**
104
+ * Memo del catálogo compartido con otro driver del mismo proceso (2A). Si
105
+ * se omite, el driver construye el suyo. Se revalida contra la versión
106
+ * compartida de la base (`authz_catalog_version`) según `catalogRevalidate`.
107
+ */
108
+ catalog?: CatalogCache;
109
+ /**
110
+ * Cuándo contrastar el memo con la versión compartida (2D · F1): `'always'`
111
+ * (default; un SELECT por clave primaria por pregunta) o `{ everyMs }`
112
+ * (opt-in: ventana acotada en la que un sync de OTRO proceso aún no se ve).
113
+ * Solo aplica al memo que construye este driver.
114
+ */
115
+ catalogRevalidate?: CatalogRevalidate;
116
+ /**
117
+ * Reloj de pared con el que el driver DECIDE la caducidad (2.5 · J1):
118
+ * `expires_at > now()` en cada lectura y los tres estados del re-grant.
119
+ * Default `() => new Date()`. Inyectable para fijar el instante en tests;
120
+ * en producción lo normal es no tocarlo (o pasar `clock` en el config del
121
+ * manager, que lo aplica con `withClock`). Los sellos de auditoría
122
+ * (`created_at`) NO lo usan (2.5-B · K5): son «cuándo se escribió», no
123
+ * una decisión, y con `TIMESTAMP` de MySQL un reloj inyectado en 2040
124
+ * hacía imposible escribir.
125
+ */
126
+ now?: Clock;
127
+ }
128
+ export declare const DEFAULT_TIMEOUT_MS = 5000;
10
129
  /**
11
130
  * Driver `database`: motor de autorización propio sobre las tablas `authz_*`.
12
131
  * Default autosuficiente del chasis (cero piezas extra en el appliance).
@@ -16,33 +135,141 @@ export declare const APP_SCOPE_DB_UUID = "00000000-0000-0000-0000-000000000000";
16
135
  * permiso vía su rol. La cadena es `[scope, ...ancestros]` — herencia solo
17
136
  * hacia abajo. Solo SQL estándar vía query builder (regla M6: nada
18
137
  * específico de un motor).
138
+ *
139
+ * Toda consulta pasa por `sql()`: un fallo del cliente SQL (conexión, tabla,
140
+ * deadline) sale como `AuthorizationBackendError` 503, nunca como el error
141
+ * crudo de knex (L0.11).
19
142
  */
20
143
  export declare class DatabaseAuthorizationDriver implements AuthorizationDriver {
21
144
  /**
22
145
  * Resolutor de jerarquía inyectado por el consumidor (el chasis pasa el
23
146
  * suyo, que conoce organizations/units, en `config/authorization.ts`).
24
- * Default puro sin dominio: todo cuelga directamente de `app`.
147
+ * Sin él, el driver solo conoce la raíz (L0.3: ya no hay default plano).
148
+ */
149
+ private chainResolver;
150
+ private timeoutMs;
151
+ /** Reloj de pared del driver (J1): el ÚNICO `now` de todas sus DECISIONES temporales (no de los sellos, K5). */
152
+ private now;
153
+ /**
154
+ * Cómo viaja `expires_at` con este motor (2.5-B · K2): cadena UTC explícita
155
+ * en MySQL (sin depender de `timezone`/`TZ`), identidad en el resto. Se
156
+ * decide por dialecto en el primer uso (la conexión puede no estar lista al
157
+ * construir el driver).
158
+ */
159
+ private expiryCodec;
160
+ /**
161
+ * Memo del catálogo (2A): `findPermission`/`findRole` leen de aquí; los
162
+ * hechos (asignaciones, denies y el join con los vínculos) siguen en SQL en
163
+ * cada pregunta. Se revalida contra `authz_catalog_version` (2D · F1);
164
+ * `catalog.invalidate()` fuerza la recarga de ESTE memo.
165
+ */
166
+ readonly catalog: CatalogCache;
167
+ constructor(options?: DatabaseDriverOptions);
168
+ /**
169
+ * Vista de este driver con OTRO resolutor de la cadena y el mismo estado
170
+ * (conexión, memo del catálogo, deadline). Es lo que usa
171
+ * `AuthorizationManager.forRequest()` para leer con un resolutor memoizado
172
+ * sin tocar el driver compartido: el objeto devuelto hereda del original
173
+ * por prototipo y solo sobrescribe el resolutor.
174
+ */
175
+ withChainResolver(resolveChain: ScopeChainResolver): AuthorizationDriver;
176
+ /**
177
+ * Vista de este driver con OTRO reloj de pared (2.5 · J1) y el mismo estado
178
+ * (conexión, memo, deadline, resolutor). Es lo que aplica el manager con
179
+ * `config.clock` y lo que el juez usa para fijar el instante. Misma
180
+ * técnica que `withChainResolver`: herencia por prototipo, un campo.
181
+ */
182
+ withClock(now: Clock): AuthorizationDriver;
183
+ /**
184
+ * `[scope canónico, ...ancestros]`, o `null` si el scope no existe
185
+ * (lecturas: denegar). `chain[0]` —la fila del consumidor, no lo que
186
+ * escribió el llamante— es la identidad con la que se leen y escriben los
187
+ * hechos de ese scope (2.5-B · K1): un alias del uuid que el árbol funde
188
+ * con la fila real (tipo `uuid` de PG, collation `*_ci`) llega aquí ya
189
+ * canónico y el deny escrito canónico casa.
25
190
  */
26
- private resolveAncestors;
27
- constructor(options?: {
28
- resolveAncestors?: ScopeAncestorsResolver;
29
- });
30
191
  private chain;
31
- /** Filtro (scope_type, scope_uuid) scopes (centinela para el nivel app). */
32
- private whereScopeIn;
33
- /** Asignación vigente: sin expiración o con expiración futura. */
192
+ /** La cadena o 422: una escritura no puede ir a un scope que nadie reconoce. */
193
+ private knownScope;
194
+ /** El scope canónico para `revoke`/`removeDeny`/`purgeScope` (ver `canonicalScope`). */
195
+ private canonicalOrSelf;
196
+ /**
197
+ * Ejecuta una consulta clasificando su fallo (503 con código propio). `fn`
198
+ * devuelve el BUILDER sin ejecutar: el guard le fija el deadline y luego lo
199
+ * ejecuta. Por eso no se usa `.first()` de Lucid (ejecuta al instante, sin
200
+ * dejar poner el timeout): `first()` de abajo hace `limit(1)` y toma la fila.
201
+ */
202
+ private sql;
203
+ private first;
204
+ private get expiry();
205
+ /** Asignación vigente: sin expiración o con expiración futura (estricta: la que vence AHORA ya no cuenta). */
34
206
  private whereActive;
35
207
  private findPermission;
36
- private findRoleOrFail;
208
+ /**
209
+ * Filtro «asignación VISIBLE en algún nivel de la cadena» (3B · B2), en
210
+ * SQL, sobre `authz_assignments as a` unida a `authz_roles as r`: por cada
211
+ * nivel `i`, el scope exacto Y el rol declarado para ese nivel Y (global O
212
+ * owner en `chain.slice(i)`). Sustituye a `whereScopeIn(chain)` en la
213
+ * consulta de `authorize`: mismo número de consultas, ahora con el owner
214
+ * decidido en la base (`owner_scope_key IN (...) OR 'global'`). La cadena
215
+ * viene validada (nunca vacía); L0.1 se conserva por si acaso.
216
+ */
217
+ private whereVisibleAssignmentIn;
37
218
  authorize(subject: SubjectRef, permission: string, scope: ScopeRef): Promise<boolean>;
38
- grant(subject: SubjectRef, role: string, scope: ScopeRef, options?: GrantOptions): Promise<void>;
39
- revoke(subject: SubjectRef, role: string, scope: ScopeRef): Promise<void>;
40
- hasRole(subject: SubjectRef, role: string, scope: ScopeRef): Promise<boolean>;
219
+ grant(subject: SubjectRef, role: RoleQuery, scope: ScopeRef, options?: GrantOptions): Promise<GrantOutcome>;
220
+ /**
221
+ * Re-grant sobre una asignación existente (L0.4): omitido preserva una
222
+ * caducidad vigente (o revive una expirada sin caducidad), `null` la quita,
223
+ * `Date` la fija. Solo se escribe si la caducidad cambia de verdad; si el
224
+ * UPDATE no toca ninguna fila (otro proceso la borró entre la lectura y la
225
+ * escritura, K4) devuelve `null`: no hay «existed: true» sobre nada.
226
+ */
227
+ private refreshAssignment;
228
+ revoke(subject: SubjectRef, role: RoleQuery, scope: ScopeRef): Promise<void>;
229
+ hasRole(subject: SubjectRef, role: RoleQuery, scope: ScopeRef): Promise<boolean>;
41
230
  deny(subject: SubjectRef, permission: string, scope: ScopeRef): Promise<void>;
42
231
  removeDeny(subject: SubjectRef, permission: string, scope: ScopeRef): Promise<void>;
43
- listSubjects(role: string, scope: ScopeRef): Promise<SubjectRef[]>;
232
+ listSubjects(role: RoleQuery, scope: ScopeRef): Promise<SubjectRef[]>;
44
233
  listRoles(subject: SubjectRef, scope: ScopeRef): Promise<string[]>;
234
+ /**
235
+ * Roles directos vigentes del holder en cada scope de la cadena (2D · G5):
236
+ * UNA consulta con `whereScopeIn(chain)` en vez de un `listRoles` por
237
+ * nivel. El filtro por catálogo (D5) es el memo, por uuid (3A · A2): el
238
+ * rol tiene que existir y estar declarado para el nivel de la asignación.
239
+ * La cadena viene ya resuelta por el manager.
240
+ */
241
+ rolesInChain(subject: SubjectRef, chain: ScopeRef[]): Promise<Array<{
242
+ scope: ScopeRef;
243
+ role: CatalogRoleRef;
244
+ }>>;
45
245
  listRoleScopes(subject: SubjectRef, scopeType: ScopeType): Promise<ScopeRef[]>;
246
+ /** ¿El rol (por uuid) existe en el scope cuya cadena tiene esas claves? (3B · B2, `declaredRoleAt`) */
247
+ private visibleAt;
46
248
  listScopes(subject: SubjectRef, permission: string): Promise<ScopeRef[]>;
249
+ /**
250
+ * Denies directos del holder (2.1, B5): del scope exacto o todos. Solo los
251
+ * de permisos que el catálogo declara (memo); los de scopes que el árbol
252
+ * no conoce no se listan (D8), como en `listRoleScopes`.
253
+ */
254
+ listDenies(subject: SubjectRef, scope?: ScopeRef): Promise<DenyRef[]>;
255
+ /**
256
+ * Borra asignaciones y denies del scope exacto, en una transacción. Si el
257
+ * árbol aún lo conoce se purga su identidad canónica (K1); si ya no (el
258
+ * consumidor borró la fila antes de avisar) se purga tal cual llegó. Con
259
+ * `DELETE` en SQL la propia sentencia demuestra el cero: no hay residuo
260
+ * posible.
261
+ */
262
+ purgeScope(purged: ScopeRef): Promise<void>;
263
+ /**
264
+ * Purga un rol con sus hechos (3B · B4): sus asignaciones en TODOS los
265
+ * scopes, sus vínculos y la fila, en UNA transacción que sube la versión
266
+ * compartida del catálogo como última sentencia (`withAuthzCatalogWrite`):
267
+ * los demás procesos dejan de verlo en su siguiente pregunta. Se lee la
268
+ * fila en fresco (no el memo): purgar es escribir. Con `DELETE` la propia
269
+ * sentencia demuestra el cero. Global o local: la barrera «los globales son
270
+ * inmutables» es del manager (`deleteScopedRole`); por aquí (plataforma,
271
+ * `manager.driver()`) se purga lo que se pida.
272
+ */
273
+ purgeRole(roleUuid: string): Promise<void>;
47
274
  }
48
275
  //# sourceMappingURL=database_driver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"database_driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/database_driver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,UAAU,EACX,MAAM,aAAa,CAAA;AAEpB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAIzD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,yCAAyC,CAAA;AAUvE;;;;;;;;;GASG;AACH,qBAAa,2BAA4B,YAAW,mBAAmB;IACrE;;;;OAIG;IACH,OAAO,CAAC,gBAAgB,CAAwB;gBAEpC,OAAO,GAAE;QAAE,gBAAgB,CAAC,EAAE,sBAAsB,CAAA;KAAO;YAKzD,KAAK;IAInB,8EAA8E;IAC9E,OAAO,CAAC,YAAY;IAUpB,kEAAkE;IAClE,OAAO,CAAC,WAAW;YAML,cAAc;YAId,cAAc;IAetB,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAkCrF,KAAK,CACT,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,QAAQ,EACf,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,IAAI,CAAC;IAqDV,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBzE,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB7E,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA2C7E,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAenF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAiBlE,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAgBlE,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAY9E,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAkC/E"}
1
+ {"version":3,"file":"database_driver.d.ts","sourceRoot":"","sources":["../../../src/drivers/database_driver.ts"],"names":[],"mappings":"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"}