From 895ace2dd11a558bc1eead64e4a2e097f91de5a1 Mon Sep 17 00:00:00 2001 From: ajulaybeeb Date: Mon, 29 Jun 2026 23:42:25 +0100 Subject: [PATCH] fix: contextualize email redaction in audit logs and error reports --- src/app/api/errors/report/route.ts | 16 +++++++++++++++- src/lib/logging/index.ts | 4 ---- src/lib/logging/logger.test.ts | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/app/api/errors/report/route.ts b/src/app/api/errors/report/route.ts index 32e09404..8902c478 100644 --- a/src/app/api/errors/report/route.ts +++ b/src/app/api/errors/report/route.ts @@ -10,9 +10,23 @@ class ClientError extends Error { } } +function redactEmailFields(obj: any): any { + if (!obj || typeof obj !== 'object') return obj; + if (Array.isArray(obj)) return obj.map(redactEmailFields); + const redacted = { ...obj }; + for (const [key, value] of Object.entries(redacted)) { + if (key.toLowerCase().includes('email')) { + redacted[key] = '[REDACTED]'; + } else if (typeof value === 'object' && value !== null) { + redacted[key] = redactEmailFields(value); + } + } + return redacted; +} + export async function POST(request: NextRequest): Promise { try { - const report = await request.json(); + const report = redactEmailFields(await request.json()); // Build a real Error so normalizeError captures name + message + stack properly const clientError = report.errorData?.message diff --git a/src/lib/logging/index.ts b/src/lib/logging/index.ts index 38f45809..3cfe8425 100644 --- a/src/lib/logging/index.ts +++ b/src/lib/logging/index.ts @@ -39,7 +39,6 @@ const SENSITIVE_KEYS = [ 'token', 'key', 'authorization', - 'email', 'phone', 'ssn', 'creditcard', @@ -117,7 +116,6 @@ const pinoLogger = pino({ 'token', 'key', 'authorization', - 'email', 'phone', 'ssn', '*.password', @@ -125,7 +123,6 @@ const pinoLogger = pino({ '*.token', '*.key', '*.authorization', - '*.email', '*.phone', '*.ssn', 'context.password', @@ -133,7 +130,6 @@ const pinoLogger = pino({ 'context.token', 'context.key', 'context.authorization', - 'context.email', 'context.phone', 'context.ssn', 'context.auth', diff --git a/src/lib/logging/logger.test.ts b/src/lib/logging/logger.test.ts index 248ecdee..4f0fd3b1 100644 --- a/src/lib/logging/logger.test.ts +++ b/src/lib/logging/logger.test.ts @@ -57,7 +57,7 @@ describe('structured logging', () => { const record = results[0]; // Check that sensitive fields and strings are fully redacted expect(record.message).toContain('Bearer [REDACTED]'); - expect(record.context?.email).toBe('[REDACTED]'); + expect(record.context?.email).toBe('user@example.com'); expect(record.context?.password).toBe('[REDACTED]'); expect(record.context?.authHeader).toBe('[REDACTED]');