diff --git a/client/src/Pages/StatusPage/Create/index.tsx b/client/src/Pages/StatusPage/Create/index.tsx index f54b981ba..e3b82f554 100644 --- a/client/src/Pages/StatusPage/Create/index.tsx +++ b/client/src/Pages/StatusPage/Create/index.tsx @@ -27,7 +27,6 @@ import { getMonitorTypeLabel } from "@/Types/StatusPage"; import { timezoneOptions } from "@/Utils/timezoneOptions"; import { useNavigate, useParams } from "react-router-dom"; import { mutate } from "swr"; -import axios from "axios"; import { HeaderConfigStatusControls } from "./Components/HeaderConfigStatusControls"; import { ThemePicker } from "./Components/ThemePicker"; import { FormSwitchField } from "@/Components/inputs/forms/FormSwitchField"; @@ -59,7 +58,9 @@ const LogoUploadField = () => { { - field.onChange(file ? { data: file.src, contentType: file.file.type } : null); + field.onChange( + file ? { data: file.src, contentType: file.file.type, file: file.file } : null + ); }} /> ); @@ -204,18 +205,8 @@ const CreateStatusPage = () => { if (data.logo === null) { // Signal to remove the logo fd.append("removeLogo", "true"); - } else if (data.logo?.data && data.logo.data !== "") { - if (data.logo.data.startsWith("blob:")) { - try { - const imageResult = await axios.get(data.logo.data, { - responseType: "blob", - }); - fd.append("logo", imageResult.data); - URL.revokeObjectURL(data.logo.data); - } catch (e) { - logger.error("Failed to fetch logo blob", e instanceof Error ? e : undefined); - } - } + } else if (data.logo?.file) { + fd.append("logo", data.logo.file); } let result; diff --git a/client/src/Validation/statusPage.ts b/client/src/Validation/statusPage.ts index eddde8ab7..08d12cdde 100644 --- a/client/src/Validation/statusPage.ts +++ b/client/src/Validation/statusPage.ts @@ -79,6 +79,7 @@ export const statusPageSchema = z.object({ .object({ data: z.string(), contentType: z.string(), + file: z.instanceof(File).optional(), }) .nullable() .optional() diff --git a/server/src/api/middleware/statusPageDocumentCsp.ts b/server/src/api/middleware/statusPageDocumentCsp.ts index c5175b81d..a04820ebd 100644 --- a/server/src/api/middleware/statusPageDocumentCsp.ts +++ b/server/src/api/middleware/statusPageDocumentCsp.ts @@ -7,7 +7,7 @@ const PUBLIC_STATUS_PAGE_DOCUMENT_PREFIX = "/status/public"; // the status page on top of the global helmet policy, blocking external images, // fonts, and stylesheets from custom CSS while keeping the app's Google Fonts. const STATUS_PAGE_CSP = [ - "img-src 'self' data:", + "img-src 'self' data: blob:", "font-src 'self' data: https://fonts.gstatic.com", "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com", ].join("; "); diff --git a/server/src/app.ts b/server/src/app.ts index 12e552406..181fa6064 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -76,7 +76,7 @@ export const createApp = ({ directives: { upgradeInsecureRequests: null, "script-src": ["'self'", "'unsafe-inline'", "'unsafe-eval'"], - "img-src": ["'self'", "data:", "https://img.shields.io"], + "img-src": ["'self'", "data:", "blob:", "https://img.shields.io"], "object-src": ["'none'"], "base-uri": ["'self'"], },