You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix request-scoped logger fields leaking across concurrent captcha requests, and give every endpoint a proper request/response envelope in OpenObserve.
8
+
9
+
Three interlocking changes:
10
+
11
+
-**`Tasks.setLogger` no longer mutates `db.logger`.**`env.getDb()` returns a
12
+
process-wide singleton; overwriting `db.logger` on every request meant two
13
+
concurrent captcha submits raced, and whichever request landed second
14
+
stamped its `user`/`siteKey`/`sessionId` bindings onto the *other* request's
15
+
DB-level log lines. In practice you'd see a `PuzzleCaptcha record updated
16
+
successfully` for user A's challenge tagged with user B's account and site
17
+
key, breaking log-based forensics. `setLogger` still updates the per-request
18
+
Tasks instance and its per-request manager instances (those are safe —
19
+
they're constructed inside the Tasks constructor) but stops mutating the
20
+
shared DB. Callers in `getPoWCaptchaChallenge` and `getPuzzleCaptchaChallenge`
21
+
now pass `req.logger` directly into `new Tasks(env, req.logger)` and drop
22
+
the redundant `.setLogger(req.logger)` call that followed.
23
+
24
+
-**`requestLoggerMiddleware` now emits `Request received` and `Response sent`
25
+
envelope lines on every route** (with `method`, `path`, `status`,
26
+
`durationMs`, and the request id). Previously only `/frictionless` had a
27
+
`res.on('finish', ...)` block, so `getPow/PuzzleCaptchaChallenge`,
28
+
`submitPow/PuzzleCaptchaSolution`, `verify.ts` etc. produced no envelope in
29
+
OO — a challenge issued by one endpoint and verified by another shared
30
+
nothing you could group on. Health-probe paths (`/healthz`, `/health`,
31
+
`/readyz`) are excluded so they don't drown the stream. The middleware
32
+
also now mirrors `x-request-id` back on the outbound response so callers
33
+
downstream of the Node process can correlate without depending on Caddy.
34
+
35
+
-**`requestId` (set on the request logger via `.with({requestId})`) is
36
+
promoted to a top-level `req_id` field on the emitted JSON log record.**
37
+
OpenObserve indexes top-level fields as their own columns, so
38
+
`WHERE req_id = '…'` is now cheap; previously the id only lived inside
39
+
`data.requestId`, which flattened to `data_requestid` in OO's ingestion
40
+
and had no top-level column. `data.requestId` is preserved for backwards
41
+
compatibility with existing dashboards. Two new unit tests in
42
+
`@prosopo/logger` cover the promotion and the "absent when unset" case.
0 commit comments