mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 10:37:11 -04:00 
			
		
		
		
	refactor(server): partner ids (#10321)
This commit is contained in:
		
							parent
							
								
									c896fe393f
								
							
						
					
					
						commit
						78f600ebce
					
				| @ -39,6 +39,7 @@ import { ILoggerRepository } from 'src/interfaces/logger.interface'; | ||||
| import { IPartnerRepository } from 'src/interfaces/partner.interface'; | ||||
| import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; | ||||
| import { IUserRepository } from 'src/interfaces/user.interface'; | ||||
| import { getMyPartnerIds } from 'src/utils/asset.util'; | ||||
| import { usePagination } from 'src/utils/pagination'; | ||||
| 
 | ||||
| export class AssetService { | ||||
| @ -62,18 +63,16 @@ export class AssetService { | ||||
|   } | ||||
| 
 | ||||
|   async getMemoryLane(auth: AuthDto, dto: MemoryLaneDto): Promise<MemoryLaneResponseDto[]> { | ||||
|     const currentYear = new Date().getFullYear(); | ||||
| 
 | ||||
|     // get partners id
 | ||||
|     const userIds: string[] = [auth.user.id]; | ||||
|     const partners = await this.partnerRepository.getAll(auth.user.id); | ||||
|     const partnersIds = partners | ||||
|       .filter((partner) => partner.sharedBy && partner.inTimeline) | ||||
|       .map((partner) => partner.sharedById); | ||||
|     userIds.push(...partnersIds); | ||||
|     const partnerIds = await getMyPartnerIds({ | ||||
|       userId: auth.user.id, | ||||
|       repository: this.partnerRepository, | ||||
|       timelineEnabled: true, | ||||
|     }); | ||||
|     const userIds = [auth.user.id, ...partnerIds]; | ||||
| 
 | ||||
|     const assets = await this.assetRepository.getByDayOfYear(userIds, dto); | ||||
|     const groups: Record<number, AssetEntity[]> = {}; | ||||
|     const currentYear = new Date().getFullYear(); | ||||
|     for (const asset of assets) { | ||||
|       const yearsAgo = currentYear - asset.localDateTime.getFullYear(); | ||||
|       if (!groups[yearsAgo]) { | ||||
|  | ||||
| @ -7,6 +7,7 @@ import { ILoggerRepository } from 'src/interfaces/logger.interface'; | ||||
| import { IMapRepository } from 'src/interfaces/map.interface'; | ||||
| import { IPartnerRepository } from 'src/interfaces/partner.interface'; | ||||
| import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; | ||||
| import { getMyPartnerIds } from 'src/utils/asset.util'; | ||||
| 
 | ||||
| export class MapService { | ||||
|   private configCore: SystemConfigCore; | ||||
| @ -23,14 +24,10 @@ export class MapService { | ||||
|   } | ||||
| 
 | ||||
|   async getMapMarkers(auth: AuthDto, options: MapMarkerDto): Promise<MapMarkerResponseDto[]> { | ||||
|     const userIds: string[] = [auth.user.id]; | ||||
|     // TODO convert to SQL join
 | ||||
|     const userIds = [auth.user.id]; | ||||
|     if (options.withPartners) { | ||||
|       const partners = await this.partnerRepository.getAll(auth.user.id); | ||||
|       const partnersIds = partners | ||||
|         .filter((partner) => partner.sharedBy && partner.sharedWith && partner.sharedById != auth.user.id) | ||||
|         .map((partner) => partner.sharedById); | ||||
|       userIds.push(...partnersIds); | ||||
|       const partnerIds = await getMyPartnerIds({ userId: auth.user.id, repository: this.partnerRepository }); | ||||
|       userIds.push(...partnerIds); | ||||
|     } | ||||
| 
 | ||||
|     // TODO convert to SQL join
 | ||||
|  | ||||
| @ -24,6 +24,7 @@ import { IPartnerRepository } from 'src/interfaces/partner.interface'; | ||||
| import { IPersonRepository } from 'src/interfaces/person.interface'; | ||||
| import { ISearchRepository, SearchExploreItem } from 'src/interfaces/search.interface'; | ||||
| import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface'; | ||||
| import { getMyPartnerIds } from 'src/utils/asset.util'; | ||||
| import { isSmartSearchEnabled } from 'src/utils/misc'; | ||||
| 
 | ||||
| @Injectable() | ||||
| @ -140,13 +141,12 @@ export class SearchService { | ||||
|   } | ||||
| 
 | ||||
|   private async getUserIdsToSearch(auth: AuthDto): Promise<string[]> { | ||||
|     const userIds: string[] = [auth.user.id]; | ||||
|     const partners = await this.partnerRepository.getAll(auth.user.id); | ||||
|     const partnersIds = partners | ||||
|       .filter((partner) => partner.sharedBy && partner.inTimeline) | ||||
|       .map((partner) => partner.sharedById); | ||||
|     userIds.push(...partnersIds); | ||||
|     return userIds; | ||||
|     const partnerIds = await getMyPartnerIds({ | ||||
|       userId: auth.user.id, | ||||
|       repository: this.partnerRepository, | ||||
|       timelineEnabled: true, | ||||
|     }); | ||||
|     return [auth.user.id, ...partnerIds]; | ||||
|   } | ||||
| 
 | ||||
|   private mapResponse(assets: AssetEntity[], nextPage: string | null): SearchResponseDto { | ||||
|  | ||||
| @ -10,6 +10,7 @@ import { IAccessRepository } from 'src/interfaces/access.interface'; | ||||
| import { IAssetRepository } from 'src/interfaces/asset.interface'; | ||||
| import { IAuditRepository } from 'src/interfaces/audit.interface'; | ||||
| import { IPartnerRepository } from 'src/interfaces/partner.interface'; | ||||
| import { getMyPartnerIds } from 'src/utils/asset.util'; | ||||
| import { setIsEqual } from 'src/utils/set'; | ||||
| 
 | ||||
| const FULL_SYNC = { needsFullSync: true, deleted: [], upserted: [] }; | ||||
| @ -46,11 +47,9 @@ export class SyncService { | ||||
|       return FULL_SYNC; | ||||
|     } | ||||
| 
 | ||||
|     const authUserId = auth.user.id; | ||||
| 
 | ||||
|     // app does not have the correct partners synced
 | ||||
|     const partner = await this.partnerRepository.getAll(authUserId); | ||||
|     const userIds = [authUserId, ...partner.filter((p) => p.sharedWithId == auth.user.id).map((p) => p.sharedById)]; | ||||
|     const partnerIds = await getMyPartnerIds({ userId: auth.user.id, repository: this.partnerRepository }); | ||||
|     const userIds = [auth.user.id, ...partnerIds]; | ||||
|     if (!setIsEqual(new Set(userIds), new Set(dto.userIds))) { | ||||
|       return FULL_SYNC; | ||||
|     } | ||||
| @ -81,7 +80,7 @@ export class SyncService { | ||||
|             auth, | ||||
|             stripMetadata: false, | ||||
|             // ignore stacks for non partner users
 | ||||
|             withStack: a.ownerId === authUserId, | ||||
|             withStack: a.ownerId === auth.user.id, | ||||
|           }), | ||||
|         ), | ||||
|       deleted, | ||||
|  | ||||
| @ -6,6 +6,7 @@ import { TimeBucketAssetDto, TimeBucketDto, TimeBucketResponseDto } from 'src/dt | ||||
| import { IAccessRepository } from 'src/interfaces/access.interface'; | ||||
| import { IAssetRepository, TimeBucketOptions } from 'src/interfaces/asset.interface'; | ||||
| import { IPartnerRepository } from 'src/interfaces/partner.interface'; | ||||
| import { getMyPartnerIds } from 'src/utils/asset.util'; | ||||
| 
 | ||||
| export class TimelineService { | ||||
|   private accessCore: AccessCore; | ||||
| @ -43,14 +44,9 @@ export class TimelineService { | ||||
| 
 | ||||
|     if (userId) { | ||||
|       userIds = [userId]; | ||||
| 
 | ||||
|       if (dto.withPartners) { | ||||
|         const partners = await this.partnerRepository.getAll(auth.user.id); | ||||
|         const partnersIds = partners | ||||
|           .filter((partner) => partner.sharedBy && partner.sharedWith && partner.inTimeline) | ||||
|           .map((partner) => partner.sharedById); | ||||
| 
 | ||||
|         userIds.push(...partnersIds); | ||||
|         const partnerIds = await getMyPartnerIds({ userId: auth.user.id, repository: this.partnerRepository }); | ||||
|         userIds.push(...partnerIds); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -2,6 +2,7 @@ import { AccessCore, Permission } from 'src/cores/access.core'; | ||||
| import { BulkIdErrorReason, BulkIdResponseDto } from 'src/dtos/asset-ids.response.dto'; | ||||
| import { AuthDto } from 'src/dtos/auth.dto'; | ||||
| import { IAccessRepository } from 'src/interfaces/access.interface'; | ||||
| import { IPartnerRepository } from 'src/interfaces/partner.interface'; | ||||
| import { setDifference, setUnion } from 'src/utils/set'; | ||||
| 
 | ||||
| export interface IBulkAsset { | ||||
| @ -91,3 +92,33 @@ export const removeAssets = async ( | ||||
| 
 | ||||
|   return results; | ||||
| }; | ||||
| 
 | ||||
| export type PartnerIdOptions = { | ||||
|   userId: string; | ||||
|   repository: IPartnerRepository; | ||||
|   /** only include partners with `inTimeline: true` */ | ||||
|   timelineEnabled?: boolean; | ||||
| }; | ||||
| export const getMyPartnerIds = async ({ userId, repository, timelineEnabled }: PartnerIdOptions) => { | ||||
|   const partnerIds = new Set<string>(); | ||||
|   const partners = await repository.getAll(userId); | ||||
|   for (const partner of partners) { | ||||
|     // ignore deleted users
 | ||||
|     if (!partner.sharedBy || !partner.sharedWith) { | ||||
|       continue; | ||||
|     } | ||||
| 
 | ||||
|     // wrong direction
 | ||||
|     if (partner.sharedWithId !== userId) { | ||||
|       continue; | ||||
|     } | ||||
| 
 | ||||
|     if (timelineEnabled && !partner.inTimeline) { | ||||
|       continue; | ||||
|     } | ||||
| 
 | ||||
|     partnerIds.add(partner.sharedById); | ||||
|   } | ||||
| 
 | ||||
|   return [...partnerIds]; | ||||
| }; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user