@blamejs/core 0.4.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 (160) hide show
  1. package/CHANGELOG.md +230 -0
  2. package/LICENSE +201 -0
  3. package/LTS-CALENDAR.md +29 -0
  4. package/MIGRATING.md +7 -0
  5. package/NOTICE +59 -0
  6. package/README.md +100 -0
  7. package/bin/blamejs.js +13 -0
  8. package/index.js +253 -0
  9. package/lib/api-key.js +705 -0
  10. package/lib/api-snapshot.js +335 -0
  11. package/lib/app-shutdown.js +381 -0
  12. package/lib/app.js +364 -0
  13. package/lib/atomic-file.js +525 -0
  14. package/lib/audit-chain.js +168 -0
  15. package/lib/audit-sign.js +319 -0
  16. package/lib/audit-tools.js +682 -0
  17. package/lib/audit.js +753 -0
  18. package/lib/auth/jwt.js +280 -0
  19. package/lib/auth/oauth.js +691 -0
  20. package/lib/auth/passkey.js +185 -0
  21. package/lib/auth/password.js +139 -0
  22. package/lib/auth/totp.js +17 -0
  23. package/lib/auth-header.js +81 -0
  24. package/lib/backup/bundle.js +219 -0
  25. package/lib/backup/crypto.js +174 -0
  26. package/lib/backup/index.js +490 -0
  27. package/lib/backup/manifest.js +275 -0
  28. package/lib/bundler.js +295 -0
  29. package/lib/cache.js +819 -0
  30. package/lib/chain-writer.js +234 -0
  31. package/lib/cli-helpers.js +201 -0
  32. package/lib/cli.js +1377 -0
  33. package/lib/cluster-provider-db.js +245 -0
  34. package/lib/cluster-storage.js +166 -0
  35. package/lib/cluster.js +691 -0
  36. package/lib/consent.js +222 -0
  37. package/lib/constants.js +186 -0
  38. package/lib/cookies.js +293 -0
  39. package/lib/credential-hash.js +303 -0
  40. package/lib/crypto-field.js +159 -0
  41. package/lib/crypto.js +250 -0
  42. package/lib/db-query.js +297 -0
  43. package/lib/db-schema.js +250 -0
  44. package/lib/db.js +1054 -0
  45. package/lib/deprecate.js +226 -0
  46. package/lib/dev.js +324 -0
  47. package/lib/error-page.js +424 -0
  48. package/lib/events.js +135 -0
  49. package/lib/external-db.js +422 -0
  50. package/lib/forms.js +378 -0
  51. package/lib/framework-error.js +189 -0
  52. package/lib/framework-schema.js +604 -0
  53. package/lib/handlers.js +350 -0
  54. package/lib/html-balance.js +227 -0
  55. package/lib/http-client.js +615 -0
  56. package/lib/i18n.js +780 -0
  57. package/lib/jobs.js +181 -0
  58. package/lib/lazy-require.js +48 -0
  59. package/lib/log-stream-local.js +137 -0
  60. package/lib/log-stream-webhook.js +170 -0
  61. package/lib/log-stream.js +211 -0
  62. package/lib/log.js +355 -0
  63. package/lib/mail-bounce.js +507 -0
  64. package/lib/mail.js +701 -0
  65. package/lib/metrics.js +647 -0
  66. package/lib/middleware/api-encrypt.js +553 -0
  67. package/lib/middleware/attach-user.js +156 -0
  68. package/lib/middleware/body-parser.js +883 -0
  69. package/lib/middleware/bot-guard.js +148 -0
  70. package/lib/middleware/compression.js +436 -0
  71. package/lib/middleware/cors.js +236 -0
  72. package/lib/middleware/csp-nonce.js +332 -0
  73. package/lib/middleware/csrf-protect.js +275 -0
  74. package/lib/middleware/error-handler.js +46 -0
  75. package/lib/middleware/health.js +358 -0
  76. package/lib/middleware/index.js +52 -0
  77. package/lib/middleware/rate-limit.js +319 -0
  78. package/lib/middleware/request-id.js +53 -0
  79. package/lib/middleware/require-auth.js +95 -0
  80. package/lib/middleware/security-headers.js +91 -0
  81. package/lib/migrations.js +353 -0
  82. package/lib/mtls-ca.js +333 -0
  83. package/lib/mtls-engine-default.js +285 -0
  84. package/lib/nonce-store.js +177 -0
  85. package/lib/notify.js +643 -0
  86. package/lib/ntp-check.js +178 -0
  87. package/lib/object-store/azure-blob.js +467 -0
  88. package/lib/object-store/gcs.js +469 -0
  89. package/lib/object-store/http-put.js +153 -0
  90. package/lib/object-store/index.js +140 -0
  91. package/lib/object-store/local.js +163 -0
  92. package/lib/object-store/retry.js +15 -0
  93. package/lib/object-store/sigv4.js +535 -0
  94. package/lib/observability.js +114 -0
  95. package/lib/pagination.js +371 -0
  96. package/lib/parsers/index.js +64 -0
  97. package/lib/parsers/safe-csv.js +224 -0
  98. package/lib/parsers/safe-env.js +614 -0
  99. package/lib/parsers/safe-toml.js +745 -0
  100. package/lib/parsers/safe-xml.js +379 -0
  101. package/lib/parsers/safe-yaml.js +977 -0
  102. package/lib/permissions.js +430 -0
  103. package/lib/pqc-agent.js +85 -0
  104. package/lib/pqc-gate.js +266 -0
  105. package/lib/protocol-dispatcher.js +144 -0
  106. package/lib/queue-local.js +327 -0
  107. package/lib/queue.js +430 -0
  108. package/lib/redact.js +192 -0
  109. package/lib/render.js +193 -0
  110. package/lib/request-helpers.js +178 -0
  111. package/lib/restore-bundle.js +239 -0
  112. package/lib/restore-rollback.js +254 -0
  113. package/lib/restore.js +301 -0
  114. package/lib/retry.js +329 -0
  115. package/lib/router.js +437 -0
  116. package/lib/safe-async.js +520 -0
  117. package/lib/safe-buffer.js +162 -0
  118. package/lib/safe-json.js +532 -0
  119. package/lib/safe-schema.js +1176 -0
  120. package/lib/safe-sql.js +157 -0
  121. package/lib/safe-url.js +109 -0
  122. package/lib/scheduler.js +680 -0
  123. package/lib/seeders.js +622 -0
  124. package/lib/session.js +304 -0
  125. package/lib/slug.js +243 -0
  126. package/lib/static.js +268 -0
  127. package/lib/storage.js +470 -0
  128. package/lib/subject.js +281 -0
  129. package/lib/template.js +781 -0
  130. package/lib/testing.js +621 -0
  131. package/lib/totp.js +285 -0
  132. package/lib/tracing.js +484 -0
  133. package/lib/validate-opts.js +56 -0
  134. package/lib/vault/index.js +299 -0
  135. package/lib/vault/passphrase-ops.js +311 -0
  136. package/lib/vault/passphrase-source.js +198 -0
  137. package/lib/vault/rotate.js +761 -0
  138. package/lib/vault/wrap.js +289 -0
  139. package/lib/vendor/MANIFEST.json +84 -0
  140. package/lib/vendor/argon2/argon2.cjs +466 -0
  141. package/lib/vendor/argon2/argon2.d.cts +62 -0
  142. package/lib/vendor/argon2/package.json +1 -0
  143. package/lib/vendor/argon2/prebuilds/darwin-arm64/argon2.armv8.glibc.node +0 -0
  144. package/lib/vendor/argon2/prebuilds/darwin-x64/argon2.glibc.node +0 -0
  145. package/lib/vendor/argon2/prebuilds/freebsd-arm64/argon2.armv8.glibc.node +0 -0
  146. package/lib/vendor/argon2/prebuilds/freebsd-x64/argon2.glibc.node +0 -0
  147. package/lib/vendor/argon2/prebuilds/linux-arm/argon2.armv7.glibc.node +0 -0
  148. package/lib/vendor/argon2/prebuilds/linux-arm/argon2.armv7.musl.node +0 -0
  149. package/lib/vendor/argon2/prebuilds/linux-arm64/argon2.armv8.glibc.node +0 -0
  150. package/lib/vendor/argon2/prebuilds/linux-arm64/argon2.armv8.musl.node +0 -0
  151. package/lib/vendor/argon2/prebuilds/linux-x64/argon2.glibc.node +0 -0
  152. package/lib/vendor/argon2/prebuilds/linux-x64/argon2.musl.node +0 -0
  153. package/lib/vendor/argon2/prebuilds/win32-x64/argon2.glibc.node +0 -0
  154. package/lib/vendor/noble-ciphers.cjs +9 -0
  155. package/lib/vendor/pki.cjs +181 -0
  156. package/lib/vendor/simplewebauthn-server.cjs +328 -0
  157. package/lib/webhook.js +632 -0
  158. package/lib/websocket-channels.js +413 -0
  159. package/lib/websocket.js +833 -0
  160. package/package.json +39 -0
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ /**
3
+ * Passphrase source drivers — env / file / stdin.
4
+ *
5
+ * Single interface: `getPassphrase(opts)` returns a Promise<Buffer>. Buffers
6
+ * (not strings) preserve byte-exactness for binary passphrases and avoid
7
+ * accidental intermediate string allocations that linger in the heap.
8
+ *
9
+ * Defaults select the *vault* passphrase env vars
10
+ * (BLAMEJS_VAULT_PASSPHRASE / _FILE / _SOURCE). Callers needing a different
11
+ * env namespace (e.g. audit-signing) pass overrides via opts.envVars:
12
+ *
13
+ * vaultPassphraseSource.getPassphrase({
14
+ * envVars: {
15
+ * value: "BLAMEJS_AUDIT_SIGNING_PASSPHRASE",
16
+ * file: "BLAMEJS_AUDIT_SIGNING_PASSPHRASE_FILE",
17
+ * source: "BLAMEJS_AUDIT_SIGNING_PASSPHRASE_SOURCE",
18
+ * },
19
+ * prompt: "Audit-signing passphrase: ",
20
+ * });
21
+ *
22
+ * After reading the env source, the matching env var is deleted to limit
23
+ * exposure to later env-dump surfaces. This doesn't zero the memory
24
+ * (JavaScript can't) but does remove the env-object reference.
25
+ */
26
+ var fs = require("fs");
27
+ var readline = require("readline");
28
+ var safeEnv = require("../parsers/safe-env");
29
+ var safeBuffer = require("../safe-buffer");
30
+
31
+ var MAX_PASSPHRASE_BYTES = 4096;
32
+
33
+ var DEFAULT_ENV_VARS = {
34
+ value: "BLAMEJS_VAULT_PASSPHRASE",
35
+ file: "BLAMEJS_VAULT_PASSPHRASE_FILE",
36
+ source: "BLAMEJS_VAULT_PASSPHRASE_SOURCE",
37
+ };
38
+
39
+ function resolveEnvVars(opts) {
40
+ var override = (opts && opts.envVars) || {};
41
+ return {
42
+ value: override.value || DEFAULT_ENV_VARS.value,
43
+ file: override.file || DEFAULT_ENV_VARS.file,
44
+ source: override.source || DEFAULT_ENV_VARS.source,
45
+ };
46
+ }
47
+
48
+ function trimTrailingNewlines(buf) {
49
+ var end = buf.length;
50
+ while (end > 0) {
51
+ var b = buf[end - 1];
52
+ if (b === 0x0A || b === 0x0D) end--;
53
+ else break;
54
+ }
55
+ return end === buf.length ? buf : buf.subarray(0, end);
56
+ }
57
+
58
+ function validatePassphraseBuffer(buf, contextLabel) {
59
+ if (!buf || buf.length === 0) {
60
+ throw new Error(contextLabel + ": passphrase is empty");
61
+ }
62
+ if (buf.length > MAX_PASSPHRASE_BYTES) {
63
+ throw new Error(contextLabel + ": passphrase exceeds " + MAX_PASSPHRASE_BYTES + " byte sanity limit");
64
+ }
65
+ }
66
+
67
+ async function fromEnv(opts) {
68
+ var envVars = resolveEnvVars(opts);
69
+ // safeEnv.readVar handles: missing/empty (required), size cap, utf8→Buffer
70
+ // coercion, and process.env strip-after-read in one call.
71
+ return safeEnv.readVar(envVars.value, {
72
+ type: "buffer",
73
+ required: true,
74
+ maxBytes: MAX_PASSPHRASE_BYTES,
75
+ strip: true,
76
+ });
77
+ }
78
+
79
+ async function fromFile(filePath, opts) {
80
+ var envVars = resolveEnvVars(opts);
81
+ if (!filePath) {
82
+ throw new Error(envVars.file + " is not set");
83
+ }
84
+ var raw;
85
+ try {
86
+ raw = fs.readFileSync(filePath);
87
+ } catch (e) {
88
+ throw new Error("failed to read " + envVars.file + " (" + filePath + "): " + e.code);
89
+ }
90
+ var buf = trimTrailingNewlines(raw);
91
+ validatePassphraseBuffer(buf, "file source (" + filePath + ")");
92
+ return buf;
93
+ }
94
+
95
+ async function fromStdin(promptText) {
96
+ if (!process.stdin.isTTY) {
97
+ throw new Error("stdin passphrase source requires a TTY (use `docker run -it` or similar)");
98
+ }
99
+ promptText = promptText || "Vault passphrase: ";
100
+
101
+ return new Promise(function (resolve, reject) {
102
+ var rl = readline.createInterface({
103
+ input: process.stdin,
104
+ output: process.stdout,
105
+ terminal: true,
106
+ });
107
+ process.stdout.write(promptText);
108
+
109
+ var chunks = [];
110
+
111
+ var onData = function (chunk) {
112
+ for (var i = 0; i < chunk.length; i++) {
113
+ var b = chunk[i];
114
+ if (b === 0x03) { // ctrl-C
115
+ cleanup();
116
+ process.stdout.write("\n");
117
+ reject(new Error("passphrase input cancelled"));
118
+ return;
119
+ }
120
+ if (b === 0x0A || b === 0x0D) { // enter
121
+ cleanup();
122
+ process.stdout.write("\n");
123
+ var buf = Buffer.concat(chunks);
124
+ // Zero each per-byte chunk now that the bytes are copied into
125
+ // `buf`. Each chunk held a single passphrase character; keeping
126
+ // them around extends the secret's heap footprint.
127
+ for (var ci = 0; ci < chunks.length; ci++) safeBuffer.secureZero(chunks[ci]);
128
+ try {
129
+ validatePassphraseBuffer(buf, "stdin source");
130
+ resolve(buf);
131
+ } catch (e) {
132
+ safeBuffer.secureZero(buf);
133
+ reject(e);
134
+ }
135
+ return;
136
+ }
137
+ if (b === 0x7F || b === 0x08) { // backspace / DEL
138
+ if (chunks.length > 0) safeBuffer.secureZero(chunks.pop());
139
+ continue;
140
+ }
141
+ chunks.push(Buffer.from([b]));
142
+ }
143
+ };
144
+
145
+ var cleanup = function () {
146
+ try { process.stdin.setRawMode(false); } catch (_e) { /* best effort */ }
147
+ process.stdin.removeListener("data", onData);
148
+ rl.close();
149
+ };
150
+
151
+ process.stdin.setRawMode(true);
152
+ process.stdin.resume();
153
+ process.stdin.on("data", onData);
154
+ });
155
+ }
156
+
157
+ function sourceKind(opts) {
158
+ var envVars = resolveEnvVars(opts);
159
+ var mode = (process.env[envVars.source] || "auto").toLowerCase();
160
+ if (mode === "auto") {
161
+ if (process.env[envVars.file]) return "file";
162
+ if (process.env[envVars.value]) return "env";
163
+ if (process.stdin.isTTY) return "stdin";
164
+ return null;
165
+ }
166
+ if (mode === "env" || mode === "file" || mode === "stdin") return mode;
167
+ throw new Error("Unknown " + envVars.source + ": " + mode + " (expected auto, env, file, or stdin)");
168
+ }
169
+
170
+ async function getPassphrase(opts) {
171
+ opts = opts || {};
172
+ var envVars = resolveEnvVars(opts);
173
+ var kind = sourceKind(opts);
174
+ if (!kind) {
175
+ throw new Error(
176
+ "No passphrase source available. Set one of: " +
177
+ envVars.value + ", " + envVars.file + ", " +
178
+ "or run with a TTY on stdin."
179
+ );
180
+ }
181
+ if (kind === "env") return fromEnv(opts);
182
+ if (kind === "file") return fromFile(process.env[envVars.file], opts);
183
+ if (kind === "stdin") return fromStdin(opts.prompt);
184
+ throw new Error("Unreachable: unknown passphrase source kind " + kind);
185
+ }
186
+
187
+ module.exports = {
188
+ getPassphrase: getPassphrase,
189
+ sourceKind: sourceKind,
190
+ fromEnv: fromEnv,
191
+ fromFile: fromFile,
192
+ fromStdin: fromStdin,
193
+ MAX_PASSPHRASE_BYTES: MAX_PASSPHRASE_BYTES,
194
+ // Default vault env var names exposed for documentation/testing
195
+ ENV_PASSPHRASE: DEFAULT_ENV_VARS.value,
196
+ ENV_PASSPHRASE_FILE: DEFAULT_ENV_VARS.file,
197
+ ENV_PASSPHRASE_SRC: DEFAULT_ENV_VARS.source,
198
+ };