fix: shared link add to album (#27063)

This commit is contained in:
Jason Rasmussen
2026-03-20 14:14:07 -04:00
committed by GitHub
parent 644f705be1
commit 813d684aaa
13 changed files with 230 additions and 22 deletions

View File

@@ -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: [

View File

@@ -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",

View File

@@ -330,6 +330,7 @@ export class AlbumRepository {
await db
.insertInto('album_asset')
.values(assetIds.map((assetId) => ({ albumId, assetId })))
.onConflict((oc) => oc.doNothing())
.execute();
}

View File

@@ -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'),

View File

@@ -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
}

View File

@@ -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,

View File

@@ -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 };