From 6ba17bb86f386d95aea86c7eae6e5ae8f66523d4 Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Tue, 14 Apr 2026 20:58:02 -0400 Subject: [PATCH] refactor!: remove my shared link dto (#27023) refactor!: remove deprecated shared link apis --- .../specs/server/api/shared-link.e2e-spec.ts | 14 +++- mobile/openapi/lib/api/albums_api.dart | 42 ++--------- mobile/openapi/lib/api/shared_links_api.dart | 45 ++---------- open-api/immich-openapi-specs.json | 70 +------------------ open-api/typescript-sdk/src/fetch-client.ts | 35 +++------- server/src/controllers/album.controller.ts | 4 +- .../src/controllers/shared-link.controller.ts | 19 +---- server/src/dtos/shared-link.dto.ts | 8 --- server/src/services/album.service.spec.ts | 59 ---------------- server/src/services/album.service.ts | 12 ---- server/src/services/shared-link.service.ts | 7 -- server/src/utils/access.ts | 5 -- 12 files changed, 39 insertions(+), 281 deletions(-) diff --git a/e2e/src/specs/server/api/shared-link.e2e-spec.ts b/e2e/src/specs/server/api/shared-link.e2e-spec.ts index 00c455d6cb..1d069d0f54 100644 --- a/e2e/src/specs/server/api/shared-link.e2e-spec.ts +++ b/e2e/src/specs/server/api/shared-link.e2e-spec.ts @@ -243,9 +243,21 @@ describe('/shared-links', () => { }); it('should get data for correct password protected link', async () => { + const response = await request(app) + .post('/shared-links/login') + .send({ password: 'foo' }) + .query({ key: linkWithPassword.key }); + + expect(response.status).toBe(201); + + const cookies = response.get('Set-Cookie') ?? []; + expect(cookies).toHaveLength(1); + expect(cookies[0]).toContain('immich_shared_link_token'); + const { status, body } = await request(app) .get('/shared-links/me') - .query({ key: linkWithPassword.key, password: 'foo' }); + .query({ key: linkWithPassword.key }) + .set('Cookie', cookies); expect(status).toBe(200); expect(body).toEqual( diff --git a/mobile/openapi/lib/api/albums_api.dart b/mobile/openapi/lib/api/albums_api.dart index e2db95b9e0..000125ac7b 100644 --- a/mobile/openapi/lib/api/albums_api.dart +++ b/mobile/openapi/lib/api/albums_api.dart @@ -27,11 +27,7 @@ class AlbumsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - /// - /// * [String] key: - /// - /// * [String] slug: - Future addAssetsToAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto, { String? key, String? slug, }) async { + Future addAssetsToAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto,) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}/assets' .replaceAll('{id}', id); @@ -43,13 +39,6 @@ class AlbumsApi { final headerParams = {}; final formParams = {}; - if (key != null) { - queryParams.addAll(_queryParams('', 'key', key)); - } - if (slug != null) { - queryParams.addAll(_queryParams('', 'slug', slug)); - } - const contentTypes = ['application/json']; @@ -73,12 +62,8 @@ class AlbumsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - /// - /// * [String] key: - /// - /// * [String] slug: - Future?> addAssetsToAlbum(String id, BulkIdsDto bulkIdsDto, { String? key, String? slug, }) async { - final response = await addAssetsToAlbumWithHttpInfo(id, bulkIdsDto, key: key, slug: slug, ); + Future?> addAssetsToAlbum(String id, BulkIdsDto bulkIdsDto,) async { + final response = await addAssetsToAlbumWithHttpInfo(id, bulkIdsDto,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -104,11 +89,7 @@ class AlbumsApi { /// Parameters: /// /// * [AlbumsAddAssetsDto] albumsAddAssetsDto (required): - /// - /// * [String] key: - /// - /// * [String] slug: - Future addAssetsToAlbumsWithHttpInfo(AlbumsAddAssetsDto albumsAddAssetsDto, { String? key, String? slug, }) async { + Future addAssetsToAlbumsWithHttpInfo(AlbumsAddAssetsDto albumsAddAssetsDto,) async { // ignore: prefer_const_declarations final apiPath = r'/albums/assets'; @@ -119,13 +100,6 @@ class AlbumsApi { final headerParams = {}; final formParams = {}; - if (key != null) { - queryParams.addAll(_queryParams('', 'key', key)); - } - if (slug != null) { - queryParams.addAll(_queryParams('', 'slug', slug)); - } - const contentTypes = ['application/json']; @@ -147,12 +121,8 @@ class AlbumsApi { /// Parameters: /// /// * [AlbumsAddAssetsDto] albumsAddAssetsDto (required): - /// - /// * [String] key: - /// - /// * [String] slug: - Future addAssetsToAlbums(AlbumsAddAssetsDto albumsAddAssetsDto, { String? key, String? slug, }) async { - final response = await addAssetsToAlbumsWithHttpInfo(albumsAddAssetsDto, key: key, slug: slug, ); + Future addAssetsToAlbums(AlbumsAddAssetsDto albumsAddAssetsDto,) async { + final response = await addAssetsToAlbumsWithHttpInfo(albumsAddAssetsDto,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/shared_links_api.dart b/mobile/openapi/lib/api/shared_links_api.dart index 084662ace8..4750442287 100644 --- a/mobile/openapi/lib/api/shared_links_api.dart +++ b/mobile/openapi/lib/api/shared_links_api.dart @@ -27,11 +27,7 @@ class SharedLinksApi { /// * [String] id (required): /// /// * [AssetIdsDto] assetIdsDto (required): - /// - /// * [String] key: - /// - /// * [String] slug: - Future addSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto, { String? key, String? slug, }) async { + Future addSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto,) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/{id}/assets' .replaceAll('{id}', id); @@ -43,13 +39,6 @@ class SharedLinksApi { final headerParams = {}; final formParams = {}; - if (key != null) { - queryParams.addAll(_queryParams('', 'key', key)); - } - if (slug != null) { - queryParams.addAll(_queryParams('', 'slug', slug)); - } - const contentTypes = ['application/json']; @@ -73,12 +62,8 @@ class SharedLinksApi { /// * [String] id (required): /// /// * [AssetIdsDto] assetIdsDto (required): - /// - /// * [String] key: - /// - /// * [String] slug: - Future?> addSharedLinkAssets(String id, AssetIdsDto assetIdsDto, { String? key, String? slug, }) async { - final response = await addSharedLinkAssetsWithHttpInfo(id, assetIdsDto, key: key, slug: slug, ); + Future?> addSharedLinkAssets(String id, AssetIdsDto assetIdsDto,) async { + final response = await addSharedLinkAssetsWithHttpInfo(id, assetIdsDto,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -235,14 +220,8 @@ class SharedLinksApi { /// /// * [String] key: /// - /// * [String] password: - /// Link password - /// /// * [String] slug: - /// - /// * [String] token: - /// Access token - Future getMySharedLinkWithHttpInfo({ String? key, String? password, String? slug, String? token, }) async { + Future getMySharedLinkWithHttpInfo({ String? key, String? slug, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/me'; @@ -256,15 +235,9 @@ class SharedLinksApi { if (key != null) { queryParams.addAll(_queryParams('', 'key', key)); } - if (password != null) { - queryParams.addAll(_queryParams('', 'password', password)); - } if (slug != null) { queryParams.addAll(_queryParams('', 'slug', slug)); } - if (token != null) { - queryParams.addAll(_queryParams('', 'token', token)); - } const contentTypes = []; @@ -288,15 +261,9 @@ class SharedLinksApi { /// /// * [String] key: /// - /// * [String] password: - /// Link password - /// /// * [String] slug: - /// - /// * [String] token: - /// Access token - Future getMySharedLink({ String? key, String? password, String? slug, String? token, }) async { - final response = await getMySharedLinkWithHttpInfo( key: key, password: password, slug: slug, token: token, ); + Future getMySharedLink({ String? key, String? slug, }) async { + final response = await getMySharedLinkWithHttpInfo( key: key, slug: slug, ); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 4ab8a1d584..bc855058c2 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -1768,24 +1768,7 @@ "put": { "description": "Send a list of asset IDs and album IDs to add each asset to each album.", "operationId": "addAssetsToAlbums", - "parameters": [ - { - "name": "key", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "slug", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - } - ], + "parameters": [], "requestBody": { "content": { "application/json": { @@ -2184,22 +2167,6 @@ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$", "type": "string" } - }, - { - "name": "key", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "slug", - "required": false, - "in": "query", - "schema": { - "type": "string" - } } ], "requestBody": { @@ -11427,15 +11394,6 @@ "type": "string" } }, - { - "name": "password", - "required": false, - "in": "query", - "description": "Link password", - "schema": { - "type": "string" - } - }, { "name": "slug", "required": false, @@ -11443,15 +11401,6 @@ "schema": { "type": "string" } - }, - { - "name": "token", - "required": false, - "in": "query", - "description": "Access token", - "schema": { - "type": "string" - } } ], "responses": { @@ -11766,22 +11715,6 @@ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$", "type": "string" } - }, - { - "name": "key", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "slug", - "required": false, - "in": "query", - "schema": { - "type": "string" - } } ], "requestBody": { @@ -11838,6 +11771,7 @@ "state": "Stable" } ], + "x-immich-permission": "sharedLink.update", "x-immich-state": "Stable" } }, diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index 6bb17f6834..520948b820 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -3684,18 +3684,13 @@ export function createAlbum({ createAlbumDto }: { /** * Add assets to albums */ -export function addAssetsToAlbums({ key, slug, albumsAddAssetsDto }: { - key?: string; - slug?: string; +export function addAssetsToAlbums({ albumsAddAssetsDto }: { albumsAddAssetsDto: AlbumsAddAssetsDto; }, opts?: Oazapfts.RequestOpts) { return oazapfts.ok(oazapfts.fetchJson<{ status: 200; data: AlbumsAddAssetsResponseDto; - }>(`/albums/assets${QS.query(QS.explode({ - key, - slug - }))}`, oazapfts.json({ + }>("/albums/assets", oazapfts.json({ ...opts, method: "PUT", body: albumsAddAssetsDto @@ -3778,19 +3773,14 @@ export function removeAssetFromAlbum({ id, bulkIdsDto }: { /** * Add assets to an album */ -export function addAssetsToAlbum({ id, key, slug, bulkIdsDto }: { +export function addAssetsToAlbum({ id, bulkIdsDto }: { id: string; - key?: string; - slug?: string; bulkIdsDto: BulkIdsDto; }, opts?: Oazapfts.RequestOpts) { return oazapfts.ok(oazapfts.fetchJson<{ status: 200; data: BulkIdResponseDto[]; - }>(`/albums/${encodeURIComponent(id)}/assets${QS.query(QS.explode({ - key, - slug - }))}`, oazapfts.json({ + }>(`/albums/${encodeURIComponent(id)}/assets`, oazapfts.json({ ...opts, method: "PUT", body: bulkIdsDto @@ -5906,20 +5896,16 @@ export function sharedLinkLogin({ key, slug, sharedLinkLoginDto }: { /** * Retrieve current shared link */ -export function getMySharedLink({ key, password, slug, token }: { +export function getMySharedLink({ key, slug }: { key?: string; - password?: string; slug?: string; - token?: string; }, opts?: Oazapfts.RequestOpts) { return oazapfts.ok(oazapfts.fetchJson<{ status: 200; data: SharedLinkResponseDto; }>(`/shared-links/me${QS.query(QS.explode({ key, - password, - slug, - token + slug }))}`, { ...opts })); @@ -5983,19 +5969,14 @@ export function removeSharedLinkAssets({ id, assetIdsDto }: { /** * Add assets to a shared link */ -export function addSharedLinkAssets({ id, key, slug, assetIdsDto }: { +export function addSharedLinkAssets({ id, assetIdsDto }: { id: string; - key?: string; - slug?: string; assetIdsDto: AssetIdsDto; }, opts?: Oazapfts.RequestOpts) { return oazapfts.ok(oazapfts.fetchJson<{ status: 200; data: AssetIdsResponseDto[]; - }>(`/shared-links/${encodeURIComponent(id)}/assets${QS.query(QS.explode({ - key, - slug - }))}`, oazapfts.json({ + }>(`/shared-links/${encodeURIComponent(id)}/assets`, oazapfts.json({ ...opts, method: "PUT", body: assetIdsDto diff --git a/server/src/controllers/album.controller.ts b/server/src/controllers/album.controller.ts index dad70257a7..df326a395f 100644 --- a/server/src/controllers/album.controller.ts +++ b/server/src/controllers/album.controller.ts @@ -103,7 +103,7 @@ export class AlbumController { } @Put(':id/assets') - @Authenticated({ permission: Permission.AlbumAssetCreate, sharedLink: true }) + @Authenticated({ permission: Permission.AlbumAssetCreate }) @Endpoint({ summary: 'Add assets to an album', description: 'Add multiple assets to a specific album by its ID.', @@ -118,7 +118,7 @@ export class AlbumController { } @Put('assets') - @Authenticated({ permission: Permission.AlbumAssetCreate, sharedLink: true }) + @Authenticated({ permission: Permission.AlbumAssetCreate }) @Endpoint({ summary: 'Add assets to albums', description: 'Send a list of asset IDs and album IDs to add each asset to each album.', diff --git a/server/src/controllers/shared-link.controller.ts b/server/src/controllers/shared-link.controller.ts index c7ba589a9f..b3a8dd9f59 100644 --- a/server/src/controllers/shared-link.controller.ts +++ b/server/src/controllers/shared-link.controller.ts @@ -23,7 +23,6 @@ import { SharedLinkCreateDto, SharedLinkEditDto, SharedLinkLoginDto, - SharedLinkPasswordDto, SharedLinkResponseDto, SharedLinkSearchDto, } from 'src/dtos/shared-link.dto'; @@ -96,21 +95,7 @@ export class SharedLinkController { description: 'Retrieve the current shared link associated with authentication method.', history: new HistoryBuilder().added('v1').beta('v1').stable('v2'), }) - async getMySharedLink( - @Auth() auth: AuthDto, - @Query() dto: SharedLinkPasswordDto, - @Req() req: Request, - @Res({ passthrough: true }) res: Response, - @GetLoginDetails() loginDetails: LoginDetails, - ): Promise { - if (dto.password) { - this.logger.deprecate( - 'Passing shared link password via query parameters is deprecated and will be removed in the next major release. Please use POST /shared-links/login instead.', - ); - - return this.sharedLinkLogin(auth, { password: dto.password }, req, res, loginDetails); - } - + getMySharedLink(@Auth() auth: AuthDto, @Req() req: Request): Promise { return this.service.getMine(auth, getAuthTokens(req.cookies)); } @@ -164,7 +149,7 @@ export class SharedLinkController { } @Put(':id/assets') - @Authenticated({ sharedLink: true }) + @Authenticated({ permission: Permission.SharedLinkUpdate }) @Endpoint({ summary: 'Add assets to a shared link', description: diff --git a/server/src/dtos/shared-link.dto.ts b/server/src/dtos/shared-link.dto.ts index 7dcec034dc..95f52dd24d 100644 --- a/server/src/dtos/shared-link.dto.ts +++ b/server/src/dtos/shared-link.dto.ts @@ -57,13 +57,6 @@ const SharedLinkLoginSchema = z }) .meta({ id: 'SharedLinkLoginDto' }); -const SharedLinkPasswordSchema = z - .object({ - password: z.string().optional().describe('Link password'), - token: z.string().optional().describe('Access token'), - }) - .meta({ id: 'SharedLinkPasswordDto' }); - const SharedLinkResponseSchema = z .object({ id: z.string().describe('Shared link ID'), @@ -96,7 +89,6 @@ export class SharedLinkSearchDto extends createZodDto(SharedLinkSearchSchema) {} export class SharedLinkCreateDto extends createZodDto(SharedLinkCreateSchema) {} export class SharedLinkEditDto extends createZodDto(SharedLinkEditSchema) {} export class SharedLinkLoginDto extends createZodDto(SharedLinkLoginSchema) {} -export class SharedLinkPasswordDto extends createZodDto(SharedLinkPasswordSchema) {} export class SharedLinkResponseDto extends createZodDto(SharedLinkResponseSchema) {} export function mapSharedLink(sharedLink: SharedLink, options: { stripAssetMetadata: boolean }): SharedLinkResponseDto { diff --git a/server/src/services/album.service.spec.ts b/server/src/services/album.service.spec.ts index 47646d0c6d..d24786fbb6 100644 --- a/server/src/services/album.service.spec.ts +++ b/server/src/services/album.service.spec.ts @@ -717,31 +717,6 @@ describe(AlbumService.name, () => { expect(mocks.album.update).not.toHaveBeenCalled(); }); - it('should allow a shared link user to add assets', async () => { - const album = AlbumFactory.create(); - const [asset1, asset2, asset3] = [AssetFactory.create(), AssetFactory.create(), AssetFactory.create()]; - const auth = AuthFactory.from(album.owner).sharedLink({ allowUpload: true, userId: album.ownerId }).build(); - mocks.access.album.checkSharedLinkAccess.mockResolvedValue(new Set([album.id])); - mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([asset1.id, asset2.id, asset3.id])); - mocks.album.getById.mockResolvedValue(getForAlbum(album)); - mocks.album.getAssetIds.mockResolvedValueOnce(new Set()); - - await expect(sut.addAssets(auth, album.id, { ids: [asset1.id, asset2.id, asset3.id] })).resolves.toEqual([ - { success: true, id: asset1.id }, - { success: true, id: asset2.id }, - { success: true, id: asset3.id }, - ]); - - expect(mocks.album.update).toHaveBeenCalledWith(album.id, { - id: album.id, - updatedAt: expect.any(Date), - albumThumbnailAssetId: asset1.id, - }); - expect(mocks.album.addAssetIds).toHaveBeenCalledWith(album.id, [asset1.id, asset2.id, asset3.id]); - - expect(mocks.access.album.checkSharedLinkAccess).toHaveBeenCalledWith(auth.sharedLink?.id, new Set([album.id])); - }); - it('should allow adding assets shared via partner sharing', async () => { const album = AlbumFactory.create(); const asset = AssetFactory.create(); @@ -964,40 +939,6 @@ describe(AlbumService.name, () => { expect(mocks.album.update).not.toHaveBeenCalled(); }); - it('should not allow a shared link user to add assets to multiple albums', async () => { - const album1 = AlbumFactory.create(); - const album2 = AlbumFactory.create(); - const [asset1, asset2, asset3] = [AssetFactory.create(), AssetFactory.create(), AssetFactory.create()]; - mocks.access.album.checkSharedLinkAccess.mockResolvedValueOnce(new Set([album1.id])); - mocks.access.asset.checkOwnerAccess.mockResolvedValue(new Set([asset1.id, asset2.id, asset3.id])); - mocks.album.getById.mockResolvedValueOnce(getForAlbum(album1)).mockResolvedValueOnce(getForAlbum(album2)); - mocks.album.getAssetIds.mockResolvedValueOnce(new Set()).mockResolvedValueOnce(new Set()); - - const auth = AuthFactory.from(album1.owner).sharedLink({ allowUpload: true }).build(); - await expect( - sut.addAssetsToAlbums(auth, { - albumIds: [album1.id, album2.id], - assetIds: [asset1.id, asset2.id, asset3.id], - }), - ).resolves.toEqual({ success: true, error: undefined }); - - expect(mocks.album.update).toHaveBeenCalledTimes(1); - expect(mocks.album.update).toHaveBeenNthCalledWith(1, album1.id, { - id: album1.id, - updatedAt: expect.any(Date), - albumThumbnailAssetId: asset1.id, - }); - expect(mocks.album.addAssetIdsToAlbums).toHaveBeenCalledWith([ - { albumId: album1.id, assetId: asset1.id }, - { albumId: album1.id, assetId: asset2.id }, - { albumId: album1.id, assetId: asset3.id }, - ]); - expect(mocks.access.album.checkSharedLinkAccess).toHaveBeenCalledWith( - auth.sharedLink?.id, - new Set([album1.id, album2.id]), - ); - }); - it('should allow adding assets shared via partner sharing', async () => { const user = UserFactory.create(); const album1 = AlbumFactory.create(); diff --git a/server/src/services/album.service.ts b/server/src/services/album.service.ts index 547ec63bf8..24b9b165c9 100644 --- a/server/src/services/album.service.ts +++ b/server/src/services/album.service.ts @@ -165,12 +165,6 @@ export class AlbumService extends BaseService { } async addAssets(auth: AuthDto, id: string, dto: BulkIdsDto): Promise { - 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] }); @@ -201,12 +195,6 @@ export class AlbumService extends BaseService { } async addAssetsToAlbums(auth: AuthDto, dto: AlbumsAddAssetsDto): Promise { - 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, diff --git a/server/src/services/shared-link.service.ts b/server/src/services/shared-link.service.ts index 26b15031ee..31c50b7c2c 100644 --- a/server/src/services/shared-link.service.ts +++ b/server/src/services/shared-link.service.ts @@ -150,14 +150,7 @@ export class SharedLinkService extends BaseService { } async addAssets(auth: AuthDto, id: string, dto: AssetIdsDto): Promise { - 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) { throw new BadRequestException('Invalid shared link type'); } diff --git a/server/src/utils/access.ts b/server/src/utils/access.ts index 21e8bdd66e..b8e7733772 100644 --- a/server/src/utils/access.ts +++ b/server/src/utils/access.ts @@ -79,11 +79,6 @@ const checkSharedLinkAccess = async ( return sharedLink.allowUpload ? ids : new Set(); } - case Permission.AssetShare: { - // TODO: fix this to not use sharedLink.userId for access control - return await access.asset.checkOwnerAccess(sharedLink.userId, ids, false); - } - case Permission.AlbumRead: { return await access.album.checkSharedLinkAccess(sharedLinkId, ids); }