@blamejs/core 0.14.26 → 0.15.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 (150) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -2
  3. package/index.js +4 -0
  4. package/lib/agent-envelope-mac.js +104 -0
  5. package/lib/agent-event-bus.js +105 -4
  6. package/lib/agent-posture-chain.js +8 -42
  7. package/lib/ai-content-detect.js +9 -10
  8. package/lib/api-key.js +107 -74
  9. package/lib/atomic-file.js +62 -4
  10. package/lib/audit-chain.js +47 -11
  11. package/lib/audit-sign.js +77 -2
  12. package/lib/audit-tools.js +79 -51
  13. package/lib/audit.js +249 -123
  14. package/lib/auth/openid-federation.js +108 -47
  15. package/lib/backup/index.js +13 -10
  16. package/lib/break-glass.js +202 -144
  17. package/lib/cache.js +174 -105
  18. package/lib/chain-writer.js +38 -16
  19. package/lib/cli.js +19 -14
  20. package/lib/cluster-provider-db.js +130 -104
  21. package/lib/cluster-storage.js +119 -22
  22. package/lib/cluster.js +119 -71
  23. package/lib/compliance.js +169 -4
  24. package/lib/consent.js +73 -24
  25. package/lib/constants.js +16 -11
  26. package/lib/crypto-field.js +474 -92
  27. package/lib/db-declare-row-policy.js +35 -22
  28. package/lib/db-file-lifecycle.js +3 -2
  29. package/lib/db-query.js +497 -255
  30. package/lib/db-schema.js +209 -44
  31. package/lib/db.js +176 -95
  32. package/lib/error-page.js +14 -1
  33. package/lib/external-db-migrate.js +229 -139
  34. package/lib/external-db.js +25 -15
  35. package/lib/file-upload.js +52 -7
  36. package/lib/framework-error.js +14 -1
  37. package/lib/framework-files.js +73 -0
  38. package/lib/framework-schema.js +695 -394
  39. package/lib/gate-contract.js +649 -1
  40. package/lib/guard-agent-registry.js +26 -44
  41. package/lib/guard-all.js +1 -0
  42. package/lib/guard-auth.js +42 -112
  43. package/lib/guard-cidr.js +33 -154
  44. package/lib/guard-csv.js +46 -113
  45. package/lib/guard-domain.js +34 -157
  46. package/lib/guard-dsn.js +27 -43
  47. package/lib/guard-email.js +47 -69
  48. package/lib/guard-envelope.js +19 -32
  49. package/lib/guard-event-bus-payload.js +24 -42
  50. package/lib/guard-event-bus-topic.js +25 -43
  51. package/lib/guard-filename.js +42 -106
  52. package/lib/guard-graphql.js +42 -123
  53. package/lib/guard-html.js +53 -108
  54. package/lib/guard-idempotency-key.js +24 -42
  55. package/lib/guard-image.js +46 -103
  56. package/lib/guard-imap-command.js +18 -32
  57. package/lib/guard-jmap.js +16 -30
  58. package/lib/guard-json.js +38 -108
  59. package/lib/guard-jsonpath.js +38 -171
  60. package/lib/guard-jwt.js +49 -179
  61. package/lib/guard-list-id.js +25 -41
  62. package/lib/guard-list-unsubscribe.js +27 -43
  63. package/lib/guard-mail-compose.js +24 -42
  64. package/lib/guard-mail-move.js +26 -44
  65. package/lib/guard-mail-query.js +28 -46
  66. package/lib/guard-mail-reply.js +24 -42
  67. package/lib/guard-mail-sieve.js +24 -42
  68. package/lib/guard-managesieve-command.js +17 -31
  69. package/lib/guard-markdown.js +37 -104
  70. package/lib/guard-message-id.js +26 -45
  71. package/lib/guard-mime.js +39 -151
  72. package/lib/guard-oauth.js +54 -135
  73. package/lib/guard-pdf.js +45 -101
  74. package/lib/guard-pop3-command.js +21 -31
  75. package/lib/guard-posture-chain.js +24 -42
  76. package/lib/guard-regex.js +33 -107
  77. package/lib/guard-saga-config.js +24 -42
  78. package/lib/guard-shell.js +42 -172
  79. package/lib/guard-smtp-command.js +48 -54
  80. package/lib/guard-snapshot-envelope.js +24 -42
  81. package/lib/guard-sql.js +1491 -0
  82. package/lib/guard-stream-args.js +24 -43
  83. package/lib/guard-svg.js +47 -65
  84. package/lib/guard-template.js +35 -172
  85. package/lib/guard-tenant-id.js +26 -45
  86. package/lib/guard-time.js +32 -154
  87. package/lib/guard-trace-context.js +25 -44
  88. package/lib/guard-uuid.js +32 -153
  89. package/lib/guard-xml.js +38 -113
  90. package/lib/guard-yaml.js +51 -163
  91. package/lib/http-client.js +37 -9
  92. package/lib/inbox.js +120 -107
  93. package/lib/legal-hold.js +107 -50
  94. package/lib/log-stream-cloudwatch.js +47 -31
  95. package/lib/log-stream-otlp.js +32 -18
  96. package/lib/mail-crypto-smime.js +2 -6
  97. package/lib/mail-greylist.js +2 -6
  98. package/lib/mail-helo.js +2 -6
  99. package/lib/mail-journal.js +85 -64
  100. package/lib/mail-rbl.js +2 -6
  101. package/lib/mail-scan.js +2 -6
  102. package/lib/mail-server-jmap.js +117 -12
  103. package/lib/mail-spam-score.js +2 -6
  104. package/lib/mail-store.js +287 -154
  105. package/lib/middleware/body-parser.js +71 -25
  106. package/lib/middleware/csrf-protect.js +19 -8
  107. package/lib/middleware/fetch-metadata.js +17 -7
  108. package/lib/middleware/idempotency-key.js +54 -38
  109. package/lib/middleware/rate-limit.js +102 -32
  110. package/lib/middleware/security-headers.js +21 -5
  111. package/lib/migrations.js +108 -66
  112. package/lib/network-heartbeat.js +7 -0
  113. package/lib/nonce-store.js +31 -9
  114. package/lib/object-store/azure-blob-bucket-ops.js +9 -4
  115. package/lib/object-store/azure-blob.js +57 -3
  116. package/lib/object-store/sigv4.js +10 -0
  117. package/lib/observability.js +87 -0
  118. package/lib/otel-export.js +25 -1
  119. package/lib/outbox.js +136 -82
  120. package/lib/parsers/safe-xml.js +47 -7
  121. package/lib/pqc-agent.js +44 -0
  122. package/lib/pubsub-cluster.js +42 -20
  123. package/lib/queue-local.js +202 -139
  124. package/lib/queue-redis.js +9 -1
  125. package/lib/queue-sqs.js +6 -0
  126. package/lib/redact.js +68 -11
  127. package/lib/redis-client.js +160 -31
  128. package/lib/retention.js +82 -39
  129. package/lib/router.js +212 -5
  130. package/lib/safe-dns.js +29 -45
  131. package/lib/safe-ical.js +18 -33
  132. package/lib/safe-icap.js +27 -43
  133. package/lib/safe-sieve.js +21 -40
  134. package/lib/safe-sql.js +124 -3
  135. package/lib/safe-vcard.js +18 -33
  136. package/lib/scheduler.js +35 -12
  137. package/lib/seeders.js +122 -74
  138. package/lib/session-stores.js +42 -14
  139. package/lib/session.js +109 -72
  140. package/lib/sql.js +3885 -0
  141. package/lib/ssrf-guard.js +51 -4
  142. package/lib/static.js +177 -34
  143. package/lib/subject.js +55 -17
  144. package/lib/vault/index.js +3 -2
  145. package/lib/vault/passphrase-ops.js +3 -2
  146. package/lib/vault/rotate.js +104 -64
  147. package/lib/vendor-data.js +2 -0
  148. package/lib/websocket.js +35 -5
  149. package/package.json +1 -1
  150. package/sbom.cdx.json +6 -6
