fix(audit): LOWs sweep — truncate auth entityId, fix legacy berthId in seed-data
L3: failed-login audit's entityId could carry an unbounded attempted-email value (the form lets you type anything). Truncate to 256 chars before using as entityId; full original still in metadata for forensic context. L2: seed-data.ts (the realistic fixture) inserted interests with berthId — that column was dropped in migration 0029 and the realistic seed would fail at insert on a fresh DB. Now inserts via the interestBerths junction (mirrors the synthetic seed's pattern). L1 (no-op): next-in-line notification already gets the 5-min cooldownMs default from createNotification, so retries are idempotent without extra code. Verified. L5 (no-op): import worker comment already explains the stub state adequately; no code change. 1175/1175 vitest passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -50,12 +50,17 @@ function logSignIn(args: {
|
||||
const email = parsed?.user?.email ?? parsed?.email ?? args.attemptedEmail ?? null;
|
||||
const ok = args.status >= 200 && args.status < 300;
|
||||
|
||||
// entityId is text/unbounded but indexed; truncate the attempted-
|
||||
// email fallback to keep the row predictably sized when the form
|
||||
// sends a giant value. The audit metadata still carries the full
|
||||
// original attempted email for forensic context.
|
||||
const safeAttempted = (args.attemptedEmail ?? '').slice(0, 256);
|
||||
void createAuditLog({
|
||||
userId,
|
||||
portId: null,
|
||||
action: 'login',
|
||||
entityType: 'session',
|
||||
entityId: userId ?? args.attemptedEmail ?? 'unknown',
|
||||
entityId: userId ?? safeAttempted ?? 'unknown',
|
||||
metadata: {
|
||||
ok,
|
||||
status: args.status,
|
||||
|
||||
Reference in New Issue
Block a user