mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 10:37:11 -04: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