Sfoglia il codice sorgente

fix(server): fk constraint violation when updating to 1.46 with deleted users and albums (#1716)

Fixes #1715
Zack Pollard 2 anni fa
parent
commit
dab74662e9

+ 19 - 2
server/apps/microservices/src/microservices.module.ts

@@ -1,5 +1,14 @@
 import { immichAppConfig } from '@app/common/config';
-import { AssetEntity, ExifEntity, SmartInfoEntity, UserEntity, APIKeyEntity, InfraModule } from '@app/infra';
+import {
+  AssetEntity,
+  ExifEntity,
+  SmartInfoEntity,
+  UserEntity,
+  APIKeyEntity,
+  InfraModule,
+  UserTokenEntity,
+  AlbumEntity,
+} from '@app/infra';
 import { StorageModule } from '@app/storage';
 import { Module } from '@nestjs/common';
 import { ConfigModule } from '@nestjs/config';
@@ -23,7 +32,15 @@ import { DomainModule } from '@app/domain';
     DomainModule.register({
       imports: [InfraModule],
     }),
-    TypeOrmModule.forFeature([UserEntity, ExifEntity, AssetEntity, SmartInfoEntity, APIKeyEntity]),
+    TypeOrmModule.forFeature([
+      UserEntity,
+      ExifEntity,
+      AssetEntity,
+      SmartInfoEntity,
+      APIKeyEntity,
+      UserTokenEntity,
+      AlbumEntity,
+    ]),
     StorageModule,
     CommunicationModule,
   ],

+ 17 - 1
server/apps/microservices/src/processors/user-deletion.processor.ts

@@ -1,5 +1,5 @@
 import { APP_UPLOAD_LOCATION, userUtils } from '@app/common';
-import { APIKeyEntity, AssetEntity, UserEntity } from '@app/infra';
+import { AlbumEntity, APIKeyEntity, AssetEntity, UserEntity, UserTokenEntity } from '@app/infra';
 import { QueueName, JobName } from '@app/domain';
 import { IUserDeletionJob } from '@app/domain';
 import { Process, Processor } from '@nestjs/bull';
@@ -23,6 +23,12 @@ export class UserDeletionProcessor {
 
     @InjectRepository(APIKeyEntity)
     private apiKeyRepository: Repository<APIKeyEntity>,
+
+    @InjectRepository(UserTokenEntity)
+    private userTokenRepository: Repository<UserTokenEntity>,
+
+    @InjectRepository(AlbumEntity)
+    private albumRepository: Repository<AlbumEntity>,
   ) {}
 
   @Process(JobName.USER_DELETION)
@@ -44,6 +50,16 @@ export class UserDeletionProcessor {
       fs.rmSync(userAssetDir, { recursive: true, force: true });
 
       this.logger.warn(`Removing user from database: ${user.id}`);
+      const userTokens = await this.userTokenRepository.find({
+        where: { user: { id: user.id } },
+        relations: { user: true },
+        withDeleted: true,
+      });
+      await this.userTokenRepository.remove(userTokens);
+
+      const albums = await this.albumRepository.find({ where: { ownerId: user.id } });
+      await this.albumRepository.remove(albums);
+
       await this.apiKeyRepository.delete({ userId: user.id });
       await this.assetRepository.delete({ userId: user.id });
       await this.userRepository.remove(user);

+ 1 - 0
server/libs/infra/src/db/migrations/1675701909594-AddAlbumUserForeignKeyConstraint.ts

@@ -4,6 +4,7 @@ export class AddAlbumUserForeignKeyConstraint1675701909594 implements MigrationI
   name = 'AddAlbumUserForeignKeyConstraint1675701909594';
 
   public async up(queryRunner: QueryRunner): Promise<void> {
+    await queryRunner.query(`DELETE FROM "albums" WHERE "ownerId"::uuid NOT IN (SELECT id FROM "users") `)
     await queryRunner.query(`ALTER TABLE "albums" ALTER COLUMN "ownerId" TYPE varchar(36)`);
     await queryRunner.query(`ALTER TABLE "albums" ALTER COLUMN "ownerId" TYPE uuid using "ownerId"::uuid`);
     await queryRunner.query(