56 lines
5.1 KiB
Markdown
56 lines
5.1 KiB
Markdown
---
|
|
name: account-deletion
|
|
description: Make account deletion pass App Store and Google Play review for an app with sign-up or sign-in - Apple Guideline 5.1.1(v) in-app deletion (the whole account, not deactivation; Sign in with Apple token revocation; subscription billing note), Google Play's in-app path plus a public web page declared in Data safety, the config (accounts.enabled, deletionUrl, inApp) and the storebound checks. Use when the app has accounts, when the user adds sign-up, or after a 5.1.1(v) / Play account deletion rejection.
|
|
---
|
|
|
|
# Account deletion (both stores)
|
|
|
|
`storebound scan` finds sign-up and sign-in code (Firebase Auth, Supabase, Google / Facebook / Apple sign-in, custom endpoints) without a deletion path (5.1.1(v)) and accounts without `accounts.deletionUrl` (Play): run it after adding deletion.
|
|
|
|
Applies to every app that lets people create an account (email, phone, social sign-in, Sign in with Apple). Games
|
|
without accounts can skip it. Sources: Apple, "Offering account deletion in your app"
|
|
(https://developer.apple.com/support/offering-account-deletion-in-your-app/) and App Review Guideline 5.1.1(v)
|
|
(https://developer.apple.com/app-store/review/guidelines/); Google Play, "Understanding Google Play's app account
|
|
deletion requirements" (https://support.google.com/googleplay/android-developer/answer/13327111).
|
|
|
|
## What the stores require
|
|
- **Apple 5.1.1(v)**: people can **start** deleting their account **inside the app**, easy to find (e.g. Settings >
|
|
Account > Delete account). Delete the whole account and its personal data, not only deactivate it. A link to a web
|
|
page that completes the deletion is fine; "email or call us" is only acceptable in highly regulated industries.
|
|
With Sign in with Apple, revoke the user's tokens (Sign in with Apple REST API). With auto-renewable
|
|
subscriptions, tell people that billing continues through Apple until they cancel, and how to cancel.
|
|
- **Google Play**: if the app lets people create an account, it must offer deletion **in the app** and on a **web
|
|
page** people can reach without the app (no reinstall needed). The URL goes into the Data safety form ("Data
|
|
deletion"). People can also ask to delete some data without deleting the account; say how.
|
|
|
|
## Steps
|
|
1. Config: `accounts: { enabled: true, deletionUrl: 'https://example.com/delete-account', inApp: 'Settings > Account >
|
|
Delete account' }`. `storebound check` errors without `deletionUrl` (Play) and warns without `inApp` (Apple);
|
|
`storebound apple review-details` adds "Account deletion: <inApp>" to the review notes.
|
|
2. Web page at `deletionUrl`: names the app and developer, the steps to request deletion (sign in, or a form that
|
|
verifies the email), what is deleted and what is kept (and for how long, e.g. invoices for tax law), and how long it
|
|
takes. No login wall to read it. `storebound validate --play` checks that it answers.
|
|
3. In the app: a clear entry, a confirmation step, then the deletion (or the web page). Sign people out afterwards.
|
|
4. Play Data safety: `accountCreation` set to the sign-up methods you offer (not
|
|
`PSL_ACM_NONE`). Say how people sign up in `accounts.signUp` and `storebound scan` proposes it: `username` (a name
|
|
picked in the app, no password, no email; a server token on the device) is Play's "Username and other
|
|
authentication" (`PSL_ACM_USER_ID_OTHER_AUTH`) with User ID as the only account data; `username-password` and
|
|
`email-password` are "Username and password" (`PSL_ACM_USER_ID_PASSWORD`); `email-link` and `phone` are
|
|
`PSL_ACM_USER_ID_OTHER_AUTH`; `oauth` is `PSL_ACM_OAUTH`; `other` is `PSL_ACM_OTHER`. An account alone never means
|
|
an email address: declare Email only when the app asks for one. With accounts Play requires more rows, and storebound
|
|
writes them: the delete-account URL (`PSL_ACCOUNT_DELETION_URL` = `accounts.deletionUrl`) and "Do you provide a way
|
|
for users to request that their data is deleted?" (`PSL_SUPPORT_DATA_DELETION_BY_USER`, a single choice). The
|
|
delete-account page is such a way, so the answer is yes (`DATA_DELETION_YES`); answering no next to a delete-account
|
|
URL contradicts it and `check` flags it. The yes needs a "Delete data URL" (`PSL_DATA_DELETION_URL`):
|
|
`dataSafety.partialDeletionUrl` when there is a page that deletes data without deleting the account
|
|
(`partialDeletion: true`), else the delete-account page. `storebound check` and
|
|
`play data-safety --dry` say `missing: <id> (... set <field>)` for any of them; without them Play answers 400
|
|
"Response missing for PSL_ACCOUNT_DELETION_URL". Play removed the old "users can request deletion" question, so
|
|
`dataSafety.deletionRequest` is no longer used (`check` notes it; remove it).
|
|
5. Privacy policy: a "Deleting your account" section with both paths (`privacy-policy` skill).
|
|
6. Test it on a fresh account before every submission; the reviewer will.
|
|
|
|
## Gotchas
|
|
- "Deactivate" or "contact support" is not deletion for Apple.
|
|
- Deleting the account does not cancel a store subscription: say so in the app and on the web page.
|
|
- Keep the in-app path, the web page, Data safety and the privacy policy saying the same thing.
|