ts-prorm-orm 1.1.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/CHANGELOG.md +1111 -0
- package/LICENSE +21 -0
- package/README.md +573 -0
- package/dist/audit/history-query.js +180 -0
- package/dist/audit/index.js +23 -0
- package/dist/audit/logger.js +236 -0
- package/dist/cache/cache-manager.js +84 -0
- package/dist/cache/index.js +16 -0
- package/dist/cache/redis-cluster-cache.js +557 -0
- package/dist/cli.js +2200 -0
- package/dist/compliance/audit-trail.js +68 -0
- package/dist/compliance/backup-verification.js +685 -0
- package/dist/compliance/breach-detector.js +505 -0
- package/dist/compliance/consent-record.js +227 -0
- package/dist/compliance/consent-versioning.js +331 -0
- package/dist/compliance/cross-border-log.js +530 -0
- package/dist/compliance/data-classifier.js +258 -0
- package/dist/compliance/data-lineage.js +565 -0
- package/dist/compliance/data-masker.js +303 -0
- package/dist/compliance/data-portability.js +265 -0
- package/dist/compliance/data-retention.js +195 -0
- package/dist/compliance/dsar-workflow.js +342 -0
- package/dist/compliance/field-encryption.js +223 -0
- package/dist/compliance/immutable-record.js +148 -0
- package/dist/compliance/index.js +260 -0
- package/dist/compliance/privacy-impact-assessment.js +364 -0
- package/dist/compliance/pseudonymization.js +269 -0
- package/dist/compliance/query-firewall.js +1182 -0
- package/dist/compliance/rate-limiter.js +580 -0
- package/dist/compliance/right-to-erasure.js +117 -0
- package/dist/compliance/row-level-security.js +246 -0
- package/dist/compliance/security-decorator.js +574 -0
- package/dist/compliance/security-monitor.js +525 -0
- package/dist/compliance/sensitive-data-discovery.js +476 -0
- package/dist/compliance/session-isolation.js +472 -0
- package/dist/compliance/tls-enforcer.js +108 -0
- package/dist/compliance/worm-storage.js +712 -0
- package/dist/connection-manager.js +198 -0
- package/dist/connection-pool.js +519 -0
- package/dist/decorators/audit.js +136 -0
- package/dist/decorators/belongs-to-many.js +115 -0
- package/dist/decorators/belongs-to.js +115 -0
- package/dist/decorators/check.js +435 -0
- package/dist/decorators/collate.js +329 -0
- package/dist/decorators/comment.js +205 -0
- package/dist/decorators/database-settings.js +236 -0
- package/dist/decorators/default.js +244 -0
- package/dist/decorators/encryption.js +235 -0
- package/dist/decorators/engine.js +97 -0
- package/dist/decorators/fk-constraints.js +594 -0
- package/dist/decorators/foreign-table.js +136 -0
- package/dist/decorators/generated.js +274 -0
- package/dist/decorators/has-many.js +127 -0
- package/dist/decorators/has-one.js +116 -0
- package/dist/decorators/hstore.js +129 -0
- package/dist/decorators/index.js +355 -0
- package/dist/decorators/json-column.js +83 -0
- package/dist/decorators/jsonb.js +101 -0
- package/dist/decorators/orm-decorators.js +425 -0
- package/dist/decorators/permissions.js +294 -0
- package/dist/decorators/procedure.js +210 -0
- package/dist/decorators/query-options.js +556 -0
- package/dist/decorators/range.js +167 -0
- package/dist/decorators/set-column.js +83 -0
- package/dist/decorators/spatial.js +114 -0
- package/dist/decorators/storage.js +580 -0
- package/dist/decorators/timezone.js +512 -0
- package/dist/decorators/trigger.js +90 -0
- package/dist/decorators/uuid.js +135 -0
- package/dist/decorators/view.js +258 -0
- package/dist/diagrams/chen-diagram.js +354 -0
- package/dist/diagrams/class-diagram.js +384 -0
- package/dist/diagrams/dependency-diagram.js +432 -0
- package/dist/diagrams/er-diagram.js +605 -0
- package/dist/diagrams/flow-diagram.js +394 -0
- package/dist/diagrams/gantt-diagram.js +411 -0
- package/dist/diagrams/index-diagram.js +353 -0
- package/dist/diagrams/index.js +184 -0
- package/dist/diagrams/migration-diagram.js +316 -0
- package/dist/diagrams/model-diagram.js +616 -0
- package/dist/diagrams/package-diagram.js +376 -0
- package/dist/diagrams/palette.js +85 -0
- package/dist/diagrams/relational-diagram.js +455 -0
- package/dist/diagrams/schemadoc-diagram.js +309 -0
- package/dist/diagrams/sequence-diagram.js +307 -0
- package/dist/diagrams/state-diagram.js +344 -0
- package/dist/diagrams/svg-dom.js +111 -0
- package/dist/diagrams/tree-diagram.js +250 -0
- package/dist/dialects/clickhouse/index.js +1742 -0
- package/dist/dialects/cockroachdb/index.js +4677 -0
- package/dist/dialects/cratedb/index.js +441 -0
- package/dist/dialects/databricks/index.js +517 -0
- package/dist/dialects/db2/index.js +2225 -0
- package/dist/dialects/dialect.js +720 -0
- package/dist/dialects/duckdb/index.js +2014 -0
- package/dist/dialects/exasol/index.js +357 -0
- package/dist/dialects/firebird/index.js +495 -0
- package/dist/dialects/greenplum/index.js +457 -0
- package/dist/dialects/hana/index.js +1741 -0
- package/dist/dialects/mariadb/index.js +3590 -0
- package/dist/dialects/mssql/index.js +2296 -0
- package/dist/dialects/mysql/index.js +4058 -0
- package/dist/dialects/oracle/index.js +2999 -0
- package/dist/dialects/postgres/index.js +5319 -0
- package/dist/dialects/query-stream-helper.js +152 -0
- package/dist/dialects/questdb/index.js +433 -0
- package/dist/dialects/redshift/index.js +2277 -0
- package/dist/dialects/singlestore/index.js +354 -0
- package/dist/dialects/snowflake/index.js +2082 -0
- package/dist/dialects/spanner/index.js +1768 -0
- package/dist/dialects/sqlite/index.js +3382 -0
- package/dist/dialects/tidb/index.js +377 -0
- package/dist/dialects/timescaledb/index.js +164 -0
- package/dist/dialects/trino/index.js +420 -0
- package/dist/dialects/turso/index.js +227 -0
- package/dist/dialects/vertica/index.js +317 -0
- package/dist/dialects/yugabytedb/index.js +424 -0
- package/dist/errors/index.js +472 -0
- package/dist/errors/utils.js +340 -0
- package/dist/errors.js +21 -0
- package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
- package/dist/extensions/catalog/mssql-features.js +147 -0
- package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
- package/dist/extensions/catalog/oracle-db2-features.js +196 -0
- package/dist/extensions/catalog/postgres-extensions.js +516 -0
- package/dist/extensions/index.js +71 -0
- package/dist/extensions/types.js +13 -0
- package/dist/foreign-data.js +173 -0
- package/dist/hooks/hooks-manager.js +350 -0
- package/dist/hooks/index.js +37 -0
- package/dist/index.js +463 -0
- package/dist/logging.js +335 -0
- package/dist/migrations/index.js +40 -0
- package/dist/migrations/migration.js +196 -0
- package/dist/migrations/migrator.js +411 -0
- package/dist/migrations/prormmigration.js +275 -0
- package/dist/migrations/query-interface.js +435 -0
- package/dist/migrations/seeder.js +353 -0
- package/dist/models/associations.js +852 -0
- package/dist/models/constraints.js +288 -0
- package/dist/models/data-types.js +2518 -0
- package/dist/models/decorators.js +445 -0
- package/dist/models/index.js +33 -0
- package/dist/models/indexes.js +531 -0
- package/dist/models/methods.js +382 -0
- package/dist/models/model-manager.js +103 -0
- package/dist/models/model.js +5349 -0
- package/dist/models/operators.js +67 -0
- package/dist/models/scopes.js +189 -0
- package/dist/models/typescript-types.js +26 -0
- package/dist/nosql/aerospike/index.js +205 -0
- package/dist/nosql/allegrograph/index.js +169 -0
- package/dist/nosql/arangodb/index.js +364 -0
- package/dist/nosql/azure-blob/index.js +206 -0
- package/dist/nosql/beanstalkd/index.js +231 -0
- package/dist/nosql/beequeue/index.js +210 -0
- package/dist/nosql/bigchaindb/index.js +195 -0
- package/dist/nosql/bigtable/index.js +224 -0
- package/dist/nosql/blazegraph/index.js +173 -0
- package/dist/nosql/bullmq/index.js +191 -0
- package/dist/nosql/cassandra/index.js +174 -0
- package/dist/nosql/chroma/index.js +190 -0
- package/dist/nosql/cloudflare-kv/index.js +220 -0
- package/dist/nosql/coherence/index.js +200 -0
- package/dist/nosql/cosmosdb/index.js +157 -0
- package/dist/nosql/couchbase/index.js +213 -0
- package/dist/nosql/dax/index.js +212 -0
- package/dist/nosql/deno-kv/index.js +206 -0
- package/dist/nosql/dgraph/index.js +171 -0
- package/dist/nosql/doris/index.js +169 -0
- package/dist/nosql/druid/index.js +162 -0
- package/dist/nosql/dynamodb/index.js +937 -0
- package/dist/nosql/elasticsearch/index.js +377 -0
- package/dist/nosql/etcd/index.js +502 -0
- package/dist/nosql/eventhubs/index.js +213 -0
- package/dist/nosql/eventstore/index.js +254 -0
- package/dist/nosql/faunadb/index.js +188 -0
- package/dist/nosql/firestore/index.js +177 -0
- package/dist/nosql/fluree/index.js +148 -0
- package/dist/nosql/fuseki/index.js +170 -0
- package/dist/nosql/gcs/index.js +172 -0
- package/dist/nosql/gearman/index.js +160 -0
- package/dist/nosql/geode/index.js +196 -0
- package/dist/nosql/graphdb/index.js +169 -0
- package/dist/nosql/graylog/index.js +188 -0
- package/dist/nosql/gridgain/index.js +171 -0
- package/dist/nosql/hazelcast/index.js +162 -0
- package/dist/nosql/hbase/index.js +230 -0
- package/dist/nosql/ignite/index.js +173 -0
- package/dist/nosql/immudb/index.js +184 -0
- package/dist/nosql/index.js +232 -0
- package/dist/nosql/infinispan/index.js +200 -0
- package/dist/nosql/influxdb/index.js +0 -0
- package/dist/nosql/kafka/index.js +234 -0
- package/dist/nosql/keyspaces/index.js +189 -0
- package/dist/nosql/kinesis/index.js +253 -0
- package/dist/nosql/leveldb/index.js +153 -0
- package/dist/nosql/lmdb/index.js +160 -0
- package/dist/nosql/loki/index.js +201 -0
- package/dist/nosql/marklogic/index.js +204 -0
- package/dist/nosql/materialize/index.js +145 -0
- package/dist/nosql/meilisearch/index.js +154 -0
- package/dist/nosql/memcached/index.js +223 -0
- package/dist/nosql/milvus/index.js +410 -0
- package/dist/nosql/minio/index.js +265 -0
- package/dist/nosql/momento/index.js +179 -0
- package/dist/nosql/mongodb/index.js +461 -0
- package/dist/nosql/nats/index.js +247 -0
- package/dist/nosql/nedb/index.js +164 -0
- package/dist/nosql/neo4j/index.js +450 -0
- package/dist/nosql/neptune/index.js +470 -0
- package/dist/nosql/nsq/index.js +200 -0
- package/dist/nosql/opensearch/index.js +186 -0
- package/dist/nosql/orientdb/index.js +175 -0
- package/dist/nosql/papertrail/index.js +200 -0
- package/dist/nosql/pinecone/index.js +0 -0
- package/dist/nosql/pinot/index.js +133 -0
- package/dist/nosql/pouchdb/index.js +172 -0
- package/dist/nosql/prometheus/index.js +174 -0
- package/dist/nosql/provendb/index.js +147 -0
- package/dist/nosql/pubsub/index.js +187 -0
- package/dist/nosql/pulsar/index.js +232 -0
- package/dist/nosql/qdrant/index.js +295 -0
- package/dist/nosql/qldb/index.js +192 -0
- package/dist/nosql/r2/index.js +281 -0
- package/dist/nosql/rabbitmq/index.js +237 -0
- package/dist/nosql/ravendb/index.js +175 -0
- package/dist/nosql/redis/index.js +607 -0
- package/dist/nosql/redpanda/index.js +237 -0
- package/dist/nosql/resque/index.js +203 -0
- package/dist/nosql/rethinkdb/index.js +232 -0
- package/dist/nosql/rocksdb/index.js +152 -0
- package/dist/nosql/rockset/index.js +126 -0
- package/dist/nosql/s3/index.js +298 -0
- package/dist/nosql/scylladb/index.js +178 -0
- package/dist/nosql/signoz/index.js +227 -0
- package/dist/nosql/sns/index.js +201 -0
- package/dist/nosql/solr/index.js +231 -0
- package/dist/nosql/splunk/index.js +227 -0
- package/dist/nosql/sqs/index.js +246 -0
- package/dist/nosql/stardog/index.js +169 -0
- package/dist/nosql/starrocks/index.js +170 -0
- package/dist/nosql/store.js +2 -0
- package/dist/nosql/sumologic/index.js +213 -0
- package/dist/nosql/surrealdb/index.js +179 -0
- package/dist/nosql/terminusdb/index.js +151 -0
- package/dist/nosql/tigergraph/index.js +469 -0
- package/dist/nosql/typesense/index.js +148 -0
- package/dist/nosql/unqlite/index.js +157 -0
- package/dist/nosql/upstash/index.js +167 -0
- package/dist/nosql/vercel-kv/index.js +166 -0
- package/dist/nosql/victoriametrics/index.js +213 -0
- package/dist/nosql/virtuoso/index.js +169 -0
- package/dist/nosql/weaviate/index.js +276 -0
- package/dist/operators/index.js +108 -0
- package/dist/operators.js +2690 -0
- package/dist/prisma-migrate/index.js +38 -0
- package/dist/prisma-migrate/migration-generator.js +125 -0
- package/dist/prisma-migrate/model-generator.js +172 -0
- package/dist/prisma-migrate/relations.js +100 -0
- package/dist/prisma-migrate/schema-parser.js +167 -0
- package/dist/prisma-migrate/type-mapper.js +40 -0
- package/dist/prorm.js +6832 -0
- package/dist/query-builders/cte-builder.js +80 -0
- package/dist/query-builders/functions/aggregate.js +390 -0
- package/dist/query-builders/functions/conditional.js +503 -0
- package/dist/query-builders/functions/datetime.js +695 -0
- package/dist/query-builders/functions/fulltext.js +439 -0
- package/dist/query-builders/functions/index.js +93 -0
- package/dist/query-builders/functions/json.js +427 -0
- package/dist/query-builders/functions/math.js +399 -0
- package/dist/query-builders/functions/string.js +518 -0
- package/dist/query-builders/functions/window.js +328 -0
- package/dist/query-builders/include-builder.js +323 -0
- package/dist/query-builders/index-expression-builder.js +242 -0
- package/dist/query-builders/index.js +161 -0
- package/dist/query-builders/insert-builder.js +164 -0
- package/dist/query-builders/model-helpers.js +38 -0
- package/dist/query-builders/order-limit-builder.js +239 -0
- package/dist/query-builders/sql-compiler.js +2040 -0
- package/dist/query-builders/subquery-builder.js +152 -0
- package/dist/query-builders/update-builder.js +182 -0
- package/dist/query-builders/view-builder.js +218 -0
- package/dist/query-builders/where-builder.js +1532 -0
- package/dist/query-interface.js +622 -0
- package/dist/query-optimizers/batch-optimizer.js +426 -0
- package/dist/query-optimizers/explain-plans.js +415 -0
- package/dist/query-optimizers/index.js +51 -0
- package/dist/query-optimizers/prepared-statement-cache.js +423 -0
- package/dist/query-optimizers/query-hints.js +438 -0
- package/dist/query-optimizers/query-optimizer.js +278 -0
- package/dist/query-optimizers/slow-query-logger.js +271 -0
- package/dist/replica-manager.js +507 -0
- package/dist/schema/index.js +15 -0
- package/dist/schema/migration-generator.js +374 -0
- package/dist/schema/schema-differ.js +549 -0
- package/dist/schema/types.js +6 -0
- package/dist/sql-constants.js +300 -0
- package/dist/sqlite-advanced.js +1047 -0
- package/dist/streams/index.js +12 -0
- package/dist/streams/transforms.js +178 -0
- package/dist/transaction.js +456 -0
- package/dist/types/index.js +180 -0
- package/dist/user-management.js +127 -0
- package/dist/utils/date.js +300 -0
- package/dist/utils/index.js +1079 -0
- package/dist/utils/string.js +161 -0
- package/dist/validators/index.js +19 -0
- package/dist/validators/validator.js +911 -0
- package/package.json +190 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RowLevelSecurity
|
|
4
|
+
*
|
|
5
|
+
* Applies dynamic scoping to filter all queries by the current user's context
|
|
6
|
+
* (e.g. tenant_id, organization_id, user_id). Uses AsyncLocalStorage to
|
|
7
|
+
* store the request context so it's automatically available without passing
|
|
8
|
+
* it through every function call.
|
|
9
|
+
*
|
|
10
|
+
* Covers ~64 compliance frameworks including:
|
|
11
|
+
* GDPR, HIPAA, PCI DSS, SOX, NIST SP 800-53, NIS2, DORA, Zero Trust,
|
|
12
|
+
* FedRAMP, CJIS, APRA CPS 234, TISAX, and more.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* // At app startup, set up the context storage:
|
|
16
|
+
* RowLevelSecurity.init();
|
|
17
|
+
*
|
|
18
|
+
* // In your request middleware, set the current user context:
|
|
19
|
+
* RowLevelSecurity.setContext({ tenantId: 'acme-corp', userId: 'user-123', role: 'admin' });
|
|
20
|
+
*
|
|
21
|
+
* // Apply RLS to a model (all queries are automatically filtered):
|
|
22
|
+
* RowLevelSecurity.apply(Document, (ctx) => ({
|
|
23
|
+
* where: { tenantId: ctx.tenantId }
|
|
24
|
+
* }));
|
|
25
|
+
*
|
|
26
|
+
* // Express middleware example:
|
|
27
|
+
* app.use((req, res, next) => {
|
|
28
|
+
* RowLevelSecurity.setContext({
|
|
29
|
+
* tenantId: req.user.tenantId,
|
|
30
|
+
* userId: req.user.id,
|
|
31
|
+
* role: req.user.role,
|
|
32
|
+
* });
|
|
33
|
+
* next();
|
|
34
|
+
* });
|
|
35
|
+
*/
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.RowLevelSecurityAPI = exports.RLS = void 0;
|
|
38
|
+
exports.initRLS = initRLS;
|
|
39
|
+
exports.getContext = getContext;
|
|
40
|
+
exports.runInContext = runInContext;
|
|
41
|
+
exports.setContext = setContext;
|
|
42
|
+
exports.clearContext = clearContext;
|
|
43
|
+
exports.apply = apply;
|
|
44
|
+
exports.remove = remove;
|
|
45
|
+
exports.getFilteredQuery = getFilteredQuery;
|
|
46
|
+
exports.RowLevelSecurity = RowLevelSecurity;
|
|
47
|
+
exports.rlsMiddleware = rlsMiddleware;
|
|
48
|
+
exports.registerHooks = registerHooks;
|
|
49
|
+
const async_hooks_1 = require("async_hooks");
|
|
50
|
+
// ==================== AsyncLocalStorage ====================
|
|
51
|
+
const contextStore = new async_hooks_1.AsyncLocalStorage();
|
|
52
|
+
let globalScopeSelector = null;
|
|
53
|
+
const modelSelectors = new Map();
|
|
54
|
+
/**
|
|
55
|
+
* Initialize the RLS subsystem.
|
|
56
|
+
* Call once at application startup.
|
|
57
|
+
*/
|
|
58
|
+
function initRLS() {
|
|
59
|
+
// AsyncLocalStorage is already initialized
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get the current security context (or undefined if not set).
|
|
63
|
+
*/
|
|
64
|
+
function getContext() {
|
|
65
|
+
return contextStore.getStore();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Run a function within a specific security context.
|
|
69
|
+
* Use this to simulate a different user for testing.
|
|
70
|
+
*/
|
|
71
|
+
function runInContext(ctx, fn) {
|
|
72
|
+
return contextStore.run(ctx, fn);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Set the current security context for the request.
|
|
76
|
+
* Call this in your authentication middleware.
|
|
77
|
+
*
|
|
78
|
+
* @param ctx - The security context for the current request
|
|
79
|
+
*/
|
|
80
|
+
function setContext(ctx) {
|
|
81
|
+
// enterWith() mutates the store for the remainder of the current
|
|
82
|
+
// synchronous execution and any asynchronous operations chained from it,
|
|
83
|
+
// without requiring a wrapping callback (unlike run()).
|
|
84
|
+
contextStore.enterWith(ctx);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Clear the current security context.
|
|
88
|
+
*/
|
|
89
|
+
function clearContext() {
|
|
90
|
+
contextStore.enterWith(undefined);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Apply row-level security to a model.
|
|
94
|
+
* Registers a dynamic scope selector that is applied to ALL queries on that model.
|
|
95
|
+
*
|
|
96
|
+
* @param Model - The model to protect
|
|
97
|
+
* @param selector - A function that returns query modifiers based on the current context
|
|
98
|
+
*/
|
|
99
|
+
function apply(Model, selector) {
|
|
100
|
+
modelSelectors.set(Model, selector);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Remove RLS protection from a model.
|
|
104
|
+
*/
|
|
105
|
+
function remove(Model) {
|
|
106
|
+
modelSelectors.delete(Model);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the filtered query options for a model given the current context.
|
|
110
|
+
* Returns empty object if no RLS is configured or no context is set.
|
|
111
|
+
*/
|
|
112
|
+
function getFilteredQuery(Model) {
|
|
113
|
+
const selector = modelSelectors.get(Model);
|
|
114
|
+
const ctx = contextStore.getStore();
|
|
115
|
+
if (!selector || !ctx) {
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
118
|
+
return selector(ctx) ?? {};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Decorator to apply RLS to a model class.
|
|
122
|
+
*
|
|
123
|
+
* @RowLevelSecurity((ctx) => ({ where: { tenantId: ctx.tenantId } }))
|
|
124
|
+
* class Document extends Model { ... }
|
|
125
|
+
*/
|
|
126
|
+
function RowLevelSecurity(selector) {
|
|
127
|
+
return function (target) {
|
|
128
|
+
apply(target, selector);
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Middleware to integrate RLS with Express/Connect.
|
|
133
|
+
* Use after your authentication middleware.
|
|
134
|
+
*
|
|
135
|
+
* app.use(authMiddleware); // sets req.user
|
|
136
|
+
* app.use(rowLevelSecurityMiddleware);
|
|
137
|
+
*/
|
|
138
|
+
function rlsMiddleware(req, res, next) {
|
|
139
|
+
if (req.user) {
|
|
140
|
+
const ctx = {
|
|
141
|
+
tenantId: req.user.tenantId ?? req.user.organizationId,
|
|
142
|
+
userId: req.user.id,
|
|
143
|
+
role: req.user.role,
|
|
144
|
+
...req.user,
|
|
145
|
+
};
|
|
146
|
+
// Wrap the downstream middleware/handler chain in the ALS context so
|
|
147
|
+
// the context actually propagates to whatever `next()` triggers
|
|
148
|
+
// (including further async work), rather than being set-and-discarded
|
|
149
|
+
// before the real work runs.
|
|
150
|
+
contextStore.run(ctx, next);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
next();
|
|
154
|
+
}
|
|
155
|
+
// ==================== Hook Integration ====================
|
|
156
|
+
/**
|
|
157
|
+
* Register beforeFind hooks on all models that have RLS configured.
|
|
158
|
+
* Call this once after all models are defined.
|
|
159
|
+
*/
|
|
160
|
+
function registerHooks(prorm) {
|
|
161
|
+
const models = prorm.getModels?.() ?? [];
|
|
162
|
+
for (const [name, Model] of models) {
|
|
163
|
+
const selector = modelSelectors.get(Model);
|
|
164
|
+
if (!selector)
|
|
165
|
+
continue;
|
|
166
|
+
// Use a dynamic default scope that re-evaluates on every query
|
|
167
|
+
Model.addScope('__rls__', {
|
|
168
|
+
// This scope is applied manually in the hook below
|
|
169
|
+
});
|
|
170
|
+
Model.hook('beforeFind', 'orm:rlsFilter', (opts) => {
|
|
171
|
+
const ctx = contextStore.getStore();
|
|
172
|
+
if (!ctx)
|
|
173
|
+
return; // No context = no filtering (admin queries)
|
|
174
|
+
const filter = selector(ctx);
|
|
175
|
+
if (!filter)
|
|
176
|
+
return;
|
|
177
|
+
// Merge the RLS filter into the query options
|
|
178
|
+
if (filter.where) {
|
|
179
|
+
opts.where = opts.where ? { [Symbol.for('and')]: [opts.where, filter.where] } : filter.where;
|
|
180
|
+
}
|
|
181
|
+
if (filter.include) {
|
|
182
|
+
opts.include = [...(opts.include ?? []), ...filter.include];
|
|
183
|
+
}
|
|
184
|
+
if (filter.attributes) {
|
|
185
|
+
opts.attributes = filter.attributes;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// ==================== Class Export ====================
|
|
191
|
+
// Note: The decorator function RowLevelSecurity is exported separately
|
|
192
|
+
// This class groups all static methods for convenience
|
|
193
|
+
exports.RLS = {
|
|
194
|
+
init: initRLS,
|
|
195
|
+
apply,
|
|
196
|
+
remove,
|
|
197
|
+
setContext,
|
|
198
|
+
getContext,
|
|
199
|
+
clearContext,
|
|
200
|
+
runInContext,
|
|
201
|
+
getFilteredQuery,
|
|
202
|
+
registerHooks,
|
|
203
|
+
middleware: rlsMiddleware,
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Row-level security class with static methods.
|
|
207
|
+
* Provides the same functionality as the RLS object but as class methods.
|
|
208
|
+
*
|
|
209
|
+
* RowLevelSecurity.init();
|
|
210
|
+
* RowLevelSecurity.apply(Document, ctx => ({ where: { tenantId: ctx.tenantId } }));
|
|
211
|
+
* RowLevelSecurity.remove(Document);
|
|
212
|
+
* RowLevelSecurity.getFilteredQuery(Document);
|
|
213
|
+
*/
|
|
214
|
+
class RowLevelSecurityAPI {
|
|
215
|
+
static init() {
|
|
216
|
+
return initRLS();
|
|
217
|
+
}
|
|
218
|
+
static apply(Model, selector) {
|
|
219
|
+
return apply(Model, selector);
|
|
220
|
+
}
|
|
221
|
+
static remove(Model) {
|
|
222
|
+
return remove(Model);
|
|
223
|
+
}
|
|
224
|
+
static setContext(ctx) {
|
|
225
|
+
return setContext(ctx);
|
|
226
|
+
}
|
|
227
|
+
static getContext() {
|
|
228
|
+
return getContext();
|
|
229
|
+
}
|
|
230
|
+
static clearContext() {
|
|
231
|
+
return clearContext();
|
|
232
|
+
}
|
|
233
|
+
static runInContext(ctx, fn) {
|
|
234
|
+
return runInContext(ctx, fn);
|
|
235
|
+
}
|
|
236
|
+
static getFilteredQuery(Model) {
|
|
237
|
+
return getFilteredQuery(Model);
|
|
238
|
+
}
|
|
239
|
+
static registerHooks(prorm) {
|
|
240
|
+
return registerHooks(prorm);
|
|
241
|
+
}
|
|
242
|
+
static middleware(req, res, next) {
|
|
243
|
+
return rlsMiddleware(req, res, next);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
exports.RowLevelSecurityAPI = RowLevelSecurityAPI;
|