feat: account deletion in settings + privacy policy with deletion link

This commit is contained in:
2026-07-17 15:47:29 -04:00
parent e79505d8b4
commit aa0af5db4f
49 changed files with 1152 additions and 2 deletions
+26 -1
View File
@@ -5,7 +5,7 @@ import { usePushStore } from '../stores/push.ts';
import { ThemeToggle } from './ThemeToggle.tsx';
export function UserSettings() {
const { user, updateProfile, changePassword, isLoading, error, clearError } = useAuthStore();
const { user, updateProfile, changePassword, deleteAccount, isLoading, error, clearError } = useAuthStore();
const { isSupported, isSubscribed, subscribe, unsubscribe, checkSubscription } = usePushStore();
const navigate = useNavigate();
@@ -440,6 +440,31 @@ export function UserSettings() {
</div>
</form>
{/* Account Deletion */}
<div className="mt-6 pt-4 border-t border-gb-bg-t">
<details className="group">
<summary className="text-gb-red font-mono text-xs cursor-pointer hover:text-gb-bright-red select-none">
[DELETE ACCOUNT]
</summary>
<div className="mt-3 p-3 border border-gb-red/40 bg-gb-bg-t/30">
<p className="text-gb-fg-f text-xs font-mono mb-3">
This action is permanent and cannot be undone. All your messages, servers you own, and uploaded files will be deleted.
</p>
<button
type="button"
onClick={async () => {
if (!confirm('Are you sure you want to permanently delete your account? This cannot be undone.')) return;
await deleteAccount();
navigate('/login');
}}
className="terminal-button text-xs border-gb-red text-gb-red hover:bg-gb-red/20"
>
[CONFIRM DELETE ACCOUNT]
</button>
</div>
</details>
</div>
{/* Footer info */}
<div className="mt-6 pt-4 border-t border-gb-bg-t">
<p className="text-gb-fg-f text-xs font-mono">
+5
View File
@@ -69,6 +69,7 @@ interface AuthState {
blockUser: (userId: string) => Promise<void>;
unblockUser: (userId: string) => Promise<void>;
clearError: () => void;
deleteAccount: () => Promise<void>;
}
// ponytail: auto-subscribe to push notifications on auth
@@ -249,4 +250,8 @@ export const useAuthStore = create<AuthState>((set) => ({
unblockUser: async (userId) => {
await api.delete(`/users/me/blocks/${userId}`);
},
deleteAccount: async () => {
await api.delete("/auth/me");
},
}));