From 7f14b6960513bb31e122da1546fe0618863f1af8 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Tue, 5 Sep 2023 10:26:18 -0500 Subject: [PATCH] Redirect when photo can't be retrieved --- .../admin/photos/[photoId]/edit/page.tsx | 3 +++ src/app/(isr)/photos/[photoId]/layout.tsx | 8 ++++++++ src/app/(isr)/photos/[photoId]/share/page.tsx | 4 ++++ src/services/postgres.ts | 18 +++++++++++------- src/utility/string.ts | 2 ++ 5 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 src/utility/string.ts diff --git a/src/app/(auth-state)/admin/photos/[photoId]/edit/page.tsx b/src/app/(auth-state)/admin/photos/[photoId]/edit/page.tsx index b515eb23..056cb2ad 100644 --- a/src/app/(auth-state)/admin/photos/[photoId]/edit/page.tsx +++ b/src/app/(auth-state)/admin/photos/[photoId]/edit/page.tsx @@ -2,6 +2,7 @@ import PhotoForm from '@/photo/PhotoForm'; import { convertPhotoToFormData } from '@/photo/form'; import AdminChildPage from '@/components/AdminChildPage'; import { getPhoto } from '@/services/postgres'; +import { redirect } from 'next/navigation'; export const runtime = 'edge'; @@ -12,6 +13,8 @@ interface Props { export default async function PhotoPageEdit({ params: { photoId } }: Props) { const photo = await getPhoto(photoId); + if (!photo) { redirect('/admin'); } + return ( { const photo = await getPhoto(photoId); + + if (!photo) { return {}; } + const title = photo.title; const description = ogImageDescriptionForPhoto(photo); const images = ogImageUrlForPhoto(photo); + return { title, description, @@ -46,6 +51,9 @@ export default async function PhotoPage({ children, }: Props) { const photo = await getPhoto(photoId); + + if (!photo) { redirect('/'); } + const photos = await getPhotos(); return <> diff --git a/src/app/(isr)/photos/[photoId]/share/page.tsx b/src/app/(isr)/photos/[photoId]/share/page.tsx index 29936898..023e320b 100644 --- a/src/app/(isr)/photos/[photoId]/share/page.tsx +++ b/src/app/(isr)/photos/[photoId]/share/page.tsx @@ -1,5 +1,6 @@ import PhotoModal from '@/photo/PhotoModal'; import { getPhoto } from '@/services/postgres'; +import { redirect } from 'next/navigation'; export const runtime = 'edge'; @@ -9,5 +10,8 @@ interface Props { export default async function Share({ params: { photoId }}: Props) { const photo = await getPhoto(photoId); + + if (!photo) { return redirect('/'); } + return ; } diff --git a/src/services/postgres.ts b/src/services/postgres.ts index 9fd6765a..28b5f770 100644 --- a/src/services/postgres.ts +++ b/src/services/postgres.ts @@ -4,7 +4,9 @@ import { PhotoDbInsert, translatePhotoId, parsePhotoFromDb, + Photo, } from '@/photo'; +import { isValidUUID } from '@/utility/string'; const PHOTO_DEFAULT_LIMIT = 100; @@ -184,10 +186,12 @@ export const getPhotos = async ( return photos; }; -export const getPhoto = (id: string) => - sqlGetPhotoFromDb( - // Check for photo id forwarding - // and convert short ids to uuids - translatePhotoId(id) - ) - .then(photos => photos[0]); +export const getPhoto = async (id: string): Promise => { + // Check for photo id forwarding + // and convert short ids to uuids + const photoId = translatePhotoId(id); + return isValidUUID(photoId) + ? sqlGetPhotoFromDb(photoId) + .then(photos => photos.length > 0 ? photos[0] : undefined) + : Promise.resolve(undefined); +}; diff --git a/src/utility/string.ts b/src/utility/string.ts new file mode 100644 index 00000000..efd8fd76 --- /dev/null +++ b/src/utility/string.ts @@ -0,0 +1,2 @@ +export const isValidUUID = (id: string): boolean => + /^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/i.test(id); \ No newline at end of file