fix: redact invite codes in logs using last4 policy

This commit is contained in:
Nico 2026-02-16 01:34:09 -08:00
parent 05ad576206
commit e2e9ec9eb4
3 changed files with 44 additions and 4 deletions

View File

@ -1,5 +1,6 @@
const householdModel = require("../models/household.model"); const householdModel = require("../models/household.model");
const { sendError } = require("../utils/http"); const { sendError } = require("../utils/http");
const { inviteCodeLast4, safeErrorMessage } = require("../utils/redaction");
// Get all households user belongs to // Get all households user belongs to
exports.getUserHouseholds = async (req, res) => { exports.getUserHouseholds = async (req, res) => {
@ -107,13 +108,18 @@ exports.refreshInviteCode = async (req, res) => {
household household
}); });
} catch (error) { } catch (error) {
console.error("Refresh invite code error:", error); console.error(
`Refresh invite code error request_id=${req.request_id} invite_last4=${inviteCodeLast4(
req.body?.inviteCode
)} message=${safeErrorMessage(error)}`
);
sendError(res, 500, "Failed to refresh invite code"); sendError(res, 500, "Failed to refresh invite code");
} }
}; };
// Join household via invite code // Join household via invite code
exports.joinHousehold = async (req, res) => { exports.joinHousehold = async (req, res) => {
const inviteLast4 = inviteCodeLast4(req.params.inviteCode);
try { try {
const { inviteCode } = req.params; const { inviteCode } = req.params;
if (!inviteCode) return sendError(res, 400, "Invite code is required"); if (!inviteCode) return sendError(res, 400, "Invite code is required");
@ -138,7 +144,11 @@ exports.joinHousehold = async (req, res) => {
household: { id: result.id, name: result.name } household: { id: result.id, name: result.name }
}); });
} catch (error) { } catch (error) {
console.error("Join household error:", error); console.error(
`Join household error request_id=${req.request_id} invite_last4=${inviteLast4} message=${safeErrorMessage(
error
)}`
);
sendError(res, 500, "Failed to join household"); sendError(res, 500, "Failed to join household");
} }
}; };

View File

@ -0,0 +1,20 @@
function inviteCodeLast4(inviteCode) {
if (!inviteCode || typeof inviteCode !== "string") return "none";
const trimmed = inviteCode.trim();
if (!trimmed) return "none";
return trimmed.slice(-4);
}
function safeErrorMessage(error) {
if (!error) return "unknown_error";
if (typeof error === "string") return error;
if (typeof error.message === "string" && error.message.trim()) {
return error.message;
}
return "unknown_error";
}
module.exports = {
inviteCodeLast4,
safeErrorMessage,
};

View File

@ -64,9 +64,19 @@ export default function ManageHousehold() {
try { try {
const response = await refreshInviteCode(activeHousehold.id); const response = await refreshInviteCode(activeHousehold.id);
await refreshHouseholds(); await refreshHouseholds();
alert(`New invite code: ${response.data.inviteCode}`); const refreshedInviteCode = response.data?.household?.invite_code;
if (refreshedInviteCode) {
alert(`New invite code: ${refreshedInviteCode}`);
} else {
alert("Invite code refreshed successfully");
}
} catch (error) { } catch (error) {
console.error("Failed to refresh invite code:", error); console.error(
"Failed to refresh invite code:",
error?.response?.data?.error?.message ||
error?.response?.data?.message ||
error?.message
);
alert("Failed to refresh invite code"); alert("Failed to refresh invite code");
} }
}; };