@jantstack/adonis-authz 2.0.0-alpha.1 → 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.
- package/README.md +462 -35
- package/build/commands/authz_catalog_diff.js +1 -1
- package/build/commands/authz_catalog_diff.js.map +1 -1
- package/build/commands/authz_catalog_prune_orphans.d.ts +78 -0
- package/build/commands/authz_catalog_prune_orphans.d.ts.map +1 -0
- package/build/commands/authz_catalog_prune_orphans.js +136 -0
- package/build/commands/authz_catalog_prune_orphans.js.map +1 -0
- package/build/commands/authz_catalog_sync.d.ts +17 -0
- package/build/commands/authz_catalog_sync.d.ts.map +1 -1
- package/build/commands/authz_catalog_sync.js +27 -4
- package/build/commands/authz_catalog_sync.js.map +1 -1
- package/build/commands/authz_freeze.d.ts +44 -0
- package/build/commands/authz_freeze.d.ts.map +1 -0
- package/build/commands/authz_freeze.js +95 -0
- package/build/commands/authz_freeze.js.map +1 -0
- package/build/commands/authz_reconcile.d.ts +102 -0
- package/build/commands/authz_reconcile.d.ts.map +1 -0
- package/build/commands/authz_reconcile.js +294 -0
- package/build/commands/authz_reconcile.js.map +1 -0
- package/build/commands/authz_relations_reconcile.d.ts +73 -0
- package/build/commands/authz_relations_reconcile.d.ts.map +1 -0
- package/build/commands/authz_relations_reconcile.js +225 -0
- package/build/commands/authz_relations_reconcile.js.map +1 -0
- package/build/commands/authz_scopes_relay.d.ts +47 -0
- package/build/commands/authz_scopes_relay.d.ts.map +1 -0
- package/build/commands/authz_scopes_relay.js +141 -0
- package/build/commands/authz_scopes_relay.js.map +1 -0
- package/build/commands/authz_unfreeze.d.ts +37 -0
- package/build/commands/authz_unfreeze.d.ts.map +1 -0
- package/build/commands/authz_unfreeze.js +92 -0
- package/build/commands/authz_unfreeze.js.map +1 -0
- package/build/commands/main.d.ts +6 -1
- package/build/commands/main.d.ts.map +1 -1
- package/build/commands/main.js +6 -1
- package/build/commands/main.js.map +1 -1
- package/build/commands/openfga_provision.d.ts +46 -4
- package/build/commands/openfga_provision.d.ts.map +1 -1
- package/build/commands/openfga_provision.js +90 -7
- package/build/commands/openfga_provision.js.map +1 -1
- package/build/configure.d.ts +11 -0
- package/build/configure.d.ts.map +1 -1
- package/build/configure.js +37 -1
- package/build/configure.js.map +1 -1
- package/build/index.d.ts +39 -10
- package/build/index.d.ts.map +1 -1
- package/build/index.js +35 -6
- package/build/index.js.map +1 -1
- package/build/providers/authz_provider.d.ts +26 -2
- package/build/providers/authz_provider.d.ts.map +1 -1
- package/build/providers/authz_provider.js +48 -2
- package/build/providers/authz_provider.js.map +1 -1
- package/build/services/relations.d.ts +14 -0
- package/build/services/relations.d.ts.map +1 -0
- package/build/services/relations.js +17 -0
- package/build/services/relations.js.map +1 -0
- package/build/src/{catalog.d.ts → catalog/catalog.d.ts} +41 -2
- package/build/src/catalog/catalog.d.ts.map +1 -0
- package/build/src/{catalog.js → catalog/catalog.js} +120 -14
- package/build/src/catalog/catalog.js.map +1 -0
- package/build/src/{catalog_cache.d.ts → catalog/catalog_cache.d.ts} +46 -22
- package/build/src/catalog/catalog_cache.d.ts.map +1 -0
- package/build/src/{catalog_cache.js → catalog/catalog_cache.js} +53 -43
- package/build/src/catalog/catalog_cache.js.map +1 -0
- package/build/src/define_config.d.ts +101 -3
- package/build/src/define_config.d.ts.map +1 -1
- package/build/src/define_config.js.map +1 -1
- package/build/src/drivers/database_driver.d.ts +86 -4
- package/build/src/drivers/database_driver.d.ts.map +1 -1
- package/build/src/drivers/database_driver.js +425 -11
- package/build/src/drivers/database_driver.js.map +1 -1
- package/build/src/drivers/database_relations_driver.d.ts +75 -0
- package/build/src/drivers/database_relations_driver.d.ts.map +1 -0
- package/build/src/drivers/database_relations_driver.js +450 -0
- package/build/src/drivers/database_relations_driver.js.map +1 -0
- package/build/src/drivers/openfga_driver.d.ts +713 -119
- package/build/src/drivers/openfga_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_driver.js +2048 -476
- package/build/src/drivers/openfga_driver.js.map +1 -1
- package/build/src/drivers/openfga_facts.d.ts +369 -0
- package/build/src/drivers/openfga_facts.d.ts.map +1 -0
- package/build/src/drivers/openfga_facts.js +813 -0
- package/build/src/drivers/openfga_facts.js.map +1 -0
- package/build/src/drivers/openfga_relations_driver.d.ts +120 -0
- package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -0
- package/build/src/drivers/openfga_relations_driver.js +466 -0
- package/build/src/drivers/openfga_relations_driver.js.map +1 -0
- package/build/src/errors.d.ts +258 -5
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +238 -7
- package/build/src/errors.js.map +1 -1
- package/build/src/freeze.d.ts +120 -0
- package/build/src/freeze.d.ts.map +1 -0
- package/build/src/freeze.js +172 -0
- package/build/src/freeze.js.map +1 -0
- package/build/src/http/app_access_middleware.d.ts.map +1 -0
- package/build/src/http/app_access_middleware.js.map +1 -0
- package/build/src/http/resource_access_middleware.d.ts +105 -0
- package/build/src/http/resource_access_middleware.d.ts.map +1 -0
- package/build/src/http/resource_access_middleware.js +81 -0
- package/build/src/http/resource_access_middleware.js.map +1 -0
- package/build/src/identity.d.ts +74 -1
- package/build/src/identity.d.ts.map +1 -1
- package/build/src/identity.js +100 -2
- package/build/src/identity.js.map +1 -1
- package/build/src/manager.d.ts +315 -4
- package/build/src/manager.d.ts.map +1 -1
- package/build/src/manager.js +1187 -181
- package/build/src/manager.js.map +1 -1
- package/build/src/models/authz_assignment.d.ts +6 -6
- package/build/src/models/authz_assignment.d.ts.map +1 -1
- package/build/src/models/authz_deny.d.ts +6 -6
- package/build/src/models/authz_deny.d.ts.map +1 -1
- package/build/src/models/authz_permission.d.ts +6 -6
- package/build/src/models/authz_permission.d.ts.map +1 -1
- package/build/src/models/authz_role.d.ts +6 -6
- package/build/src/models/authz_role.d.ts.map +1 -1
- package/build/src/models/authz_role_permission.d.ts +6 -6
- package/build/src/models/authz_role_permission.d.ts.map +1 -1
- package/build/src/openfga.d.ts +18 -2
- package/build/src/openfga.d.ts.map +1 -1
- package/build/src/openfga.js +15 -1
- package/build/src/openfga.js.map +1 -1
- package/build/src/reconcile.d.ts +37 -0
- package/build/src/reconcile.d.ts.map +1 -0
- package/build/src/reconcile.js +69 -0
- package/build/src/reconcile.js.map +1 -0
- package/build/src/relation_partition_trigger.d.ts +8 -0
- package/build/src/relation_partition_trigger.d.ts.map +1 -0
- package/build/src/relation_partition_trigger.js +85 -0
- package/build/src/relation_partition_trigger.js.map +1 -0
- package/build/src/relations/define_relations_config.d.ts +58 -0
- package/build/src/relations/define_relations_config.d.ts.map +1 -0
- package/build/src/relations/define_relations_config.js +144 -0
- package/build/src/relations/define_relations_config.js.map +1 -0
- package/build/src/relations/manager.d.ts +38 -0
- package/build/src/relations/manager.d.ts.map +1 -0
- package/build/src/relations/manager.js +156 -0
- package/build/src/relations/manager.js.map +1 -0
- package/build/src/relations/reconcile.d.ts +62 -0
- package/build/src/relations/reconcile.d.ts.map +1 -0
- package/build/src/relations/reconcile.js +138 -0
- package/build/src/relations/reconcile.js.map +1 -0
- package/build/src/relations_config_store.d.ts +22 -0
- package/build/src/relations_config_store.d.ts.map +1 -0
- package/build/src/relations_config_store.js +74 -0
- package/build/src/relations_config_store.js.map +1 -0
- package/build/src/scope_outbox.d.ts +69 -0
- package/build/src/scope_outbox.d.ts.map +1 -0
- package/build/src/scope_outbox.js +291 -0
- package/build/src/scope_outbox.js.map +1 -0
- package/build/src/{drivers → shared}/backend_guard.d.ts +14 -0
- package/build/src/shared/backend_guard.d.ts.map +1 -0
- package/build/src/{drivers → shared}/backend_guard.js +26 -1
- package/build/src/shared/backend_guard.js.map +1 -0
- package/build/src/shared/sql_expiry.d.ts.map +1 -0
- package/build/src/shared/sql_expiry.js.map +1 -0
- package/build/src/sql_descendants.d.ts +47 -1
- package/build/src/sql_descendants.d.ts.map +1 -1
- package/build/src/sql_descendants.js +75 -1
- package/build/src/sql_descendants.js.map +1 -1
- package/build/src/testing/contract.d.ts +74 -0
- package/build/src/testing/contract.d.ts.map +1 -1
- package/build/src/testing/contract.js +672 -169
- package/build/src/testing/contract.js.map +1 -1
- package/build/src/testing/main.d.ts +6 -0
- package/build/src/testing/main.d.ts.map +1 -1
- package/build/src/testing/main.js +3 -0
- package/build/src/testing/main.js.map +1 -1
- package/build/src/testing/migration_contract.d.ts +284 -0
- package/build/src/testing/migration_contract.d.ts.map +1 -0
- package/build/src/testing/migration_contract.js +586 -0
- package/build/src/testing/migration_contract.js.map +1 -0
- package/build/src/testing/relations_contract.d.ts +51 -0
- package/build/src/testing/relations_contract.d.ts.map +1 -0
- package/build/src/testing/relations_contract.js +654 -0
- package/build/src/testing/relations_contract.js.map +1 -0
- package/build/src/testing/relations_reconcile_contract.d.ts +24 -0
- package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -0
- package/build/src/testing/relations_reconcile_contract.js +172 -0
- package/build/src/testing/relations_reconcile_contract.js.map +1 -0
- package/build/src/traits/authz_scopes.js +1 -1
- package/build/src/traits/authz_scopes.js.map +1 -1
- package/build/src/traits/has_uuid.d.ts +7 -7
- package/build/src/traits/has_uuid.d.ts.map +1 -1
- package/build/src/types.d.ts +865 -82
- package/build/src/types.d.ts.map +1 -1
- package/build/src/types.js +10 -0
- package/build/src/types.js.map +1 -1
- package/build/stubs/config/authorization.stub +104 -4
- package/build/stubs/migration.stub +126 -0
- package/build/stubs/scopes_outbox_migration.stub +57 -0
- package/package.json +4 -2
- package/build/commands/openfga_import.d.ts +0 -34
- package/build/commands/openfga_import.d.ts.map +0 -1
- package/build/commands/openfga_import.js +0 -97
- package/build/commands/openfga_import.js.map +0 -1
- package/build/src/catalog.d.ts.map +0 -1
- package/build/src/catalog.js.map +0 -1
- package/build/src/catalog_cache.d.ts.map +0 -1
- package/build/src/catalog_cache.js.map +0 -1
- package/build/src/drivers/backend_guard.d.ts.map +0 -1
- package/build/src/drivers/backend_guard.js.map +0 -1
- package/build/src/drivers/sql_expiry.d.ts.map +0 -1
- package/build/src/drivers/sql_expiry.js.map +0 -1
- package/build/src/middleware/app_access_middleware.d.ts.map +0 -1
- package/build/src/middleware/app_access_middleware.js.map +0 -1
- /package/build/src/{middleware → http}/app_access_middleware.d.ts +0 -0
- /package/build/src/{middleware → http}/app_access_middleware.js +0 -0
- /package/build/src/{drivers → shared}/sql_expiry.d.ts +0 -0
- /package/build/src/{drivers → shared}/sql_expiry.js +0 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **La outbox del árbol sobre Lucid** (3b-2d; panel 2, cruce 4 · S5).
|
|
3
|
+
*
|
|
4
|
+
* El puerto es `ScopeOutbox` (`src/types.ts`) y el paquete NO impone tabla:
|
|
5
|
+
* cualquier implementación vale. Esta es la que se publica para quien no
|
|
6
|
+
* quiera escribir la suya, junto con su migración
|
|
7
|
+
* (`stubs/scopes_outbox_migration.stub`, que hay que COPIAR al proyecto:
|
|
8
|
+
* `configure` no la publica sola porque la outbox es opt-in).
|
|
9
|
+
*
|
|
10
|
+
* import { sqlScopeOutbox } from '@jantstack/adonis-authz'
|
|
11
|
+
*
|
|
12
|
+
* const outbox = sqlScopeOutbox()
|
|
13
|
+
* export default defineConfig({
|
|
14
|
+
* scopes: { resolveChain, outbox },
|
|
15
|
+
* ...
|
|
16
|
+
* })
|
|
17
|
+
*
|
|
18
|
+
* // y en el sitio donde mueves tu árbol:
|
|
19
|
+
* await db.transaction(async (trx) => {
|
|
20
|
+
* await authorization.scopes.moved(unit, nuevaOrg, { within, actor, transaction: trx })
|
|
21
|
+
* await unit.useTransaction(trx).merge({ organizationId: nuevaOrg.uuid }).save()
|
|
22
|
+
* })
|
|
23
|
+
*
|
|
24
|
+
* Lo único que tiene que cumplir una implementación del puerto es que
|
|
25
|
+
* `enqueue` escriba DENTRO de la transacción que le pasan: es lo que hace
|
|
26
|
+
* que el cambio del árbol y su propagación al backend confirmen —o se vayan—
|
|
27
|
+
* juntos. Todo lo demás (nombres de columna, si las filas aplicadas se
|
|
28
|
+
* borran o se marcan, si hay reintento con backoff) es del consumidor.
|
|
29
|
+
*
|
|
30
|
+
* Aquí las filas aplicadas se MARCAN (`applied_at`), no se borran: la cola
|
|
31
|
+
* es también el registro de lo que se propagó y cuándo, y `authz:scopes:relay`
|
|
32
|
+
* no puede ser silencioso.
|
|
33
|
+
*/
|
|
34
|
+
import db from '@adonisjs/lucid/services/db';
|
|
35
|
+
import { AuthorizationConfigError } from './errors.js';
|
|
36
|
+
import { systemClock } from './clock.js';
|
|
37
|
+
import { assertScope, assertSubject } from './identity.js';
|
|
38
|
+
import { guardSql } from './shared/backend_guard.js';
|
|
39
|
+
import { dialectOf, isSqliteDialect } from './shared/sql_expiry.js';
|
|
40
|
+
import { APP_SCOPE, APP_SCOPE_TYPE } from './types.js';
|
|
41
|
+
const DEFAULT_TABLE = 'authz_scope_outbox';
|
|
42
|
+
const DEFAULT_TIMEOUT_MS = 5_000;
|
|
43
|
+
/** Intentos antes de aparcar una entrada (3b-2h · 🔴 2). */
|
|
44
|
+
const DEFAULT_MAX_ATTEMPTS = 5;
|
|
45
|
+
/**
|
|
46
|
+
* Leases tomados por ESTE proceso (SQLite y cualquier dialecto sin cerrojo de
|
|
47
|
+
* sesión): la exclusión es entonces de proceso, no de despliegue, y va escrita
|
|
48
|
+
* en el README. Con PostgreSQL y MySQL el cerrojo es del servidor.
|
|
49
|
+
*/
|
|
50
|
+
const localLeases = new Set();
|
|
51
|
+
const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
52
|
+
/** Las tres operaciones del árbol, tal como se guardan en la columna `op`. */
|
|
53
|
+
const OPS = ['attached', 'moved', 'detached'];
|
|
54
|
+
/** El scope que va a la fila: la raíz se guarda como `app` con uuid nulo. */
|
|
55
|
+
function columnsOf(scope) {
|
|
56
|
+
return { type: scope.type, uuid: scope.type === APP_SCOPE_TYPE ? null : scope.uuid };
|
|
57
|
+
}
|
|
58
|
+
/** La vuelta: `app` sin uuid es `APP_SCOPE`; el resto, la fila tal cual. */
|
|
59
|
+
function scopeOf(type, uuid) {
|
|
60
|
+
return type === APP_SCOPE_TYPE ? APP_SCOPE : { type, uuid: uuid === null ? null : String(uuid) };
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Valida el cambio ANTES del INSERT (422): una cola es un diferido, y un
|
|
64
|
+
* `ScopeRef` mal formado que entrara aquí explotaría días después dentro del
|
|
65
|
+
* relay, lejos del call-site que lo escribió.
|
|
66
|
+
*/
|
|
67
|
+
function assertChange(change) {
|
|
68
|
+
if (!change || !OPS.includes(change.op)) {
|
|
69
|
+
throw new AuthorizationConfigError(`sqlScopeOutbox: 'op' debe ser uno de ${OPS.join(', ')} (llegó ${String(change?.op)})`);
|
|
70
|
+
}
|
|
71
|
+
assertScope(change.child);
|
|
72
|
+
if (change.op !== 'detached')
|
|
73
|
+
assertScope(change.parent);
|
|
74
|
+
}
|
|
75
|
+
/** Namespace de los advisory locks del paquete en PostgreSQL. */
|
|
76
|
+
const ADVISORY_LOCK_NAMESPACE = 0x617a;
|
|
77
|
+
/** Hash de 32 bits con signo (lo que acepta `pg_try_advisory_xact_lock`). */
|
|
78
|
+
function hash32(value) {
|
|
79
|
+
let hash = 0;
|
|
80
|
+
for (let i = 0; i < value.length; i++)
|
|
81
|
+
hash = (Math.imul(hash, 31) + value.charCodeAt(i)) | 0;
|
|
82
|
+
return hash;
|
|
83
|
+
}
|
|
84
|
+
/** El primer valor de un `rawQuery`, sea cual sea la forma del dialecto. */
|
|
85
|
+
function firstValue(result, column) {
|
|
86
|
+
const rows = Array.isArray(result) ? result[0] : (result?.rows ?? result);
|
|
87
|
+
const row = Array.isArray(rows) ? rows[0] : rows;
|
|
88
|
+
return row?.[column];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* El cliente con el que se toma el lease: la conexión con nombre, la primaria
|
|
92
|
+
* del `db` de Lucid, o `null` si lo que se inyectó no es un cliente de Lucid
|
|
93
|
+
* (los dobles de test) — entonces el lease es de proceso.
|
|
94
|
+
*/
|
|
95
|
+
function lockClientOf(database, connection) {
|
|
96
|
+
if (connection)
|
|
97
|
+
return db.connection(connection);
|
|
98
|
+
const client = database;
|
|
99
|
+
if (typeof client?.transaction === 'function' && client?.dialect)
|
|
100
|
+
return client;
|
|
101
|
+
if (typeof client?.connection === 'function') {
|
|
102
|
+
const primary = client.connection();
|
|
103
|
+
return typeof primary?.transaction === 'function' ? primary : null;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
/** Una fila de la cola, tal como la ve el puerto. */
|
|
108
|
+
function rowToPending(row) {
|
|
109
|
+
const child = scopeOf(String(row.child_type), row.child_uuid);
|
|
110
|
+
const change = row.op === 'detached'
|
|
111
|
+
? { op: 'detached', child }
|
|
112
|
+
: { op: row.op, child, parent: scopeOf(String(row.parent_type), row.parent_uuid) };
|
|
113
|
+
const actor = row.actor_type === null || row.actor_type === undefined
|
|
114
|
+
? undefined
|
|
115
|
+
: { type: String(row.actor_type), uuid: String(row.actor_uuid) };
|
|
116
|
+
return {
|
|
117
|
+
id: row.id,
|
|
118
|
+
change,
|
|
119
|
+
attempts: Number(row.attempts ?? 0),
|
|
120
|
+
actor,
|
|
121
|
+
...(row.last_error === null || row.last_error === undefined ? {} : { lastError: String(row.last_error) }),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/** La cota de `pending`/`dead`: entera y positiva o 500 (config rota). */
|
|
125
|
+
function assertLimit(limit) {
|
|
126
|
+
if (!(Number.isInteger(limit) && limit >= 1)) {
|
|
127
|
+
throw new AuthorizationConfigError(`sqlScopeOutbox: limit debe ser un entero >= 1 (llegó ${String(limit)})`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export function sqlScopeOutbox(options = {}, database = db) {
|
|
131
|
+
const table = options.table ?? DEFAULT_TABLE;
|
|
132
|
+
if (!IDENTIFIER.test(table)) {
|
|
133
|
+
throw new AuthorizationConfigError(`sqlScopeOutbox: table '${table}' no es un identificador SQL simple (letras, dígitos y _).`);
|
|
134
|
+
}
|
|
135
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
136
|
+
const connection = options.connection;
|
|
137
|
+
const now = options.now ?? systemClock;
|
|
138
|
+
const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
139
|
+
if (!(Number.isInteger(maxAttempts) && maxAttempts >= 1)) {
|
|
140
|
+
throw new AuthorizationConfigError(`sqlScopeOutbox: maxAttempts debe ser un entero >= 1 (llegó ${String(options.maxAttempts)})`);
|
|
141
|
+
}
|
|
142
|
+
/** El cliente de la consulta: la transacción del consumidor si la hay. */
|
|
143
|
+
const clientOf = (context) => {
|
|
144
|
+
const trx = context?.transaction;
|
|
145
|
+
if (trx === undefined || trx === null)
|
|
146
|
+
return database;
|
|
147
|
+
if (typeof trx.from !== 'function' || typeof trx.table !== 'function') {
|
|
148
|
+
throw new AuthorizationConfigError("sqlScopeOutbox: 'transaction' no parece un cliente de Lucid (le faltan .from()/.table()). " +
|
|
149
|
+
'Pasa el `trx` de db.transaction(); si tu outbox usa otra cosa, implementa el puerto a mano.');
|
|
150
|
+
}
|
|
151
|
+
return trx;
|
|
152
|
+
};
|
|
153
|
+
const query = (operation, run) => guardSql('sqlScopeOutbox', operation, timeoutMs, run);
|
|
154
|
+
/** Igual que el resto del paquete: la conexión con nombre si se declaró. */
|
|
155
|
+
const on = (client) => (connection && client === database ? db.connection(connection) : client);
|
|
156
|
+
return {
|
|
157
|
+
async enqueue(change, context) {
|
|
158
|
+
assertChange(change);
|
|
159
|
+
if (context?.actor !== undefined)
|
|
160
|
+
assertSubject(context.actor);
|
|
161
|
+
const child = columnsOf(change.child);
|
|
162
|
+
const parent = change.op === 'detached' ? { type: null, uuid: null } : columnsOf(change.parent);
|
|
163
|
+
const client = on(clientOf(context));
|
|
164
|
+
await query('enqueue', () => client.table(table).insert({
|
|
165
|
+
op: change.op,
|
|
166
|
+
child_type: child.type,
|
|
167
|
+
child_uuid: child.uuid,
|
|
168
|
+
parent_type: parent.type,
|
|
169
|
+
parent_uuid: parent.uuid,
|
|
170
|
+
actor_type: context?.actor?.type ?? null,
|
|
171
|
+
actor_uuid: context?.actor?.uuid ?? null,
|
|
172
|
+
attempts: 0,
|
|
173
|
+
last_error: null,
|
|
174
|
+
created_at: now(),
|
|
175
|
+
applied_at: null,
|
|
176
|
+
}));
|
|
177
|
+
},
|
|
178
|
+
async pending(limit, after) {
|
|
179
|
+
assertLimit(limit);
|
|
180
|
+
const client = on(database);
|
|
181
|
+
const rows = await query('pending', () => {
|
|
182
|
+
// Lo APARCADO (`attempts >= maxAttempts`) sale por `dead()`, no por
|
|
183
|
+
// aquí: si volviera, la pasada la reintentaría eternamente.
|
|
184
|
+
const q = client
|
|
185
|
+
.from(table)
|
|
186
|
+
.whereNull('applied_at')
|
|
187
|
+
.where('attempts', '<', maxAttempts)
|
|
188
|
+
.orderBy('id', 'asc')
|
|
189
|
+
.limit(limit);
|
|
190
|
+
// `after` es el último id que el relay ya vio EN ESTA PASADA: lo que
|
|
191
|
+
// dejó sin aplicar sigue pendiente y sin esto volvería a salir el
|
|
192
|
+
// primero para siempre (3b-2h · 🔴 2).
|
|
193
|
+
return after === undefined ? q : q.where('id', '>', after);
|
|
194
|
+
});
|
|
195
|
+
return rows.map(rowToPending);
|
|
196
|
+
},
|
|
197
|
+
/**
|
|
198
|
+
* Las entradas APARCADAS: pendientes que agotaron sus intentos. No se
|
|
199
|
+
* reintentan, se MIRAN (3b-2h · 🔴 2).
|
|
200
|
+
*/
|
|
201
|
+
async dead(limit) {
|
|
202
|
+
assertLimit(limit);
|
|
203
|
+
const client = on(database);
|
|
204
|
+
const rows = await query('dead', () => client
|
|
205
|
+
.from(table)
|
|
206
|
+
.whereNull('applied_at')
|
|
207
|
+
.where('attempts', '>=', maxAttempts)
|
|
208
|
+
.orderBy('id', 'asc')
|
|
209
|
+
.limit(limit));
|
|
210
|
+
return rows.map(rowToPending);
|
|
211
|
+
},
|
|
212
|
+
/**
|
|
213
|
+
* **El lease del escritor ÚNICO** (3b-2h · 🟠 4). Cerrojo del SERVIDOR en
|
|
214
|
+
* PostgreSQL (`pg_try_advisory_xact_lock`, que se suelta con la
|
|
215
|
+
* transacción) y en MySQL (`GET_LOCK(name, 0)`); en SQLite —y en
|
|
216
|
+
* cualquier dialecto sin cerrojo de sesión— es un cerrojo de PROCESO, y
|
|
217
|
+
* eso está escrito: SQLite ya serializa sus escrituras y no es el motor
|
|
218
|
+
* de un despliegue con dos réplicas del relay.
|
|
219
|
+
*
|
|
220
|
+
* La transacción se abre SOLO para sostener el cerrojo (no escribe nada)
|
|
221
|
+
* y se revierte al soltarlo: es una conexión ocupada mientras dura la
|
|
222
|
+
* pasada, que es el precio de que dos pasadas no se pisen.
|
|
223
|
+
*/
|
|
224
|
+
async acquire() {
|
|
225
|
+
const name = `authz_scope_outbox:${connection ?? 'default'}:${table}`;
|
|
226
|
+
const client = lockClientOf(database, connection);
|
|
227
|
+
if (client === null || isSqliteDialect(client)) {
|
|
228
|
+
if (localLeases.has(name))
|
|
229
|
+
return null;
|
|
230
|
+
localLeases.add(name);
|
|
231
|
+
return { release: async () => void localLeases.delete(name) };
|
|
232
|
+
}
|
|
233
|
+
const dialect = dialectOf(client);
|
|
234
|
+
const trx = await query('acquire', () => client.transaction());
|
|
235
|
+
try {
|
|
236
|
+
if (dialect.startsWith('postgres')) {
|
|
237
|
+
const result = await query('acquire', () => trx.rawQuery('select pg_try_advisory_xact_lock(?, ?) as taken', [ADVISORY_LOCK_NAMESPACE, hash32(name)]));
|
|
238
|
+
if (!firstValue(result, 'taken')) {
|
|
239
|
+
await trx.rollback();
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
// El cerrojo es de la TRANSACCIÓN: revertirla lo suelta.
|
|
243
|
+
return { release: async () => void (await trx.rollback()) };
|
|
244
|
+
}
|
|
245
|
+
if (dialect.startsWith('mysql')) {
|
|
246
|
+
const result = await query('acquire', () => trx.rawQuery('select get_lock(?, 0) as taken', [name.slice(0, 64)]));
|
|
247
|
+
if (Number(firstValue(result, 'taken') ?? 0) !== 1) {
|
|
248
|
+
await trx.rollback();
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
release: async () => {
|
|
253
|
+
try {
|
|
254
|
+
await trx.rawQuery('select release_lock(?)', [name.slice(0, 64)]);
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
await trx.rollback();
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
// Un dialecto que no sabemos cerrar: se cierra en el proceso y se
|
|
263
|
+
// suelta la transacción (nunca se devuelve un lease de mentira).
|
|
264
|
+
await trx.rollback();
|
|
265
|
+
if (localLeases.has(name))
|
|
266
|
+
return null;
|
|
267
|
+
localLeases.add(name);
|
|
268
|
+
return { release: async () => void localLeases.delete(name) };
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
await trx.rollback().catch(() => { });
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
async markApplied(id) {
|
|
276
|
+
const client = on(database);
|
|
277
|
+
await query('markApplied', () => client.from(table).where('id', id).update({ applied_at: now(), last_error: null }));
|
|
278
|
+
},
|
|
279
|
+
async markFailed(id, error) {
|
|
280
|
+
const client = on(database);
|
|
281
|
+
// El intento se cuenta aunque el mensaje sea larguísimo: se recorta el
|
|
282
|
+
// texto, nunca el hecho de que falló.
|
|
283
|
+
await query('markFailed', () => client
|
|
284
|
+
.from(table)
|
|
285
|
+
.where('id', id)
|
|
286
|
+
.update({ last_error: String(error).slice(0, 2000) })
|
|
287
|
+
.increment('attempts', 1));
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=scope_outbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope_outbox.js","sourceRoot":"","sources":["../../src/scope_outbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -87,6 +87,20 @@ export declare function resolveChain(resolver: ScopeChainResolver, scope: ScopeR
|
|
|
87
87
|
* sigue siendo 503: no se limpia a ciegas cuando el árbol está caído.
|
|
88
88
|
*/
|
|
89
89
|
export declare function canonicalScope(resolver: ScopeChainResolver, scope: ScopeRef, operation: string): Promise<ScopeRef>;
|
|
90
|
+
/**
|
|
91
|
+
* **Los scopes destino de un DELETE que no exige que el scope exista**
|
|
92
|
+
* (`revoke`/`removeDeny`; 3b-8 · A4, mismo cierre que 3b-2h · 🟠 3 dio a
|
|
93
|
+
* `scopes.detached`). Con la fila viva es exactamente UNO, el canónico
|
|
94
|
+
* (`chain[0]`). Sin cadena con la que canonizar —la fila ya borrada, o sin
|
|
95
|
+
* resolutor— la ortografía del llamante a secas hacía del delete un no-op
|
|
96
|
+
* SILENCIOSO cuando llegaba un alias del uuid (el mismo uuid sin guiones,
|
|
97
|
+
* que el tipo `uuid` de PG o una collation `*_ci` funden con la fila real):
|
|
98
|
+
* el hecho canónico seguía escrito y volvía a conceder si el scope se
|
|
99
|
+
* restauraba. Se reusa el fan-out de `scopeSpellings`: la ortografía del
|
|
100
|
+
* llamante Y la canónica de la que puede ser alias. Quitar nunca concede,
|
|
101
|
+
* así que borrar de más no existe aquí.
|
|
102
|
+
*/
|
|
103
|
+
export declare function canonicalScopeTargets(resolver: ScopeChainResolver, scope: ScopeRef, operation: string): Promise<ScopeRef[]>;
|
|
90
104
|
/** La cadena canónica, o 422 `E_AUTHZ_UNKNOWN_SCOPE` si el scope no existe (para escrituras). */
|
|
91
105
|
export declare function assertKnownScope(resolver: ScopeChainResolver, scope: ScopeRef, operation: string): Promise<ScopeRef[]>;
|
|
92
106
|
//# sourceMappingURL=backend_guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend_guard.d.ts","sourceRoot":"","sources":["../../../src/shared/backend_guard.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAI/D;;;;;;;;;;;GAWG;AAEH,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQxD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQrD;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAOnG;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAO9B,CAAA;AAeD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CA0C5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,kBAAkB,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAQxH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAQrB;AAED,iGAAiG;AACjG,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,EAAE,CAAC,CASrB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AuthorizationBackendError, AuthorizationBackendTimeoutError, NoScopeResolverError, ScopeResolverError, UnknownScopeError, } from '../errors.js';
|
|
2
2
|
import { APP_SCOPE, APP_SCOPE_TYPE } from '../types.js';
|
|
3
|
-
import { assertScope } from '../identity.js';
|
|
3
|
+
import { assertScope, scopeSpellings } from '../identity.js';
|
|
4
4
|
/**
|
|
5
5
|
* Clasificación de fallos de dependencias, compartida por ambos drivers.
|
|
6
6
|
*
|
|
@@ -209,6 +209,31 @@ export async function canonicalScope(resolver, scope, operation) {
|
|
|
209
209
|
throw error;
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* **Los scopes destino de un DELETE que no exige que el scope exista**
|
|
214
|
+
* (`revoke`/`removeDeny`; 3b-8 · A4, mismo cierre que 3b-2h · 🟠 3 dio a
|
|
215
|
+
* `scopes.detached`). Con la fila viva es exactamente UNO, el canónico
|
|
216
|
+
* (`chain[0]`). Sin cadena con la que canonizar —la fila ya borrada, o sin
|
|
217
|
+
* resolutor— la ortografía del llamante a secas hacía del delete un no-op
|
|
218
|
+
* SILENCIOSO cuando llegaba un alias del uuid (el mismo uuid sin guiones,
|
|
219
|
+
* que el tipo `uuid` de PG o una collation `*_ci` funden con la fila real):
|
|
220
|
+
* el hecho canónico seguía escrito y volvía a conceder si el scope se
|
|
221
|
+
* restauraba. Se reusa el fan-out de `scopeSpellings`: la ortografía del
|
|
222
|
+
* llamante Y la canónica de la que puede ser alias. Quitar nunca concede,
|
|
223
|
+
* así que borrar de más no existe aquí.
|
|
224
|
+
*/
|
|
225
|
+
export async function canonicalScopeTargets(resolver, scope, operation) {
|
|
226
|
+
try {
|
|
227
|
+
const chain = await resolveChain(resolver, scope, operation);
|
|
228
|
+
if (chain)
|
|
229
|
+
return [chain[0]];
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
if (!(error instanceof NoScopeResolverError))
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
return scopeSpellings(scope);
|
|
236
|
+
}
|
|
212
237
|
/** La cadena canónica, o 422 `E_AUTHZ_UNKNOWN_SCOPE` si el scope no existe (para escrituras). */
|
|
213
238
|
export async function assertKnownScope(resolver, scope, operation) {
|
|
214
239
|
const chain = await resolveChain(resolver, scope, operation);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend_guard.js","sourceRoot":"","sources":["../../../src/shared/backend_guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql_expiry.d.ts","sourceRoot":"","sources":["../../../src/shared/sql_expiry.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAA;IACrC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,EAAE,IAAI,GAAG,OAAO,CAAA;IACvB,yGAAyG;IACzG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC/C,kEAAkE;IAClE,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAAA;CACpC;AAID,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,UAAU,EAAE,GAAG,GAAG,MAAM,CAEjD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,GAAG,GAAG,OAAO,CAGxD;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,IAAI,GAAG,MAAM,CAElD;AAED,qGAAqG;AACrG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAM3D;AA6BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,GAAE,GAAqB,GAAG,WAAW,CAE7E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql_expiry.js","sourceRoot":"","sources":["../../../src/shared/sql_expiry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ScopeDescendantsResolver } from './types.js';
|
|
1
|
+
import type { ScopeDescendantsResolver, ScopeEdgesEnumerator } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* `descendantsOf` opt-in sobre una tabla del consumidor con columna padre
|
|
4
4
|
* (2.1, B2). Genera UNA CTE recursiva (`WITH RECURSIVE`), la misma para
|
|
@@ -47,5 +47,51 @@ interface DatabaseLike {
|
|
|
47
47
|
connection(name?: string): any;
|
|
48
48
|
}
|
|
49
49
|
export declare function sqlDescendantsOf(options: SqlDescendantsOptions, database?: DatabaseLike): ScopeDescendantsResolver;
|
|
50
|
+
/**
|
|
51
|
+
* `scopes.enumerateEdges` sobre la MISMA tabla que `sqlDescendantsOf`
|
|
52
|
+
* (3b-3a): una página de aristas `hijo → padre` por llamada, ordenadas por la
|
|
53
|
+
* clave primaria y continuadas con un cursor.
|
|
54
|
+
*
|
|
55
|
+
* scopes: {
|
|
56
|
+
* resolveChain,
|
|
57
|
+
* enumerateEdges: sqlScopeEdges({
|
|
58
|
+
* table: 'organization_nodes', uuidColumn: 'uuid',
|
|
59
|
+
* parentColumn: 'parent_uuid', typeColumn: 'kind',
|
|
60
|
+
* }),
|
|
61
|
+
* }
|
|
62
|
+
*
|
|
63
|
+
* Lo usa `authz:reconcile --to=openfga` para reconstruir el árbol del store
|
|
64
|
+
* (y para borrar las aristas que la tabla ya no respalda).
|
|
65
|
+
*
|
|
66
|
+
* Decisiones que hay que conocer:
|
|
67
|
+
* - **el cursor es el uuid de la última fila**, y el orden es `ORDER BY
|
|
68
|
+
* uuid` (clave primaria: orden total y estable). Una pasada reanudada no
|
|
69
|
+
* se salta nodos aunque el árbol cambie entre páginas; lo que cambie por
|
|
70
|
+
* debajo del cursor entra en la siguiente pasada, que es idempotente.
|
|
71
|
+
* - **una fila cuyo padre NO existe no produce arista** (LEFT JOIN sin
|
|
72
|
+
* pareja). Es coherente con `resolveChain`, que devuelve `null` para ese
|
|
73
|
+
* nodo: no está en el árbol. No es silencioso: el destino conserva la
|
|
74
|
+
* arista vieja, `authz:reconcile` la cuenta como sobrante y sus hechos
|
|
75
|
+
* salen en `skipped` con el motivo.
|
|
76
|
+
* - `parentColumn IS NULL` es la raíz (`APP_SCOPE`).
|
|
77
|
+
*
|
|
78
|
+
* Mismos dialectos que `sqlDescendantsOf` (PG, MySQL 8, SQLite) y el mismo
|
|
79
|
+
* 500 `E_AUTHZ_UNSUPPORTED_DIALECT` para cualquier otro.
|
|
80
|
+
*/
|
|
81
|
+
export interface SqlScopeEdgesOptions {
|
|
82
|
+
table: string;
|
|
83
|
+
uuidColumn: string;
|
|
84
|
+
/** Columna con el uuid del padre; `NULL` = el nodo cuelga de `app`. */
|
|
85
|
+
parentColumn: string;
|
|
86
|
+
/** Columna con el `ScopeRef.type` de cada fila. Excluyente con `scopeType`. */
|
|
87
|
+
typeColumn?: string;
|
|
88
|
+
/** Tipo fijo de todos los nodos de la tabla (sin columna de tipo). Excluyente con `typeColumn`. */
|
|
89
|
+
scopeType?: string;
|
|
90
|
+
/** Nombre de la conexión Lucid (default: la primaria). */
|
|
91
|
+
connection?: string;
|
|
92
|
+
/** Deadline de cada consulta en ms (default 5000): vencido ⇒ 503. */
|
|
93
|
+
timeoutMs?: number;
|
|
94
|
+
}
|
|
95
|
+
export declare function sqlScopeEdges(options: SqlScopeEdgesOptions, database?: DatabaseLike): ScopeEdgesEnumerator;
|
|
50
96
|
export {};
|
|
51
97
|
//# sourceMappingURL=sql_descendants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql_descendants.d.ts","sourceRoot":"","sources":["../../src/sql_descendants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sql_descendants.d.ts","sourceRoot":"","sources":["../../src/sql_descendants.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,wBAAwB,EAAa,oBAAoB,EAAY,MAAM,YAAY,CAAA;AAErG;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAA;IACpB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mGAAmG;IACnG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAuBD,0FAA0F;AAC1F,UAAU,YAAY;IACpB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;CAC/B;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,qBAAqB,EAC9B,QAAQ,GAAE,YAAiB,GAC1B,wBAAwB,CAiH1B;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAA;IACpB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mGAAmG;IACnG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,GAAE,YAAiB,GAC1B,oBAAoB,CA+EtB"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import db from '@adonisjs/lucid/services/db';
|
|
2
2
|
import { AuthorizationConfigError, TooManyScopesError, UnsupportedDialectError } from './errors.js';
|
|
3
3
|
import { assertScope, assertScopeType } from './identity.js';
|
|
4
|
-
import { guardSql } from './
|
|
4
|
+
import { guardSql } from './shared/backend_guard.js';
|
|
5
5
|
import { APP_SCOPE_TYPE } from './types.js';
|
|
6
|
+
import { APP_SCOPE } from './types.js';
|
|
6
7
|
const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
7
8
|
/** Dialecto → carácter con el que cita identificadores (MySQL: backtick; el resto: comilla doble ANSI). */
|
|
8
9
|
const QUOTE_BY_DIALECT = {
|
|
@@ -126,4 +127,77 @@ export function sqlDescendantsOf(options, database = db) {
|
|
|
126
127
|
return rows.map((row) => ({ type: typeCol ? row.type : fixedType, uuid: row.uuid }));
|
|
127
128
|
};
|
|
128
129
|
}
|
|
130
|
+
export function sqlScopeEdges(options, database = db) {
|
|
131
|
+
const table = identifier('table', options.table);
|
|
132
|
+
const uuidCol = identifier('uuidColumn', options.uuidColumn);
|
|
133
|
+
const parentCol = identifier('parentColumn', options.parentColumn);
|
|
134
|
+
if ((options.typeColumn === undefined) === (options.scopeType === undefined)) {
|
|
135
|
+
throw new AuthorizationConfigError('sqlScopeEdges: declara exactamente uno de typeColumn (el tipo viene de la fila) o scopeType (tipo fijo).');
|
|
136
|
+
}
|
|
137
|
+
const typeCol = options.typeColumn === undefined ? null : identifier('typeColumn', options.typeColumn);
|
|
138
|
+
const fixedType = options.scopeType ?? null;
|
|
139
|
+
if (fixedType !== null) {
|
|
140
|
+
try {
|
|
141
|
+
assertScopeType(fixedType);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
throw new AuthorizationConfigError(`sqlScopeEdges: scopeType inválido: ${error.message}`);
|
|
145
|
+
}
|
|
146
|
+
if (fixedType === APP_SCOPE_TYPE) {
|
|
147
|
+
throw new AuthorizationConfigError("sqlScopeEdges: scopeType no puede ser 'app' (la raíz no tiene fila)");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
151
|
+
const connectionName = options.connection;
|
|
152
|
+
return async ({ limit, after }) => {
|
|
153
|
+
if (!Number.isInteger(limit) || limit < 1) {
|
|
154
|
+
throw new AuthorizationConfigError(`sqlScopeEdges: limit debe ser un entero >= 1 (llegó ${String(limit)})`);
|
|
155
|
+
}
|
|
156
|
+
const connection = database.connection(connectionName);
|
|
157
|
+
const dialect = connection?.dialect?.name ?? connection?.client?.driverName ?? 'desconocido';
|
|
158
|
+
const quote = QUOTE_BY_DIALECT[dialect];
|
|
159
|
+
if (!quote) {
|
|
160
|
+
throw new UnsupportedDialectError(`sqlScopeEdges: dialecto '${dialect}' sin observación en la suite (hoy: PostgreSQL, MySQL 8 y SQLite). ` +
|
|
161
|
+
`Implementa scopes.enumerateEdges a mano para este motor.`);
|
|
162
|
+
}
|
|
163
|
+
const q = (name) => `${quote}${name}${quote}`;
|
|
164
|
+
const childType = typeCol ? `t.${q(typeCol)}` : 'NULL';
|
|
165
|
+
const parentType = typeCol ? `p.${q(typeCol)}` : 'NULL';
|
|
166
|
+
const text = `SELECT t.${q(uuidCol)} AS ${q('child_uuid')}, ${childType} AS ${q('child_type')},` +
|
|
167
|
+
` t.${q(parentCol)} AS ${q('parent_uuid')}, ${parentType} AS ${q('parent_type')},` +
|
|
168
|
+
` p.${q(uuidCol)} AS ${q('parent_row')}` +
|
|
169
|
+
` FROM ${q(table)} t LEFT JOIN ${q(table)} p ON t.${q(parentCol)} = p.${q(uuidCol)}` +
|
|
170
|
+
(after === undefined ? '' : ` WHERE t.${q(uuidCol)} > ?`) +
|
|
171
|
+
` ORDER BY t.${q(uuidCol)} LIMIT ?`;
|
|
172
|
+
const bindings = after === undefined ? [limit] : [after, limit];
|
|
173
|
+
const result = await guardSql('sqlScopeEdges', 'enumerateEdges', timeoutMs, () => connection.rawQuery(text, bindings));
|
|
174
|
+
const rows = Array.isArray(result)
|
|
175
|
+
? result.length === 2 && Array.isArray(result[0]) && Array.isArray(result[1])
|
|
176
|
+
? result[0]
|
|
177
|
+
: result
|
|
178
|
+
: (result?.rows ?? []);
|
|
179
|
+
const edges = [];
|
|
180
|
+
for (const row of rows) {
|
|
181
|
+
const child = { type: typeCol ? row.child_type : fixedType, uuid: String(row.child_uuid) };
|
|
182
|
+
if (row.parent_uuid === null || row.parent_uuid === undefined) {
|
|
183
|
+
edges.push({ child, parent: APP_SCOPE });
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
// Padre declarado que no tiene fila: el nodo NO está en el árbol
|
|
187
|
+
// (`resolveChain` devuelve `null` ahí). No se inventa la arista.
|
|
188
|
+
if (row.parent_row === null || row.parent_row === undefined)
|
|
189
|
+
continue;
|
|
190
|
+
edges.push({
|
|
191
|
+
child,
|
|
192
|
+
parent: { type: typeCol ? row.parent_type : fixedType, uuid: String(row.parent_uuid) },
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
// El cursor es la ÚLTIMA FILA LEÍDA, no la última arista emitida: si no,
|
|
196
|
+
// una fila con el padre colgando pararía la paginación en seco.
|
|
197
|
+
const last = rows[rows.length - 1];
|
|
198
|
+
return rows.length < limit
|
|
199
|
+
? { edges }
|
|
200
|
+
: { edges, cursor: String(last.child_uuid) };
|
|
201
|
+
};
|
|
202
|
+
}
|
|
129
203
|
//# sourceMappingURL=sql_descendants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql_descendants.js","sourceRoot":"","sources":["../../src/sql_descendants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAC5C,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACnG,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"sql_descendants.js","sourceRoot":"","sources":["../../src/sql_descendants.ts"],"names":[],"mappings":"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"}
|