@@ -54,6 +54,7 @@
54
54
  * }
55
55
  */
56
56
  var safeSql = require("./safe-sql");
57
+ var sql = require("./sql");
57
58
  var validateOpts = require("./validate-opts");
58
59
  var { defineClass } = require("./framework-error");
59
60
 
@@ -64,6 +65,8 @@ var ALLOWED_OPTS = [
64
65
  "using", "withCheck", "command", "permissive", "backend",
65
66
  ];
66
67
 
68
+ // allow:hand-rolled-sql — RLS FOR-<command> keyword allowlist, not SQL text;
69
+ // the policy itself is composed through b.sql.createPolicy.
67
70
  var ALLOWED_COMMANDS = ["ALL", "SELECT", "INSERT", "UPDATE", "DELETE"];
68
71
 
69
72
  function _err(code, message) {
@@ -192,9 +195,9 @@ function _ensureBackendIsPostgres(externalDb, backendName) {
192
195
 
193
196
  function declareRowPolicy(opts) {
194
197
  var spec = _validateOpts(opts);
195
- var qTable = safeSql.quoteQualified([spec.schema, spec.table], "postgres");
196
- var qPolicy = safeSql.quoteIdentifier(spec.name, "postgres");
197
- var qRole = spec.role ? safeSql.quoteIdentifier(spec.role, "postgres") : null;
198
+ // The dotted "schema.table" form b.sql's RLS builders accept (each
199
+ // segment validated + quoted by construction inside b.sql).
200
+ var tableRef = spec.schema + "." + spec.table;
198
201
 
199
202
  var description = "declareRowPolicy " + spec.schema + "." + spec.table + "." + spec.name;
200
203
 
@@ -206,13 +209,18 @@ function declareRowPolicy(opts) {
206
209
  // Idempotent ENABLE — Postgres has no IF NOT EXISTS for this. Read
207
210
  // the current setting from pg_class and skip the ALTER when already
208
211
  // on, so re-running a migration set in a partially-applied state
209
- // doesn't fail with a no-op error from the lock acquisition.
210
- var rlsCheck = await xdb.query(
211
- "SELECT relrowsecurity FROM pg_class c " +
212
- "JOIN pg_namespace n ON n.oid = c.relnamespace " +
213
- "WHERE n.nspname = $1 AND c.relname = $2",
214
- [spec.schema, spec.table]
215
- );
212
+ // doesn't fail with a no-op error from the lock acquisition. The
213
+ // pg_class / pg_namespace catalog join is composed through b.sql with
214
+ // a guarded raw join (system-catalog columns are outside any operator
215
+ // schema, so a column gate has no set to check); the schema + table
216
+ // names bind as parameters, never interpolate.
217
+ var rlsQuery = sql.select("pg_class", { dialect: "postgres", alias: "c" })
218
+ .columns(["c.relrowsecurity"])
219
+ .joinRaw("JOIN pg_namespace n ON n.oid = c.relnamespace")
220
+ .whereRaw("n.nspname = ?", [spec.schema])
221
+ .whereRaw("c.relname = ?", [spec.table])
222
+ .toExternalSql("postgres");
223
+ var rlsCheck = await xdb.query(rlsQuery.sql, rlsQuery.params);
216
224
  var rows = (rlsCheck && rlsCheck.rows) || [];
217
225
  if (rows.length === 0) {
218
226
  throw _err("declare-row-policy/table-not-found",
@@ -220,19 +228,23 @@ function declareRowPolicy(opts) {
220
228
  "' not found (does it exist? does the migration role have visibility?)");
221
229
  }
222
230
  if (!rows[0].relrowsecurity) {
223
- await xdb.query("ALTER TABLE " + qTable + " ENABLE ROW LEVEL SECURITY", []);
231
+ var enableStmt = sql.enableRowLevelSecurity(tableRef, { dialect: "postgres" });
232
+ await xdb.query(enableStmt.sql, enableStmt.params);
224
233
  }
225
234
 
226
- // CREATE POLICY assembled in canonical order: name → table → AS
227
- // PERMISSIVE/RESTRICTIVE → FOR command → TO role → USING → WITH CHECK.
228
- var sql = "CREATE POLICY " + qPolicy + " ON " + qTable;
229
- sql += " AS " + (spec.permissive ? "PERMISSIVE" : "RESTRICTIVE");
230
- sql += " FOR " + spec.command;
231
- if (qRole) sql += " TO " + qRole;
232
- sql += " USING (" + spec.using + ")";
233
- if (spec.withCheck) sql += " WITH CHECK (" + spec.withCheck + ")";
234
-
235
- await xdb.query(sql, []);
235
+ // CREATE POLICY assembled in canonical order by b.sql.createPolicy:
236
+ // name → table → AS PERMISSIVE/RESTRICTIVE → FOR command → TO role →
237
+ // USING WITH CHECK. The using / withCheck boolean predicates ride
238
+ // b.sql's guarded raw-fragment path (the same b.guardSql gate the
239
+ // operator-facing whereRaw uses).
240
+ var policyStmt = sql.createPolicy(spec.name, tableRef, {
241
+ command: spec.command,
242
+ permissive: spec.permissive,
243
+ role: spec.role || undefined,
244
+ using: spec.using,
245
+ withCheck: spec.withCheck || undefined,
246
+ }, { dialect: "postgres" });
247
+ await xdb.query(policyStmt.sql, policyStmt.params);
236
248
 
237
249
  return {
238
250
  policy: spec.schema + "." + spec.table + "." + spec.name,
@@ -248,7 +260,8 @@ function declareRowPolicy(opts) {
248
260
  if (ctx && ctx.externalDb && ctx.backendName) {
249
261
  _ensureBackendIsPostgres(ctx.externalDb, ctx.backendName);
250
262
  }
251
- await xdb.query("DROP POLICY IF EXISTS " + qPolicy + " ON " + qTable, []);
263
+ var dropStmt = sql.dropPolicy(spec.name, tableRef, { dialect: "postgres", ifExists: true });
264
+ await xdb.query(dropStmt.sql, dropStmt.params);
252
265
  }
253
266
 
254
267
  return {
@@ -63,6 +63,7 @@ var nodePath = require("node:path");
63
63
  var atomicFile = require("./atomic-file");
64
64
  var C = require("./constants");
65
65
  var { generateBytes, generateToken, encryptPacked, decryptPacked } = require("./crypto");
66
+ var frameworkFiles = require("./framework-files");
66
67
  var lazyRequire = require("./lazy-require");
67
68
  var validateOpts = require("./validate-opts");
68
69
  var { defineClass } = require("./framework-error");
@@ -162,13 +163,13 @@ function fileLifecycle(opts) {
162
163
  DbFileLifecycleError, "db-file-lifecycle/bad-flush-interval");
163
164
 
164
165
  var label = opts.label || "default";
165
- var encName = opts.encryptedDbName || "db.enc";
166
+ var encName = opts.encryptedDbName || frameworkFiles.fileName("dbEnc");
166
167
  var encPath = opts.encryptedDbPath
167
168
  ? nodePath.resolve(opts.encryptedDbPath)
168
169
  : nodePath.join(opts.dataDir, encName);
169
170
  var keyPath = opts.dbKeyPath
170
171
  ? nodePath.resolve(opts.dbKeyPath)
171
- : nodePath.join(opts.dataDir, "db.key.enc");
172
+ : nodePath.join(opts.dataDir, frameworkFiles.fileName("dbKeyEnc"));
172
173
  var flushIntervalMs = opts.flushIntervalMs || DEFAULT_FLUSH_INTERVAL_MS;
173
174
  var tmpDir = _resolveTmpDir(opts.tmpDir, opts.allowDiskFallback === true);
174
175
  if (!nodeFs.existsSync(tmpDir)) nodeFs.mkdirSync(tmpDir, { recursive: true });