UNPKG

@accounter/server

Version:
38 lines 1.56 kB
/** * Run `fn` inside a single transaction whose RLS context is pinned to the given * tenant. `set_config(..., true)` is transaction-local (SET LOCAL), so the * context is cleared on COMMIT/ROLLBACK and never leaks to the pooled * connection's next user. * * Control-plane and gateway-initiated ingestion present an auth session with an * empty businessId, so TenantAwareDBClient (which derives the tenant from the * auth session) cannot be used. The authoritative tenant instead comes from the * resolved alias / cryptographically-validated grant and is pinned here so the * `tenant_isolation` RLS policies (USING / WITH CHECK `owner_id = * get_current_business_id()`) on the email_ingestion_* tables are satisfied — * these tables use FORCE ROW LEVEL SECURITY, so even the table owner is subject * to them and the raw pool cannot bypass the policy. */ export async function withTenantContext(pool, tenantId, fn) { const client = await pool.connect(); try { await client.query('BEGIN'); await client.query("SELECT set_config('app.current_business_id', $1, true)", [tenantId]); const result = await fn(client); await client.query('COMMIT'); return result; } catch (err) { try { await client.query('ROLLBACK'); } catch { // Ignore rollback failures (e.g. the connection is already broken). } throw err; } finally { client.release(); } } //# sourceMappingURL=email-ingestion-tenant-context.helper.js.map