mirror of
https://github.com/immich-app/immich.git
synced 2026-03-26 20:00:44 +03:00
fix: shared link add to album (#27063)
This commit is contained in:
@@ -169,6 +169,7 @@ export type AuthSharedLink = {
|
||||
id: string;
|
||||
expiresAt: Date | null;
|
||||
userId: string;
|
||||
albumId: string | null;
|
||||
showExif: boolean;
|
||||
allowUpload: boolean;
|
||||
allowDownload: boolean;
|
||||
@@ -357,15 +358,6 @@ export const columns = {
|
||||
authUser: ['user.id', 'user.name', 'user.email', 'user.isAdmin', 'user.quotaUsageInBytes', 'user.quotaSizeInBytes'],
|
||||
authApiKey: ['api_key.id', 'api_key.permissions'],
|
||||
authSession: ['session.id', 'session.updatedAt', 'session.pinExpiresAt', 'session.appVersion'],
|
||||
authSharedLink: [
|
||||
'shared_link.id',
|
||||
'shared_link.userId',
|
||||
'shared_link.expiresAt',
|
||||
'shared_link.showExif',
|
||||
'shared_link.allowUpload',
|
||||
'shared_link.allowDownload',
|
||||
'shared_link.password',
|
||||
],
|
||||
user: userColumns,
|
||||
userWithPrefix: userWithPrefixColumns,
|
||||
userAdmin: [
|
||||
|
||||
@@ -173,6 +173,7 @@ order by
|
||||
select
|
||||
"shared_link"."id",
|
||||
"shared_link"."userId",
|
||||
"shared_link"."albumId",
|
||||
"shared_link"."expiresAt",
|
||||
"shared_link"."showExif",
|
||||
"shared_link"."allowUpload",
|
||||
@@ -211,6 +212,7 @@ where
|
||||
select
|
||||
"shared_link"."id",
|
||||
"shared_link"."userId",
|
||||
"shared_link"."albumId",
|
||||
"shared_link"."expiresAt",
|
||||
"shared_link"."showExif",
|
||||
"shared_link"."allowUpload",
|
||||
|
||||
@@ -330,6 +330,7 @@ export class AlbumRepository {
|
||||
await db
|
||||
.insertInto('album_asset')
|
||||
.values(assetIds.map((assetId) => ({ albumId, assetId })))
|
||||
.onConflict((oc) => oc.doNothing())
|
||||
.execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +202,14 @@ export class SharedLinkRepository {
|
||||
.leftJoin('album', 'album.id', 'shared_link.albumId')
|
||||
.where('album.deletedAt', 'is', null)
|
||||
.select((eb) => [
|
||||
...columns.authSharedLink,
|
||||
'shared_link.id',
|
||||
'shared_link.userId',
|
||||
'shared_link.albumId',
|
||||
'shared_link.expiresAt',
|
||||
'shared_link.showExif',
|
||||
'shared_link.allowUpload',
|
||||
'shared_link.allowDownload',
|
||||
'shared_link.password',
|
||||
jsonObjectFrom(
|
||||
eb.selectFrom('user').select(columns.authUser).whereRef('user.id', '=', 'shared_link.userId'),
|
||||
).as('user'),
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Kysely, sql } from 'kysely';
|
||||
|
||||
export async function up(db: Kysely<any>): Promise<void> {
|
||||
await sql`
|
||||
DELETE FROM "shared_link_asset"
|
||||
USING "shared_link"
|
||||
WHERE "shared_link_asset"."sharedLinkId" = "shared_link"."id" AND "shared_link"."type" = 'ALBUM';
|
||||
`.execute(db);
|
||||
}
|
||||
|
||||
export async function down(): Promise<void> {
|
||||
// noop
|
||||
}
|
||||
@@ -165,6 +165,12 @@ export class AlbumService extends BaseService {
|
||||
}
|
||||
|
||||
async addAssets(auth: AuthDto, id: string, dto: BulkIdsDto): Promise<BulkIdResponseDto[]> {
|
||||
if (auth.sharedLink) {
|
||||
this.logger.deprecate(
|
||||
'Assets uploaded to a shared link are automatically added and calling this endpoint is no longer necessary. It will be removed in the next major release.',
|
||||
);
|
||||
}
|
||||
|
||||
const album = await this.findOrFail(id, { withAssets: false });
|
||||
await this.requireAccess({ auth, permission: Permission.AlbumAssetCreate, ids: [id] });
|
||||
|
||||
@@ -195,6 +201,12 @@ export class AlbumService extends BaseService {
|
||||
}
|
||||
|
||||
async addAssetsToAlbums(auth: AuthDto, dto: AlbumsAddAssetsDto): Promise<AlbumsAddAssetsResponseDto> {
|
||||
if (auth.sharedLink) {
|
||||
this.logger.deprecate(
|
||||
'Assets uploaded to a shared link are automatically added and calling this endpoint is no longer necessary. It will be removed in the next major release.',
|
||||
);
|
||||
}
|
||||
|
||||
const results: AlbumsAddAssetsResponseDto = {
|
||||
success: false,
|
||||
error: BulkIdErrorReason.DUPLICATE,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { BadRequestException, Injectable, InternalServerErrorException, NotFound
|
||||
import { extname } from 'node:path';
|
||||
import sanitize from 'sanitize-filename';
|
||||
import { StorageCore } from 'src/cores/storage.core';
|
||||
import { Asset } from 'src/database';
|
||||
import { Asset, AuthSharedLink } from 'src/database';
|
||||
import {
|
||||
AssetBulkUploadCheckResponseDto,
|
||||
AssetMediaResponseDto,
|
||||
@@ -152,7 +152,7 @@ export class AssetMediaService extends BaseService {
|
||||
const asset = await this.create(auth.user.id, dto, file, sidecarFile);
|
||||
|
||||
if (auth.sharedLink) {
|
||||
await this.sharedLinkRepository.addAssets(auth.sharedLink.id, [asset.id]);
|
||||
await this.addToSharedLink(auth.sharedLink, asset.id);
|
||||
}
|
||||
|
||||
await this.userRepository.updateUsage(auth.user.id, file.size);
|
||||
@@ -326,6 +326,12 @@ export class AssetMediaService extends BaseService {
|
||||
};
|
||||
}
|
||||
|
||||
private async addToSharedLink(sharedLink: AuthSharedLink, assetId: string) {
|
||||
await (sharedLink.albumId
|
||||
? this.albumRepository.addAssetIds(sharedLink.albumId, [assetId])
|
||||
: this.sharedLinkRepository.addAssets(sharedLink.id, [assetId]));
|
||||
}
|
||||
|
||||
private async handleUploadError(
|
||||
error: any,
|
||||
auth: AuthDto,
|
||||
@@ -347,7 +353,7 @@ export class AssetMediaService extends BaseService {
|
||||
}
|
||||
|
||||
if (auth.sharedLink) {
|
||||
await this.sharedLinkRepository.addAssets(auth.sharedLink.id, [duplicateId]);
|
||||
await this.addToSharedLink(auth.sharedLink, duplicateId);
|
||||
}
|
||||
|
||||
return { status: AssetMediaStatus.DUPLICATE, id: duplicateId };
|
||||
|
||||
Reference in New Issue
Block a user