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.
Files changed (310) hide show
  1. package/CHANGELOG.md +1111 -0
  2. package/LICENSE +21 -0
  3. package/README.md +573 -0
  4. package/dist/audit/history-query.js +180 -0
  5. package/dist/audit/index.js +23 -0
  6. package/dist/audit/logger.js +236 -0
  7. package/dist/cache/cache-manager.js +84 -0
  8. package/dist/cache/index.js +16 -0
  9. package/dist/cache/redis-cluster-cache.js +557 -0
  10. package/dist/cli.js +2200 -0
  11. package/dist/compliance/audit-trail.js +68 -0
  12. package/dist/compliance/backup-verification.js +685 -0
  13. package/dist/compliance/breach-detector.js +505 -0
  14. package/dist/compliance/consent-record.js +227 -0
  15. package/dist/compliance/consent-versioning.js +331 -0
  16. package/dist/compliance/cross-border-log.js +530 -0
  17. package/dist/compliance/data-classifier.js +258 -0
  18. package/dist/compliance/data-lineage.js +565 -0
  19. package/dist/compliance/data-masker.js +303 -0
  20. package/dist/compliance/data-portability.js +265 -0
  21. package/dist/compliance/data-retention.js +195 -0
  22. package/dist/compliance/dsar-workflow.js +342 -0
  23. package/dist/compliance/field-encryption.js +223 -0
  24. package/dist/compliance/immutable-record.js +148 -0
  25. package/dist/compliance/index.js +260 -0
  26. package/dist/compliance/privacy-impact-assessment.js +364 -0
  27. package/dist/compliance/pseudonymization.js +269 -0
  28. package/dist/compliance/query-firewall.js +1182 -0
  29. package/dist/compliance/rate-limiter.js +580 -0
  30. package/dist/compliance/right-to-erasure.js +117 -0
  31. package/dist/compliance/row-level-security.js +246 -0
  32. package/dist/compliance/security-decorator.js +574 -0
  33. package/dist/compliance/security-monitor.js +525 -0
  34. package/dist/compliance/sensitive-data-discovery.js +476 -0
  35. package/dist/compliance/session-isolation.js +472 -0
  36. package/dist/compliance/tls-enforcer.js +108 -0
  37. package/dist/compliance/worm-storage.js +712 -0
  38. package/dist/connection-manager.js +198 -0
  39. package/dist/connection-pool.js +519 -0
  40. package/dist/decorators/audit.js +136 -0
  41. package/dist/decorators/belongs-to-many.js +115 -0
  42. package/dist/decorators/belongs-to.js +115 -0
  43. package/dist/decorators/check.js +435 -0
  44. package/dist/decorators/collate.js +329 -0
  45. package/dist/decorators/comment.js +205 -0
  46. package/dist/decorators/database-settings.js +236 -0
  47. package/dist/decorators/default.js +244 -0
  48. package/dist/decorators/encryption.js +235 -0
  49. package/dist/decorators/engine.js +97 -0
  50. package/dist/decorators/fk-constraints.js +594 -0
  51. package/dist/decorators/foreign-table.js +136 -0
  52. package/dist/decorators/generated.js +274 -0
  53. package/dist/decorators/has-many.js +127 -0
  54. package/dist/decorators/has-one.js +116 -0
  55. package/dist/decorators/hstore.js +129 -0
  56. package/dist/decorators/index.js +355 -0
  57. package/dist/decorators/json-column.js +83 -0
  58. package/dist/decorators/jsonb.js +101 -0
  59. package/dist/decorators/orm-decorators.js +425 -0
  60. package/dist/decorators/permissions.js +294 -0
  61. package/dist/decorators/procedure.js +210 -0
  62. package/dist/decorators/query-options.js +556 -0
  63. package/dist/decorators/range.js +167 -0
  64. package/dist/decorators/set-column.js +83 -0
  65. package/dist/decorators/spatial.js +114 -0
  66. package/dist/decorators/storage.js +580 -0
  67. package/dist/decorators/timezone.js +512 -0
  68. package/dist/decorators/trigger.js +90 -0
  69. package/dist/decorators/uuid.js +135 -0
  70. package/dist/decorators/view.js +258 -0
  71. package/dist/diagrams/chen-diagram.js +354 -0
  72. package/dist/diagrams/class-diagram.js +384 -0
  73. package/dist/diagrams/dependency-diagram.js +432 -0
  74. package/dist/diagrams/er-diagram.js +605 -0
  75. package/dist/diagrams/flow-diagram.js +394 -0
  76. package/dist/diagrams/gantt-diagram.js +411 -0
  77. package/dist/diagrams/index-diagram.js +353 -0
  78. package/dist/diagrams/index.js +184 -0
  79. package/dist/diagrams/migration-diagram.js +316 -0
  80. package/dist/diagrams/model-diagram.js +616 -0
  81. package/dist/diagrams/package-diagram.js +376 -0
  82. package/dist/diagrams/palette.js +85 -0
  83. package/dist/diagrams/relational-diagram.js +455 -0
  84. package/dist/diagrams/schemadoc-diagram.js +309 -0
  85. package/dist/diagrams/sequence-diagram.js +307 -0
  86. package/dist/diagrams/state-diagram.js +344 -0
  87. package/dist/diagrams/svg-dom.js +111 -0
  88. package/dist/diagrams/tree-diagram.js +250 -0
  89. package/dist/dialects/clickhouse/index.js +1742 -0
  90. package/dist/dialects/cockroachdb/index.js +4677 -0
  91. package/dist/dialects/cratedb/index.js +441 -0
  92. package/dist/dialects/databricks/index.js +517 -0
  93. package/dist/dialects/db2/index.js +2225 -0
  94. package/dist/dialects/dialect.js +720 -0
  95. package/dist/dialects/duckdb/index.js +2014 -0
  96. package/dist/dialects/exasol/index.js +357 -0
  97. package/dist/dialects/firebird/index.js +495 -0
  98. package/dist/dialects/greenplum/index.js +457 -0
  99. package/dist/dialects/hana/index.js +1741 -0
  100. package/dist/dialects/mariadb/index.js +3590 -0
  101. package/dist/dialects/mssql/index.js +2296 -0
  102. package/dist/dialects/mysql/index.js +4058 -0
  103. package/dist/dialects/oracle/index.js +2999 -0
  104. package/dist/dialects/postgres/index.js +5319 -0
  105. package/dist/dialects/query-stream-helper.js +152 -0
  106. package/dist/dialects/questdb/index.js +433 -0
  107. package/dist/dialects/redshift/index.js +2277 -0
  108. package/dist/dialects/singlestore/index.js +354 -0
  109. package/dist/dialects/snowflake/index.js +2082 -0
  110. package/dist/dialects/spanner/index.js +1768 -0
  111. package/dist/dialects/sqlite/index.js +3382 -0
  112. package/dist/dialects/tidb/index.js +377 -0
  113. package/dist/dialects/timescaledb/index.js +164 -0
  114. package/dist/dialects/trino/index.js +420 -0
  115. package/dist/dialects/turso/index.js +227 -0
  116. package/dist/dialects/vertica/index.js +317 -0
  117. package/dist/dialects/yugabytedb/index.js +424 -0
  118. package/dist/errors/index.js +472 -0
  119. package/dist/errors/utils.js +340 -0
  120. package/dist/errors.js +21 -0
  121. package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
  122. package/dist/extensions/catalog/mssql-features.js +147 -0
  123. package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
  124. package/dist/extensions/catalog/oracle-db2-features.js +196 -0
  125. package/dist/extensions/catalog/postgres-extensions.js +516 -0
  126. package/dist/extensions/index.js +71 -0
  127. package/dist/extensions/types.js +13 -0
  128. package/dist/foreign-data.js +173 -0
  129. package/dist/hooks/hooks-manager.js +350 -0
  130. package/dist/hooks/index.js +37 -0
  131. package/dist/index.js +463 -0
  132. package/dist/logging.js +335 -0
  133. package/dist/migrations/index.js +40 -0
  134. package/dist/migrations/migration.js +196 -0
  135. package/dist/migrations/migrator.js +411 -0
  136. package/dist/migrations/prormmigration.js +275 -0
  137. package/dist/migrations/query-interface.js +435 -0
  138. package/dist/migrations/seeder.js +353 -0
  139. package/dist/models/associations.js +852 -0
  140. package/dist/models/constraints.js +288 -0
  141. package/dist/models/data-types.js +2518 -0
  142. package/dist/models/decorators.js +445 -0
  143. package/dist/models/index.js +33 -0
  144. package/dist/models/indexes.js +531 -0
  145. package/dist/models/methods.js +382 -0
  146. package/dist/models/model-manager.js +103 -0
  147. package/dist/models/model.js +5349 -0
  148. package/dist/models/operators.js +67 -0
  149. package/dist/models/scopes.js +189 -0
  150. package/dist/models/typescript-types.js +26 -0
  151. package/dist/nosql/aerospike/index.js +205 -0
  152. package/dist/nosql/allegrograph/index.js +169 -0
  153. package/dist/nosql/arangodb/index.js +364 -0
  154. package/dist/nosql/azure-blob/index.js +206 -0
  155. package/dist/nosql/beanstalkd/index.js +231 -0
  156. package/dist/nosql/beequeue/index.js +210 -0
  157. package/dist/nosql/bigchaindb/index.js +195 -0
  158. package/dist/nosql/bigtable/index.js +224 -0
  159. package/dist/nosql/blazegraph/index.js +173 -0
  160. package/dist/nosql/bullmq/index.js +191 -0
  161. package/dist/nosql/cassandra/index.js +174 -0
  162. package/dist/nosql/chroma/index.js +190 -0
  163. package/dist/nosql/cloudflare-kv/index.js +220 -0
  164. package/dist/nosql/coherence/index.js +200 -0
  165. package/dist/nosql/cosmosdb/index.js +157 -0
  166. package/dist/nosql/couchbase/index.js +213 -0
  167. package/dist/nosql/dax/index.js +212 -0
  168. package/dist/nosql/deno-kv/index.js +206 -0
  169. package/dist/nosql/dgraph/index.js +171 -0
  170. package/dist/nosql/doris/index.js +169 -0
  171. package/dist/nosql/druid/index.js +162 -0
  172. package/dist/nosql/dynamodb/index.js +937 -0
  173. package/dist/nosql/elasticsearch/index.js +377 -0
  174. package/dist/nosql/etcd/index.js +502 -0
  175. package/dist/nosql/eventhubs/index.js +213 -0
  176. package/dist/nosql/eventstore/index.js +254 -0
  177. package/dist/nosql/faunadb/index.js +188 -0
  178. package/dist/nosql/firestore/index.js +177 -0
  179. package/dist/nosql/fluree/index.js +148 -0
  180. package/dist/nosql/fuseki/index.js +170 -0
  181. package/dist/nosql/gcs/index.js +172 -0
  182. package/dist/nosql/gearman/index.js +160 -0
  183. package/dist/nosql/geode/index.js +196 -0
  184. package/dist/nosql/graphdb/index.js +169 -0
  185. package/dist/nosql/graylog/index.js +188 -0
  186. package/dist/nosql/gridgain/index.js +171 -0
  187. package/dist/nosql/hazelcast/index.js +162 -0
  188. package/dist/nosql/hbase/index.js +230 -0
  189. package/dist/nosql/ignite/index.js +173 -0
  190. package/dist/nosql/immudb/index.js +184 -0
  191. package/dist/nosql/index.js +232 -0
  192. package/dist/nosql/infinispan/index.js +200 -0
  193. package/dist/nosql/influxdb/index.js +0 -0
  194. package/dist/nosql/kafka/index.js +234 -0
  195. package/dist/nosql/keyspaces/index.js +189 -0
  196. package/dist/nosql/kinesis/index.js +253 -0
  197. package/dist/nosql/leveldb/index.js +153 -0
  198. package/dist/nosql/lmdb/index.js +160 -0
  199. package/dist/nosql/loki/index.js +201 -0
  200. package/dist/nosql/marklogic/index.js +204 -0
  201. package/dist/nosql/materialize/index.js +145 -0
  202. package/dist/nosql/meilisearch/index.js +154 -0
  203. package/dist/nosql/memcached/index.js +223 -0
  204. package/dist/nosql/milvus/index.js +410 -0
  205. package/dist/nosql/minio/index.js +265 -0
  206. package/dist/nosql/momento/index.js +179 -0
  207. package/dist/nosql/mongodb/index.js +461 -0
  208. package/dist/nosql/nats/index.js +247 -0
  209. package/dist/nosql/nedb/index.js +164 -0
  210. package/dist/nosql/neo4j/index.js +450 -0
  211. package/dist/nosql/neptune/index.js +470 -0
  212. package/dist/nosql/nsq/index.js +200 -0
  213. package/dist/nosql/opensearch/index.js +186 -0
  214. package/dist/nosql/orientdb/index.js +175 -0
  215. package/dist/nosql/papertrail/index.js +200 -0
  216. package/dist/nosql/pinecone/index.js +0 -0
  217. package/dist/nosql/pinot/index.js +133 -0
  218. package/dist/nosql/pouchdb/index.js +172 -0
  219. package/dist/nosql/prometheus/index.js +174 -0
  220. package/dist/nosql/provendb/index.js +147 -0
  221. package/dist/nosql/pubsub/index.js +187 -0
  222. package/dist/nosql/pulsar/index.js +232 -0
  223. package/dist/nosql/qdrant/index.js +295 -0
  224. package/dist/nosql/qldb/index.js +192 -0
  225. package/dist/nosql/r2/index.js +281 -0
  226. package/dist/nosql/rabbitmq/index.js +237 -0
  227. package/dist/nosql/ravendb/index.js +175 -0
  228. package/dist/nosql/redis/index.js +607 -0
  229. package/dist/nosql/redpanda/index.js +237 -0
  230. package/dist/nosql/resque/index.js +203 -0
  231. package/dist/nosql/rethinkdb/index.js +232 -0
  232. package/dist/nosql/rocksdb/index.js +152 -0
  233. package/dist/nosql/rockset/index.js +126 -0
  234. package/dist/nosql/s3/index.js +298 -0
  235. package/dist/nosql/scylladb/index.js +178 -0
  236. package/dist/nosql/signoz/index.js +227 -0
  237. package/dist/nosql/sns/index.js +201 -0
  238. package/dist/nosql/solr/index.js +231 -0
  239. package/dist/nosql/splunk/index.js +227 -0
  240. package/dist/nosql/sqs/index.js +246 -0
  241. package/dist/nosql/stardog/index.js +169 -0
  242. package/dist/nosql/starrocks/index.js +170 -0
  243. package/dist/nosql/store.js +2 -0
  244. package/dist/nosql/sumologic/index.js +213 -0
  245. package/dist/nosql/surrealdb/index.js +179 -0
  246. package/dist/nosql/terminusdb/index.js +151 -0
  247. package/dist/nosql/tigergraph/index.js +469 -0
  248. package/dist/nosql/typesense/index.js +148 -0
  249. package/dist/nosql/unqlite/index.js +157 -0
  250. package/dist/nosql/upstash/index.js +167 -0
  251. package/dist/nosql/vercel-kv/index.js +166 -0
  252. package/dist/nosql/victoriametrics/index.js +213 -0
  253. package/dist/nosql/virtuoso/index.js +169 -0
  254. package/dist/nosql/weaviate/index.js +276 -0
  255. package/dist/operators/index.js +108 -0
  256. package/dist/operators.js +2690 -0
  257. package/dist/prisma-migrate/index.js +38 -0
  258. package/dist/prisma-migrate/migration-generator.js +125 -0
  259. package/dist/prisma-migrate/model-generator.js +172 -0
  260. package/dist/prisma-migrate/relations.js +100 -0
  261. package/dist/prisma-migrate/schema-parser.js +167 -0
  262. package/dist/prisma-migrate/type-mapper.js +40 -0
  263. package/dist/prorm.js +6832 -0
  264. package/dist/query-builders/cte-builder.js +80 -0
  265. package/dist/query-builders/functions/aggregate.js +390 -0
  266. package/dist/query-builders/functions/conditional.js +503 -0
  267. package/dist/query-builders/functions/datetime.js +695 -0
  268. package/dist/query-builders/functions/fulltext.js +439 -0
  269. package/dist/query-builders/functions/index.js +93 -0
  270. package/dist/query-builders/functions/json.js +427 -0
  271. package/dist/query-builders/functions/math.js +399 -0
  272. package/dist/query-builders/functions/string.js +518 -0
  273. package/dist/query-builders/functions/window.js +328 -0
  274. package/dist/query-builders/include-builder.js +323 -0
  275. package/dist/query-builders/index-expression-builder.js +242 -0
  276. package/dist/query-builders/index.js +161 -0
  277. package/dist/query-builders/insert-builder.js +164 -0
  278. package/dist/query-builders/model-helpers.js +38 -0
  279. package/dist/query-builders/order-limit-builder.js +239 -0
  280. package/dist/query-builders/sql-compiler.js +2040 -0
  281. package/dist/query-builders/subquery-builder.js +152 -0
  282. package/dist/query-builders/update-builder.js +182 -0
  283. package/dist/query-builders/view-builder.js +218 -0
  284. package/dist/query-builders/where-builder.js +1532 -0
  285. package/dist/query-interface.js +622 -0
  286. package/dist/query-optimizers/batch-optimizer.js +426 -0
  287. package/dist/query-optimizers/explain-plans.js +415 -0
  288. package/dist/query-optimizers/index.js +51 -0
  289. package/dist/query-optimizers/prepared-statement-cache.js +423 -0
  290. package/dist/query-optimizers/query-hints.js +438 -0
  291. package/dist/query-optimizers/query-optimizer.js +278 -0
  292. package/dist/query-optimizers/slow-query-logger.js +271 -0
  293. package/dist/replica-manager.js +507 -0
  294. package/dist/schema/index.js +15 -0
  295. package/dist/schema/migration-generator.js +374 -0
  296. package/dist/schema/schema-differ.js +549 -0
  297. package/dist/schema/types.js +6 -0
  298. package/dist/sql-constants.js +300 -0
  299. package/dist/sqlite-advanced.js +1047 -0
  300. package/dist/streams/index.js +12 -0
  301. package/dist/streams/transforms.js +178 -0
  302. package/dist/transaction.js +456 -0
  303. package/dist/types/index.js +180 -0
  304. package/dist/user-management.js +127 -0
  305. package/dist/utils/date.js +300 -0
  306. package/dist/utils/index.js +1079 -0
  307. package/dist/utils/string.js +161 -0
  308. package/dist/validators/index.js +19 -0
  309. package/dist/validators/validator.js +911 -0
  310. package/package.json +190 -0
