diff --git a/e2e/src/api/specs/shared-link.e2e-spec.ts b/e2e/src/api/specs/shared-link.e2e-spec.ts index d9f8672c66..f56a058529 100644 --- a/e2e/src/api/specs/shared-link.e2e-spec.ts +++ b/e2e/src/api/specs/shared-link.e2e-spec.ts @@ -9,7 +9,7 @@ import { } from '@immich/sdk'; import { createUserDto, uuidDto } from 'src/fixtures'; import { errorDto } from 'src/responses'; -import { app, asBearerAuth, shareUrl, utils } from 'src/utils'; +import { app, asBearerAuth, baseUrl, shareUrl, utils } from 'src/utils'; import request from 'supertest'; import { beforeAll, describe, expect, it } from 'vitest'; @@ -78,6 +78,7 @@ describe('/shared-links', () => { type: SharedLinkType.Album, albumId: metadataAlbum.id, showMetadata: true, + slug: 'metadata-album', }), utils.createSharedLink(user1.accessToken, { type: SharedLinkType.Album, @@ -138,6 +139,17 @@ describe('/shared-links', () => { }); }); + describe('GET /s/:slug', () => { + it('should work for slug auth', async () => { + const resp = await request(baseUrl).get(`/s/${linkWithMetadata.slug}`); + expect(resp.status).toBe(200); + expect(resp.header['content-type']).toContain('text/html'); + expect(resp.text).toContain( + ``, + ); + }); + }); + describe('GET /shared-links', () => { it('should require authentication', async () => { const { status, body } = await request(app).get('/shared-links'); diff --git a/server/src/services/api.service.ts b/server/src/services/api.service.ts index ced74482c2..143b470750 100644 --- a/server/src/services/api.service.ts +++ b/server/src/services/api.service.ts @@ -76,23 +76,36 @@ export class ApiService { let status = 200; let html = index; - const shareMatches = request.url.match(/^\/share\/(.+)$/); - if (shareMatches) { + const defaultDomain = request.host ? `${request.protocol}://${request.host}` : undefined; + + let meta: OpenGraphTags | null = null; + + const shareKey = request.url.match(/^\/share\/(.+)$/); + if (shareKey) { try { - const key = shareMatches[1]; + const key = shareKey[1]; const auth = await this.authService.validateSharedLinkKey(key); - const meta = await this.sharedLinkService.getMetadataTags( - auth, - request.host ? `${request.protocol}://${request.host}` : undefined, - ); - if (meta) { - html = render(index, meta); - } + meta = await this.sharedLinkService.getMetadataTags(auth, defaultDomain); } catch { status = 404; } } + const shareSlug = request.url.match(/^\/s\/(.+)$/); + if (shareSlug) { + try { + const slug = shareSlug[1]; + const auth = await this.authService.validateSharedLinkSlug(slug); + meta = await this.sharedLinkService.getMetadataTags(auth, defaultDomain); + } catch { + status = 404; + } + } + + if (meta) { + html = render(index, meta); + } + res.status(status).type('text/html').header('Cache-Control', 'no-store').send(html); }; }