@jantstack/adonis-authz 2.4.0-alpha.1 → 2.4.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +299 -19
- package/build/commands/authz_relations_reconcile.d.ts +25 -1
- package/build/commands/authz_relations_reconcile.d.ts.map +1 -1
- package/build/commands/authz_relations_reconcile.js +94 -6
- package/build/commands/authz_relations_reconcile.js.map +1 -1
- package/build/index.d.ts +13 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +15 -1
- package/build/index.js.map +1 -1
- package/build/providers/authz_provider.d.ts +6 -1
- package/build/providers/authz_provider.d.ts.map +1 -1
- package/build/providers/authz_provider.js +18 -2
- package/build/providers/authz_provider.js.map +1 -1
- package/build/src/define_config.d.ts +73 -1
- 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 +53 -14
- package/build/src/drivers/database_driver.d.ts.map +1 -1
- package/build/src/drivers/database_driver.js +104 -32
- package/build/src/drivers/database_driver.js.map +1 -1
- package/build/src/drivers/database_relations_driver.d.ts +57 -9
- package/build/src/drivers/database_relations_driver.d.ts.map +1 -1
- package/build/src/drivers/database_relations_driver.js +344 -89
- package/build/src/drivers/database_relations_driver.js.map +1 -1
- package/build/src/drivers/openfga_driver.d.ts +17 -4
- package/build/src/drivers/openfga_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_driver.js +38 -3
- package/build/src/drivers/openfga_driver.js.map +1 -1
- package/build/src/drivers/openfga_facts.d.ts +15 -0
- package/build/src/drivers/openfga_facts.d.ts.map +1 -1
- package/build/src/drivers/openfga_facts.js +25 -2
- package/build/src/drivers/openfga_facts.js.map +1 -1
- package/build/src/drivers/openfga_relations_driver.d.ts +40 -6
- package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -1
- package/build/src/drivers/openfga_relations_driver.js +244 -44
- package/build/src/drivers/openfga_relations_driver.js.map +1 -1
- package/build/src/errors.d.ts +83 -4
- package/build/src/errors.d.ts.map +1 -1
- package/build/src/errors.js +139 -3
- package/build/src/errors.js.map +1 -1
- package/build/src/freeze.d.ts +37 -16
- package/build/src/freeze.d.ts.map +1 -1
- package/build/src/freeze.js +53 -8
- package/build/src/freeze.js.map +1 -1
- package/build/src/manager.d.ts +16 -1
- package/build/src/manager.d.ts.map +1 -1
- package/build/src/manager.js +116 -25
- package/build/src/manager.js.map +1 -1
- package/build/src/models/authz_assignment.d.ts +2 -2
- package/build/src/models/authz_assignment.d.ts.map +1 -1
- package/build/src/models/authz_deny.d.ts +2 -2
- package/build/src/models/authz_deny.d.ts.map +1 -1
- package/build/src/models/authz_permission.d.ts +2 -2
- package/build/src/models/authz_permission.d.ts.map +1 -1
- package/build/src/models/authz_role.d.ts +2 -2
- package/build/src/models/authz_role.d.ts.map +1 -1
- package/build/src/models/authz_role_permission.d.ts +2 -2
- package/build/src/models/authz_role_permission.d.ts.map +1 -1
- package/build/src/relation_partition_trigger.d.ts.map +1 -1
- package/build/src/relation_partition_trigger.js +11 -3
- package/build/src/relation_partition_trigger.js.map +1 -1
- package/build/src/relations/define_relations_config.d.ts +51 -0
- package/build/src/relations/define_relations_config.d.ts.map +1 -1
- package/build/src/relations/define_relations_config.js +68 -1
- package/build/src/relations/define_relations_config.js.map +1 -1
- package/build/src/relations/manager.d.ts +71 -6
- package/build/src/relations/manager.d.ts.map +1 -1
- package/build/src/relations/manager.js +301 -29
- package/build/src/relations/manager.js.map +1 -1
- package/build/src/relations/reconcile.d.ts +53 -4
- package/build/src/relations/reconcile.d.ts.map +1 -1
- package/build/src/relations/reconcile.js +92 -30
- package/build/src/relations/reconcile.js.map +1 -1
- package/build/src/scope_outbox.d.ts.map +1 -1
- package/build/src/scope_outbox.js +17 -10
- package/build/src/scope_outbox.js.map +1 -1
- package/build/src/shared/backend_guard.d.ts +28 -0
- package/build/src/shared/backend_guard.d.ts.map +1 -1
- package/build/src/shared/backend_guard.js +52 -0
- package/build/src/shared/backend_guard.js.map +1 -1
- package/build/src/shared/transaction_guard.d.ts +50 -0
- package/build/src/shared/transaction_guard.d.ts.map +1 -0
- package/build/src/shared/transaction_guard.js +60 -0
- package/build/src/shared/transaction_guard.js.map +1 -0
- package/build/src/testing/contract.d.ts +55 -4
- package/build/src/testing/contract.d.ts.map +1 -1
- package/build/src/testing/contract.js +240 -8
- package/build/src/testing/contract.js.map +1 -1
- package/build/src/testing/main.d.ts +4 -4
- package/build/src/testing/main.d.ts.map +1 -1
- package/build/src/testing/main.js +2 -2
- package/build/src/testing/main.js.map +1 -1
- package/build/src/testing/relations_contract.d.ts +23 -1
- package/build/src/testing/relations_contract.d.ts.map +1 -1
- package/build/src/testing/relations_contract.js +603 -19
- package/build/src/testing/relations_contract.js.map +1 -1
- package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -1
- package/build/src/testing/relations_reconcile_contract.js +49 -1
- package/build/src/testing/relations_reconcile_contract.js.map +1 -1
- package/build/src/traits/has_uuid.d.ts +2 -2
- package/build/src/traits/has_uuid.d.ts.map +1 -1
- package/build/src/types.d.ts +284 -16
- package/build/src/types.d.ts.map +1 -1
- package/build/src/types.js +4 -0
- package/build/src/types.js.map +1 -1
- package/build/stubs/config/authorization.stub +45 -1
- package/build/stubs/migration.stub +20 -10
- package/package.json +1 -1
|
@@ -183,13 +183,20 @@ export default class extends BaseSchema {
|
|
|
183
183
|
table.timestamp('updated_at').notNullable()
|
|
184
184
|
})
|
|
185
185
|
|
|
186
|
-
// Tuplas de ReBAC (Fase 4): una fila por relación, INSERT/DELETE-ONLY
|
|
187
|
-
//
|
|
188
|
-
//
|
|
189
|
-
//
|
|
186
|
+
// Tuplas de ReBAC (Fase 4): una fila por relación, INSERT/DELETE-ONLY
|
|
187
|
+
// (renovar la caducidad es delete+insert, nunca UPDATE). Sin FK: las
|
|
188
|
+
// relaciones NO cuelgan del catálogo (viven en su propio espacio de ids,
|
|
189
|
+
// disjunto de `authz_*` por construcción). Identidad byte a byte
|
|
190
190
|
// (`utf8mb4_bin`) como el resto (2.5 · J3). La partición (tenant) es la
|
|
191
191
|
// clave del scope; `subject_relation` con valor = userset (`group:g#member`),
|
|
192
|
-
// `
|
|
192
|
+
// `''` = holder (L-4b: **NOT NULL DEFAULT ''** — con NULL el UNIQUE
|
|
193
|
+
// `authz_rel_tuple_uq` solo defendía usersets, porque NULL ≠ NULL en los
|
|
194
|
+
// tres motores, y dos `relate` concurrentes del mismo holder confirmaban
|
|
195
|
+
// DOS filas; `''` es la única forma con paridad: el índice parcial no
|
|
196
|
+
// existe en MySQL y `NULLS NOT DISTINCT` es solo PG 15+),
|
|
197
|
+
// `subject_partition` = la partición del userset. `expires_at` (R-15,
|
|
198
|
+
// 2.4.0-alpha.2) es la caducidad de la tupla: NULL = no caduca; misma
|
|
199
|
+
// decisión de motor que `authz_assignments.expires_at` (DATETIME(3)).
|
|
193
200
|
this.schema.createTable('authz_relations', (table) => {
|
|
194
201
|
table.uuid('uuid').primary().notNullable()
|
|
195
202
|
table.string('partition_key', 64).notNullable().collate('utf8mb4_bin')
|
|
@@ -198,8 +205,9 @@ export default class extends BaseSchema {
|
|
|
198
205
|
table.string('relation', 50).notNullable().collate('utf8mb4_bin')
|
|
199
206
|
table.string('subject_type', 50).notNullable().collate('utf8mb4_bin')
|
|
200
207
|
table.string('subject_uuid', 64).notNullable().collate('utf8mb4_bin')
|
|
201
|
-
table.string('subject_relation', 50).
|
|
208
|
+
table.string('subject_relation', 50).notNullable().defaultTo('').collate('utf8mb4_bin')
|
|
202
209
|
table.string('subject_partition', 64).nullable().collate('utf8mb4_bin')
|
|
210
|
+
table.datetime('expires_at', { precision: 3 }).nullable()
|
|
203
211
|
table.timestamp('created_at').notNullable()
|
|
204
212
|
|
|
205
213
|
table.unique(
|
|
@@ -211,7 +219,9 @@ export default class extends BaseSchema {
|
|
|
211
219
|
})
|
|
212
220
|
|
|
213
221
|
// El TRIGGER de partición, por dialecto. Defiende al escritor «a mano»: una
|
|
214
|
-
// fila con userset (`subject_relation
|
|
222
|
+
// fila con userset (`subject_relation <> ''`; un holder lleva `''` desde
|
|
223
|
+
// L-4b, y una fila vieja con NULL que nadie rellenó tampoco dispara: en los
|
|
224
|
+
// tres motores `NULL <> ''` es NULL, o sea falso) de OTRA partición que la
|
|
215
225
|
// de la tupla se rechaza en el motor. La DDL es radicalmente distinta en
|
|
216
226
|
// cada uno (SQLite `RAISE(ABORT)`, PostgreSQL función plpgsql + trigger,
|
|
217
227
|
// MySQL `SIGNAL SQLSTATE`), y el cuerpo `BEGIN…END` lleva `;` dentro: cada
|
|
@@ -263,7 +273,7 @@ function relationPartitionTriggerStatements(dialect) {
|
|
|
263
273
|
const body = (event) =>
|
|
264
274
|
`CREATE TRIGGER authz_relations_partition_b${event === 'INSERT' ? 'i' : 'u'} ` +
|
|
265
275
|
`BEFORE ${event} ON authz_relations FOR EACH ROW ` +
|
|
266
|
-
`WHEN NEW.subject_relation
|
|
276
|
+
`WHEN NEW.subject_relation <> '' AND NEW.subject_partition IS NOT NEW.partition_key ` +
|
|
267
277
|
`BEGIN SELECT RAISE(ABORT, '${msg}'); END`
|
|
268
278
|
return [body('INSERT'), body('UPDATE')]
|
|
269
279
|
}
|
|
@@ -271,7 +281,7 @@ function relationPartitionTriggerStatements(dialect) {
|
|
|
271
281
|
return [
|
|
272
282
|
`CREATE OR REPLACE FUNCTION authz_relations_partition_guard() RETURNS trigger LANGUAGE plpgsql AS $authz$ ` +
|
|
273
283
|
`BEGIN ` +
|
|
274
|
-
`IF NEW.subject_relation
|
|
284
|
+
`IF NEW.subject_relation <> '' AND NEW.subject_partition IS DISTINCT FROM NEW.partition_key THEN ` +
|
|
275
285
|
`RAISE EXCEPTION '${msg} (subject_partition=%, partition_key=%)', NEW.subject_partition, NEW.partition_key; ` +
|
|
276
286
|
`END IF; RETURN NEW; END; $authz$`,
|
|
277
287
|
`CREATE TRIGGER authz_relations_partition_biu BEFORE INSERT OR UPDATE ON authz_relations ` +
|
|
@@ -283,7 +293,7 @@ function relationPartitionTriggerStatements(dialect) {
|
|
|
283
293
|
`CREATE TRIGGER authz_relations_partition_b${event === 'INSERT' ? 'i' : 'u'} ` +
|
|
284
294
|
`BEFORE ${event} ON authz_relations FOR EACH ROW ` +
|
|
285
295
|
`BEGIN ` +
|
|
286
|
-
`IF NEW.subject_relation
|
|
296
|
+
`IF NEW.subject_relation <> '' AND NOT (NEW.subject_partition <=> NEW.partition_key) THEN ` +
|
|
287
297
|
`SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '${msg}'; ` +
|
|
288
298
|
`END IF; END`
|
|
289
299
|
return [body('INSERT'), body('UPDATE')]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jantstack/adonis-authz",
|
|
3
|
-
"version": "2.4.0-alpha.
|
|
3
|
+
"version": "2.4.0-alpha.3",
|
|
4
4
|
"description": "Driver-based authorization engine for AdonisJS + Lucid: hierarchical scopes with downward inheritance, explicit denies, expiring assignments and polymorphic holders. Ships a self-contained database driver and an OpenFGA driver, both judged by the same executable contract suite.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|