fix: stop logging password reset secrets
This commit is contained in:
@@ -16,7 +16,9 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"check": "tsc -p tsconfig.json --noEmit"
|
||||
"check": "tsc -p tsconfig.json --noEmit",
|
||||
"pretest": "pnpm build",
|
||||
"test": "node --test dist/**/*.test.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nproxy/domain": "workspace:*"
|
||||
|
||||
43
packages/providers/src/email.test.ts
Normal file
43
packages/providers/src/email.test.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import { createEmailTransport } from "./email.js";
|
||||
|
||||
test("example email transport redacts password-reset tokens before logging", async () => {
|
||||
const transport = createEmailTransport({
|
||||
provider: "example",
|
||||
from: "noreply@nproxy.test",
|
||||
apiKey: "unused",
|
||||
});
|
||||
const logMessages: string[] = [];
|
||||
const originalConsoleLog = console.log;
|
||||
console.log = (message?: unknown) => {
|
||||
logMessages.push(String(message ?? ""));
|
||||
};
|
||||
|
||||
try {
|
||||
await transport.send({
|
||||
to: "user@example.com",
|
||||
subject: "Reset your password",
|
||||
text: "Reset link: https://app.nproxy.test/reset-password?token=secret-token-123",
|
||||
});
|
||||
} finally {
|
||||
console.log = originalConsoleLog;
|
||||
}
|
||||
|
||||
assert.equal(logMessages.length, 1);
|
||||
assert.match(logMessages[0] ?? "", /"mode":"debug_redacted"/);
|
||||
assert.match(logMessages[0] ?? "", /token=\[REDACTED\]/);
|
||||
assert.doesNotMatch(logMessages[0] ?? "", /secret-token-123/);
|
||||
});
|
||||
|
||||
test("unsupported email providers fail closed", () => {
|
||||
assert.throws(
|
||||
() =>
|
||||
createEmailTransport({
|
||||
provider: "smtp",
|
||||
from: "noreply@nproxy.test",
|
||||
apiKey: "unused",
|
||||
}),
|
||||
/Unsupported email provider: smtp/,
|
||||
);
|
||||
});
|
||||
@@ -20,29 +20,20 @@ export function createEmailTransport(config: {
|
||||
JSON.stringify({
|
||||
service: "email",
|
||||
provider: config.provider,
|
||||
mode: "debug_redacted",
|
||||
from: config.from,
|
||||
to: input.to,
|
||||
subject: input.subject,
|
||||
text: input.text,
|
||||
textPreview: redactEmailText(input.text),
|
||||
}),
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
async send(input) {
|
||||
console.log(
|
||||
JSON.stringify({
|
||||
service: "email",
|
||||
provider: config.provider,
|
||||
mode: "noop_fallback",
|
||||
from: config.from,
|
||||
to: input.to,
|
||||
subject: input.subject,
|
||||
text: input.text,
|
||||
}),
|
||||
);
|
||||
},
|
||||
};
|
||||
throw new Error(`Unsupported email provider: ${config.provider}`);
|
||||
}
|
||||
|
||||
function redactEmailText(text: string): string {
|
||||
return text.replace(/([?&]token=)[^&\s]+/gi, "$1[REDACTED]");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user