@blamejs/core 0.8.43 → 0.8.50

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 (222) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +10 -10
  3. package/index.js +52 -0
  4. package/lib/a2a.js +159 -34
  5. package/lib/acme.js +762 -0
  6. package/lib/ai-pref.js +166 -43
  7. package/lib/api-key.js +108 -47
  8. package/lib/api-snapshot.js +157 -40
  9. package/lib/app-shutdown.js +113 -77
  10. package/lib/archive.js +337 -40
  11. package/lib/arg-parser.js +697 -0
  12. package/lib/asyncapi.js +99 -55
  13. package/lib/atomic-file.js +465 -104
  14. package/lib/audit-chain.js +123 -34
  15. package/lib/audit-daily-review.js +389 -0
  16. package/lib/audit-sign.js +302 -56
  17. package/lib/audit-tools.js +412 -63
  18. package/lib/audit.js +656 -35
  19. package/lib/auth/jwt-external.js +17 -0
  20. package/lib/auth/oauth.js +7 -0
  21. package/lib/auth-bot-challenge.js +505 -0
  22. package/lib/auth-header.js +92 -25
  23. package/lib/backup/bundle.js +26 -0
  24. package/lib/backup/index.js +512 -89
  25. package/lib/backup/manifest.js +168 -7
  26. package/lib/break-glass.js +415 -39
  27. package/lib/budr.js +103 -30
  28. package/lib/bundler.js +86 -66
  29. package/lib/cache.js +192 -72
  30. package/lib/chain-writer.js +65 -40
  31. package/lib/circuit-breaker.js +56 -33
  32. package/lib/cli-helpers.js +106 -75
  33. package/lib/cli.js +6 -30
  34. package/lib/cloud-events.js +99 -32
  35. package/lib/cluster-storage.js +162 -37
  36. package/lib/cluster.js +340 -49
  37. package/lib/codepoint-class.js +66 -0
  38. package/lib/compliance.js +424 -24
  39. package/lib/config-drift.js +111 -46
  40. package/lib/config.js +94 -40
  41. package/lib/consent.js +165 -18
  42. package/lib/constants.js +1 -0
  43. package/lib/content-credentials.js +153 -48
  44. package/lib/cookies.js +154 -62
  45. package/lib/credential-hash.js +133 -61
  46. package/lib/crypto-field.js +702 -18
  47. package/lib/crypto-hpke.js +256 -0
  48. package/lib/crypto.js +744 -22
  49. package/lib/csv.js +178 -35
  50. package/lib/daemon.js +456 -0
  51. package/lib/dark-patterns.js +186 -55
  52. package/lib/db-query.js +79 -2
  53. package/lib/db.js +1431 -60
  54. package/lib/ddl-change-control.js +523 -0
  55. package/lib/deprecate.js +195 -40
  56. package/lib/dev.js +82 -39
  57. package/lib/dora.js +67 -48
  58. package/lib/dr-runbook.js +368 -0
  59. package/lib/dsr.js +142 -11
  60. package/lib/dual-control.js +91 -56
  61. package/lib/events.js +120 -41
  62. package/lib/external-db-migrate.js +192 -2
  63. package/lib/external-db.js +795 -50
  64. package/lib/fapi2.js +122 -1
  65. package/lib/fda-21cfr11.js +395 -0
  66. package/lib/fdx.js +132 -2
  67. package/lib/file-type.js +87 -0
  68. package/lib/file-upload.js +93 -0
  69. package/lib/flag.js +82 -20
  70. package/lib/forms.js +132 -29
  71. package/lib/framework-error.js +169 -0
  72. package/lib/framework-schema.js +163 -35
  73. package/lib/gate-contract.js +849 -175
  74. package/lib/graphql-federation.js +68 -7
  75. package/lib/guard-all.js +172 -55
  76. package/lib/guard-archive.js +286 -124
  77. package/lib/guard-auth.js +194 -21
  78. package/lib/guard-cidr.js +190 -28
  79. package/lib/guard-csv.js +397 -51
  80. package/lib/guard-domain.js +213 -91
  81. package/lib/guard-email.js +236 -29
  82. package/lib/guard-filename.js +307 -75
  83. package/lib/guard-graphql.js +263 -30
  84. package/lib/guard-html.js +310 -116
  85. package/lib/guard-image.js +243 -30
  86. package/lib/guard-json.js +260 -54
  87. package/lib/guard-jsonpath.js +235 -23
  88. package/lib/guard-jwt.js +284 -30
  89. package/lib/guard-markdown.js +204 -22
  90. package/lib/guard-mime.js +190 -26
  91. package/lib/guard-oauth.js +277 -28
  92. package/lib/guard-pdf.js +251 -27
  93. package/lib/guard-regex.js +226 -18
  94. package/lib/guard-shell.js +229 -26
  95. package/lib/guard-svg.js +177 -10
  96. package/lib/guard-template.js +232 -21
  97. package/lib/guard-time.js +195 -29
  98. package/lib/guard-uuid.js +189 -30
  99. package/lib/guard-xml.js +259 -36
  100. package/lib/guard-yaml.js +241 -44
  101. package/lib/honeytoken.js +63 -27
  102. package/lib/html-balance.js +83 -0
  103. package/lib/http-client.js +486 -59
  104. package/lib/http-message-signature.js +582 -0
  105. package/lib/i18n.js +102 -49
  106. package/lib/iab-mspa.js +112 -32
  107. package/lib/iab-tcf.js +107 -2
  108. package/lib/inbox.js +90 -52
  109. package/lib/keychain.js +865 -0
  110. package/lib/legal-hold.js +374 -0
  111. package/lib/local-db-thin.js +320 -0
  112. package/lib/log-stream.js +281 -51
  113. package/lib/log.js +184 -86
  114. package/lib/mail-bounce.js +107 -62
  115. package/lib/mail.js +295 -58
  116. package/lib/mcp.js +108 -27
  117. package/lib/metrics.js +98 -89
  118. package/lib/middleware/age-gate.js +36 -0
  119. package/lib/middleware/ai-act-disclosure.js +37 -0
  120. package/lib/middleware/api-encrypt.js +45 -0
  121. package/lib/middleware/assetlinks.js +40 -0
  122. package/lib/middleware/asyncapi-serve.js +35 -0
  123. package/lib/middleware/attach-user.js +40 -0
  124. package/lib/middleware/bearer-auth.js +40 -0
  125. package/lib/middleware/body-parser.js +230 -0
  126. package/lib/middleware/bot-disclose.js +34 -0
  127. package/lib/middleware/bot-guard.js +39 -0
  128. package/lib/middleware/compression.js +37 -0
  129. package/lib/middleware/cookies.js +32 -0
  130. package/lib/middleware/cors.js +40 -0
  131. package/lib/middleware/csp-nonce.js +40 -0
  132. package/lib/middleware/csp-report.js +34 -0
  133. package/lib/middleware/csrf-protect.js +43 -0
  134. package/lib/middleware/daily-byte-quota.js +53 -85
  135. package/lib/middleware/db-role-for.js +40 -0
  136. package/lib/middleware/dpop.js +40 -0
  137. package/lib/middleware/error-handler.js +37 -14
  138. package/lib/middleware/fetch-metadata.js +39 -0
  139. package/lib/middleware/flag-context.js +34 -0
  140. package/lib/middleware/gpc.js +33 -0
  141. package/lib/middleware/headers.js +35 -0
  142. package/lib/middleware/health.js +46 -0
  143. package/lib/middleware/host-allowlist.js +30 -0
  144. package/lib/middleware/network-allowlist.js +38 -0
  145. package/lib/middleware/openapi-serve.js +34 -0
  146. package/lib/middleware/rate-limit.js +160 -18
  147. package/lib/middleware/request-id.js +36 -18
  148. package/lib/middleware/request-log.js +37 -0
  149. package/lib/middleware/require-aal.js +29 -0
  150. package/lib/middleware/require-auth.js +32 -0
  151. package/lib/middleware/require-bound-key.js +41 -0
  152. package/lib/middleware/require-content-type.js +32 -0
  153. package/lib/middleware/require-methods.js +27 -0
  154. package/lib/middleware/require-mtls.js +33 -0
  155. package/lib/middleware/require-step-up.js +37 -0
  156. package/lib/middleware/security-headers.js +44 -0
  157. package/lib/middleware/security-txt.js +38 -0
  158. package/lib/middleware/span-http-server.js +37 -0
  159. package/lib/middleware/sse.js +36 -0
  160. package/lib/middleware/trace-log-correlation.js +33 -0
  161. package/lib/middleware/trace-propagate.js +32 -0
  162. package/lib/middleware/tus-upload.js +90 -0
  163. package/lib/middleware/web-app-manifest.js +53 -0
  164. package/lib/mtls-ca.js +100 -70
  165. package/lib/network-byte-quota.js +308 -0
  166. package/lib/network-heartbeat.js +135 -0
  167. package/lib/network-tls.js +534 -4
  168. package/lib/network.js +103 -0
  169. package/lib/notify.js +114 -43
  170. package/lib/ntp-check.js +192 -51
  171. package/lib/observability.js +145 -47
  172. package/lib/openapi.js +90 -44
  173. package/lib/outbox.js +99 -1
  174. package/lib/pagination.js +168 -86
  175. package/lib/parsers/index.js +16 -5
  176. package/lib/permissions.js +93 -40
  177. package/lib/pqc-agent.js +84 -8
  178. package/lib/pqc-software.js +94 -60
  179. package/lib/process-spawn.js +95 -21
  180. package/lib/pubsub.js +96 -66
  181. package/lib/queue.js +375 -54
  182. package/lib/redact.js +793 -21
  183. package/lib/render.js +139 -47
  184. package/lib/request-helpers.js +485 -121
  185. package/lib/restore-bundle.js +142 -39
  186. package/lib/restore-rollback.js +136 -45
  187. package/lib/retention.js +178 -50
  188. package/lib/retry.js +116 -33
  189. package/lib/router.js +475 -23
  190. package/lib/safe-async.js +543 -94
  191. package/lib/safe-buffer.js +337 -41
  192. package/lib/safe-json.js +467 -62
  193. package/lib/safe-jsonpath.js +285 -0
  194. package/lib/safe-schema.js +631 -87
  195. package/lib/safe-sql.js +221 -59
  196. package/lib/safe-url.js +278 -46
  197. package/lib/sandbox-worker.js +135 -0
  198. package/lib/sandbox.js +358 -0
  199. package/lib/scheduler.js +135 -70
  200. package/lib/self-update.js +647 -0
  201. package/lib/session-device-binding.js +431 -0
  202. package/lib/session.js +259 -49
  203. package/lib/slug.js +138 -26
  204. package/lib/ssrf-guard.js +316 -56
  205. package/lib/storage.js +433 -70
  206. package/lib/subject.js +405 -23
  207. package/lib/template.js +148 -8
  208. package/lib/tenant-quota.js +545 -0
  209. package/lib/testing.js +440 -53
  210. package/lib/time.js +291 -23
  211. package/lib/tls-exporter.js +239 -0
  212. package/lib/tracing.js +90 -74
  213. package/lib/uuid.js +97 -22
  214. package/lib/vault/index.js +284 -22
  215. package/lib/vault/seal-pem-file.js +66 -0
  216. package/lib/watcher.js +368 -0
  217. package/lib/webhook.js +196 -63
  218. package/lib/websocket.js +393 -68
  219. package/lib/wiki-concepts.js +338 -0
  220. package/lib/worker-pool.js +464 -0
  221. package/package.json +3 -3
  222. package/sbom.cyclonedx.json +7 -7
