Merge commit from fork

* fix: advisory

* fix: typo
This commit is contained in:
dicedtomato
2026-03-16 13:13:06 -07:00
committed by GitHub
parent dee86aaa86
commit 842dac2660
4 changed files with 56 additions and 27 deletions

View File

@@ -69,6 +69,7 @@
"fastify-plugin": "^5.1.0",
"fastify-type-provider-zod": "^6.1.0",
"fluent-ffmpeg": "^2.1.3",
"he": "^1.2.0",
"highlight.js": "^11.11.1",
"iron-session": "^8.0.4",
"isomorphic-dompurify": "^2.33.0",
@@ -96,6 +97,7 @@
"@types/archiver": "^7.0.0",
"@types/bytes": "^3.1.5",
"@types/fluent-ffmpeg": "^2.1.28",
"@types/he": "^1.2.3",
"@types/katex": "^0.16.7",
"@types/ms": "^2.1.0",
"@types/multer": "^2.0.0",

17
pnpm-lock.yaml generated
View File

@@ -149,6 +149,9 @@ importers:
fluent-ffmpeg:
specifier: ^2.1.3
version: 2.1.3
he:
specifier: ^1.2.0
version: 1.2.0
highlight.js:
specifier: ^11.11.1
version: 11.11.1
@@ -225,6 +228,9 @@ importers:
'@types/fluent-ffmpeg':
specifier: ^2.1.28
version: 2.1.28
'@types/he':
specifier: ^1.2.3
version: 1.2.3
'@types/katex':
specifier: ^0.16.7
version: 0.16.7
@@ -2067,6 +2073,9 @@ packages:
'@types/hast@3.0.4':
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
'@types/he@1.2.3':
resolution: {integrity: sha512-q67/qwlxblDzEDvzHhVkwc1gzVWxaNxeyHUBF4xElrvjL11O+Ytze+1fGpBHlr/H9myiBUaUXNnNPmBHxxfAcA==}
'@types/http-errors@2.0.5':
resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==}
@@ -3262,6 +3271,10 @@ packages:
hast-util-whitespace@3.0.0:
resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
he@1.2.0:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
hermes-estree@0.25.1:
resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==}
@@ -7467,6 +7480,8 @@ snapshots:
dependencies:
'@types/unist': 3.0.3
'@types/he@1.2.3': {}
'@types/http-errors@2.0.5': {}
'@types/json-schema@7.0.15': {}
@@ -8876,6 +8891,8 @@ snapshots:
dependencies:
'@types/hast': 3.0.4
he@1.2.0: {}
hermes-estree@0.25.1: {}
hermes-parser@0.25.1:

View File

