diff --git a/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/page.tsx b/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/page.tsx index d980279ce..768255a6e 100644 --- a/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/page.tsx +++ b/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/page.tsx @@ -1,7 +1,12 @@ import type { Metadata } from 'next'; +import { notFound } from 'next/navigation'; import { HeatmapsPage } from './HeatmapsPage'; export default async function ({ params }: { params: Promise<{ websiteId: string }> }) { + if (!process.env.UMAMI_SELF_RECORD) { + notFound(); + } + const { websiteId } = await params; return ; diff --git a/src/app/api/config/route.ts b/src/app/api/config/route.ts index 101a12243..56a60bed8 100644 --- a/src/app/api/config/route.ts +++ b/src/app/api/config/route.ts @@ -14,6 +14,7 @@ export async function GET(request: Request) { linksUrl: process.env.LINKS_URL, pixelsUrl: process.env.PIXELS_URL, privateMode: !!process.env.PRIVATE_MODE, + selfRecordEnabled: !!process.env.UMAMI_SELF_RECORD, telemetryDisabled: !!process.env.DISABLE_TELEMETRY, trackerScriptName: process.env.TRACKER_SCRIPT_NAME, updatesDisabled: !!process.env.DISABLE_UPDATES, diff --git a/src/app/api/reports/heatmap/route.ts b/src/app/api/reports/heatmap/route.ts index 79af35c3e..5c3b1844b 100644 --- a/src/app/api/reports/heatmap/route.ts +++ b/src/app/api/reports/heatmap/route.ts @@ -1,10 +1,14 @@ import { parseRequest, setWebsiteDate } from '@/lib/request'; -import { json, unauthorized } from '@/lib/response'; +import { forbidden, json, unauthorized } from '@/lib/response'; import { reportResultSchema } from '@/lib/schema'; import { canViewWebsite } from '@/permissions'; import { getHeatmap, type HeatmapParameters } from '@/queries/sql'; export async function POST(request: Request) { + if (!process.env.UMAMI_SELF_RECORD) { + return forbidden({ message: 'Heatmap recording is disabled.' }); + } + const { auth, body, error } = await parseRequest(request, reportResultSchema); if (error) { diff --git a/src/components/hooks/useConfig.ts b/src/components/hooks/useConfig.ts index c1cdcaf67..baf0b4828 100644 --- a/src/components/hooks/useConfig.ts +++ b/src/components/hooks/useConfig.ts @@ -8,6 +8,7 @@ export type Config = { linksUrl?: string; pixelsUrl?: string; privateMode: boolean; + selfRecordEnabled: boolean; telemetryDisabled: boolean; trackerScriptName?: string; updatesDisabled: boolean; diff --git a/src/components/hooks/useWebsiteNavItems.tsx b/src/components/hooks/useWebsiteNavItems.tsx index 09731f101..37b661d03 100644 --- a/src/components/hooks/useWebsiteNavItems.tsx +++ b/src/components/hooks/useWebsiteNavItems.tsx @@ -11,12 +11,14 @@ import { Video, } from '@/components/icons'; import { Funnel, Gauge, Lightning, Magnet, Money, Network, Path, Target } from '@/components/svg'; +import { useConfig } from './useConfig'; import { useMessages } from './useMessages'; import { useNavigation } from './useNavigation'; export function useWebsiteNavItems(websiteId: string) { const { t, labels } = useMessages(); const { pathname, renderUrl } = useNavigation(); + const config = useConfig(); const renderPath = (path: string) => renderUrl(`/websites/${websiteId}${path}`, { @@ -108,12 +110,16 @@ export function useWebsiteNavItems(websiteId: string) { icon: