Repository navigation
feat: delete your account (GDPR) (#134) - #167
Merged
Merged
Conversation
…ntacts' data (#134) GET /account/deletion previews what happens to each organization and what blocks the delete; POST /account/deletion/code emails a confirmation code; DELETE /account takes the typed email and code. Dashboard sessions only, with the billing actions' origin and CSRF checks. Organizations the person is the last owner of are deleted through deleteOrganization (MediaLit files included) and their contacts' personal data erased; suppression hashes stay. Shared organizations are only left. Sessions, sign-in methods, OAuth tokens, consents and codes are deleted and the user row becomes an anonymous tombstone (user.deleted_at), which auth refuses. Blocked by a running subscription, an open checkout, other members depending on them as last owner, or paying for a shared organization.
…d-code confirmation (#134)
…board proxy forwards the body (#134) The web proxy drops DELETE bodies, so the typed email and code never reached the API. Also rate-limit deletion codes per person rather than per IP, which the proxy shares.
Contributor
Author
Browser e2e (Playwright, isolated stack on 5180/3180, fresh DB, MediaLit stubbed, real SMTP to Mailpit)Two users: the owner has a sole-owned org (team, 2 contacts, a broadcast with an uploaded image sent through Mailpit) and is co-owner of the partner's org. Screenshots checked: danger zone, blocked dialog ("Add another owner first", Send code and Delete disabled), ready dialog with the sole-owned org expanded, wrong-code error, signed-out login page, empty fresh account. The first e2e run found that the web proxy drops DELETE bodies; fixed in 60f451b by moving the confirm step to |
8 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #134. Final sub-issue of #152.
What
GET /account/deletion(preview),POST /account/deletion/code(emails a code),POST /account/deletion(typed email + code). Dashboard session only, same origin/CSRF checks as billing actions; REST-only (MCP parity exemption).deleteOrganization()(keys, domains, ESPs, MediaLit files) +eraseOrganizationPersonalData()(contacts and cascades, signup confirmations, transactional recipients/bodies, recipient addresses via the now-usedanonymize…ForPrivacyDeletionhelpers, raw webhook payloads, reputation connections). Suppression hashes stay.removeOrganizationMember, auditorganization.member_account_deleted).userrow becomes a tombstone (deleted_at, migration 0029, Better Auth additional field) refused byresolve-auth/ensureDefaultOrganization. Re-signup with the same email = fresh empty account. Abuse flags drop email/IP.account_deletedevent with user id + counts only (allowlist updated).deleteUser, what's kept for billing/trial/audit, no later purge job).Checks
check:drift,test:conformance.