From bfa20a90eca892c9b907b81b5a67974e7ef020b5 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 12 Jun 2026 11:09:21 +0000 Subject: [PATCH] fix: protect unpublished notes and saved page edits Co-authored-by: theg1239 --- .../moderation/past-paper-page-editor.tsx | 16 ++++++++-------- app/components/pdfviewer.tsx | 8 ++++---- lib/data/note-detail.ts | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/components/moderation/past-paper-page-editor.tsx b/app/components/moderation/past-paper-page-editor.tsx index e586d014..c94943d4 100644 --- a/app/components/moderation/past-paper-page-editor.tsx +++ b/app/components/moderation/past-paper-page-editor.tsx @@ -39,7 +39,7 @@ type PastPaperPageEditorProps = { }; type PageEditorDraftState = { - sourceKey: string; + propKey: string; baseline: PdfPageEdits | null; draft: PdfPageEdits | null; }; @@ -156,7 +156,7 @@ export default function PastPaperPageEditor({ [normalizedSavedPageEdits, totalPages], ); const [pageEditState, setPageEditState] = useState({ - sourceKey: normalizedSavedKey, + propKey: normalizedSavedKey, baseline: normalizedSavedPageEdits, draft: normalizedSavedPageEdits, }); @@ -164,26 +164,26 @@ export default function PastPaperPageEditor({ const [saveError, setSaveError] = useState(null); const [isPending, startTransition] = useTransition(); const baselinePageEdits = - pageEditState.sourceKey === normalizedSavedKey + pageEditState.propKey === normalizedSavedKey ? pageEditState.baseline : normalizedSavedPageEdits; const draftPageEdits = - pageEditState.sourceKey === normalizedSavedKey + pageEditState.propKey === normalizedSavedKey ? pageEditState.draft : normalizedSavedPageEdits; const setDraftPageEdits = (nextDraft: PageEditsUpdate) => { setPageEditState((currentState) => { const currentBaseline = - currentState.sourceKey === normalizedSavedKey + currentState.propKey === normalizedSavedKey ? currentState.baseline : normalizedSavedPageEdits; const currentDraft = - currentState.sourceKey === normalizedSavedKey + currentState.propKey === normalizedSavedKey ? currentState.draft : normalizedSavedPageEdits; return { - sourceKey: normalizedSavedKey, + propKey: normalizedSavedKey, baseline: currentBaseline, draft: typeof nextDraft === "function" ? nextDraft(currentDraft) : nextDraft, @@ -197,7 +197,7 @@ export default function PastPaperPageEditor({ ); setPageEditState({ - sourceKey: serializePdfPageEdits(normalizedNextPageEdits, totalPages), + propKey: normalizedSavedKey, baseline: normalizedNextPageEdits, draft: normalizedNextPageEdits, }); diff --git a/app/components/pdfviewer.tsx b/app/components/pdfviewer.tsx index 5db7837c..e091e43d 100644 --- a/app/components/pdfviewer.tsx +++ b/app/components/pdfviewer.tsx @@ -150,7 +150,7 @@ type PdfViewerProps = { }; type SavedPageEditsState = { - sourceKey: string; + propKey: string; value: PdfPageEdits | null; }; @@ -2016,7 +2016,7 @@ export default function PDFViewer({ const [isPdfDarkMode, setIsPdfDarkMode] = useState(false); const [savedPageEditsState, setSavedPageEditsState] = useState({ - sourceKey: normalizedInitialPageEditsKey, + propKey: normalizedInitialPageEditsKey, value: normalizedInitialPageEdits, }); const [bufferLifecycleState, dispatchBufferLifecycle] = useReducer( @@ -2030,13 +2030,13 @@ export default function PDFViewer({ showSlowLoadFallback, } = bufferLifecycleState; const savedPageEdits = - savedPageEditsState.sourceKey === normalizedInitialPageEditsKey + savedPageEditsState.propKey === normalizedInitialPageEditsKey ? savedPageEditsState.value : normalizedInitialPageEdits; const setSavedPageEdits = (nextPageEdits: PdfPageEdits | null) => { const normalizedNextPageEdits = normalizePdfPageEdits(nextPageEdits); setSavedPageEditsState({ - sourceKey: serializePdfPageEdits(normalizedNextPageEdits), + propKey: normalizedInitialPageEditsKey, value: normalizedNextPageEdits, }); }; diff --git a/lib/data/note-detail.ts b/lib/data/note-detail.ts index 27a5dcec..e5da265e 100644 --- a/lib/data/note-detail.ts +++ b/lib/data/note-detail.ts @@ -1,5 +1,5 @@ import { cacheLife, cacheTag } from "next/cache"; -import { asc, eq } from "drizzle-orm"; +import { and, asc, eq } from "drizzle-orm"; import { cache } from "react"; import { normalizeGcsUrl } from "@/lib/normalize-gcs-url"; import { course, db, note, noteToTag, tag, user } from "@/db"; @@ -28,7 +28,7 @@ const loadNoteDetail = cache(async (id: string) => { .leftJoin(course, eq(note.courseId, course.id)) .leftJoin(noteToTag, eq(noteToTag.a, note.id)) .leftJoin(tag, eq(noteToTag.b, tag.id)) - .where(eq(note.id, id)) + .where(and(eq(note.id, id), eq(note.isClear, true))) .orderBy(asc(tag.name)); const firstRow = rows[0];