@blamejs/core 0.14.27 → 0.15.1

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 (134) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -2
  3. package/index.js +4 -0
  4. package/lib/ai-content-detect.js +9 -10
  5. package/lib/api-key.js +158 -77
  6. package/lib/atomic-file.js +29 -1
  7. package/lib/audit-chain.js +47 -11
  8. package/lib/audit-sign.js +77 -2
  9. package/lib/audit-tools.js +79 -51
  10. package/lib/audit.js +228 -100
  11. package/lib/backup/index.js +13 -10
  12. package/lib/break-glass.js +202 -144
  13. package/lib/cache.js +174 -105
  14. package/lib/chain-writer.js +38 -16
  15. package/lib/cli.js +19 -14
  16. package/lib/cluster-provider-db.js +130 -104
  17. package/lib/cluster-storage.js +119 -22
  18. package/lib/cluster.js +119 -71
  19. package/lib/compliance.js +22 -0
  20. package/lib/consent.js +82 -29
  21. package/lib/constants.js +16 -11
  22. package/lib/crypto-field.js +387 -91
  23. package/lib/db-declare-row-policy.js +35 -22
  24. package/lib/db-file-lifecycle.js +3 -2
  25. package/lib/db-query.js +517 -256
  26. package/lib/db-schema.js +209 -44
  27. package/lib/db.js +202 -95
  28. package/lib/external-db-migrate.js +229 -139
  29. package/lib/external-db.js +25 -15
  30. package/lib/framework-error.js +11 -0
  31. package/lib/framework-files.js +73 -0
  32. package/lib/framework-schema.js +695 -394
  33. package/lib/gate-contract.js +596 -1
  34. package/lib/guard-agent-registry.js +26 -44
  35. package/lib/guard-all.js +1 -0
  36. package/lib/guard-auth.js +42 -112
  37. package/lib/guard-cidr.js +33 -154
  38. package/lib/guard-csv.js +46 -113
  39. package/lib/guard-domain.js +34 -157
  40. package/lib/guard-dsn.js +27 -43
  41. package/lib/guard-email.js +47 -69
  42. package/lib/guard-envelope.js +19 -32
  43. package/lib/guard-event-bus-payload.js +24 -42
  44. package/lib/guard-event-bus-topic.js +25 -43
  45. package/lib/guard-filename.js +42 -106
  46. package/lib/guard-graphql.js +42 -123
  47. package/lib/guard-html.js +53 -108
  48. package/lib/guard-idempotency-key.js +24 -42
  49. package/lib/guard-image.js +46 -103
  50. package/lib/guard-imap-command.js +18 -32
  51. package/lib/guard-jmap.js +16 -30
  52. package/lib/guard-json.js +38 -108
  53. package/lib/guard-jsonpath.js +38 -171
  54. package/lib/guard-jwt.js +49 -179
  55. package/lib/guard-list-id.js +25 -41
  56. package/lib/guard-list-unsubscribe.js +27 -43
  57. package/lib/guard-mail-compose.js +24 -42
  58. package/lib/guard-mail-move.js +26 -44
  59. package/lib/guard-mail-query.js +28 -46
  60. package/lib/guard-mail-reply.js +24 -42
  61. package/lib/guard-mail-sieve.js +24 -42
  62. package/lib/guard-managesieve-command.js +17 -31
  63. package/lib/guard-markdown.js +37 -104
  64. package/lib/guard-message-id.js +26 -45
  65. package/lib/guard-mime.js +39 -151
  66. package/lib/guard-oauth.js +54 -135
  67. package/lib/guard-pdf.js +45 -101
  68. package/lib/guard-pop3-command.js +21 -31
  69. package/lib/guard-posture-chain.js +24 -42
  70. package/lib/guard-regex.js +33 -107
  71. package/lib/guard-saga-config.js +24 -42
  72. package/lib/guard-shell.js +42 -172
  73. package/lib/guard-smtp-command.js +48 -54
  74. package/lib/guard-snapshot-envelope.js +24 -42
  75. package/lib/guard-sql.js +1491 -0
  76. package/lib/guard-stream-args.js +24 -43
  77. package/lib/guard-svg.js +47 -65
  78. package/lib/guard-template.js +35 -172
  79. package/lib/guard-tenant-id.js +26 -45
  80. package/lib/guard-time.js +32 -154
  81. package/lib/guard-trace-context.js +25 -44
  82. package/lib/guard-uuid.js +32 -153
  83. package/lib/guard-xml.js +38 -113
  84. package/lib/guard-yaml.js +51 -163
  85. package/lib/http-client.js +14 -0
  86. package/lib/inbox.js +120 -107
  87. package/lib/legal-hold.js +107 -50
  88. package/lib/log-stream-cloudwatch.js +47 -31
  89. package/lib/log-stream-otlp.js +32 -18
  90. package/lib/mail-crypto-smime.js +2 -6
  91. package/lib/mail-greylist.js +2 -6
  92. package/lib/mail-helo.js +2 -6
  93. package/lib/mail-journal.js +85 -64
  94. package/lib/mail-rbl.js +2 -6
  95. package/lib/mail-scan.js +2 -6
  96. package/lib/mail-spam-score.js +2 -6
  97. package/lib/mail-store.js +293 -154
  98. package/lib/middleware/fetch-metadata.js +17 -7
  99. package/lib/middleware/idempotency-key.js +54 -38
  100. package/lib/middleware/rate-limit.js +102 -32
  101. package/lib/middleware/security-headers.js +21 -5
  102. package/lib/migrations.js +108 -66
  103. package/lib/network-heartbeat.js +7 -0
  104. package/lib/nonce-store.js +31 -9
  105. package/lib/object-store/azure-blob-bucket-ops.js +9 -4
  106. package/lib/object-store/azure-blob.js +31 -3
  107. package/lib/object-store/sigv4.js +10 -0
  108. package/lib/outbox.js +136 -82
  109. package/lib/pqc-agent.js +44 -0
  110. package/lib/pubsub-cluster.js +42 -20
  111. package/lib/queue-local.js +202 -139
  112. package/lib/queue-redis.js +9 -1
  113. package/lib/queue-sqs.js +6 -0
  114. package/lib/retention.js +82 -39
  115. package/lib/safe-dns.js +29 -45
  116. package/lib/safe-ical.js +18 -33
  117. package/lib/safe-icap.js +27 -43
  118. package/lib/safe-sieve.js +21 -40
  119. package/lib/safe-sql.js +124 -3
  120. package/lib/safe-vcard.js +18 -33
  121. package/lib/scheduler.js +35 -12
  122. package/lib/seeders.js +122 -74
  123. package/lib/session-stores.js +42 -14
  124. package/lib/session.js +116 -72
  125. package/lib/sql.js +3885 -0
  126. package/lib/static.js +45 -7
  127. package/lib/subject.js +89 -49
  128. package/lib/vault/index.js +3 -2
  129. package/lib/vault/passphrase-ops.js +3 -2
  130. package/lib/vault/rotate.js +104 -64
  131. package/lib/vendor-data.js +2 -0
  132. package/lib/websocket.js +16 -0
  133. package/package.json +1 -1
  134. 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 });