From 6171301cbb51b52918d88dd20e0fde218852b5c9 Mon Sep 17 00:00:00 2001 From: Muneerali199 Date: Wed, 11 Mar 2026 14:27:59 +0530 Subject: [PATCH] fix: implement account deletion to permanently remove user data - Add deleteAccount() orchestrator in DeleteAccountController that: - Deletes user profile picture from Appwrite Storage - Deletes username record from the usernames table - Deletes user document from the users table - Calls account.updateStatus() to permanently block the auth account - Calls account.deleteSessions() to invalidate all active sessions - Navigates to the welcome screen on completion - Add isLoading reactive state to prevent duplicate submissions - Wire the delete button in DeleteAccountScreen to call deleteAccount() - Show a CircularProgressIndicator in the button while deletion is in progress Fixes #758 --- .../delete_account_controller.dart | 37 ++++++++++++++++--- lib/views/screens/delete_account_screen.dart | 25 +++++++++---- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/lib/controllers/delete_account_controller.dart b/lib/controllers/delete_account_controller.dart index 2bcc1393..018e55d2 100644 --- a/lib/controllers/delete_account_controller.dart +++ b/lib/controllers/delete_account_controller.dart @@ -3,22 +3,19 @@ import 'dart:developer'; import 'package:appwrite/appwrite.dart'; import 'package:get/get.dart'; import 'package:resonate/controllers/auth_state_controller.dart'; +import 'package:resonate/routes/app_routes.dart'; import 'package:resonate/services/appwrite_service.dart'; import 'package:resonate/utils/constants.dart'; class DeleteAccountController extends GetxController { RxBool isButtonActive = false.obs; + RxBool isLoading = false.obs; AuthStateController authStateController = Get.put(AuthStateController()); late final Storage storage; late final TablesDB tables; - - // - //------------------------------------------------------------------- - // PLEASE DO NOT TOUCH THIS CODE WITHOUT PERMISSION - - //------------------------------------------------------------------- - // + late final Account account; @override void onInit() { @@ -26,6 +23,7 @@ class DeleteAccountController extends GetxController { storage = AppwriteService.getStorage(); tables = AppwriteService.getTables(); + account = AppwriteService.getAccount(); } Future deleteUserProfilePicture() async { @@ -62,4 +60,31 @@ class DeleteAccountController extends GetxController { log(e.toString()); } } + + /// Permanently removes all user data and blocks the auth account, + /// then redirects to the welcome screen. + Future deleteAccount() async { + try { + isLoading.value = true; + + // Delete all associated user data + await deleteUserProfilePicture(); + await deleteUsernamesCollectionDocument(); + await deleteUsersCollectionDocument(); + + // Block the auth account so the user can no longer log in. + // The Appwrite client SDK does not expose a hard-delete endpoint; + // updateStatus() permanently blocks the account from any access. + await account.updateStatus(); + + // Invalidate all active sessions + await account.deleteSessions(); + + Get.offAllNamed(AppRoutes.welcomeScreen); + } catch (e) { + log(e.toString()); + } finally { + isLoading.value = false; + } + } } diff --git a/lib/views/screens/delete_account_screen.dart b/lib/views/screens/delete_account_screen.dart index 647fc0d3..f74140c7 100644 --- a/lib/views/screens/delete_account_screen.dart +++ b/lib/views/screens/delete_account_screen.dart @@ -90,15 +90,24 @@ class DeleteAccountScreen extends StatelessWidget { disabledForegroundColor: Colors.redAccent.withAlpha(100), disabledBackgroundColor: Colors.redAccent.withAlpha(50), ), - onPressed: (controller.isButtonActive.value) - ? () { - // DO NOT IMPLEMENT THIS WITHOUT PERMISSION - } + onPressed: (controller.isButtonActive.value && + !controller.isLoading.value) + ? () => controller.deleteAccount() : null, - child: Text( - AppLocalizations.of(context)!.iUnderstandDeleteMyAccount, - style: const TextStyle(fontSize: 16), - ), + child: controller.isLoading.value + ? const SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator( + color: Colors.white, + strokeWidth: 2, + ), + ) + : Text( + AppLocalizations.of(context)! + .iUnderstandDeleteMyAccount, + style: const TextStyle(fontSize: 16), + ), ), ), ),