Fix supporter wallet address exposure and ProfileReport IP retention - #900
Conversation
The contribution-received email subject included the supporter's full 56-character Stellar address, which is exposed through channels beyond our control (email provider indexing, push notification previews, marketing/analytics logs). The subject now shows a truncated address; the full address is still included in the email body.
…eport ProfileReport.reporterIp had no expiry, contradicting the privacy policy's claim that IP addresses are not stored long-term. Add an expiresAt field (90 days from creation), a daily scheduled job that nulls out reporterIp once expired, and update the privacy policy copy to accurately describe the retention window.
|
@meshackyaro Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
CI status noteAll four CI checks on this PR are red, but none of the failures are caused by this PR — they're pre-existing, repo-wide issues on
This PR's own changes were fully validated locally against the CI environment (Postgres 16, Node 22): backend tests, lint (0 errors), build, and Happy to open a separate PR to stabilize these pre-existing CI issues if that's useful, but keeping this PR scoped to #869 and #870 as assigned. |
Summary
contribution-receivedemail subject exposed the supporter's full 56-character Stellar wallet address (email subjects are indexed/cached by providers and shown in push notification previews). The subject now shows a truncated address (GABCDE...UVWX); the full address is still in the email body.ProfileReport.reporterIpwas stored indefinitely, contradicting the privacy policy's claim that IP addresses are "not stored long-term". Added anexpiresAtfield (90 days from creation) and a daily scheduled job (ip-retention-purge.ts, following the existingweekly-digest.tspattern) that nulls outreporterIponce expired. The report itself (reason/details) is kept for moderation history. Updated the privacy policy copy to accurately describe this retention window.Notes
mainindependent of this PR (pre-existingreact/no-unescaped-entitieslint errors interms/page.tsxand unrelated lines ofprivacy/page.tsx) — confirmed viagh run listacross the last several merges. This PR's own edits toprivacy/page.tsxdon't introduce any new lint errors; fixing the pre-existing repo-wide issue is out of scope for [Backend] contribution-received email subject exposes supporter's full Stellar wallet address — privacy concern #869/[Privacy] ProfileReport model permanently stores IP addresses but privacy policy states IPs are not stored long-term #870.Closes #869, Closes #870
Test plan
npm run test(backend) — all suites pass except pre-existing, network-dependent failures reproduced identically on a cleanupstream/maincheckout (Horizon/Redis-dependent tests unreachable in a sandboxed environment)npx prisma migrate deploy+ CI's exactprisma migrate diffdrift check — no driftnpm run build(backend) — cleannpm run lint(backend) — 0 errors (pre-existing warnings only)