mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 04:21:09 +02:00
logEvent() builds its INSERT via a raw `sql` tagged template:
sql\`INSERT INTO auth.security_events
(..., user_id, ip_address, user_agent, metadata, ...)
VALUES (..., \${params.userId}, \${params.ipAddress},
\${params.userAgent}, \${...metadata}, ...)\`
Most call sites only pass userId+eventType (or only eventType for the
LOGIN_FAILURE / PASSWORD_RESET_REQUESTED / PROFILE_UPDATED /
PASSWORD_CHANGED / ACCOUNT_DELETED events). The other params land in
the template as `undefined`, and postgres-js's tagged-template renderer
collapses `${undefined}` into literal nothing — producing this:
VALUES (gen_random_uuid(), $1, $2, , , $3::jsonb, NOW())
^^^^
Postgres rejects with "syntax error at or near \",\"". The catch block
swallowed it as a `console.warn('Failed to log security event
(non-critical):', params.eventType)` with no error detail, which is why
this has been silently broken for who knows how long — every register,
every login, every password change has been losing its audit row.
Fix:
- Coerce optional params to `null` (`params.userId ?? null`) before
interpolation. NULL is what postgres-js renders for an explicit null.
- Surface the actual error in the catch warn so the next time something
similar happens it shows up in logs instead of just "non-critical".
Verified the diagnosis by toggling `log_statement = all` on the test
postgres, triggering a register, and reading the literal failed
statement out of postgres logs.
|
||
|---|---|---|
| .. | ||
| sql | ||
| src | ||
| CLAUDE.md | ||
| Dockerfile | ||
| drizzle.config.ts | ||
| package.json | ||
| tsconfig.json | ||