From 9bbef4a97b6c63aae26b971a5da02e3bb22d89d9 Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Fri, 25 Aug 2023 00:03:28 -0400 Subject: [PATCH] refactor(web): shared link key auth (#3855) --- web/src/api/api.ts | 21 ++++++++-- .../components/album-page/album-viewer.svelte | 12 +++--- .../asset-viewer/asset-viewer.svelte | 23 ++++++----- .../asset-viewer/detail-panel.svelte | 13 ++++--- .../asset-viewer/panorama-viewer.svelte | 6 ++- .../asset-viewer/photo-viewer.svelte | 6 +-- .../asset-viewer/video-viewer.svelte | 3 +- .../assets/thumbnail/thumbnail.svelte | 11 +++--- .../actions/download-action.svelte | 5 +-- .../actions/remove-from-shared-link.svelte | 2 +- .../photos-page/asset-date-group.svelte | 4 +- .../components/photos-page/asset-grid.svelte | 8 ++-- .../individual-shared-viewer.svelte | 13 +++---- .../gallery-viewer/gallery-viewer.svelte | 6 +-- web/src/lib/stores/asset-viewing.store.ts | 4 +- web/src/lib/stores/assets.store.ts | 13 +++++-- web/src/lib/utils/asset-utils.ts | 38 ++++++++++--------- web/src/lib/utils/file-uploader.ts | 27 ++++--------- .../(user)/albums/[albumId]/+page.svelte | 2 +- .../share/[key]/photos/[assetId]/+page.svelte | 1 - web/src/routes/+layout.svelte | 5 +++ 21 files changed, 115 insertions(+), 108 deletions(-) diff --git a/web/src/api/api.ts b/web/src/api/api.ts index 3478daf2a..866b78ba3 100644 --- a/web/src/api/api.ts +++ b/web/src/api/api.ts @@ -39,6 +39,11 @@ export class ImmichApi { public userApi: UserApi; private config: Configuration; + private key?: string; + + get isSharedLink() { + return !!this.key; + } constructor(params: ConfigurationParameters) { this.config = new Configuration(params); @@ -73,6 +78,14 @@ export class ImmichApi { return (this.config.basePath || BASE_PATH) + toPathString(url); } + public setKey(key: string) { + this.key = key; + } + + public getKey(): string | undefined { + return this.key; + } + public setAccessToken(accessToken: string) { this.config.accessToken = accessToken; } @@ -85,14 +98,14 @@ export class ImmichApi { this.config.basePath = baseUrl; } - public getAssetFileUrl(...[assetId, isThumb, isWeb, key]: ApiParams) { + public getAssetFileUrl(...[assetId, isThumb, isWeb]: ApiParams) { const path = `/asset/file/${assetId}`; - return this.createUrl(path, { isThumb, isWeb, key }); + return this.createUrl(path, { isThumb, isWeb, key: this.getKey() }); } - public getAssetThumbnailUrl(...[assetId, format, key]: ApiParams) { + public getAssetThumbnailUrl(...[assetId, format]: ApiParams) { const path = `/asset/thumbnail/${assetId}`; - return this.createUrl(path, { format, key }); + return this.createUrl(path, { format, key: this.getKey() }); } public getProfileImageUrl(...[userId]: ApiParams) { diff --git a/web/src/lib/components/album-page/album-viewer.svelte b/web/src/lib/components/album-page/album-viewer.svelte index 2597bf8bf..918da85ba 100644 --- a/web/src/lib/components/album-page/album-viewer.svelte +++ b/web/src/lib/components/album-page/album-viewer.svelte @@ -27,13 +27,13 @@ let { isViewing: showAssetViewer } = assetViewingStore; - const assetStore = new AssetStore({ size: TimeBucketSize.Month, albumId: album.id, key: sharedLink.key }); + const assetStore = new AssetStore({ size: TimeBucketSize.Month, albumId: album.id }); const assetInteractionStore = createAssetInteractionStore(); const { isMultiSelectState, selectedAssets } = assetInteractionStore; dragAndDropFilesStore.subscribe((value) => { if (value.isDragging && value.files.length > 0) { - fileUploadHandler(value.files, album.id, sharedLink.key); + fileUploadHandler(value.files, album.id); dragAndDropFilesStore.set({ isDragging: false, files: [] }); } }); @@ -88,7 +88,7 @@ }; const downloadAlbum = async () => { - await downloadArchive(`${album.albumName}.zip`, { albumId: album.id }, sharedLink.key); + await downloadArchive(`${album.albumName}.zip`, { albumId: album.id }); }; @@ -97,7 +97,7 @@ assetInteractionStore.clearMultiselect()}> {#if sharedLink.allowDownload} - + {/if} {:else} @@ -117,7 +117,7 @@ {#if sharedLink.allowUpload} openFileUploadDialog(album.id, sharedLink.key)} + on:click={() => openFileUploadDialog(album.id)} logo={FileImagePlusOutline} /> {/if} @@ -135,7 +135,7 @@
- +

{ + if (api.isSharedLink) { + return; + } + try { const { data } = await api.albumApi.getAllAlbums({ assetId: asset.id }); appearsInAlbums = data; @@ -84,7 +87,9 @@ switch (key) { case 'a': case 'A': - if (shiftKey) toggleArchive(); + if (shiftKey) { + toggleArchive(); + } return; case 'ArrowLeft': navigateAssetBackward(); @@ -94,7 +99,9 @@ return; case 'd': case 'D': - if (shiftKey) downloadFile(asset, publicSharedKey); + if (shiftKey) { + downloadFile(asset); + } return; case 'Delete': isShowDeleteConfirmation = true; @@ -272,7 +279,7 @@ showDownloadButton={shouldShowDownloadButton} on:goBack={closeViewer} on:showDetail={showDetailInfoHandler} - on:download={() => downloadFile(asset, publicSharedKey)} + on:download={() => downloadFile(asset)} on:delete={() => (isShowDeleteConfirmation = true)} on:favorite={toggleFavorite} on:addToAlbum={() => openAlbumPicker(false)} @@ -304,7 +311,6 @@ {:else if asset.type === AssetTypeEnum.Image} {#if shouldPlayMotionPhoto && asset.livePhotoVideoId} (shouldPlayMotionPhoto = false)} @@ -312,12 +318,12 @@ {:else if asset.exifInfo?.projectionType === ProjectionType.EQUIRECTANGULAR || asset.originalPath .toLowerCase() .endsWith('.insp')} - + {:else} - + {/if} {:else} - + {/if} {/key} @@ -338,7 +344,6 @@ ($isShowDetail = false)} on:close-viewer={handleCloseViewer} on:description-focus-in={disableKeyDownEvent} diff --git a/web/src/lib/components/asset-viewer/detail-panel.svelte b/web/src/lib/components/asset-viewer/detail-panel.svelte index f4b9565e9..8d066b492 100644 --- a/web/src/lib/components/asset-viewer/detail-panel.svelte +++ b/web/src/lib/components/asset-viewer/detail-panel.svelte @@ -9,21 +9,20 @@ import ImageOutline from 'svelte-material-icons/ImageOutline.svelte'; import MapMarkerOutline from 'svelte-material-icons/MapMarkerOutline.svelte'; import { createEventDispatcher } from 'svelte'; - import { AssetResponseDto, AlbumResponseDto, api, ThumbnailFormat, SharedLinkResponseDto } from '@api'; + import { AssetResponseDto, AlbumResponseDto, api, ThumbnailFormat } from '@api'; import { asByteUnitString } from '../../utils/byte-units'; import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte'; import { getAssetFilename } from '$lib/utils/asset-utils'; export let asset: AssetResponseDto; export let albums: AlbumResponseDto[] = []; - export let sharedLink: SharedLinkResponseDto | undefined = undefined; let textarea: HTMLTextAreaElement; let description: string; $: { // Get latest description from server - if (asset.id && !sharedLink) { + if (asset.id && !api.isSharedLink) { api.assetApi.getAssetById({ id: asset.id }).then((res) => { people = res.data?.people || []; textarea.value = res.data?.exifInfo?.description || ''; @@ -91,13 +90,15 @@

Info

-
+