feat: use request host as default SSR domain (#19485)

fix: hostname and domain confusion

chore: e2e test
This commit is contained in:
bo0tzz 2025-07-01 05:24:44 +02:00 committed by GitHub
parent db0415bbcc
commit 3c6e9e1191
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 15 additions and 4 deletions

View File

@ -117,6 +117,13 @@ describe('/shared-links', () => {
const resp = await request(shareUrl).get(`/${linkWithAssets.key}`); const resp = await request(shareUrl).get(`/${linkWithAssets.key}`);
expect(resp.status).toBe(200); expect(resp.status).toBe(200);
expect(resp.header['content-type']).toContain('text/html'); expect(resp.header['content-type']).toContain('text/html');
expect(resp.text).toContain(`<meta property="og:image" content="http://127.0.0.1:2285`);
});
it('should fall back to my.immich.app og:image meta tag for shared asset if Host header is not present', async () => {
const resp = await request(shareUrl).get(`/${linkWithAssets.key}`).set('Host', '');
expect(resp.status).toBe(200);
expect(resp.header['content-type']).toContain('text/html');
expect(resp.text).toContain(`<meta property="og:image" content="https://my.immich.app`); expect(resp.text).toContain(`<meta property="og:image" content="https://my.immich.app`);
}); });

View File

@ -86,7 +86,10 @@ export class ApiService {
try { try {
const key = shareMatches[1]; const key = shareMatches[1];
const auth = await this.authService.validateSharedLink(key); const auth = await this.authService.validateSharedLink(key);
const meta = await this.sharedLinkService.getMetadataTags(auth); const meta = await this.sharedLinkService.getMetadataTags(
auth,
request.host ? `${request.protocol}://${request.host}` : undefined,
);
if (meta) { if (meta) {
html = render(index, meta); html = render(index, meta);
} }

View File

@ -174,7 +174,7 @@ export class SharedLinkService extends BaseService {
return results; return results;
} }
async getMetadataTags(auth: AuthDto): Promise<null | OpenGraphTags> { async getMetadataTags(auth: AuthDto, defaultDomain?: string): Promise<null | OpenGraphTags> {
if (!auth.sharedLink || auth.sharedLink.password) { if (!auth.sharedLink || auth.sharedLink.password) {
return null; return null;
} }
@ -190,7 +190,7 @@ export class SharedLinkService extends BaseService {
return { return {
title: sharedLink.album ? sharedLink.album.albumName : 'Public Share', title: sharedLink.album ? sharedLink.album.albumName : 'Public Share',
description: sharedLink.description || `${assetCount} shared photos & videos`, description: sharedLink.description || `${assetCount} shared photos & videos`,
imageUrl: new URL(imagePath, getExternalDomain(config.server)).href, imageUrl: new URL(imagePath, getExternalDomain(config.server, defaultDomain)).href,
}; };
} }

View File

@ -44,7 +44,8 @@ export const getMethodNames = (instance: any) => {
return methods; return methods;
}; };
export const getExternalDomain = (server: SystemConfig['server']) => server.externalDomain || `https://my.immich.app`; export const getExternalDomain = (server: SystemConfig['server'], defaultDomain = 'https://my.immich.app') =>
server.externalDomain || defaultDomain;
/** /**
* @returns a list of strings representing the keys of the object in dot notation * @returns a list of strings representing the keys of the object in dot notation