@@ -1,36 +1,41 @@
1
1
  "use strict";
2
2
  /**
3
- * auth-header — construct HTTP Authorization headers for the framework's
4
- * outbound consumers.
3
+ * @module b.authHeader
4
+ * @nav HTTP
5
+ * @title Auth Headers
5
6
  *
6
- * The previous shape was `_authHeaders(config)` reimplemented in three
7
- * places (log-stream-webhook, object-store-http-put, object-store-gcs).
8
- * Each handled the same { auth, token, username, password } shape with
9
- * subtly different argument names and case semantics. This module
10
- * collapses the construction.
7
+ * @intro
8
+ * RFC 7235 / RFC 7617 outbound Authorization header construction —
9
+ * the small, security-aware primitive every framework consumer that
10
+ * talks to a credentialed HTTP endpoint composes (log-stream-webhook,
11
+ * object-store-http-put, object-store-gcs, custom outbound clients).
11
12
  *
12
- * Public API:
13
+ * Previously each consumer re-implemented `_authHeaders(config)` with
14
+ * subtly different argument names and case semantics. This module
15
+ * collapses the construction so token / credential rules live in one
16
+ * place: never produce `Basic <b64('undefined:...')>`, always pass
17
+ * bearer tokens through unmodified, refuse unknown auth methods at
18
+ * call time rather than silently emitting no header.
13
19
  *
14
- * bearer(token) → { Authorization: "Bearer <token>" }
15
- * basic(username, password) { Authorization: "Basic <b64>" }
16
- * fromConfig({ auth, token, ... }) headers object for the named auth method
20
+ * Three forms:
21
+ * - `bearer(token)` -> { Authorization: "Bearer <token>" }
22
+ * - `basic(username, password)` -> { Authorization: "Basic <b64>" }
23
+ * - `fromConfig({ auth, ... })` -> dispatch by `auth` field
17
24
  *
18
- * fromConfig accepts:
25
+ * `fromConfig` accepts `{ auth: "none" }` (returns `{}`),
26
+ * `{ auth: "bearer", token }`, and `{ auth: "basic", username,
27
+ * password }`. Anything else throws `AuthHeaderError`. The "raw
28
+ * header pass-through" mode some consumers wanted is intentionally
29
+ * NOT this module's job — that's plain header merging at the call
30
+ * site, kept separate so the auth-header primitive stays pure
31
+ * string construction with no I/O.
19
32
  *
20
- * { auth: "none" } → {}
21
- * { auth: "bearer", token } → bearer(token)
22
- * { auth: "basic", username, password } → basic(username, password)
33
+ * Validation tier: config-time / entry-point. Bad opts throw
34
+ * synchronously so an operator catches the typo at boot rather than
35
+ * on the first outbound request.
23
36
  *
24
- * Anything else throws AuthHeaderError. The "header" pass-through mode
25
- * that consumers used to wedge into _authHeaders is NOT auth-header's job
26
- * — that's just header merging. Consumers do `Object.assign({}, config.headers)`
27
- * themselves and combine the two layers at the call site.
28
- *
29
- * Why this is a separate primitive vs. a helper inside http-client:
30
- * - Some callers (log-stream-local) might emit auth headers without
31
- * going through http-client (e.g. signed-URL inputs to a token).
32
- * - Keeping it pure-string-construction with no I/O makes it test-only
33
- * in 0ms and reusable from non-network contexts.
37
+ * @card
38
+ * RFC 7235 / RFC 7617 outbound Authorization header construction — the small, security-aware primitive every framework consumer that talks to a credentialed HTTP endpoint composes (log-stream-webhook, object-store-http-put, object-store-gcs, custom outbound clients).
34
39
  */
