Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion server/src/repositories/shared-link.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/postgres';
import _ from 'lodash';
import { InjectKysely } from 'nestjs-kysely';
import { Album, columns } from 'src/database';
import { DummyValue, GenerateSql } from 'src/decorators';
import { ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
import { SharedLinkType } from 'src/enum';
import { DB } from 'src/schema';
import { AssetExifTable } from 'src/schema/tables/asset-exif.table';
Expand Down Expand Up @@ -249,6 +249,20 @@ export class SharedLinkRepository {
await this.db.deleteFrom('shared_link').where('shared_link.id', '=', id).execute();
}

@ChunkedArray({ paramIndex: 1 })
async addAssets(id: string, assetIds: string[]) {
if (assetIds.length === 0) {
return [];
}

return await this.db
.insertInto('shared_link_asset')
.values(assetIds.map((assetId) => ({ assetId, sharedLinkId: id })))
.onConflict((oc) => oc.doNothing())
.returning(['shared_link_asset.assetId'])
.execute();
}

@GenerateSql({ params: [DummyValue.UUID] })
private getSharedLinks(id: string) {
return this.db
Expand Down
9 changes: 9 additions & 0 deletions server/src/services/asset-media.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ 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.userRepository.updateUsage(auth.user.id, file.size);

return { id: asset.id, status: AssetMediaStatus.CREATED };
Expand Down Expand Up @@ -341,6 +345,11 @@ export class AssetMediaService extends BaseService {
this.logger.error(`Error locating duplicate for checksum constraint`);
throw new InternalServerErrorException();
}

if (auth.sharedLink) {
await this.sharedLinkRepository.addAssets(auth.sharedLink.id, [duplicateId]);
}

return { status: AssetMediaStatus.DUPLICATE, id: duplicateId };
}

Expand Down
6 changes: 6 additions & 0 deletions server/src/services/shared-link.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ export class SharedLinkService extends BaseService {
}

async addAssets(auth: AuthDto, id: string, dto: AssetIdsDto): Promise<AssetIdsResponseDto[]> {
if (auth.sharedLink) {
this.logger.deprecate(
'Assets uploaded using shared link authentication are now automatically added to the shared link during upload and in the next major release this endpoint will no longer accept shared link authentication',
);
}

const sharedLink = await this.findOrFail(auth.user.id, id);

if (sharedLink.type !== SharedLinkType.Individual) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader';
import { handleError } from '$lib/utils/handle-error';
import { toTimelineAsset } from '$lib/utils/timeline-util';
import { addSharedLinkAssets, getAssetInfo, type SharedLinkResponseDto } from '@immich/sdk';
import { getAssetInfo, type SharedLinkResponseDto } from '@immich/sdk';
import { IconButton, Logo, toastManager } from '@immich/ui';
import { mdiArrowLeft, mdiDownload, mdiFileImagePlusOutline, mdiSelectAll } from '@mdi/js';
import { t } from 'svelte-i18n';
Expand Down Expand Up @@ -48,21 +48,11 @@

const handleUploadAssets = async (files: File[] = []) => {
try {
let results: (string | undefined)[] = [];
results = await (!files || files.length === 0 || !Array.isArray(files)
await (!files || files.length === 0 || !Array.isArray(files)
? openFileUploadDialog()
: fileUploadHandler({ files }));
const data = await addSharedLinkAssets({
...authManager.params,
id: sharedLink.id,
assetIdsDto: {
assetIds: results.filter((id) => !!id) as string[],
},
});

const added = data.filter((item) => item.success).length;

toastManager.success($t('assets_added_count', { values: { count: added } }));
toastManager.success();
} catch (error) {
handleError(error, $t('errors.unable_to_add_assets_to_shared_link'));
}
Expand Down
Loading