@@ -22,6 +22,7 @@ import { FastifyRequest } from 'fastify';
import { renderToString } from 'react-dom/server';
import { createStaticHandler, createStaticRouter, StaticRouterProvider } from 'react-router-dom';
import { createRoutes } from './routes';
import { stripHtml } from '@/lib/stripHtml';
export const getFile = async (id: string) =>
prisma.file.findFirst({
@@ -166,49 +167,53 @@ export async function render(
const router = createStaticRouter(routes, context);
const html = renderToString(<StaticRouterProvider context={context} router={router} />);
const safeFilename = stripHtml(file.name);
const safeOriginalName = stripHtml(file.originalName || '');
const safeType = stripHtml(file.type || '');
const meta = `
${
user?.view?.embedTitle && user.view.embed
? `<meta property="og:title" content="${
? `<meta property="og:title" content="${stripHtml(
parseString(user.view.embedTitle, {
file: file as unknown as File,
user: user as User,
...metrics,
}) ?? ''
}" />`
}) ?? '',
)}" />`
: ''
}
${
user?.view?.embedDescription && user.view.embed
? `<meta property="og:description" content="${
? `<meta property="og:description" content="${stripHtml(
parseString(user.view.embedDescription, {
file: file as unknown as File,
user: user as User,
...metrics,
}) ?? ''
}" />`
}) ?? '',
)}" />`
: ''
}
${
user?.view?.embedSiteName && user.view.embed
? `<meta property="og:site_name" content="${
? `<meta property="og:site_name" content="${stripHtml(
parseString(user.view.embedSiteName, {
file: file as unknown as File,
user: user as User,
...metrics,
}) ?? ''
}" />`
}) ?? '',
)}" />`
: ''
}
${
user?.view?.embedColor && user.view.embed
? `<meta property="theme-color" content="${
? `<meta property="theme-color" content="${stripHtml(
parseString(user.view.embedColor, {
file: file as unknown as File,
user: user as User,
...metrics,
}) ?? ''
}" />`
}) ?? '',
)}" />`
: ''
}
@@ -216,11 +221,11 @@ export async function render(
file.type?.startsWith('image')
? `
<meta property="og:type" content="image" />
<meta property="og:image" itemProp="image" content="${host}/raw/${file.name}" />
<meta property="og:url" content="${host}/raw/${file.name}" />
<meta property="og:image" itemProp="image" content="${host}/raw/${safeFilename}" />
<meta property="og:url" content="${host}/raw/${safeFilename}" />
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:image" content="${host}/raw/${file.name}" />
<meta property="twitter:title" content="${file.name}" />
<meta property="twitter:image" content="${host}/raw/${safeFilename}" />
<meta property="twitter:title" content="${safeFilename}" />
`
: ''
}
@@ -230,7 +235,7 @@ export async function render(
? `
${file.thumbnail ? `<meta property="og:image" content="${host}/raw/${file.thumbnail.path}" />` : ''}
<meta property="og:type" content="video.other" />
<meta property="og:video:url" content="${host}/raw/${file.name}" />
<meta property="og:video:url" content="${host}/raw/${safeFilename}" />
<meta property="og:video:width" content="1920" />
<meta property="og:video:height" content="1080" />
`
@@ -241,18 +246,18 @@ export async function render(
file.type?.startsWith('audio')
? `
<meta name="twitter:card" content="player" />
<meta name="twitter:player" content="${host}/raw/${file.name}" />
<meta name="twitter:player:stream" content="${host}/raw/${file.name}" />
<meta name="twitter:player:stream:content_type" content="${file.type}" />
<meta name="twitter:title" content="${file.name}" />
<meta name="twitter:player" content="${host}/raw/${safeFilename}" />
<meta name="twitter:player:stream" content="${host}/raw/${safeFilename}" />
<meta name="twitter:player:stream:content_type" content="${safeType}" />
<meta name="twitter:title" content="${safeFilename}" />
<meta name="twitter:player:width" content="720" />
<meta name="twitter:player:height" content="480" />
<meta property="og:type" content="music.song" />
<meta property="og:url" content="${host}/raw/${file.name}" />
<meta property="og:audio" content="${host}/raw/${file.name}" />
<meta property="og:audio:secure_url" content="${host}/raw/${file.name}" />
<meta property="og:audio:type" content="${file.type}" />
<meta property="og:url" content="${host}/raw/${safeFilename}" />
<meta property="og:audio" content="${host}/raw/${safeFilename}" />
<meta property="og:audio:secure_url" content="${host}/raw/${safeFilename}" />
<meta property="og:audio:type" content="${safeType}" />
`
: ''
}
@@ -260,12 +265,12 @@ export async function render(
${
!file.type?.startsWith('video') && !file.type?.startsWith('image')
? `
<meta property="og:url" content="${host}/raw/${file.name}" />
<meta property="og:url" content="${host}/raw/${safeFilename}" />
`
: ''
}
<title>${file.originalName ?? file.name}</title>
<title>${file.originalName ? safeOriginalName : safeFilename}</title>
`;
return {

5
src/lib/stripHtml.ts Normal file
View File

@@ -0,0 +1,5 @@
import he from 'he';
export function stripHtml(html: string): string {
return he.encode(html);
}