Add account export and deletion controls - #71
joan-code6 wants to merge 3 commits into
Conversation
LanisProject ID: Tip Deploy functions via zip upload or connect directly to your Git repo |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f32f6f3dd5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for (let index = localStorage.length - 1; index >= 0; index -= 1) { | ||
| const key = localStorage.key(index); | ||
| if (key) localStorage.removeItem(key); |
There was a problem hiding this comment.
Hide destructive account controls in demo mode
On /demo/settings/account, the demo API adapter falls through to a successful mocked response for DELETE /account, after which this loop clears the browser's entire real localStorage. Because DemoRoute's mock logout is a no-op and the storage snapshot itself is also removed, testing account deletion in the demo can erase real login tokens, custom-backend configuration, and other persisted settings without deleting any server account. Exclude this section in demo mode or provide a non-destructive demo implementation.
Useful? React with 👍 / 👎.
| ? await navigator.serviceWorker.getRegistration() | ||
| : undefined; | ||
| const subscription = await registration?.pushManager.getSubscription(); | ||
| if (subscription) await subscription.unsubscribe(); |
There was a problem hiding this comment.
Always finish logout after server deletion
If PushSubscription.unsubscribe() rejects after DELETE /account has already succeeded, control jumps to the outer catch before logout() and the redirect run. The account is therefore permanently deleted while the current React auth state still says the user is signed in, leaving them on the settings page with a misleading retryable-error message; make cache/push cleanup best-effort and place local logout/navigation in an unconditional post-deletion path.
Useful? React with 👍 / 👎.
| User-agent: * | ||
| Allow: / | ||
| Disallow: /login | ||
| Disallow: /impressum |
There was a problem hiding this comment.
Allow crawlers to read the Impressum noindex directive
Disallowing /impressum prevents compliant crawlers from fetching the page and observing the existing noindex meta tag in Impressum.tsx. Because the landing page still links to this URL, search engines can retain or create a URL-only result while being unable to process the directive intended to remove it; allow crawling and rely on the page-level noindex instead.
Useful? React with 👍 / 👎.
f32f6f3 to
54851bf
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 54851bf1e9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const registration = 'serviceWorker' in navigator | ||
| ? await navigator.serviceWorker.getRegistration() | ||
| : undefined; | ||
| const subscription = await registration?.pushManager.getSubscription(); |
There was a problem hiding this comment.
Guarantee logout after service-worker lookup failures
If the account deletion succeeds but getRegistration() or getSubscription() rejects—for example because the browser cannot access its push/service-worker storage—the outer catch still runs before localStorage.clear(), logout(), and navigation, leaving the UI authenticated to an account that no longer exists. Although subscription cleanup is now covered by Promise.allSettled, these newly exposed awaited lookups remain outside that best-effort boundary; local logout and redirect should run unconditionally after a successful deletion.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3dbcfae529
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| await Promise.allSettled(cleanupTasks); | ||
| try { | ||
| localStorage.clear(); |
There was a problem hiding this comment.
Preserve the configured backend when deleting an account
When the user is connected to a custom backend, localStorage.clear() also removes lanis_custom_backend_url, which is a device-level setting rather than account data. The current API client continues using the custom backend only until a reload; afterward the login page silently switches to the default backend, so a user trying to sign back into the same deployment can submit credentials to the wrong server. Use the existing scoped-storage cleanup or explicitly preserve the custom-backend key.
Useful? React with 👍 / 👎.
| await Promise.allSettled(cleanupTasks); | ||
| try { | ||
| localStorage.clear(); |
There was a problem hiding this comment.
Clear the selected-school cookies during account cleanup
Deleting an account clears local storage and Cache Storage but leaves the lastSchoolId, lastSchoolName, and lastSchoolLocation cookies intact. LoginForm reads those cookies and repopulates the deleted user's school on the next login screen, so the promised local-data cleanup is incomplete; expire these cookies as clearBackendScopedStorage() already does.
Useful? React with 👍 / 👎.

Summary
LÖSCHENconfirmation for account deletionValidation
npx tsc --noEmitNote: unrelated pre-existing worktree changes were left uncommitted.