From d8eec36d98b653dd4fafd03cc8404a323c49a092 Mon Sep 17 00:00:00 2001 From: ajnart Date: Mon, 24 Aug 2026 10:27:28 +0200 Subject: [PATCH] fix: address demo mock review --- packages/api/src/router/widgets/anchor-notes.ts | 12 +++++++++++- .../api/src/router/widgets/archive-team-warrior.ts | 2 +- packages/api/src/router/widgets/coolify.ts | 2 +- packages/api/src/router/widgets/firewall.ts | 7 ++++++- packages/api/src/router/widgets/speedtest-tracker.ts | 2 +- packages/api/src/router/widgets/tracearr.ts | 2 +- packages/api/src/router/widgets/traefik.ts | 2 +- packages/api/src/router/widgets/umami.ts | 2 +- packages/api/src/router/widgets/uptime-kuma.ts | 2 +- packages/api/src/router/widgets/vpn.ts | 2 +- packages/api/src/router/widgets/wud.ts | 6 ++++-- packages/integrations/src/mock/widget-data.ts | 1 + packages/widgets/src/iframe/component.spec.ts | 2 ++ 13 files changed, 32 insertions(+), 12 deletions(-) diff --git a/packages/api/src/router/widgets/anchor-notes.ts b/packages/api/src/router/widgets/anchor-notes.ts index 5266e455a..790c957c5 100644 --- a/packages/api/src/router/widgets/anchor-notes.ts +++ b/packages/api/src/router/widgets/anchor-notes.ts @@ -20,6 +20,12 @@ const noteIdInput = z.object({ const logger = createLogger({ module: "anchorNotesRouter" }); +const assertMockNoteExists = (noteId: string) => { + if (noteId === mockWidgetData.anchorNote.id) return; + + throw new TRPCError({ code: "NOT_FOUND", message: "Note not found" }); +}; + const isJsonDeltaString = (value: string) => { try { const parsed: unknown = JSON.parse(value); @@ -70,7 +76,10 @@ export const anchorNotesRouter = createTRPCRouter({ .concat(createOneIntegrationMiddleware("query", "anchor", "mock")) .input(noteIdInput) .query(async ({ ctx, input }) => { - if (ctx.integration.kind === "mock") return mockWidgetData.anchorNote; + if (ctx.integration.kind === "mock") { + assertMockNoteExists(input.noteId); + return mockWidgetData.anchorNote; + } const handler = anchorNoteRequestHandler.handler( { ...ctx.integration, kind: "anchor" }, @@ -90,6 +99,7 @@ export const anchorNotesRouter = createTRPCRouter({ input.content !== undefined && normalizedContent !== undefined && input.content !== normalizedContent; if (ctx.integration.kind === "mock") { + assertMockNoteExists(input.noteId); return { ...mockWidgetData.anchorNote, ...(input.title !== undefined ? { title: input.title } : {}), diff --git a/packages/api/src/router/widgets/archive-team-warrior.ts b/packages/api/src/router/widgets/archive-team-warrior.ts index d8aa865bc..9fa96b553 100644 --- a/packages/api/src/router/widgets/archive-team-warrior.ts +++ b/packages/api/src/router/widgets/archive-team-warrior.ts @@ -9,7 +9,7 @@ export const archiveTeamWarriorRouter = createTRPCRouter({ .concat(createOneIntegrationMiddleware("query", "archiveTeamWarrior", "mock")) .query(async ({ ctx }) => { if (ctx.integration.kind === "mock") { - return { status: mockWidgetData.archiveTeamWarrior, updatedAt: new Date() }; + return { status: mockWidgetData.archiveTeamWarrior, updatedAt: new Date(mockWidgetData.timestamp) }; } const handler = archiveTeamWarriorRequestHandler.handler({ ...ctx.integration, kind: "archiveTeamWarrior" }, {}); diff --git a/packages/api/src/router/widgets/coolify.ts b/packages/api/src/router/widgets/coolify.ts index e545a2f14..d0d8b8355 100644 --- a/packages/api/src/router/widgets/coolify.ts +++ b/packages/api/src/router/widgets/coolify.ts @@ -28,7 +28,7 @@ export const coolifyRouter = createTRPCRouter({ integrationName: integration.name, integrationUrl: integration.url, instanceInfo: mockWidgetData.coolify, - updatedAt: new Date(), + updatedAt: new Date(mockWidgetData.timestamp), }; } diff --git a/packages/api/src/router/widgets/firewall.ts b/packages/api/src/router/widgets/firewall.ts index ab96887e3..28888649f 100644 --- a/packages/api/src/router/widgets/firewall.ts +++ b/packages/api/src/router/widgets/firewall.ts @@ -40,7 +40,12 @@ const queryFirewall = ( async (integration): Promise> => { if (integration.kind === "mock") { return { - integration: { id: integration.id, name: integration.name, kind: integration.kind, updatedAt: new Date() }, + integration: { + id: integration.id, + name: integration.name, + kind: integration.kind, + updatedAt: new Date(mockWidgetData.timestamp), + }, summary: getMockData(), error: undefined, }; diff --git a/packages/api/src/router/widgets/speedtest-tracker.ts b/packages/api/src/router/widgets/speedtest-tracker.ts index 19c5c7179..7770ed051 100644 --- a/packages/api/src/router/widgets/speedtest-tracker.ts +++ b/packages/api/src/router/widgets/speedtest-tracker.ts @@ -18,7 +18,7 @@ export const speedtestTrackerRouter = createTRPCRouter({ integrationName: integration.name, integrationUrl: integration.url, dashboard: mockWidgetData.speedtestTracker, - updatedAt: new Date(), + updatedAt: new Date(mockWidgetData.timestamp), error: undefined, }; } diff --git a/packages/api/src/router/widgets/tracearr.ts b/packages/api/src/router/widgets/tracearr.ts index f5e03fb88..f8960d1cf 100644 --- a/packages/api/src/router/widgets/tracearr.ts +++ b/packages/api/src/router/widgets/tracearr.ts @@ -18,7 +18,7 @@ export const tracearrRouter = createTRPCRouter({ integrationName: integration.name, integrationUrl: integration.url, dashboard: mockWidgetData.tracearr, - updatedAt: new Date(), + updatedAt: new Date(mockWidgetData.timestamp), error: undefined, }; } diff --git a/packages/api/src/router/widgets/traefik.ts b/packages/api/src/router/widgets/traefik.ts index 72476a6b9..a80891fd7 100644 --- a/packages/api/src/router/widgets/traefik.ts +++ b/packages/api/src/router/widgets/traefik.ts @@ -25,7 +25,7 @@ export const traefikRouter = createTRPCRouter({ integrationName: integration.name, integrationUrl: integration.url, dashboard: mockWidgetData.traefik, - updatedAt: new Date(), + updatedAt: new Date(mockWidgetData.timestamp), error: undefined, }; } diff --git a/packages/api/src/router/widgets/umami.ts b/packages/api/src/router/widgets/umami.ts index 9ce0bfbfa..c5736be53 100644 --- a/packages/api/src/router/widgets/umami.ts +++ b/packages/api/src/router/widgets/umami.ts @@ -49,7 +49,7 @@ export const umamiRouter = createTRPCRouter({ integrationName: integration.name, integrationUrl: integration.url, visitorStats: { ...mockWidgetData.umamiVisitorStats, timeFrame: input.timeFrame }, - updatedAt: new Date(), + updatedAt: new Date(mockWidgetData.timestamp), }; } const innerHandler = umamiRequestHandler.handler( diff --git a/packages/api/src/router/widgets/uptime-kuma.ts b/packages/api/src/router/widgets/uptime-kuma.ts index a3c91f496..68104158d 100644 --- a/packages/api/src/router/widgets/uptime-kuma.ts +++ b/packages/api/src/router/widgets/uptime-kuma.ts @@ -18,7 +18,7 @@ export const uptimeKumaRouter = createTRPCRouter({ integrationName: integration.name, integrationUrl: integration.url, dashboard: mockWidgetData.uptimeKuma, - updatedAt: new Date(), + updatedAt: new Date(mockWidgetData.timestamp), error: undefined, }; } diff --git a/packages/api/src/router/widgets/vpn.ts b/packages/api/src/router/widgets/vpn.ts index 9bc4e0964..0d1ff146e 100644 --- a/packages/api/src/router/widgets/vpn.ts +++ b/packages/api/src/router/widgets/vpn.ts @@ -27,7 +27,7 @@ export const vpnRouter = createTRPCRouter({ id: integration.id, name: integration.name, kind: integration.kind, - updatedAt: new Date(), + updatedAt: new Date(mockWidgetData.timestamp), }, summary: mockWidgetData.vpn, error: undefined, diff --git a/packages/api/src/router/widgets/wud.ts b/packages/api/src/router/widgets/wud.ts index 2b06c41b8..bb7ed3f3f 100644 --- a/packages/api/src/router/widgets/wud.ts +++ b/packages/api/src/router/widgets/wud.ts @@ -10,12 +10,14 @@ export const wudRouter = createTRPCRouter({ mcp: { enabled: true, description: - "Returns monitored-container counts and available updates from a What's Up Docker integration. REQUIRED: integrationId from integration_all. The caller needs query permission for that integration.", + "Returns monitored-container counts and available updates from a What's Up Docker integration, or mock statistics from a mock integration. REQUIRED: integrationId from integration_all. The caller needs query permission for that integration.", }, }) .concat(createOneIntegrationMiddleware("query", "wud", "mock")) .query(async ({ ctx }) => { - if (ctx.integration.kind === "mock") return { stats: mockWidgetData.wud, updatedAt: new Date() }; + if (ctx.integration.kind === "mock") { + return { stats: mockWidgetData.wud, updatedAt: new Date(mockWidgetData.timestamp) }; + } const handler = wudStatsRequestHandler.handler({ ...ctx.integration, kind: "wud" }, {}); const { data, timestamp } = await handler.getDataAsync(); diff --git a/packages/integrations/src/mock/widget-data.ts b/packages/integrations/src/mock/widget-data.ts index ce0bd62c9..ea673152f 100644 --- a/packages/integrations/src/mock/widget-data.ts +++ b/packages/integrations/src/mock/widget-data.ts @@ -47,6 +47,7 @@ const anchorNote: AnchorNote = { }; export const mockWidgetData = { + timestamp: demoTimestamp, anchorNote, anchorNotes: [ { diff --git a/packages/widgets/src/iframe/component.spec.ts b/packages/widgets/src/iframe/component.spec.ts index d1faa15c5..5ec11f07d 100644 --- a/packages/widgets/src/iframe/component.spec.ts +++ b/packages/widgets/src/iframe/component.spec.ts @@ -21,6 +21,8 @@ describe("iframe policy", () => { it("accepts HTTP URLs and same-origin paths", () => { expect(isSupportedProtocol("https://example.com")).toBe(true); expect(isSupportedProtocol("/api/demo-assets/overview")).toBe(true); + expect(isSupportedProtocol("//evil.example")).toBe(false); + expect(isSupportedProtocol("/\\evil.example")).toBe(false); expect(isSupportedProtocol("javascript:alert(1)")).toBe(false); expect(isSupportedProtocol("not a url")).toBe(false); });