mirror of
https://github.com/immich-app/immich.git
synced 2026-05-25 00:52:31 -04:00
fix: remove stray migration
This commit is contained in:
@@ -461,8 +461,52 @@ select
|
||||
"asset_face".*
|
||||
from
|
||||
"asset_face"
|
||||
inner join "person" on "asset_face"."faceClusterId" = "person"."faceClusterId"
|
||||
and "person"."id" = $1
|
||||
where
|
||||
"asset_face"."faceClusterId" = $1
|
||||
"asset_face"."assetId" in (
|
||||
select
|
||||
"asset"."id"
|
||||
from
|
||||
"asset"
|
||||
where
|
||||
(
|
||||
"asset"."ownerId" = "person"."ownerId"
|
||||
or exists (
|
||||
select
|
||||
from
|
||||
"partner"
|
||||
where
|
||||
"partner"."sharedById" = "asset"."ownerId"
|
||||
and "partner"."sharedWithId" = "person"."ownerId"
|
||||
and (
|
||||
$2 = any ("partner"."permissions")
|
||||
or "partner"."permissions" @> $3
|
||||
)
|
||||
)
|
||||
or exists (
|
||||
select
|
||||
from
|
||||
"album_asset"
|
||||
inner join "album_user" on "album_user"."albumId" = "album_asset"."albumId"
|
||||
and "album_user"."userId" = "person"."ownerId"
|
||||
where
|
||||
"album_asset"."assetId" = "asset"."id"
|
||||
and "album_user"."albumId" in (
|
||||
select
|
||||
"album_user"."albumId"
|
||||
from
|
||||
"album_user"
|
||||
where
|
||||
"album_user"."userId" = "asset"."ownerId"
|
||||
and (
|
||||
$4 = any ("album_user"."permissions")
|
||||
or "album_user"."permissions" @> $5
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
and "asset_face"."deletedAt" is null
|
||||
and "asset_face"."isVisible" is true
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
SelectQueryBuilder,
|
||||
ShallowDehydrateObject,
|
||||
sql,
|
||||
StringReference,
|
||||
Updateable,
|
||||
UpdateResult,
|
||||
} from 'kysely';
|
||||
@@ -215,6 +216,52 @@ export const hasAssetPermissions =
|
||||
),
|
||||
]);
|
||||
|
||||
export const hasAssetPermissionsRef = <T extends keyof DB>(
|
||||
eb: ExpressionBuilder<DB, 'asset'>,
|
||||
userIdRef: StringReference<DB, 'asset' | T>,
|
||||
permissions: SharingPermission[],
|
||||
ignoreTimelineVisibility: boolean = false,
|
||||
) =>
|
||||
eb.or([
|
||||
eb('asset.ownerId', '=', eb.ref(userIdRef as never)),
|
||||
eb.exists(
|
||||
eb
|
||||
.selectFrom('partner')
|
||||
.whereRef('partner.sharedById', '=', 'asset.ownerId')
|
||||
.whereRef('partner.sharedWithId', '=', userIdRef as never)
|
||||
.where((eb) =>
|
||||
eb.or([
|
||||
eb(eb.val(SharingPermission.All), '=', eb.fn.any('partner.permissions')),
|
||||
eb('partner.permissions', '@>', eb.val(permissions)),
|
||||
]),
|
||||
)
|
||||
.$if(!ignoreTimelineVisibility, (qb) => qb.where('partner.inTimeline', '=', true)),
|
||||
),
|
||||
eb.exists(
|
||||
eb
|
||||
.selectFrom('album_asset')
|
||||
.whereRef('album_asset.assetId', '=', 'asset.id')
|
||||
.innerJoin('album_user', (join) =>
|
||||
join
|
||||
.onRef('album_user.albumId', '=', 'album_asset.albumId')
|
||||
.onRef('album_user.userId', '=', userIdRef as never),
|
||||
)
|
||||
.$if(!ignoreTimelineVisibility, (qb) => qb.where('album_user.inTimeline', '=', true))
|
||||
.where('album_user.albumId', 'in', (eb) =>
|
||||
eb
|
||||
.selectFrom('album_user')
|
||||
.select('album_user.albumId')
|
||||
.whereRef('album_user.userId', '=', 'asset.ownerId')
|
||||
.where((eb) =>
|
||||
eb.or([
|
||||
eb(eb.val(SharingPermission.All), '=', eb.fn.any('album_user.permissions')),
|
||||
eb('album_user.permissions', '@>', eb.val(permissions)),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
]);
|
||||
|
||||
@Injectable()
|
||||
export class AssetRepository {
|
||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { InjectKysely } from 'nestjs-kysely';
|
||||
import { AssetFace } from 'src/database';
|
||||
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
|
||||
import { AssetFileType, AssetVisibility, SharingPermission, SourceType } from 'src/enum';
|
||||
import { hasAssetPermissions } from 'src/repositories/asset.repository';
|
||||
import { hasAssetPermissions, hasAssetPermissionsRef } from 'src/repositories/asset.repository';
|
||||
import { DB } from 'src/schema';
|
||||
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
||||
import { FaceSearchTable } from 'src/schema/tables/face-search.table';
|
||||
@@ -557,7 +557,10 @@ export class PersonRepository {
|
||||
join.onRef('asset_face.faceClusterId', '=', 'person.faceClusterId').on('person.id', '=', personId),
|
||||
)
|
||||
.where('asset_face.assetId', 'in', (eb) =>
|
||||
eb.selectFrom('asset').select('asset.id').whereRef('asset.ownerId', '=', 'person.ownerId'),
|
||||
eb
|
||||
.selectFrom('asset')
|
||||
.select('asset.id')
|
||||
.where((eb) => hasAssetPermissionsRef(eb, 'person.ownerId', [SharingPermission.AssetRead], true)),
|
||||
)
|
||||
.where('asset_face.deletedAt', 'is', null)
|
||||
.where('asset_face.isVisible', 'is', true)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import e from 'express';
|
||||
import { Insertable, Updateable } from 'kysely';
|
||||
import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants';
|
||||
import { Person } from 'src/database';
|
||||
@@ -557,6 +556,7 @@ export class PersonService extends BaseService {
|
||||
this.logger.warn(`Face ${id} does not have an embedding`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (face.asset.ownerId === userId) {
|
||||
continue;
|
||||
}
|
||||
@@ -566,7 +566,7 @@ export class PersonService extends BaseService {
|
||||
userIds: [face.asset.ownerId],
|
||||
embedding: face.faceSearch.embedding,
|
||||
maxDistance: machineLearning.facialRecognition.maxDistance,
|
||||
numResults: 10,
|
||||
numResults: 100,
|
||||
hasPerson: true,
|
||||
minBirthDate: new Date(face.asset.fileCreatedAt),
|
||||
});
|
||||
@@ -600,7 +600,12 @@ export class PersonService extends BaseService {
|
||||
});
|
||||
|
||||
const match = matches.find((match) => match.faceClusterId);
|
||||
if (match && match.faceClusterId && face.asset.ownerId !== match.ownerId) {
|
||||
if (
|
||||
match &&
|
||||
match.faceClusterId &&
|
||||
face.asset.ownerId !== match.ownerId &&
|
||||
matches.length >= machineLearning.facialRecognition.minFaces
|
||||
) {
|
||||
// TODO should probably be a DB constraint?
|
||||
const people = await this.personRepository.getByFaceClusterId(match.faceClusterId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user