35
40
 
36
41
  var { FrameworkError } = require("./framework-error");
@@ -43,6 +48,22 @@ class AuthHeaderError extends FrameworkError {
43
48
  }
44
49
  }
45
50
 
51
+ /**
52
+ * @primitive b.authHeader.bearer
53
+ * @signature b.authHeader.bearer(token)
54
+ * @since 0.5.0
55
+ * @related b.authHeader.basic, b.authHeader.fromConfig
56
+ *
57
+ * Build an `{ Authorization: "Bearer <token>" }` header object from a
58
+ * non-empty string token. The token is passed through verbatim — no
59
+ * encoding, no whitespace trimming — because RFC 6750 b64token tokens
60
+ * are already in the legal Authorization-value alphabet. Empty / null /
61
+ * non-string input throws `AuthHeaderError`.
62
+ *
63
+ * @example
64
+ * var headers = b.authHeader.bearer("eyJhbGciOiJIUzI1NiJ9.payload.sig");
65
+ * // → { Authorization: "Bearer eyJhbGciOiJIUzI1NiJ9.payload.sig" }
66
+ */
46
67
  function bearer(token) {
47
68
  if (typeof token !== "string" || token.length === 0) {
48
69
  throw new AuthHeaderError("bearer: token must be a non-empty string");
@@ -50,6 +71,23 @@ function bearer(token) {
50
71
  return { Authorization: "Bearer " + token };
51
72
  }
52
73
 
74
+ /**
75
+ * @primitive b.authHeader.basic
76
+ * @signature b.authHeader.basic(username, password)
77
+ * @since 0.5.0
78
+ * @related b.authHeader.bearer, b.authHeader.fromConfig
79
+ *
80
+ * Build an `{ Authorization: "Basic <base64(user:pass)>" }` header per
81
+ * RFC 7617. Empty username + empty password is accepted (some legacy
82
+ * endpoints want literal `Basic <b64('::')>`), but `null` / `undefined`
83
+ * username throws `AuthHeaderError` to refuse the silent-bug shape
84
+ * `Basic <b64('undefined:...')>`. `password === null` is normalized to
85
+ * an empty string.
86
+ *
87
+ * @example
88
+ * var headers = b.authHeader.basic("svc-account", "s3cr3t");
89
+ * // → { Authorization: "Basic c3ZjLWFjY291bnQ6czNjcjN0" }
90
+ */
53
91
  function basic(username, password) {
54
92
  // Accepting empty username + empty password reflects RFC 7617's
55
93
  // tolerance — some legacy endpoints want literally "Basic <b64('::')>".
@@ -63,6 +101,35 @@ function basic(username, password) {
63
101
  return { Authorization: "Basic " + b64 };
64
102
  }
65
103
 
104
+ /**
105
+ * @primitive b.authHeader.fromConfig
106
+ * @signature b.authHeader.fromConfig(config)
107
+ * @since 0.5.0
108
+ * @related b.authHeader.bearer, b.authHeader.basic
109
+ *
110
+ * Dispatch by the `auth` field on a consumer config object — the
111
+ * shared shape every framework outbound consumer accepts. Returns an
112
+ * empty object for `auth: "none"` (or a missing config), routes to
113
+ * `bearer(token)` for `auth: "bearer"`, and to `basic(username,
114
+ * password)` for `auth: "basic"`. Any other `auth` value throws
115
+ * `AuthHeaderError` with the `auth-header/unknown-method` code so a
116
+ * typo doesn't silently produce an unauthenticated request.
117
+ *
118
+ * @opts
119
+ * {
120
+ * auth?: "none" | "bearer" | "basic", // default: "none"
121
+ * token?: string, // required when auth === "bearer"
122
+ * username?: string, // required when auth === "basic"
123
+ * password?: string, // optional when auth === "basic"
124
+ * }
125
+ *
126
+ * @example
127
+ * var headers = b.authHeader.fromConfig({
128
+ * auth: "bearer",
129
+ * token: "eyJhbGciOiJIUzI1NiJ9.payload.sig",
130
+ * });
131
+ * // → { Authorization: "Bearer eyJhbGciOiJIUzI1NiJ9.payload.sig" }
132
+ */
66
133
  function fromConfig(config) {
67
134
  if (!config || !config.auth || config.auth === "none") return {};
68
135
  if (config.auth === "bearer") return bearer(config.token);
@@ -191,6 +191,32 @@ async function create(opts) {
191
191
  files: fileEntries,
192
192
  metadata: opts.metadata || undefined,
193
193
  });
194
+ // Sign the manifest with the audit-sign keypair so a tampered
195
+ // manifest fails verification on restore. The signer is best-
196
+ // effort: callers running outside an audit-sign-initialized process
197
+ // (CLI tooling, ad-hoc bundlers) can pass `opts.sign: false` to
198
+ // emit an unsigned bundle. Default ON to match the rest of the
199
+ // framework's signed-by-default posture.
200
+ var shouldSign = opts.sign !== false;
201
+ if (shouldSign) {
202
+ try { backupManifest.sign(manifest); }
203
+ catch (e) {
204
+ var msg = (e && e.message) || String(e);
205
+ // auditSign.init() not awaited yet — emit unsigned bundle. Callers
206
+ // running outside the framework's boot sequence (CLI tooling,
207
+ // ad-hoc bundlers, primitive smoke tests) can finish without a
208
+ // signed manifest; restore-side `requireSignature: true` opt
209
+ // refuses any unsigned manifest.
210
+ if (msg.indexOf("auditSign.init() must be awaited") !== -1) {
211
+ _emit(progress, { phase: "manifest-unsigned", reason: "audit-sign-not-initialized" });
212
+ } else if (opts.signOptional === true) {
213
+ _emit(progress, { phase: "manifest-unsigned", reason: msg });
214
+ } else {
215
+ throw new BackupBundleError("backup-bundle/sign-failed",
216
+ "create: manifest sign failed: " + msg);
217
+ }
218
+ }
219
+ }
194
220
  var manifestPath = path.join(outDir, "manifest.json");
195
221
  atomicFile.writeSync(manifestPath, backupManifest.serialize(manifest), { fileMode: 0o600 });
196
222