Parcourir la source

fix(server): do not link live photos across users (#2162)

Jason Rasmussen il y a 2 ans
Parent
commit
ec6a7ae97c

+ 12 - 2
server/apps/microservices/src/processors/metadata-extraction.processor.ts

@@ -229,7 +229,12 @@ export class MetadataExtractionProcessor {
       newExif.livePhotoCID = exifData?.MediaGroupUUID || null;
 
       if (newExif.livePhotoCID && !asset.livePhotoVideoId) {
-        const motionAsset = await this.assetCore.findLivePhotoMatch(newExif.livePhotoCID, asset.id, AssetType.VIDEO);
+        const motionAsset = await this.assetCore.findLivePhotoMatch({
+          livePhotoCID: newExif.livePhotoCID,
+          otherAssetId: asset.id,
+          ownerId: asset.ownerId,
+          type: AssetType.VIDEO,
+        });
         if (motionAsset) {
           await this.assetCore.save({ id: asset.id, livePhotoVideoId: motionAsset.id });
           await this.assetCore.save({ id: motionAsset.id, isVisible: false });
@@ -331,7 +336,12 @@ export class MetadataExtractionProcessor {
       newExif.livePhotoCID = exifData?.ContentIdentifier || null;
 
       if (newExif.livePhotoCID) {
-        const photoAsset = await this.assetCore.findLivePhotoMatch(newExif.livePhotoCID, asset.id, AssetType.IMAGE);
+        const photoAsset = await this.assetCore.findLivePhotoMatch({
+          livePhotoCID: newExif.livePhotoCID,
+          ownerId: asset.ownerId,
+          otherAssetId: asset.id,
+          type: AssetType.IMAGE,
+        });
         if (photoAsset) {
           await this.assetCore.save({ id: photoAsset.id, livePhotoVideoId: asset.id });
           await this.assetCore.save({ id: asset.id, isVisible: false });

+ 4 - 4
server/libs/domain/src/asset/asset.core.ts

@@ -1,6 +1,6 @@
-import { AssetEntity, AssetType } from '@app/infra/entities';
+import { AssetEntity } from '@app/infra/entities';
 import { IJobRepository, JobName } from '../job';
-import { AssetSearchOptions, IAssetRepository } from './asset.repository';
+import { AssetSearchOptions, IAssetRepository, LivePhotoSearchOptions } from './asset.repository';
 
 export class AssetCore {
   constructor(private assetRepository: IAssetRepository, private jobRepository: IJobRepository) {}
@@ -18,7 +18,7 @@ export class AssetCore {
     return _asset;
   }
 
-  findLivePhotoMatch(livePhotoCID: string, otherAssetId: string, type: AssetType): Promise<AssetEntity | null> {
-    return this.assetRepository.findLivePhotoMatch(livePhotoCID, otherAssetId, type);
+  findLivePhotoMatch(options: LivePhotoSearchOptions): Promise<AssetEntity | null> {
+    return this.assetRepository.findLivePhotoMatch(options);
   }
 }

+ 8 - 1
server/libs/domain/src/asset/asset.repository.ts

@@ -5,6 +5,13 @@ export interface AssetSearchOptions {
   type?: AssetType;
 }
 
+export interface LivePhotoSearchOptions {
+  ownerId: string;
+  livePhotoCID: string;
+  otherAssetId: string;
+  type: AssetType;
+}
+
 export enum WithoutProperty {
   THUMBNAIL = 'thumbnail',
   ENCODED_VIDEO = 'encoded-video',
@@ -22,5 +29,5 @@ export interface IAssetRepository {
   deleteAll(ownerId: string): Promise<void>;
   getAll(options?: AssetSearchOptions): Promise<AssetEntity[]>;
   save(asset: Partial<AssetEntity>): Promise<AssetEntity>;
-  findLivePhotoMatch(livePhotoCID: string, otherAssetId: string, type: AssetType): Promise<AssetEntity | null>;
+  findLivePhotoMatch(options: LivePhotoSearchOptions): Promise<AssetEntity | null>;
 }

+ 5 - 2
server/libs/infra/src/repositories/asset.repository.ts

@@ -1,4 +1,4 @@
-import { AssetSearchOptions, IAssetRepository, WithoutProperty } from '@app/domain';
+import { AssetSearchOptions, IAssetRepository, LivePhotoSearchOptions, WithoutProperty } from '@app/domain';
 import { Injectable } from '@nestjs/common';
 import { InjectRepository } from '@nestjs/typeorm';
 import { FindOptionsRelations, FindOptionsWhere, In, IsNull, Not, Repository } from 'typeorm';
@@ -52,10 +52,13 @@ export class AssetRepository implements IAssetRepository {
     });
   }
 
-  findLivePhotoMatch(livePhotoCID: string, otherAssetId: string, type: AssetType): Promise<AssetEntity | null> {
+  findLivePhotoMatch(options: LivePhotoSearchOptions): Promise<AssetEntity | null> {
+    const { ownerId, otherAssetId, livePhotoCID, type } = options;
+
     return this.repository.findOne({
       where: {
         id: Not(otherAssetId),
+        ownerId,
         type,
         exifInfo: {
           livePhotoCID,