@nodii/db-rls 0.11.0 → 0.13.0
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/bin/migrate-gen.mjs +11 -0
- package/dist/auth-schema.d.ts +207 -1
- package/dist/auth-schema.d.ts.map +1 -1
- package/dist/auth-schema.js +331 -4
- package/dist/auth-schema.js.map +1 -1
- package/dist/context.d.ts +31 -8
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +103 -24
- package/dist/context.js.map +1 -1
- package/dist/drizzle-client.d.ts +17 -5
- package/dist/drizzle-client.d.ts.map +1 -1
- package/dist/drizzle-client.js +19 -18
- package/dist/drizzle-client.js.map +1 -1
- package/dist/fence-cli.d.ts +21 -0
- package/dist/fence-cli.d.ts.map +1 -0
- package/dist/fence-cli.js +191 -0
- package/dist/fence-cli.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -7
- package/dist/index.js.map +1 -1
- package/dist/postgres-js-client.d.ts +17 -10
- package/dist/postgres-js-client.d.ts.map +1 -1
- package/dist/postgres-js-client.js +19 -21
- package/dist/postgres-js-client.js.map +1 -1
- package/dist/rls-policy-gen.d.ts +43 -27
- package/dist/rls-policy-gen.d.ts.map +1 -1
- package/dist/rls-policy-gen.js +40 -15
- package/dist/rls-policy-gen.js.map +1 -1
- package/dist/rls-policy.d.ts +11 -1
- package/dist/rls-policy.d.ts.map +1 -1
- package/dist/rls-policy.js +31 -4
- package/dist/rls-policy.js.map +1 -1
- package/dist/tenant-fence-gate.d.ts +54 -0
- package/dist/tenant-fence-gate.d.ts.map +1 -0
- package/dist/tenant-fence-gate.js +291 -0
- package/dist/tenant-fence-gate.js.map +1 -0
- package/dist/tenant-fence.d.ts +165 -0
- package/dist/tenant-fence.d.ts.map +1 -0
- package/dist/tenant-fence.js +542 -0
- package/dist/tenant-fence.js.map +1 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -1
- package/dist/verify-rls-cli.d.ts.map +1 -1
- package/dist/verify-rls-cli.js +86 -10
- package/dist/verify-rls-cli.js.map +1 -1
- package/dist/verify-rls.d.ts +26 -5
- package/dist/verify-rls.d.ts.map +1 -1
- package/dist/verify-rls.js +73 -5
- package/dist/verify-rls.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmCA,eAAO,MAAM,QAAQ,WAAW,CAAC;AAejC,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC;AAE3C,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAEhE,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EAItB,eAAe,EACf,8CAA8C,EAC9C,YAAY,GACb,MAAM,cAAc,CAAC;AActB,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -55,16 +55,39 @@ export { withUserContext, withUserMembershipContext, withSystemContext, withOwne
|
|
|
55
55
|
// per 08-rls-doctrine § 7.5 line 280.
|
|
56
56
|
withPlatformOps, _resetWithPlatformOpsDeprecationWarnedForTests, autoDispatch, } from "./context.js";
|
|
57
57
|
export { assertMigrateAllowed } from "./migrate-guard.js";
|
|
58
|
-
// 08-rls § A1 + § 7.6 — RLS-coverage preflight guard.
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
// exempting § 7.6 reference tables (GRANT-controlled, NO RLS by design)
|
|
58
|
+
// 08-rls § A1 + § 7.6 — RLS-coverage preflight guard. Wire it into your
|
|
59
|
+
// `db:setup`, AFTER migrations apply, to catch the drizzle-snapshot RLS
|
|
60
|
+
// hazard (a tenant table created without ENABLE ROW LEVEL SECURITY),
|
|
61
|
+
// exempting § 7.6 reference tables (GRANT-controlled, NO RLS by design):
|
|
62
|
+
//
|
|
63
|
+
// // postgres-js (the fleet default)
|
|
64
|
+
// await verifyRls(getPools().owner.sql, { requiredTables: [...] });
|
|
65
|
+
// // node-postgres
|
|
66
|
+
// await verifyRls(pgPool, { requiredTables: [...] });
|
|
67
|
+
// // or as a script, no import needed:
|
|
68
|
+
// nodii-db-rls verify-rls --tables a,b,c --ref country_codes
|
|
69
|
+
//
|
|
70
|
+
// 0.12.0 — accepts BOTH driver shapes. It previously accepted only the
|
|
71
|
+
// node-postgres `{ rows }` envelope, which most Nodii services (postgres-js,
|
|
72
|
+
// no `pg` installed) could not satisfy; that is why this had zero adoption
|
|
73
|
+
// while five services hand-rolled the same pg_class query in their tests.
|
|
62
74
|
export { RlsCoverageError, verifyRls } from "./verify-rls.js";
|
|
63
|
-
export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql,
|
|
75
|
+
export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql, SESSION_TENANT_IDS_DEGRADED_MARKER, SESSION_TENANT_IDS_DEGRADED_SQL, SESSION_TENANT_IDS_GRANTS_SQL, SESSION_TENANT_IDS_SQL,
|
|
76
|
+
// THE DELIVERY PATH. `INSTALL_SESSION_RESOLVER_SQL` picks the strict or
|
|
77
|
+
// degraded resolver body from what the database actually contains;
|
|
78
|
+
// `SESSION_FENCE_BOOTSTRAP_SQL` is that plus the runtime gate, and
|
|
79
|
+
// `applySessionFenceBootstrap` applies it. A service with no other delivery
|
|
80
|
+
// path calls the last of these from its boot sequence, before anything opens
|
|
81
|
+
// an authenticated transaction.
|
|
82
|
+
applySessionFenceBootstrap, INSTALL_SESSION_RESOLVER_SQL, SESSION_FENCE_BOOTSTRAP_SQL, } from "./auth-schema.js";
|
|
83
|
+
// The RUNTIME gate. `withUserContext` calls `auth.assert_tenant_fence()` once
|
|
84
|
+
// per process on the first authenticated checkout — these are exported for the
|
|
85
|
+
// CLI, for a bespoke `db:verify`, and so the wiring is greppable.
|
|
86
|
+
export { TENANT_FENCE_GATE_CALL_SQL, TENANT_FENCE_GATE_GRANTS_SQL, TENANT_FENCE_GATE_SQL, sessionFenceBootstrapSql, } from "./tenant-fence-gate.js";
|
|
64
87
|
export { withRls, generateTableGrants,
|
|
65
88
|
// 08-rls § 6 — the authenticated-pool predicate (single source of truth,
|
|
66
89
|
// pool-mode aware). Exported so consumers can compose it directly.
|
|
67
|
-
authenticatedPredicate, withPlatformOpsTenantSql, withPlatformOpsGlobalSql, platformOpsTenantPredicateSql, platformOpsGlobalPredicateSql, platformOpsVerbClauseSql, sqlLiteral, PLATFORM_OPS_GRANTS_REPLICA_DEFAULT,
|
|
90
|
+
authenticatedPredicate, SESSION_TENANT_IDS_CALL, SESSION_TENANT_IDS_SUBQUERY, withPlatformOpsTenantSql, withPlatformOpsGlobalSql, platformOpsTenantPredicateSql, platformOpsGlobalPredicateSql, platformOpsVerbClauseSql, sqlLiteral, PLATFORM_OPS_GRANTS_REPLICA_DEFAULT,
|
|
68
91
|
// 08-rls § 7.6 — pure platform-global reference tables (GRANT-controlled).
|
|
69
92
|
referenceTableGrantsSql, findTenantColumn, ReferenceTableTenantColumnError, REFERENCE_TABLE_SKIP_RLS_MARKER, } from "./rls-policy-gen.js";
|
|
70
93
|
export { migrateGen, runMigrateGenCli, userTenantIdsRealSql, userTenantIdsStubSql, platformOpsPoliciesSql, referenceTablesSql, } from "./migrate-gen.js";
|
|
@@ -73,5 +96,6 @@ export { migrateGen, runMigrateGenCli, userTenantIdsRealSql, userTenantIdsStubSq
|
|
|
73
96
|
export { generateRlsPolicy, authSchemaHelpers } from "./rls-policy.js";
|
|
74
97
|
export { InMemoryPgPool } from "./in-memory-pool.js";
|
|
75
98
|
export { DB_RLS_METRIC_VOCABULARY, _resetMetricsWarnLedgerForTests, } from "./metrics.js";
|
|
76
|
-
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, MissingTenantContext, OwnerContextOutsideMigrate, PoolUnavailable, TransactionRolledBack, } from "./types.js";
|
|
99
|
+
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, CrossTenantSessionRefused, MissingTenantContext, OwnerContextOutsideMigrate, PoolUnavailable, TransactionRolledBack, } from "./types.js";
|
|
100
|
+
export { classifyAuthPolicy, consultsMembershipUnion, isStubMembershipHelper, resolvesThroughSession, TenantFenceError, verifyTenantFence, } from "./tenant-fence.js";
|
|
77
101
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AACpE,wDAAwD;AACxD,6CAA6C;AAC7C,EAAE;AACF,yCAAyC;AACzC,sEAAsE;AACtE,wCAAwC;AACxC,sDAAsD;AACtD,+DAA+D;AAC/D,4EAA4E;AAC5E,gDAAgD;AAChD,mEAAmE;AACnE,mDAAmD;AACnD,wEAAwE;AACxE,2EAA2E;AAC3E,+EAA+E;AAC/E,wEAAwE;AACxE,sEAAsE;AACtE,6EAA6E;AAC7E,6EAA6E;AAC7E,sCAAsC;AACtC,uEAAuE;AACvE,0EAA0E;AAC1E,8EAA8E;AAC9E,kFAAkF;AAClF,yEAAyE;AACzE,mEAAmE;AACnE,0EAA0E;AAC1E,qCAAqC;AAErC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAEjC,yEAAyE;AACzE,4EAA4E;AAC5E,sEAAsE;AACtE,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,2EAA2E;AAC3E,kEAAkE;AAClE,sEAAsE;AACtE,8BAA8B;AAC9B,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChD,MAAM,GAAG,GAAG,QAAQ,CAAC,iBAAiB,CAAwB,CAAC;AAC/D,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC;AAE3C,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB;AACtB,uEAAuE;AACvE,wEAAwE;AACxE,sCAAsC;AACtC,eAAe,EACf,8CAA8C,EAC9C,YAAY,GACb,MAAM,cAAc,CAAC;AAetB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,17 +67,24 @@ export declare class PgPostgresJsPool implements PgPool {
|
|
|
67
67
|
*/
|
|
68
68
|
export declare function withUserContextDbPostgresJs<T, TSchema extends Record<string, unknown> = Record<string, unknown>>(opts: UserContextOpts, fn: (db: PostgresJsDrizzleClient<TSchema>) => Promise<T>): Promise<T>;
|
|
69
69
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
70
|
+
* @deprecated REMOVED — always throws {@link CrossTenantSessionRefused}.
|
|
71
|
+
*
|
|
72
|
+
* Opened an `authenticated`-pool transaction binding ONLY `app.user_id`,
|
|
73
|
+
* leaving `app.tenant_id` deliberately unset so the old union predicate
|
|
74
|
+
* resolved across EVERY tenant the principal belonged to. That is the
|
|
75
|
+
* mechanism of the cross-tenant approval incident, not a side effect of it:
|
|
76
|
+
* a legitimate tenant-A session transitioned a tenant-B approval task, got
|
|
77
|
+
* HTTP 200, and released a 250,000 INR refund.
|
|
78
|
+
*
|
|
79
|
+
* Migrate to `withUserContextDbPostgresJs({ userId, tenantId }, fn)`.
|
|
80
|
+
* To LIST a user's tenants (switcher / login picker), query
|
|
81
|
+
* `auth.user_tenant_ids` from a services-pool context — that function is
|
|
82
|
+
* intact; what is gone is opening a DATA session that spans them.
|
|
83
|
+
*
|
|
84
|
+
* Retained as a throwing stub rather than deleted so a JavaScript consumer
|
|
85
|
+
* gets this explanation instead of `undefined is not a function`.
|
|
79
86
|
*/
|
|
80
|
-
export declare function withUserMembershipContextDbPostgresJs<T, TSchema extends Record<string, unknown> = Record<string, unknown>>(
|
|
87
|
+
export declare function withUserMembershipContextDbPostgresJs<T, TSchema extends Record<string, unknown> = Record<string, unknown>>(_opts: UserMembershipContextOpts, _fn: (db: PostgresJsDrizzleClient<TSchema>) => Promise<T>): Promise<T>;
|
|
81
88
|
/**
|
|
82
89
|
* postgres-js Drizzle variant of `withSystemContext`. Opens a tx on the
|
|
83
90
|
* `services` pool with `app.tenant_id` GUC bound; yields a Drizzle client.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-js-client.d.ts","sourceRoot":"","sources":["../src/postgres-js-client.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAW,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,KAAK,EAAE,GAAG,EAAkB,MAAM,UAAU,CAAC;AAYpD,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,sBAAsB,EAC3B,KAAK,QAAQ,EAEb,KAAK,iBAAiB,EACtB,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"postgres-js-client.d.ts","sourceRoot":"","sources":["../src/postgres-js-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,7 +27,7 @@ import { drizzle } from "drizzle-orm/postgres-js";
|
|
|
27
27
|
import { requirePool } from "./init.js";
|
|
28
28
|
import { emitSlowAcquireSpan, recordAcquisition, recordAcquisitionDuration, recordGucSetFailure, recordOwnerContextInvocation, recordTxDuration, withTxSpan, } from "./metrics.js";
|
|
29
29
|
import { assertMigrateAllowed, } from "./migrate-guard.js";
|
|
30
|
-
import { MissingTenantContext, TransactionRolledBack, } from "./types.js";
|
|
30
|
+
import { MissingTenantContext, TransactionRolledBack, CrossTenantSessionRefused, } from "./types.js";
|
|
31
31
|
/**
|
|
32
32
|
* PgPool adapter wrapping a postgres-js `Sql` instance. Caller owns the
|
|
33
33
|
* underlying Sql's lifecycle (creation + .end()).
|
|
@@ -263,27 +263,25 @@ export async function withUserContextDbPostgresJs(opts, fn) {
|
|
|
263
263
|
}, fn);
|
|
264
264
|
}
|
|
265
265
|
/**
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
266
|
+
* @deprecated REMOVED — always throws {@link CrossTenantSessionRefused}.
|
|
267
|
+
*
|
|
268
|
+
* Opened an `authenticated`-pool transaction binding ONLY `app.user_id`,
|
|
269
|
+
* leaving `app.tenant_id` deliberately unset so the old union predicate
|
|
270
|
+
* resolved across EVERY tenant the principal belonged to. That is the
|
|
271
|
+
* mechanism of the cross-tenant approval incident, not a side effect of it:
|
|
272
|
+
* a legitimate tenant-A session transitioned a tenant-B approval task, got
|
|
273
|
+
* HTTP 200, and released a 250,000 INR refund.
|
|
274
|
+
*
|
|
275
|
+
* Migrate to `withUserContextDbPostgresJs({ userId, tenantId }, fn)`.
|
|
276
|
+
* To LIST a user's tenants (switcher / login picker), query
|
|
277
|
+
* `auth.user_tenant_ids` from a services-pool context — that function is
|
|
278
|
+
* intact; what is gone is opening a DATA session that spans them.
|
|
279
|
+
*
|
|
280
|
+
* Retained as a throwing stub rather than deleted so a JavaScript consumer
|
|
281
|
+
* gets this explanation instead of `undefined is not a function`.
|
|
275
282
|
*/
|
|
276
|
-
export async function withUserMembershipContextDbPostgresJs(
|
|
277
|
-
|
|
278
|
-
throw new MissingTenantContext();
|
|
279
|
-
const pool = requirePostgresJsPool("authenticated");
|
|
280
|
-
return withPostgresJsTx(pool, async (db) => {
|
|
281
|
-
// ONLY app.user_id — set_user_id, not init, so no tenant is pinned.
|
|
282
|
-
await db.execute(drizzleSql `SELECT auth.set_user_id(${opts.userId}::uuid)`);
|
|
283
|
-
if (opts.sourceIp !== undefined) {
|
|
284
|
-
await db.execute(drizzleSql `SELECT set_config('app.source_ip', ${opts.sourceIp}, true)`);
|
|
285
|
-
}
|
|
286
|
-
}, fn);
|
|
283
|
+
export async function withUserMembershipContextDbPostgresJs(_opts, _fn) {
|
|
284
|
+
throw new CrossTenantSessionRefused("withUserMembershipContextDbPostgresJs");
|
|
287
285
|
}
|
|
288
286
|
/**
|
|
289
287
|
* postgres-js Drizzle variant of `withSystemContext`. Opens a tx on the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-js-client.js","sourceRoot":"","sources":["../src/postgres-js-client.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,mEAAmE;AACnE,kEAAkE;AAClE,wEAAwE;AACxE,+DAA+D;AAC/D,oEAAoE;AACpE,sBAAsB;AACtB,EAAE;AACF,WAAW;AACX,0EAA0E;AAC1E,kEAAkE;AAClE,qBAAqB;AACrB,oEAAoE;AACpE,uEAAuE;AACvE,mEAAmE;AACnE,EAAE;AACF,6DAA6D;AAC7D,gCAAgC;AAChC,2DAA2D;AAC3D,sCAAsC;AACtC,6CAA6C;AAC7C,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,EAAE,GAAG,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,OAAO,EAA2B,MAAM,yBAAyB,CAAC;AAG3E,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,yBAAyB,EACzB,mBAAmB,EACnB,4BAA4B,EAC5B,gBAAgB,EAChB,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,oBAAoB,GAErB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EAKpB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"postgres-js-client.js","sourceRoot":"","sources":["../src/postgres-js-client.ts"],"names":[],"mappings":"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"}
|
package/dist/rls-policy-gen.d.ts
CHANGED
|
@@ -1,30 +1,19 @@
|
|
|
1
1
|
export type RlsVerb = "SELECT" | "INSERT" | "UPDATE" | "DELETE";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* @deprecated Retained for source compatibility ONLY; it no longer selects
|
|
4
|
+
* anything. Both values now emit the identical, tenant-fenced predicate
|
|
5
|
+
* `<tenant> IN (SELECT auth.session_tenant_ids())`.
|
|
4
6
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* (exemplar: nodii-billing-service, D415 / drift bea9cfa8).
|
|
7
|
+
* The knob existed because the two service shapes needed different predicates:
|
|
8
|
+
* a service with a real membership mirror got the union, one with a stub got a
|
|
9
|
+
* bare `= auth.get_tenant_id()`. Moving the fence INTO the resolver collapses
|
|
10
|
+
* that distinction — the predicate is now uniform across the fleet and the
|
|
11
|
+
* per-service difference lives in the BODY of `auth.session_tenant_ids()`
|
|
12
|
+
* (strict vs degraded, see `auth-schema.ts`).
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* `nodii_services` predicate. For a service whose authenticated pool
|
|
17
|
-
* binds `app.tenant_id` per-tx (edge pre-verifies membership) and ships
|
|
18
|
-
* NO membership mirror + a STUB `auth.user_tenant_ids`, the
|
|
19
|
-
* multi-membership subquery is INERT and returns the empty set for
|
|
20
|
-
* every user-JWT session → every authenticated-pool write is RLS-denied
|
|
21
|
-
* (the P0 drift 199feabc: crm's 430 policies were dead). This flavor is
|
|
22
|
-
* isolation-equivalent for the single-tenant-session model (§ 6) and
|
|
23
|
-
* the correct opt-in for such services.
|
|
24
|
-
*
|
|
25
|
-
* SUNSET (§ 6): a `"single-tenant"` service that later adds a
|
|
26
|
-
* cross-membership read surface MUST switch to `"multi-membership"` and
|
|
27
|
-
* implement `auth.user_tenant_ids`.
|
|
14
|
+
* That collapse is what lets `@nodii/saga`, `@nodii/dsar` and
|
|
15
|
+
* `@nodii/audit-chain` inline a single static predicate string and still be
|
|
16
|
+
* correct for every consumer, including the stub-helper ones.
|
|
28
17
|
*/
|
|
29
18
|
export type AuthPoolMode = "multi-membership" | "single-tenant";
|
|
30
19
|
export interface WithRlsOpts {
|
|
@@ -42,11 +31,38 @@ export interface WithRlsOpts {
|
|
|
42
31
|
authPoolMode?: AuthPoolMode;
|
|
43
32
|
}
|
|
44
33
|
/**
|
|
45
|
-
* The
|
|
46
|
-
*
|
|
47
|
-
*
|
|
34
|
+
* The SQL text of the authenticated-pool resolver call. Every generated
|
|
35
|
+
* `authenticated` predicate resolves through exactly this, and
|
|
36
|
+
* `verifyTenantFence` asserts POSITIVELY that live policies do too.
|
|
37
|
+
*/
|
|
38
|
+
export declare const SESSION_TENANT_IDS_CALL = "auth.session_tenant_ids()";
|
|
39
|
+
/**
|
|
40
|
+
* The subquery every `authenticated` predicate fences through.
|
|
41
|
+
*
|
|
42
|
+
* Note the shape is IDENTICAL to what shipped before — `<col> IN (SELECT …)`.
|
|
43
|
+
* Only the function inside the subquery changed, from
|
|
44
|
+
* `auth.user_tenant_ids(auth.get_user_id())` (the union of every tenant the
|
|
45
|
+
* principal belongs to) to `auth.session_tenant_ids()` (at most the one tenant
|
|
46
|
+
* the session is bound to, and only if the principal really holds it).
|
|
47
|
+
*
|
|
48
|
+
* Keeping the outer shape byte-identical is the entire point: a hand-written
|
|
49
|
+
* policy can swap this subquery in without touching its column, its casts, or
|
|
50
|
+
* its surrounding `OR` — see the long note on {@link SESSION_TENANT_IDS_SQL}.
|
|
51
|
+
*/
|
|
52
|
+
export declare const SESSION_TENANT_IDS_SUBQUERY = "(SELECT auth.session_tenant_ids())";
|
|
53
|
+
/**
|
|
54
|
+
* The `authenticated`-pool predicate for the given tenant column. Single source
|
|
55
|
+
* of truth so the string-DDL surface (`withRls(table)`), the Drizzle surface
|
|
56
|
+
* (`withRls(col)`), `generateRlsPolicy`, and the three libraries that inline
|
|
57
|
+
* their own copy never drift.
|
|
58
|
+
*
|
|
59
|
+
* `mode` is accepted and IGNORED — see {@link AuthPoolMode}. Both former values
|
|
60
|
+
* were safe-to-migrate: the union one was the hole, and the bare
|
|
61
|
+
* `= auth.get_tenant_id()` one was cross-tenant-safe but silently returned zero
|
|
62
|
+
* rows for an unbound session. This predicate is correct for both, so no caller
|
|
63
|
+
* has to change anything to become safe.
|
|
48
64
|
*/
|
|
49
|
-
export declare function authenticatedPredicate(tenantColumn: string,
|
|
65
|
+
export declare function authenticatedPredicate(tenantColumn: string, _mode?: AuthPoolMode): string;
|
|
50
66
|
/**
|
|
51
67
|
* Emits the policy DDL block for `table`.
|
|
52
68
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rls-policy-gen.d.ts","sourceRoot":"","sources":["../src/rls-policy-gen.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rls-policy-gen.d.ts","sourceRoot":"","sources":["../src/rls-policy-gen.ts"],"names":[],"mappings":"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"}
|
package/dist/rls-policy-gen.js
CHANGED
|
@@ -1,22 +1,48 @@
|
|
|
1
1
|
// withRls — emits the 3-policy DDL for a tenant-scoped table per § 5.5.
|
|
2
2
|
//
|
|
3
|
-
// One policy per role: nodii_owner (FOR ALL bypass), authenticated (
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// One policy per role: nodii_owner (FOR ALL bypass), authenticated (gated
|
|
4
|
+
// on auth.session_tenant_ids() — the session tenant INTERSECT the
|
|
5
|
+
// principal's membership), nodii_services (FOR ALL gated on app.tenant_id
|
|
6
|
+
// GUC). Per § 5.5 the `{ allow }` option restricts which CRUD verbs the
|
|
7
|
+
// non-owner roles get; owner ALWAYS gets FOR ALL.
|
|
7
8
|
//
|
|
8
9
|
// Output byte-equal across TS / Python / Go ports.
|
|
9
10
|
const DEFAULT_ALLOW = ["SELECT", "INSERT"];
|
|
10
11
|
const DEFAULT_AUTH_POOL_MODE = "multi-membership";
|
|
11
12
|
/**
|
|
12
|
-
* The
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* The SQL text of the authenticated-pool resolver call. Every generated
|
|
14
|
+
* `authenticated` predicate resolves through exactly this, and
|
|
15
|
+
* `verifyTenantFence` asserts POSITIVELY that live policies do too.
|
|
15
16
|
*/
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
export const SESSION_TENANT_IDS_CALL = "auth.session_tenant_ids()";
|
|
18
|
+
/**
|
|
19
|
+
* The subquery every `authenticated` predicate fences through.
|
|
20
|
+
*
|
|
21
|
+
* Note the shape is IDENTICAL to what shipped before — `<col> IN (SELECT …)`.
|
|
22
|
+
* Only the function inside the subquery changed, from
|
|
23
|
+
* `auth.user_tenant_ids(auth.get_user_id())` (the union of every tenant the
|
|
24
|
+
* principal belongs to) to `auth.session_tenant_ids()` (at most the one tenant
|
|
25
|
+
* the session is bound to, and only if the principal really holds it).
|
|
26
|
+
*
|
|
27
|
+
* Keeping the outer shape byte-identical is the entire point: a hand-written
|
|
28
|
+
* policy can swap this subquery in without touching its column, its casts, or
|
|
29
|
+
* its surrounding `OR` — see the long note on {@link SESSION_TENANT_IDS_SQL}.
|
|
30
|
+
*/
|
|
31
|
+
export const SESSION_TENANT_IDS_SUBQUERY = `(SELECT ${SESSION_TENANT_IDS_CALL})`;
|
|
32
|
+
/**
|
|
33
|
+
* The `authenticated`-pool predicate for the given tenant column. Single source
|
|
34
|
+
* of truth so the string-DDL surface (`withRls(table)`), the Drizzle surface
|
|
35
|
+
* (`withRls(col)`), `generateRlsPolicy`, and the three libraries that inline
|
|
36
|
+
* their own copy never drift.
|
|
37
|
+
*
|
|
38
|
+
* `mode` is accepted and IGNORED — see {@link AuthPoolMode}. Both former values
|
|
39
|
+
* were safe-to-migrate: the union one was the hole, and the bare
|
|
40
|
+
* `= auth.get_tenant_id()` one was cross-tenant-safe but silently returned zero
|
|
41
|
+
* rows for an unbound session. This predicate is correct for both, so no caller
|
|
42
|
+
* has to change anything to become safe.
|
|
43
|
+
*/
|
|
44
|
+
export function authenticatedPredicate(tenantColumn, _mode = DEFAULT_AUTH_POOL_MODE) {
|
|
45
|
+
return `${tenantColumn} IN ${SESSION_TENANT_IDS_SUBQUERY}`;
|
|
20
46
|
}
|
|
21
47
|
/**
|
|
22
48
|
* Emits the policy DDL block for `table`.
|
|
@@ -39,7 +65,7 @@ export function withRls(table, opts = {}) {
|
|
|
39
65
|
lines.push(`ALTER TABLE ${table} ENABLE ROW LEVEL SECURITY;`);
|
|
40
66
|
// 1. Owner policy: FOR ALL bypass.
|
|
41
67
|
lines.push(`CREATE POLICY ${policyBase}_owner_policy ON ${table} FOR ALL TO nodii_owner USING (true) WITH CHECK (true);`);
|
|
42
|
-
// 2. Authenticated policy: gated on auth.
|
|
68
|
+
// 2. Authenticated policy: gated on auth.session_tenant_ids().
|
|
43
69
|
// One policy per verb so the surface honestly reflects sanctioned
|
|
44
70
|
// mutations.
|
|
45
71
|
for (const verb of verbs) {
|
|
@@ -70,9 +96,8 @@ export function generateTableGrants(table, opts = {}) {
|
|
|
70
96
|
return `${lines.join("\n")}\n`;
|
|
71
97
|
}
|
|
72
98
|
function authPolicyFor(table, policyBase, tenantColumn, verb, mode = DEFAULT_AUTH_POOL_MODE) {
|
|
73
|
-
// Authenticated role predicate
|
|
74
|
-
//
|
|
75
|
-
// single-tenant → tenant_id = auth.get_tenant_id()
|
|
99
|
+
// Authenticated role predicate — uniform across every service:
|
|
100
|
+
// tenant_id IN (SELECT auth.session_tenant_ids())
|
|
76
101
|
const cond = authenticatedPredicate(tenantColumn, mode);
|
|
77
102
|
return policyLine(table, policyBase, "auth", verb, "authenticated", cond);
|
|
78
103
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rls-policy-gen.js","sourceRoot":"","sources":["../src/rls-policy-gen.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"rls-policy-gen.js","sourceRoot":"","sources":["../src/rls-policy-gen.ts"],"names":[],"mappings":"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"}
|
package/dist/rls-policy.d.ts
CHANGED
|
@@ -3,11 +3,21 @@ import type { GenerateRlsPolicyOpts } from "./types.js";
|
|
|
3
3
|
* Generates the canonical 3-policy DDL block:
|
|
4
4
|
*
|
|
5
5
|
* 1. `<table>_owner_policy` — nodii_owner FOR ALL USING (true) WITH CHECK (true)
|
|
6
|
-
* 2. `<table>_auth_policy` — authenticated FOR ALL USING (<tenant_col> IN auth.
|
|
6
|
+
* 2. `<table>_auth_policy` — authenticated FOR ALL USING (<tenant_col> IN (SELECT auth.session_tenant_ids()))
|
|
7
7
|
* 3. `<table>_services_policy` — nodii_services FOR ALL USING (<tenant_col> = current_setting('app.tenant_id')::uuid)
|
|
8
8
|
*
|
|
9
9
|
* Plus the `ALTER TABLE ... ENABLE ROW LEVEL SECURITY;` prelude.
|
|
10
10
|
*
|
|
11
|
+
* The `authenticated` predicate previously read
|
|
12
|
+
* `<tenant_col> IN (SELECT auth.user_tenant_ids(current_setting('app.user_id')::uuid))`
|
|
13
|
+
* — the union of every tenant the principal belonged to, with no tenant fence.
|
|
14
|
+
* It now resolves through `auth.session_tenant_ids()`, which yields at most the
|
|
15
|
+
* one tenant the session is bound to. This is the SECOND generator (the other
|
|
16
|
+
* is `withRls` in `rls-policy-gen.ts`); both share
|
|
17
|
+
* {@link authenticatedPredicate} so they cannot drift apart again — they had
|
|
18
|
+
* separately-maintained copies of the union before, which is precisely how one
|
|
19
|
+
* of them could have been fixed while the other kept emitting the hole.
|
|
20
|
+
*
|
|
11
21
|
* Output is deterministic (no whitespace drift, stable column ordering)
|
|
12
22
|
* for cross-language byte-equality.
|
|
13
23
|
*/
|
package/dist/rls-policy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rls-policy.d.ts","sourceRoot":"","sources":["../src/rls-policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rls-policy.d.ts","sourceRoot":"","sources":["../src/rls-policy.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAYrE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CA8C1C"}
|
package/dist/rls-policy.js
CHANGED
|
@@ -3,28 +3,43 @@
|
|
|
3
3
|
//
|
|
4
4
|
// Spec § 5.5 (A1 posture): every tenant-scoped table gets RLS via this
|
|
5
5
|
// helper. The caller writes the DDL into a migration. Output is
|
|
6
|
-
// byte-equal across TS / Python / Go ports
|
|
7
|
-
// test
|
|
6
|
+
// intended to be byte-equal across TS / Python / Go ports. NOTE: there is
|
|
7
|
+
// currently NO cross-language test asserting that, and the Go port still
|
|
8
|
+
// emits the pre-fence union — see the changeset. Do not read this comment as
|
|
9
|
+
// a guarantee; it is an intent.
|
|
10
|
+
import { SESSION_TENANT_IDS_SQL } from "./auth-schema.js";
|
|
11
|
+
import { authenticatedPredicate } from "./rls-policy-gen.js";
|
|
8
12
|
/**
|
|
9
13
|
* Generates the canonical 3-policy DDL block:
|
|
10
14
|
*
|
|
11
15
|
* 1. `<table>_owner_policy` — nodii_owner FOR ALL USING (true) WITH CHECK (true)
|
|
12
|
-
* 2. `<table>_auth_policy` — authenticated FOR ALL USING (<tenant_col> IN auth.
|
|
16
|
+
* 2. `<table>_auth_policy` — authenticated FOR ALL USING (<tenant_col> IN (SELECT auth.session_tenant_ids()))
|
|
13
17
|
* 3. `<table>_services_policy` — nodii_services FOR ALL USING (<tenant_col> = current_setting('app.tenant_id')::uuid)
|
|
14
18
|
*
|
|
15
19
|
* Plus the `ALTER TABLE ... ENABLE ROW LEVEL SECURITY;` prelude.
|
|
16
20
|
*
|
|
21
|
+
* The `authenticated` predicate previously read
|
|
22
|
+
* `<tenant_col> IN (SELECT auth.user_tenant_ids(current_setting('app.user_id')::uuid))`
|
|
23
|
+
* — the union of every tenant the principal belonged to, with no tenant fence.
|
|
24
|
+
* It now resolves through `auth.session_tenant_ids()`, which yields at most the
|
|
25
|
+
* one tenant the session is bound to. This is the SECOND generator (the other
|
|
26
|
+
* is `withRls` in `rls-policy-gen.ts`); both share
|
|
27
|
+
* {@link authenticatedPredicate} so they cannot drift apart again — they had
|
|
28
|
+
* separately-maintained copies of the union before, which is precisely how one
|
|
29
|
+
* of them could have been fixed while the other kept emitting the hole.
|
|
30
|
+
*
|
|
17
31
|
* Output is deterministic (no whitespace drift, stable column ordering)
|
|
18
32
|
* for cross-language byte-equality.
|
|
19
33
|
*/
|
|
20
34
|
export function generateRlsPolicy(opts) {
|
|
21
35
|
const table = opts.table;
|
|
22
36
|
const tenantColumn = opts.tenantColumn ?? "tenant_id";
|
|
37
|
+
const authCond = authenticatedPredicate(tenantColumn);
|
|
23
38
|
// Stable single-string with trailing newline per SQL file convention.
|
|
24
39
|
const lines = [
|
|
25
40
|
`ALTER TABLE ${table} ENABLE ROW LEVEL SECURITY;`,
|
|
26
41
|
`CREATE POLICY ${table}_owner_policy ON ${table} FOR ALL TO nodii_owner USING (true) WITH CHECK (true);`,
|
|
27
|
-
`CREATE POLICY ${table}_auth_policy ON ${table} FOR ALL TO authenticated USING (${
|
|
42
|
+
`CREATE POLICY ${table}_auth_policy ON ${table} FOR ALL TO authenticated USING (${authCond}) WITH CHECK (${authCond});`,
|
|
28
43
|
`CREATE POLICY ${table}_services_policy ON ${table} FOR ALL TO nodii_services USING (${tenantColumn} = current_setting('app.tenant_id')::uuid) WITH CHECK (${tenantColumn} = current_setting('app.tenant_id')::uuid);`,
|
|
29
44
|
];
|
|
30
45
|
return `${lines.join("\n")}\n`;
|
|
@@ -69,12 +84,24 @@ export function authSchemaHelpers() {
|
|
|
69
84
|
"CREATE OR REPLACE FUNCTION auth.user_tenant_ids(p_user_id uuid) RETURNS SETOF uuid",
|
|
70
85
|
"LANGUAGE sql STABLE AS $$ SELECT NULL::uuid WHERE false $$;",
|
|
71
86
|
"",
|
|
87
|
+
"-- The authenticated-pool resolver. Policies emitted by generateRlsPolicy",
|
|
88
|
+
"-- reference this, and Postgres validates the reference at CREATE POLICY",
|
|
89
|
+
"-- time — so it MUST exist before any policy is created.",
|
|
90
|
+
//
|
|
91
|
+
// SPLICED FROM auth-schema.ts, NOT RE-TYPED. An earlier revision of this
|
|
92
|
+
// file inlined a second copy of the resolver body here, and the two had
|
|
93
|
+
// already diverged (this copy silently dropped both HINT clauses) — the
|
|
94
|
+
// exact duplication failure this module's own docblock warns about for the
|
|
95
|
+
// predicate. One definition, two emitters.
|
|
96
|
+
SESSION_TENANT_IDS_SQL.trimEnd(),
|
|
97
|
+
"",
|
|
72
98
|
"GRANT EXECUTE ON FUNCTION auth.set_user_id(uuid) TO nodii_services, authenticated;",
|
|
73
99
|
"GRANT EXECUTE ON FUNCTION auth.set_tenant_id(uuid) TO nodii_services, authenticated;",
|
|
74
100
|
"GRANT EXECUTE ON FUNCTION auth.set_source_ip(text) TO nodii_services, authenticated;",
|
|
75
101
|
"GRANT EXECUTE ON FUNCTION auth.get_user_id() TO nodii_services, authenticated;",
|
|
76
102
|
"GRANT EXECUTE ON FUNCTION auth.get_tenant_id() TO nodii_services, authenticated;",
|
|
77
103
|
"GRANT EXECUTE ON FUNCTION auth.user_tenant_ids(uuid) TO nodii_services, authenticated;",
|
|
104
|
+
"GRANT EXECUTE ON FUNCTION auth.session_tenant_ids() TO nodii_services, authenticated;",
|
|
78
105
|
"",
|
|
79
106
|
].join("\n");
|
|
80
107
|
}
|
package/dist/rls-policy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rls-policy.js","sourceRoot":"","sources":["../src/rls-policy.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,kEAAkE;AAClE,EAAE;AACF,uEAAuE;AACvE,gEAAgE;AAChE,
|
|
1
|
+
{"version":3,"file":"rls-policy.js","sourceRoot":"","sources":["../src/rls-policy.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,kEAAkE;AAClE,EAAE;AACF,uEAAuE;AACvE,gEAAgE;AAChE,0EAA0E;AAC1E,yEAAyE;AACzE,6EAA6E;AAC7E,gCAAgC;AAEhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAG7D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA2B;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACzB,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,CAAC;IACtD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;IACtD,sEAAsE;IACtE,MAAM,KAAK,GAAG;QACZ,eAAe,KAAK,6BAA6B;QACjD,iBAAiB,KAAK,oBAAoB,KAAK,yDAAyD;QACxG,iBAAiB,KAAK,mBAAmB,KAAK,oCAAoC,QAAQ,iBAAiB,QAAQ,IAAI;QACvH,iBAAiB,KAAK,uBAAuB,KAAK,qCAAqC,YAAY,0DAA0D,YAAY,6CAA6C;KACvN,CAAC;IACF,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB;IAC/B,wEAAwE;IACxE,oCAAoC;IACpC,OAAO;QACL,mCAAmC;QACnC,EAAE;QACF,0EAA0E;QAC1E,gFAAgF;QAChF,EAAE;QACF,8EAA8E;QAC9E,oFAAoF;QACpF,EAAE;QACF,8EAA8E;QAC9E,8EAA8E;QAC9E,EAAE;QACF,4DAA4D;QAC5D,6FAA6F;QAC7F,EAAE;QACF,8DAA8D;QAC9D,+FAA+F;QAC/F,EAAE;QACF,yEAAyE;QACzE,8DAA8D;QAC9D,oFAAoF;QACpF,6DAA6D;QAC7D,EAAE;QACF,2EAA2E;QAC3E,0EAA0E;QAC1E,0DAA0D;QAC1D,EAAE;QACF,yEAAyE;QACzE,wEAAwE;QACxE,wEAAwE;QACxE,2EAA2E;QAC3E,2CAA2C;QAC3C,sBAAsB,CAAC,OAAO,EAAE;QAChC,EAAE;QACF,oFAAoF;QACpF,sFAAsF;QACtF,sFAAsF;QACtF,gFAAgF;QAChF,kFAAkF;QAClF,wFAAwF;QACxF,uFAAuF;QACvF,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|