diff --git a/src/apps/settings/index.tsx b/src/apps/settings/index.tsx index 1b5b643..d2c431b 100644 --- a/src/apps/settings/index.tsx +++ b/src/apps/settings/index.tsx @@ -24,6 +24,7 @@ import { CURATED_WALLPAPERS, DEFAULT_CURATED_ID, isSafeWallpaperUrl, + MAX_WALLPAPER_URL_LENGTH, resolveCurated, type WallpaperFit, } from '@/lib/wallpaper'; @@ -207,6 +208,10 @@ export function WallpaperSection() { toast({ title: 'Enter a valid https:// image URL', variant: 'destructive' }); return; } + if (trimmed.length > MAX_WALLPAPER_URL_LENGTH) { + toast({ title: 'That URL is too long', description: `URLs must be ${MAX_WALLPAPER_URL_LENGTH} characters or fewer.`, variant: 'destructive' }); + return; + } setPendingPreviewUrl(trimmed); }; diff --git a/src/lib/wallpaper.ts b/src/lib/wallpaper.ts index 33b541f..3f286ec 100644 --- a/src/lib/wallpaper.ts +++ b/src/lib/wallpaper.ts @@ -90,6 +90,9 @@ export function sanitizeWallpaperUrl(value: string | undefined): string | undefi return isSafeWallpaperUrl(value) ? value : undefined; } +/** Kept in sync with the Zod schema's `url` length cap below. */ +export const MAX_WALLPAPER_URL_LENGTH = 2048; + const WallpaperPresentationSchema = z.object({ fit: z.enum(['cover', 'contain']), dim: z.number().min(0).max(80), @@ -102,7 +105,7 @@ const CuratedSelectionSchema = z.object({ const UrlSelectionSchema = z.object({ source: z.literal('url'), - url: z.string().max(2048).refine(isSafeWallpaperUrl, 'Wallpaper URL must be a valid https:// URL'), + url: z.string().max(MAX_WALLPAPER_URL_LENGTH).refine(isSafeWallpaperUrl, 'Wallpaper URL must be a valid https:// URL'), presentation: WallpaperPresentationSchema, });