From 7c14414cd2c69edbac59dc7527341bd8a5638462 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 30 Sep 2026 15:49:32 +0200 Subject: [PATCH] The failed-callback audit event keeps the error's class and code Self's ruling: the audit event stored error.message, and pg or resolver text can carry fragments of a database URL. It now stores the error's class name and its code, each checked against a narrow pattern. A test puts the canary in the host of an ENOTFOUND error and checks that no audit event holds it. Co-Authored-By: Claude Opus 5.5 --- src/app.ts | 15 +++++++++------ tests/app.test.ts | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/app.ts b/src/app.ts index a1d9a2f..299364a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1326,11 +1326,13 @@ export async function buildApp(options: BuildAppOptions = {}): Promise { }); }); +describe("the failed-callback audit event", () => { + it("keeps the error's class and code, not its text", async () => { + const store = new InMemoryStore(); + const app = await buildApp({ + config: createTestConfig(), + store, + oauthRuntimes: { + discord: { + ...createMockDiscordRuntime(), + async exchangeAuthorizationCode() { + throw Object.assign(new Error("getaddrinfo ENOTFOUND CANARYhost.invalid"), { code: "ENOTFOUND" }); + }, + }, + }, + }); + apps.push(app); + + const stateToken = await startDiscordSignIn(app); + const response = await app.inject({ + method: "GET", + url: `/v1/oauth/discord/callback?code=test-code&state=${encodeURIComponent(stateToken)}`, + }); + expect(response.statusCode).toBe(502); + + const events = [...(store as unknown as { auditEvents: Map }).auditEvents.values()]; + const failed = events.filter((event) => event.eventType === "oauth_callback_failed"); + expect(failed).toHaveLength(1); + expect(failed[0]!.eventPayloadJson).toEqual({ + provider: "discord", + mode: "sign_in", + errorClass: "Error", + errorCode: "ENOTFOUND", + }); + expect(JSON.stringify(events)).not.toContain("CANARY"); + }); +});