mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
parent
b5bed02300
commit
7b269d1638
4 changed files with 38 additions and 50 deletions
46
pnpm-lock.yaml
generated
46
pnpm-lock.yaml
generated
|
|
@ -553,9 +553,6 @@ importers:
|
||||||
sanitize-filename:
|
sanitize-filename:
|
||||||
specifier: ^1.6.3
|
specifier: ^1.6.3
|
||||||
version: 1.6.4
|
version: 1.6.4
|
||||||
sanitize-html:
|
|
||||||
specifier: ^2.14.0
|
|
||||||
version: 2.17.2
|
|
||||||
semver:
|
semver:
|
||||||
specifier: ^7.6.2
|
specifier: ^7.6.2
|
||||||
version: 7.7.4
|
version: 7.7.4
|
||||||
|
|
@ -659,9 +656,6 @@ importers:
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^19.0.0
|
specifier: ^19.0.0
|
||||||
version: 19.2.14
|
version: 19.2.14
|
||||||
'@types/sanitize-html':
|
|
||||||
specifier: ^2.13.0
|
|
||||||
version: 2.16.1
|
|
||||||
'@types/semver':
|
'@types/semver':
|
||||||
specifier: ^7.5.8
|
specifier: ^7.5.8
|
||||||
version: 7.7.1
|
version: 7.7.1
|
||||||
|
|
@ -5167,9 +5161,6 @@ packages:
|
||||||
'@types/retry@0.12.2':
|
'@types/retry@0.12.2':
|
||||||
resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==}
|
resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==}
|
||||||
|
|
||||||
'@types/sanitize-html@2.16.1':
|
|
||||||
resolution: {integrity: sha512-n9wjs8bCOTyN/ynwD8s/nTcTreIHB1vf31vhLMGqUPNHaweKC4/fAl4Dj+hUlCTKYgm4P3k83fmiFfzkZ6sgMA==}
|
|
||||||
|
|
||||||
'@types/sax@1.2.7':
|
'@types/sax@1.2.7':
|
||||||
resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
|
resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
|
||||||
|
|
||||||
|
|
@ -7971,9 +7962,6 @@ packages:
|
||||||
webpack:
|
webpack:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
htmlparser2@10.1.0:
|
|
||||||
resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==}
|
|
||||||
|
|
||||||
htmlparser2@6.1.0:
|
htmlparser2@6.1.0:
|
||||||
resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
|
resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
|
||||||
|
|
||||||
|
|
@ -8303,10 +8291,6 @@ packages:
|
||||||
resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
|
resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
is-plain-object@5.0.0:
|
|
||||||
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
|
|
||||||
is-potential-custom-element-name@1.0.1:
|
is-potential-custom-element-name@1.0.1:
|
||||||
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
||||||
|
|
||||||
|
|
@ -9692,9 +9676,6 @@ packages:
|
||||||
parse-numeric-range@1.3.0:
|
parse-numeric-range@1.3.0:
|
||||||
resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==}
|
resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==}
|
||||||
|
|
||||||
parse-srcset@1.0.2:
|
|
||||||
resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==}
|
|
||||||
|
|
||||||
parse5-htmlparser2-tree-adapter@7.1.0:
|
parse5-htmlparser2-tree-adapter@7.1.0:
|
||||||
resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==}
|
resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==}
|
||||||
|
|
||||||
|
|
@ -10892,9 +10873,6 @@ packages:
|
||||||
sanitize-filename@1.6.4:
|
sanitize-filename@1.6.4:
|
||||||
resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==}
|
resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==}
|
||||||
|
|
||||||
sanitize-html@2.17.2:
|
|
||||||
resolution: {integrity: sha512-EnffJUl46VE9uvZ0XeWzObHLurClLlT12gsOk1cHyP2Ol1P0BnBnsXmShlBmWVJM+dKieQI68R0tsPY5m/B+Jg==}
|
|
||||||
|
|
||||||
sass@1.97.1:
|
sass@1.97.1:
|
||||||
resolution: {integrity: sha512-uf6HoO8fy6ClsrShvMgaKUn14f2EHQLQRtpsZZLeU/Mv0Q1K5P0+x2uvH6Cub39TVVbWNSrraUhDAoFph6vh0A==}
|
resolution: {integrity: sha512-uf6HoO8fy6ClsrShvMgaKUn14f2EHQLQRtpsZZLeU/Mv0Q1K5P0+x2uvH6Cub39TVVbWNSrraUhDAoFph6vh0A==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
|
|
@ -17459,10 +17437,6 @@ snapshots:
|
||||||
|
|
||||||
'@types/retry@0.12.2': {}
|
'@types/retry@0.12.2': {}
|
||||||
|
|
||||||
'@types/sanitize-html@2.16.1':
|
|
||||||
dependencies:
|
|
||||||
htmlparser2: 10.1.0
|
|
||||||
|
|
||||||
'@types/sax@1.2.7':
|
'@types/sax@1.2.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 24.12.2
|
'@types/node': 24.12.2
|
||||||
|
|
@ -20865,13 +20839,6 @@ snapshots:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
webpack: 5.104.1
|
webpack: 5.104.1
|
||||||
|
|
||||||
htmlparser2@10.1.0:
|
|
||||||
dependencies:
|
|
||||||
domelementtype: 2.3.0
|
|
||||||
domhandler: 5.0.3
|
|
||||||
domutils: 3.2.2
|
|
||||||
entities: 7.0.1
|
|
||||||
|
|
||||||
htmlparser2@6.1.0:
|
htmlparser2@6.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype: 2.3.0
|
domelementtype: 2.3.0
|
||||||
|
|
@ -21200,8 +21167,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
isobject: 3.0.1
|
isobject: 3.0.1
|
||||||
|
|
||||||
is-plain-object@5.0.0: {}
|
|
||||||
|
|
||||||
is-potential-custom-element-name@1.0.1:
|
is-potential-custom-element-name@1.0.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
@ -22933,8 +22898,6 @@ snapshots:
|
||||||
|
|
||||||
parse-numeric-range@1.3.0: {}
|
parse-numeric-range@1.3.0: {}
|
||||||
|
|
||||||
parse-srcset@1.0.2: {}
|
|
||||||
|
|
||||||
parse5-htmlparser2-tree-adapter@7.1.0:
|
parse5-htmlparser2-tree-adapter@7.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
domhandler: 5.0.3
|
domhandler: 5.0.3
|
||||||
|
|
@ -24278,15 +24241,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
truncate-utf8-bytes: 1.0.2
|
truncate-utf8-bytes: 1.0.2
|
||||||
|
|
||||||
sanitize-html@2.17.2:
|
|
||||||
dependencies:
|
|
||||||
deepmerge: 4.3.1
|
|
||||||
escape-string-regexp: 4.0.0
|
|
||||||
htmlparser2: 10.1.0
|
|
||||||
is-plain-object: 5.0.0
|
|
||||||
parse-srcset: 1.0.2
|
|
||||||
postcss: 8.5.8
|
|
||||||
|
|
||||||
sass@1.97.1:
|
sass@1.97.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar: 4.0.3
|
chokidar: 4.0.3
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,6 @@
|
||||||
"reflect-metadata": "^0.2.0",
|
"reflect-metadata": "^0.2.0",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"sanitize-filename": "^1.6.3",
|
"sanitize-filename": "^1.6.3",
|
||||||
"sanitize-html": "^2.14.0",
|
|
||||||
"semver": "^7.6.2",
|
"semver": "^7.6.2",
|
||||||
"sharp": "^0.34.5",
|
"sharp": "^0.34.5",
|
||||||
"sirv": "^3.0.0",
|
"sirv": "^3.0.0",
|
||||||
|
|
@ -147,7 +146,6 @@
|
||||||
"@types/picomatch": "^4.0.0",
|
"@types/picomatch": "^4.0.0",
|
||||||
"@types/pngjs": "^6.0.5",
|
"@types/pngjs": "^6.0.5",
|
||||||
"@types/react": "^19.0.0",
|
"@types/react": "^19.0.0",
|
||||||
"@types/sanitize-html": "^2.13.0",
|
|
||||||
"@types/semver": "^7.5.8",
|
"@types/semver": "^7.5.8",
|
||||||
"@types/supertest": "^7.0.0",
|
"@types/supertest": "^7.0.0",
|
||||||
"@types/ua-parser-js": "^0.7.36",
|
"@types/ua-parser-js": "^0.7.36",
|
||||||
|
|
|
||||||
36
server/src/services/api.service.spec.ts
Normal file
36
server/src/services/api.service.spec.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { ApiService, render } from 'src/services/api.service';
|
||||||
|
|
||||||
|
describe(ApiService.name, () => {
|
||||||
|
describe('render', () => {
|
||||||
|
it('should correctly render open graph tags', () => {
|
||||||
|
const output = render('<!-- metadata:tags -->', {
|
||||||
|
title: 'title',
|
||||||
|
description: 'description',
|
||||||
|
imageUrl: 'https://demo.immich.app/api/assets/123',
|
||||||
|
});
|
||||||
|
expect(output).toContain('<meta property="og:title" content="title" />');
|
||||||
|
expect(output).toContain('<meta property="og:description" content="description" />');
|
||||||
|
expect(output).toContain('<meta property="og:image" content="https://demo.immich.app/api/assets/123" />');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should escape html tags', () => {
|
||||||
|
expect(
|
||||||
|
render('<!-- metadata:tags -->', {
|
||||||
|
title: "<script>console.log('hello')</script>Test",
|
||||||
|
description: 'description',
|
||||||
|
}),
|
||||||
|
).toContain(
|
||||||
|
'<meta property="og:title" content="<script>console.log('hello')</script>Test" />',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should escape quotes', () => {
|
||||||
|
expect(
|
||||||
|
render('<!-- metadata:tags -->', {
|
||||||
|
title: `0;url=https://example.com" http-equiv="refresh`,
|
||||||
|
description: 'description',
|
||||||
|
}),
|
||||||
|
).toContain('<meta property="og:title" content="0;url=https://example.com" http-equiv="refresh" />');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Injectable, NotAcceptableException } from '@nestjs/common';
|
import { Injectable, NotAcceptableException } from '@nestjs/common';
|
||||||
import { NextFunction, Request, Response } from 'express';
|
import { NextFunction, Request, Response } from 'express';
|
||||||
|
import { escape } from 'lodash';
|
||||||
import { readFileSync } from 'node:fs';
|
import { readFileSync } from 'node:fs';
|
||||||
import sanitizeHtml from 'sanitize-html';
|
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { AuthService } from 'src/services/auth.service';
|
import { AuthService } from 'src/services/auth.service';
|
||||||
|
|
@ -10,7 +10,7 @@ import { OpenGraphTags } from 'src/utils/misc';
|
||||||
|
|
||||||
export const render = (index: string, meta: OpenGraphTags) => {
|
export const render = (index: string, meta: OpenGraphTags) => {
|
||||||
const [title, description, imageUrl] = [meta.title, meta.description, meta.imageUrl].map((item) =>
|
const [title, description, imageUrl] = [meta.title, meta.description, meta.imageUrl].map((item) =>
|
||||||
item ? sanitizeHtml(item, { allowedTags: [] }) : '',
|
item ? escape(item) : '',
|
||||||
);
|
);
|
||||||
|
|
||||||
const tags = `
|
const tags = `
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue