Skip to content

Commit 5207475

Browse files
committed
fix(api): ensure all user data is deleted on account deletion
Fixes a critical bug in the `AuthService.deleteAccount` method where only the main user document was being deleted. The previous logic incorrectly assumed a relational `CASCADE` delete behavior. This change adds explicit calls to delete the user's associated documents from the `user_app_settings` and `user_content_preferences` collections, ensuring that no orphaned data is left in the database after an account is deleted.
1 parent 4ce3cc5 commit 5207475

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

lib/src/services/auth_service.dart

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -549,25 +549,29 @@ class AuthService {
549549
/// Throws [NotFoundException] if the user does not exist.
550550
/// Throws [OperationFailedException] for other errors during deletion or cleanup.
551551
Future<void> deleteAccount({required String userId}) async {
552-
// Note: The user record itself is deleted via a CASCADE constraint
553-
// when the corresponding entry in the `users` table is deleted.
554-
// This is because `user_app_settings.user_id` and
555-
// `user_content_preferences.user_id` have `ON DELETE CASCADE`.
556-
// Therefore, we only need to delete the main user record.
557552
try {
558553
// Fetch the user first to get their email if needed for cleanup
559554
final userToDelete = await _userRepository.read(id: userId);
560555
_log.info('Found user ${userToDelete.id} for deletion.');
561556

562-
// 1. Delete the main user record from the `users` table.
563-
// The `ON DELETE CASCADE` constraint on the `user_app_settings` and
564-
// `user_content_preferences` tables will automatically delete the
565-
// associated records in those tables. This also implicitly invalidates
557+
// 1. Explicitly delete associated user data. Unlike relational databases
558+
// with CASCADE constraints, MongoDB requires manual deletion of related
559+
// documents in different collections.
560+
await _userAppSettingsRepository.delete(id: userId, userId: userId);
561+
_log.info('Deleted UserAppSettings for user ${userToDelete.id}.');
562+
563+
await _userContentPreferencesRepository.delete(
564+
id: userId,
565+
userId: userId,
566+
);
567+
_log.info('Deleted UserContentPreferences for user ${userToDelete.id}.');
568+
569+
// 2. Delete the main user record. This also implicitly invalidates
566570
// tokens that rely on user lookup, as the user will no longer exist.
567571
await _userRepository.delete(id: userId);
568572
_log.info('User ${userToDelete.id} deleted from repository.');
569573

570-
// 2. Clear any pending verification codes for this user ID (linking).
574+
// 3. Clear any pending verification codes for this user ID (linking).
571575
try {
572576
await _verificationCodeStorageService.clearLinkCode(userId);
573577
_log.info('Cleared link code for user ${userToDelete.id}.');
@@ -578,7 +582,7 @@ class AuthService {
578582
);
579583
}
580584

581-
// 3. Clear any pending sign-in codes for the user's email (if they had one).
585+
// 4. Clear any pending sign-in codes for the user's email (if they had one).
582586
// The email for anonymous users is a placeholder and not used for sign-in.
583587
if (userToDelete.appRole != AppUserRole.guestUser) {
584588
try {

0 commit comments

Comments
 (0)