mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	refactor: user delete (#23163)
This commit is contained in:
		
							parent
							
								
									8c27ba3e52
								
							
						
					
					
						commit
						834e52fda6
					
				@ -94,6 +94,9 @@ type EventMap = {
 | 
				
			|||||||
  // user events
 | 
					  // user events
 | 
				
			||||||
  UserSignup: [{ notify: boolean; id: string; password?: string }];
 | 
					  UserSignup: [{ notify: boolean; id: string; password?: string }];
 | 
				
			||||||
  UserCreate: [UserEvent];
 | 
					  UserCreate: [UserEvent];
 | 
				
			||||||
 | 
					  /** user is soft deleted */
 | 
				
			||||||
 | 
					  UserTrash: [UserEvent];
 | 
				
			||||||
 | 
					  /** user is permanently deleted */
 | 
				
			||||||
  UserDelete: [UserEvent];
 | 
					  UserDelete: [UserEvent];
 | 
				
			||||||
  UserRestore: [UserEvent];
 | 
					  UserRestore: [UserEvent];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -421,11 +421,6 @@ export class JobService extends BaseService {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      case JobName.UserDelete: {
 | 
					 | 
				
			||||||
        this.eventRepository.clientBroadcast('on_user_delete', item.data.id);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -202,6 +202,11 @@ export class NotificationService extends BaseService {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @OnEvent({ name: 'UserDelete' })
 | 
				
			||||||
 | 
					  onUserDelete({ id }: ArgOf<'UserDelete'>) {
 | 
				
			||||||
 | 
					    this.eventRepository.clientBroadcast('on_user_delete', id);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @OnEvent({ name: 'AlbumUpdate' })
 | 
					  @OnEvent({ name: 'AlbumUpdate' })
 | 
				
			||||||
  async onAlbumUpdate({ id, recipientId }: ArgOf<'AlbumUpdate'>) {
 | 
					  async onAlbumUpdate({ id, recipientId }: ArgOf<'AlbumUpdate'>) {
 | 
				
			||||||
    await this.jobRepository.removeJob(JobName.NotifyAlbumUpdate, `${id}/${recipientId}`);
 | 
					    await this.jobRepository.removeJob(JobName.NotifyAlbumUpdate, `${id}/${recipientId}`);
 | 
				
			||||||
 | 
				
			|||||||
@ -16,8 +16,8 @@ export class TelemetryService extends BaseService {
 | 
				
			|||||||
    this.telemetryRepository.api.addToGauge(`immich.users.total`, 1);
 | 
					    this.telemetryRepository.api.addToGauge(`immich.users.total`, 1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @OnEvent({ name: 'UserDelete' })
 | 
					  @OnEvent({ name: 'UserTrash' })
 | 
				
			||||||
  onUserDelete() {
 | 
					  onUserTrash() {
 | 
				
			||||||
    this.telemetryRepository.api.addToGauge(`immich.users.total`, -1);
 | 
					    this.telemetryRepository.api.addToGauge(`immich.users.total`, -1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -104,7 +104,7 @@ export class UserAdminService extends BaseService {
 | 
				
			|||||||
    const status = force ? UserStatus.Removing : UserStatus.Deleted;
 | 
					    const status = force ? UserStatus.Removing : UserStatus.Deleted;
 | 
				
			||||||
    const user = await this.userRepository.update(id, { status, deletedAt: new Date() });
 | 
					    const user = await this.userRepository.update(id, { status, deletedAt: new Date() });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await this.eventRepository.emit('UserDelete', user);
 | 
					    await this.eventRepository.emit('UserTrash', user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (force) {
 | 
					    if (force) {
 | 
				
			||||||
      await this.jobRepository.queue({ name: JobName.UserDelete, data: { id: user.id, force } });
 | 
					      await this.jobRepository.queue({ name: JobName.UserDelete, data: { id: user.id, force } });
 | 
				
			||||||
 | 
				
			|||||||
@ -228,17 +228,17 @@ export class UserService extends BaseService {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @OnJob({ name: JobName.UserDelete, queue: QueueName.BackgroundTask })
 | 
					  @OnJob({ name: JobName.UserDelete, queue: QueueName.BackgroundTask })
 | 
				
			||||||
  async handleUserDelete({ id, force }: JobOf<JobName.UserDelete>): Promise<JobStatus> {
 | 
					  async handleUserDelete({ id, force }: JobOf<JobName.UserDelete>) {
 | 
				
			||||||
    const config = await this.getConfig({ withCache: false });
 | 
					    const config = await this.getConfig({ withCache: false });
 | 
				
			||||||
    const user = await this.userRepository.get(id, { withDeleted: true });
 | 
					    const user = await this.userRepository.get(id, { withDeleted: true });
 | 
				
			||||||
    if (!user) {
 | 
					    if (!user) {
 | 
				
			||||||
      return JobStatus.Failed;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // just for extra protection here
 | 
					    // just for extra protection here
 | 
				
			||||||
    if (!force && !this.isReadyForDeletion(user, config.user.deleteDelay)) {
 | 
					    if (!force && !this.isReadyForDeletion(user, config.user.deleteDelay)) {
 | 
				
			||||||
      this.logger.warn(`Skipped user that was not ready for deletion: id=${id}`);
 | 
					      this.logger.warn(`Skipped user that was not ready for deletion: id=${id}`);
 | 
				
			||||||
      return JobStatus.Skipped;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.logger.log(`Deleting user: ${user.id}`);
 | 
					    this.logger.log(`Deleting user: ${user.id}`);
 | 
				
			||||||
@ -260,7 +260,7 @@ export class UserService extends BaseService {
 | 
				
			|||||||
    await this.albumRepository.deleteAll(user.id);
 | 
					    await this.albumRepository.deleteAll(user.id);
 | 
				
			||||||
    await this.userRepository.delete(user, true);
 | 
					    await this.userRepository.delete(user, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return JobStatus.Success;
 | 
					    await this.eventRepository.emit('UserDelete', user);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private isReadyForDeletion(user: { id: string; deletedAt?: Date | null }, deleteDelay: number): boolean {
 | 
					  private isReadyForDeletion(user: { id: string; deletedAt?: Date | null }, deleteDelay: number): boolean {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user