@bymax-one/nest-logger 1.2.3 → 1.2.4

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 (3) hide show
  1. package/CHANGELOG.md +56 -1
  2. package/README.md +11 -0
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -11,8 +11,62 @@ heading here.
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [1.2.4] - 2026-08-14
15
+
16
+ ### Documentation
17
+
18
+ - **The `1.2.3` notes below were amended after release: they were missing a `### Security` section.**
19
+ The terminal-escaping hardening described there shipped **in 1.2.3** — `toSingleLineMessage` is in
20
+ that bundle — but the release notes did not mention it, so a reader auditing the CHANGELOG for
21
+ security-relevant changes would have missed it. Found by a consumer reading the bundle diff rather
22
+ than the notes. The section was added to `[1.2.3]` where it belongs chronologically, and this entry
23
+ exists so anyone who already read those notes learns they changed. No code moved; the amendment is
24
+ the correction.
25
+
26
+ - **An optional peer dependency is NOT absent from a pruned production install.** Two consumers
27
+ independently reasoned that because `pino-pretty` is a `devDependency`, `pnpm prune --prod` strips
28
+ it and `PrettyDevDestination` therefore cannot run in production. That is false under pnpm, and one
29
+ of them disproved it inside a real production image: `prune --prod` removes the **top-level link**
30
+ while the package stays in the store, linked beside this library as the resolved optional peer, so
31
+ the lazy `import('pino-pretty')` inside `onInit` resolves relative to the library's own directory
32
+ and succeeds.
33
+
34
+ The practical consequence is documented in the README and the destinations guideline: do not treat
35
+ "it is a devDependency" as proof that a code path is unreachable in production. A `PrettyDevDestination`
36
+ left registered in a production deployment will not crash and will not warn — it will render ANSI
37
+ colour into a log pipeline that has silently failed to parse every line since the deploy.
38
+
39
+ ### Tests
40
+
41
+ - **The rescue path now asserts the audit signal it was written to protect.** The end-to-end case for
42
+ the total-init-failure fallback names `LOGGER_BOOTSTRAP_WARNING` — the signal that exists so a
43
+ security review can see PII redaction was disabled — as its justification, then asserted
44
+ `LOGGER_BOOTSTRAP_OK` instead. The guarantee was covered transitively (same path, and `warn` clears
45
+ any filter `info` clears), but the test did not pin the promise it cited, so it could have been
46
+ weakened without anyone noticing what was surrendered. A dedicated case now boots with
47
+ `shouldDisableDefaultRedact: true` and asserts the warning survives the rescue, with its flag and
48
+ level. Verified to fail when the rescuer election is moved after `announceBootstrap()`.
49
+
14
50
  ## [1.2.3] - 2026-08-14
15
51
 
52
+ ### Security
53
+
54
+ - **Control characters in a destination failure report are escaped before reaching a terminal.**
55
+ The `LOGGER_DESTINATION_INIT_FAILED` and `LOGGER_DESTINATION_WRITE_FAILED` lines are written
56
+ straight to `process.stderr` and read by a human in a terminal, and `JSON.stringify` escapes C0 and
57
+ nothing else — DEL, the C1 range (U+0085 NEL included), U+2028 and U+2029 survive verbatim, which is
58
+ enough to drive a terminal or forge what looks like a separate log entry. The destination `name` is
59
+ consumer-chosen and the failure text is frequently remote-derived, so both are attacker-influenced
60
+ surfaces. `destination`, `err.type`, `err.message` and `msg` now pass through `toSingleLineMessage`,
61
+ the same per-sink escaping the rest of the library applies.
62
+
63
+ - **A rejected value that throws while being coerced can no longer abort application bootstrap.**
64
+ The failure reporter normalized the thrown value _outside_ its own guard, so `String(cause)` on a
65
+ value with a throwing `toString`/`Symbol.toPrimitive` — or the `name`/`message` reads on an `Error`
66
+ with hostile getters — escaped the reporter. It runs inside the registry catch that exists to keep a
67
+ bad sink from mattering, so the escape aborted boot: the failure handler became a harder failure
68
+ than the one it was handling. Coercion now happens inside the guard.
69
+
16
70
  ### Fixed
17
71
 
18
72
  - **A destination that fails to initialize no longer silences the entire application.** Reported
@@ -868,7 +922,8 @@ published `dist/` is identical — no runtime behaviour changes for consumers.
868
922
  - Professional CI suite: `ci.yml`, `bench.yml`, `codeql.yml`, `scorecard.yml`,
869
923
  `release.yml`, Dependabot, and issue templates
870
924
 
871
- [Unreleased]: https://github.com/bymaxone/nest-logger/compare/v1.2.3...HEAD
925
+ [Unreleased]: https://github.com/bymaxone/nest-logger/compare/v1.2.4...HEAD
926
+ [1.2.4]: https://github.com/bymaxone/nest-logger/compare/v1.2.3...v1.2.4
872
927
  [1.2.3]: https://github.com/bymaxone/nest-logger/compare/v1.2.2...v1.2.3
873
928
  [1.2.2]: https://github.com/bymaxone/nest-logger/compare/v1.2.1...v1.2.2
874
929
  [1.2.1]: https://github.com/bymaxone/nest-logger/compare/v1.2.0...v1.2.1
package/README.md CHANGED
@@ -149,6 +149,17 @@ pnpm add @opentelemetry/api @opentelemetry/sdk-node
149
149
 
150
150
  ```
151
151
 
152
+ > ⚠️ **`-D` does not make it absent in production.** Under pnpm, `pnpm prune --prod` removes the
153
+ > **top-level link** but leaves the package in the store, linked beside this library as the resolved
154
+ > optional peer — and `PrettyDevDestination` imports it lazily, relative to the library's own
155
+ > directory, so it resolves. Verified inside a real pruned production image by a consumer who had
156
+ > assumed the opposite.
157
+ >
158
+ > So "it is a devDependency, therefore this path cannot run in production" is **not** a safe premise.
159
+ > A `PrettyDevDestination` left registered in production will not crash and will not warn: it renders
160
+ > ANSI colour into a log pipeline that has silently failed to parse every line since the deploy. Gate
161
+ > it on an explicit configuration value you can see, not on the packaging.
162
+
152
163
  > [!NOTE]
153
164
  > `@opentelemetry/api` is resolved lazily when the Pino instance is built. When it is absent the trace mixin silently steps aside — the logger never fails to start, and never warns, over an optional peer.
154
165
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-logger",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "Structured JSON logging for NestJS based on Pino 10, with optional OpenTelemetry correlation.",
5
5
  "author": "Bymax One <support@bymax.one>",
6
6
  "license": "MIT",