@@ -0,0 +1,525 @@
1
+ "use strict";
2
+ /**
3
+ * MTAT - Monitoring and Threat Assessment Tool
4
+ *
5
+ * A comprehensive security monitoring system that:
6
+ * - Screens SQL logs for suspicious patterns
7
+ * - Flags security-relevant events
8
+ * - Monitors compliance violations (invalid data movement)
9
+ * - Tracks slow/invalid queries
10
+ * - Provides real-time alerts
11
+ *
12
+ * Usage:
13
+ * // Initialize with the MTAT monitor
14
+ * const monitor = new SecurityMonitor(prorm, {
15
+ * frameworks: ['GDPR', 'HIPAA'],
16
+ * alertLevel: 'high',
17
+ * onAlert: (alert) => console.log('Security Alert:', alert),
18
+ * });
19
+ *
20
+ * // Start monitoring
21
+ * await monitor.start();
22
+ *
23
+ * // Query the dashboard
24
+ * const stats = monitor.getStats();
25
+ * const alerts = monitor.getAlerts();
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.ComplianceSecurityMonitor = exports.SecurityMonitor = void 0;
29
+ exports.getGlobalMonitor = getGlobalMonitor;
30
+ exports.initSecurityMonitor = initSecurityMonitor;
31
+ exports.analyzeQuerySecurity = analyzeQuerySecurity;
32
+ // SQL Injection patterns
33
+ const SQL_INJECTION_PATTERNS = [
34
+ /('\s*or\s*'1'\s*=\s*'1)/i,
35
+ /('\s*or\s*1\s*=\s*1)/i,
36
+ /(union\s+select)/i,
37
+ /(union\s+all\s+select)/i,
38
+ /(\bor\b.*\b=\b)/,
39
+ /(exec\s*\()/i,
40
+ /(execute\s*\()/i,
41
+ /(xp_cmdshell)/i,
42
+ /(load_file\s*\()/i,
43
+ /(into\s+outfile)/i,
44
+ /(sleep\s*\()/i,
45
+ /(waitfor\s+delay)/i,
46
+ /('\s*;\s*drop\s+table)/i,
47
+ /(;\s*drop\s+table)/i,
48
+ /(\/\*.*\*\/)/,
49
+ /(--\s*)/,
50
+ /(char\s*\(\s*\d+)/,
51
+ /(0x[0-9a-f]+)/i,
52
+ /(\bunion\b.*\bselect\b)/i,
53
+ /(\bselect\b.*\bfrom\b)/i,
54
+ /(having\s+.*\b=\b)/i,
55
+ /(\border\s+by\s+\d+)/i,
56
+ ];
57
+ // Sensitive data patterns
58
+ const PII_PATTERNS = {
59
+ email: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,
60
+ ssn: /\b\d{3}-\d{2}-\d{4}\b/g,
61
+ phone: /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g,
62
+ creditCard: /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g,
63
+ ipAddress: /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g,
64
+ };
65
+ // High-risk operations
66
+ const RISKY_OPERATIONS = [
67
+ 'DROP TABLE',
68
+ 'DROP DATABASE',
69
+ 'TRUNCATE',
70
+ 'DELETE FROM',
71
+ 'ALTER TABLE',
72
+ 'DROP COLUMN',
73
+ 'DROP INDEX',
74
+ ];
75
+ // ==================== Security Monitor Class ====================
76
+ class SecurityMonitor {
77
+ constructor(prorm, options = {}) {
78
+ this.alerts = [];
79
+ this.queryCount = 0;
80
+ this.slowQueryCount = 0;
81
+ this.blockedCount = 0;
82
+ this.isRunning = false;
83
+ this.prorm = prorm;
84
+ this.options = {
85
+ frameworks: options.frameworks ?? [],
86
+ alertLevel: options.alertLevel ?? 'medium',
87
+ onAlert: options.onAlert ?? (() => { }),
88
+ detectSQLInjection: options.detectSQLInjection ?? true,
89
+ monitorSlowQueries: options.monitorSlowQueries ?? true,
90
+ slowQueryThreshold: options.slowQueryThreshold ?? 1000,
91
+ detectExfiltration: options.detectExfiltration ?? true,
92
+ detectComplianceViolations: options.detectComplianceViolations ?? true,
93
+ maxAlerts: options.maxAlerts ?? 1000,
94
+ rateLimitThreshold: options.rateLimitThreshold ?? 100,
95
+ detectAnomalies: options.detectAnomalies ?? true,
96
+ bulkOperationThreshold: options.bulkOperationThreshold ?? 100,
97
+ };
98
+ this.startTime = new Date();
99
+ }
100
+ /**
101
+ * Start monitoring queries
102
+ */
103
+ async start() {
104
+ if (this.isRunning)
105
+ return;
106
+ this.isRunning = true;
107
+ // Hook into Prorm query events
108
+ this.originalQuery = this.prorm.query;
109
+ this.prorm.query = async (...args) => {
110
+ const startTime = Date.now();
111
+ const query = typeof args[0] === 'string' ? args[0] : args[0]?.sql ?? '';
112
+ try {
113
+ const result = await this.originalQuery.apply(this.prorm, args);
114
+ const duration = Date.now() - startTime;
115
+ this.queryCount++;
116
+ this.analyzeQuery(query, duration);
117
+ return result;
118
+ }
119
+ catch (error) {
120
+ this.analyzeError(query, error);
121
+ throw error;
122
+ }
123
+ };
124
+ // Also hook into model operations via hooks
125
+ this.setupHooks();
126
+ }
127
+ /**
128
+ * Stop monitoring
129
+ */
130
+ stop() {
131
+ if (!this.isRunning)
132
+ return;
133
+ this.isRunning = false;
134
+ if (this.originalQuery) {
135
+ this.prorm.query = this.originalQuery;
136
+ }
137
+ }
138
+ /**
139
+ * Setup hooks for model-level monitoring
140
+ */
141
+ setupHooks() {
142
+ const models = this.prorm.getModels?.() ?? [];
143
+ for (const [, Model] of models) {
144
+ // Monitor bulk operations
145
+ Model.hook('beforeBulkCreate', 'mtat:bulkCreate', (instances) => {
146
+ if (instances.length > this.options.bulkOperationThreshold) {
147
+ this.addAlert({
148
+ severity: 'medium',
149
+ category: 'bulk_operation',
150
+ message: `Bulk create operation detected: ${instances.length} records`,
151
+ details: { count: instances.length, model: Model.name },
152
+ });
153
+ }
154
+ });
155
+ Model.hook('beforeBulkUpdate', 'mtat:bulkUpdate', (opts) => {
156
+ // Check if this looks like a dangerous bulk update
157
+ if (!opts.where || Object.keys(opts.where).length === 0) {
158
+ this.addAlert({
159
+ severity: 'critical',
160
+ category: 'bulk_operation',
161
+ message: 'Dangerous bulk update without where clause',
162
+ details: { model: Model.name, attributes: opts.attributes },
163
+ query: JSON.stringify(opts),
164
+ });
165
+ }
166
+ });
167
+ Model.hook('beforeBulkDestroy', 'mtat:bulkDestroy', (opts) => {
168
+ if (!opts.where || Object.keys(opts.where).length === 0) {
169
+ this.addAlert({
170
+ severity: 'critical',
171
+ category: 'data_exfiltration',
172
+ message: 'Dangerous bulk delete without where clause',
173
+ details: { model: Model.name },
174
+ query: JSON.stringify(opts),
175
+ });
176
+ }
177
+ });
178
+ }
179
+ }
180
+ /**
181
+ * Analyze a query for security issues
182
+ */
183
+ analyzeQuery(query, duration) {
184
+ const analysis = this.analyzeQueryInternal(query);
185
+ // SQL Injection detection
186
+ if (this.options.detectSQLInjection) {
187
+ for (const pattern of SQL_INJECTION_PATTERNS) {
188
+ if (pattern.test(query)) {
189
+ this.addAlert({
190
+ severity: 'critical',
191
+ category: 'sql_injection',
192
+ message: 'Potential SQL injection detected',
193
+ details: { pattern: pattern.source, riskScore: analysis.riskScore },
194
+ query,
195
+ });
196
+ this.blockedCount++;
197
+ return;
198
+ }
199
+ }
200
+ }
201
+ // Slow query monitoring
202
+ if (this.options.monitorSlowQueries && duration > this.options.slowQueryThreshold) {
203
+ this.slowQueryCount++;
204
+ this.addAlert({
205
+ severity: 'medium',
206
+ category: 'slow_query',
207
+ message: `Slow query detected: ${duration}ms`,
208
+ details: { duration, threshold: this.options.slowQueryThreshold },
209
+ query,
210
+ });
211
+ }
212
+ // High-risk operations
213
+ for (const op of RISKY_OPERATIONS) {
214
+ if (query.toUpperCase().includes(op)) {
215
+ this.addAlert({
216
+ severity: 'high',
217
+ category: 'unauthorized_access',
218
+ message: `High-risk operation: ${op}`,
219
+ details: { operation: op },
220
+ query,
221
+ });
222
+ }
223
+ }
224
+ // Data exfiltration detection
225
+ if (this.options.detectExfiltration && analysis.isBulkOperation) {
226
+ this.addAlert({
227
+ severity: 'medium',
228
+ category: 'data_exfiltration',
229
+ message: 'Potential data exfiltration: bulk SELECT operation',
230
+ details: { tables: analysis.tables },
231
+ query,
232
+ });
233
+ }
234
+ // Compliance violation detection
235
+ if (this.options.detectComplianceViolations && this.options.frameworks.length > 0) {
236
+ this.checkComplianceViolationDetection(query, analysis);
237
+ }
238
+ }
239
+ /**
240
+ * Analyze errors for security issues
241
+ */
242
+ analyzeError(query, error) {
243
+ const message = error?.message ?? '';
244
+ // Detect injection errors
245
+ if (message.includes('syntax error') || message.includes('SQL syntax')) {
246
+ this.addAlert({
247
+ severity: 'low',
248
+ category: 'invalid_query',
249
+ message: 'Invalid SQL query detected',
250
+ details: { error: message.substring(0, 100) },
251
+ query,
252
+ });
253
+ }
254
+ // Access denied patterns
255
+ if (message.includes('permission denied') || message.includes('access denied')) {
256
+ this.addAlert({
257
+ severity: 'high',
258
+ category: 'unauthorized_access',
259
+ message: 'Unauthorized access attempt',
260
+ details: { error: message.substring(0, 100) },
261
+ query,
262
+ });
263
+ }
264
+ }
265
+ /**
266
+ * Internal query analysis
267
+ */
268
+ analyzeQueryInternal(query) {
269
+ const upperQuery = query.toUpperCase();
270
+ let operation = 'UNKNOWN';
271
+ if (upperQuery.includes('SELECT'))
272
+ operation = 'SELECT';
273
+ else if (upperQuery.includes('INSERT'))
274
+ operation = 'INSERT';
275
+ else if (upperQuery.includes('UPDATE'))
276
+ operation = 'UPDATE';
277
+ else if (upperQuery.includes('DELETE'))
278
+ operation = 'DELETE';
279
+ else if (upperQuery.includes('DROP'))
280
+ operation = 'DROP';
281
+ else if (upperQuery.includes('TRUNCATE'))
282
+ operation = 'TRUNCATE';
283
+ else if (upperQuery.includes('ALTER'))
284
+ operation = 'ALTER';
285
+ // Extract table names (simple regex)
286
+ const tableMatches = query.match(/(?:from|into|update|table)\s+`?(\w+)`?/gi) || [];
287
+ const tables = tableMatches.map(m => m.replace(/`/g, '').split(' ').pop() || '');
288
+ // Check for PII in query
289
+ let involvesPII = false;
290
+ for (const pattern of Object.values(PII_PATTERNS)) {
291
+ if (pattern.test(query)) {
292
+ involvesPII = true;
293
+ break;
294
+ }
295
+ }
296
+ // Calculate risk score
297
+ let riskScore = 0;
298
+ if (operation === 'SELECT' && involvesPII)
299
+ riskScore += 30;
300
+ if (RISKY_OPERATIONS.some(op => upperQuery.includes(op)))
301
+ riskScore += 50;
302
+ if (query.length > 1000)
303
+ riskScore += 10;
304
+ return {
305
+ query,
306
+ tables,
307
+ operation,
308
+ isSensitive: involvesPII,
309
+ involvesPII,
310
+ isBulkOperation: false, // Determined by hook
311
+ riskScore,
312
+ };
313
+ }
314
+ /**
315
+ * Check for compliance violations
316
+ */
317
+ checkComplianceViolationDetection(query, analysis) {
318
+ const frameworks = this.options.frameworks;
319
+ // GDPR-specific checks
320
+ if (frameworks.includes('GDPR') || frameworks.includes('UK_GDPR')) {
321
+ // Check for unauthorized personal data access
322
+ if (analysis.involvesPII && analysis.operation === 'SELECT') {
323
+ this.addAlert({
324
+ severity: 'medium',
325
+ category: 'compliance_violation',
326
+ message: 'GDPR: Personal data access detected',
327
+ details: { framework: 'GDPR', dataType: 'PII' },
328
+ query,
329
+ });
330
+ }
331
+ }
332
+ // HIPAA-specific checks
333
+ if (frameworks.includes('HIPAA')) {
334
+ // Check for PHI access
335
+ if (query.toLowerCase().includes('medical') ||
336
+ query.toLowerCase().includes('diagnosis') ||
337
+ query.toLowerCase().includes('prescription')) {
338
+ this.addAlert({
339
+ severity: 'high',
340
+ category: 'compliance_violation',
341
+ message: 'HIPAA: Protected Health Information access',
342
+ details: { framework: 'HIPAA', dataType: 'PHI' },
343
+ query,
344
+ });
345
+ }
346
+ }
347
+ // PCI DSS checks
348
+ if (frameworks.includes('PCI_DSS')) {
349
+ if (query.toLowerCase().includes('credit') ||
350
+ query.toLowerCase().includes('card') ||
351
+ query.toLowerCase().includes('payment')) {
352
+ this.addAlert({
353
+ severity: 'critical',
354
+ category: 'compliance_violation',
355
+ message: 'PCI DSS: Cardholder data access',
356
+ details: { framework: 'PCI_DSS', dataType: 'PCI' },
357
+ query,
358
+ });
359
+ }
360
+ }
361
+ }
362
+ /**
363
+ * Add an alert
364
+ */
365
+ addAlert(alert) {
366
+ const fullAlert = {
367
+ ...alert,
368
+ id: `alert-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
369
+ timestamp: new Date(),
370
+ };
371
+ // Check severity threshold
372
+ const severityOrder = ['low', 'medium', 'high', 'critical'];
373
+ if (severityOrder.indexOf(fullAlert.severity) < severityOrder.indexOf(this.options.alertLevel)) {
374
+ return;
375
+ }
376
+ this.alerts.push(fullAlert);
377
+ // Trim old alerts
378
+ if (this.alerts.length > this.options.maxAlerts) {
379
+ this.alerts = this.alerts.slice(-this.options.maxAlerts);
380
+ }
381
+ // Callback
382
+ if (this.options.onAlert) {
383
+ this.options.onAlert(fullAlert);
384
+ }
385
+ }
386
+ // ==================== Public API ====================
387
+ /**
388
+ * Get current statistics
389
+ */
390
+ getStats() {
391
+ const alertsBySeverity = {
392
+ low: 0, medium: 0, high: 0, critical: 0,
393
+ };
394
+ const alertsByCategory = {
395
+ sql_injection: 0,
396
+ data_exfiltration: 0,
397
+ unauthorized_access: 0,
398
+ compliance_violation: 0,
399
+ slow_query: 0,
400
+ invalid_query: 0,
401
+ anomaly: 0,
402
+ rate_limit: 0,
403
+ bulk_operation: 0,
404
+ sensitive_access: 0,
405
+ };
406
+ for (const alert of this.alerts) {
407
+ alertsBySeverity[alert.severity]++;
408
+ alertsByCategory[alert.category]++;
409
+ }
410
+ return {
411
+ uptime: Date.now() - this.startTime.getTime(),
412
+ totalQueries: this.queryCount,
413
+ slowQueries: this.slowQueryCount,
414
+ blockedQueries: this.blockedCount,
415
+ totalAlerts: this.alerts.length,
416
+ alertsBySeverity,
417
+ alertsByCategory,
418
+ };
419
+ }
420
+ /**
421
+ * Get all alerts
422
+ */
423
+ getAlerts(options) {
424
+ let filtered = [...this.alerts];
425
+ if (options?.severity) {
426
+ filtered = filtered.filter(a => a.severity === options.severity);
427
+ }
428
+ if (options?.category) {
429
+ filtered = filtered.filter(a => a.category === options.category);
430
+ }
431
+ if (options?.limit) {
432
+ filtered = filtered.slice(-options.limit);
433
+ }
434
+ return filtered;
435
+ }
436
+ /**
437
+ * Get critical alerts
438
+ */
439
+ getCriticalAlerts() {
440
+ return this.getAlerts({ severity: 'critical' });
441
+ }
442
+ /**
443
+ * Clear all alerts
444
+ */
445
+ clearAlerts() {
446
+ this.alerts = [];
447
+ }
448
+ /**
449
+ * Check if running
450
+ */
451
+ isActive() {
452
+ return this.isRunning;
453
+ }
454
+ /**
455
+ * Manual alert trigger (for custom security checks)
456
+ */
457
+ alert(options) {
458
+ this.addAlert(options);
459
+ }
460
+ }
461
+ exports.SecurityMonitor = SecurityMonitor;
462
+ // ==================== Static Factory ====================
463
+ let globalMonitor = null;
464
+ /**
465
+ * Create or get the global security monitor singleton
466
+ */
467
+ function getGlobalMonitor() {
468
+ return globalMonitor;
469
+ }
470
+ /**
471
+ * Initialize the global security monitor
472
+ */
473
+ function initSecurityMonitor(prorm, options) {
474
+ globalMonitor = new SecurityMonitor(prorm, options);
475
+ return globalMonitor;
476
+ }
477
+ /**
478
+ * Quick security check for a query (static method)
479
+ */
480
+ function analyzeQuerySecurity(query) {
481
+ const detectedPatterns = [];
482
+ // Check SQL injection patterns
483
+ for (const pattern of SQL_INJECTION_PATTERNS) {
484
+ if (pattern.test(query)) {
485
+ detectedPatterns.push(`SQL_INJECTION:${pattern.source}`);
486
+ }
487
+ }
488
+ // Check for sensitive data
489
+ let isSensitive = false;
490
+ for (const [name, pattern] of Object.entries(PII_PATTERNS)) {
491
+ if (pattern.test(query)) {
492
+ detectedPatterns.push(`SENSITIVE:${name}`);
493
+ isSensitive = true;
494
+ }
495
+ }
496
+ // Determine risk level
497
+ let riskLevel = 'low';
498
+ if (detectedPatterns.some(p => p.startsWith('SQL_INJECTION'))) {
499
+ riskLevel = 'critical';
500
+ }
501
+ else if (detectedPatterns.length > 0) {
502
+ riskLevel = 'high';
503
+ }
504
+ else if (isSensitive) {
505
+ riskLevel = 'medium';
506
+ }
507
+ return {
508
+ isSQLInjection: detectedPatterns.some(p => p.startsWith('SQL_INJECTION')),
509
+ isSensitive,
510
+ riskLevel,
511
+ detectedPatterns,
512
+ };
513
+ }
514
+ // ==================== Compliance Integration ====================
515
+ /**
516
+ * MTAT with Compliance Integration
517
+ * Extends the basic monitor with framework-specific rules
518
+ */
519
+ class ComplianceSecurityMonitor extends SecurityMonitor {
520
+ constructor(prorm, options = {}) {
521
+ super(prorm, options);
522
+ // Additional setup for compliance-specific monitoring
523
+ }
524
+ }
525
+ exports.ComplianceSecurityMonitor = ComplianceSecurityMonitor;