diff --git a/actions/deleteLeaflet.ts b/actions/deleteLeaflet.ts index 55534656..d6108def 100644 --- a/actions/deleteLeaflet.ts +++ b/actions/deleteLeaflet.ts @@ -16,6 +16,52 @@ import { supabaseServerClient } from "supabase/serverClient"; export async function deleteLeaflet(permission_token: PermissionToken) { const client = await pool.connect(); const db = drizzle(client); + + // Get the current user's identity + let identity = await getIdentityData(); + + // Check publication and document ownership in one query + let { data: tokenData } = await supabaseServerClient + .from("permission_tokens") + .select(` + id, + leaflets_in_publications(publication, publications!inner(identity_did)), + leaflets_to_documents(document, documents!inner(uri)) + `) + .eq("id", permission_token.id) + .single(); + + if (tokenData) { + // Check if leaflet is in a publication + const leafletInPubs = tokenData.leaflets_in_publications || []; + if (leafletInPubs.length > 0) { + if (!identity) { + throw new Error("Unauthorized: You must be logged in to delete a leaflet in a publication"); + } + const isOwner = leafletInPubs.some( + (pub: any) => pub.publications.identity_did === identity.atp_did + ); + if (!isOwner) { + throw new Error("Unauthorized: You must own the publication to delete this leaflet"); + } + } + + // Check if there's a standalone published document + const leafletDocs = tokenData.leaflets_to_documents || []; + if (leafletDocs.length > 0) { + if (!identity) { + throw new Error("Unauthorized: You must be logged in to delete a published leaflet"); + } + for (let leafletDoc of leafletDocs) { + const docUri = leafletDoc.documents?.uri; + // Extract the DID from the document URI (format: at://did:plc:xxx/...) + if (docUri && !docUri.includes(identity.atp_did)) { + throw new Error("Unauthorized: You must own the published document to delete this leaflet"); + } + } + } + } + await db.transaction(async (tx) => { let [token] = await tx .select() diff --git a/app/(home-pages)/home/LeafletList/LeafletOptions.tsx b/app/(home-pages)/home/LeafletList/LeafletOptions.tsx index 58287b02..2afc85ca 100644 --- a/app/(home-pages)/home/LeafletList/LeafletOptions.tsx +++ b/app/(home-pages)/home/LeafletList/LeafletOptions.tsx @@ -86,9 +86,15 @@ const DefaultOptions = (props: { const pubStatus = useLeafletPublicationStatus(); const toaster = useToaster(); const { setArchived } = useArchiveMutations(); + const { identity } = useIdentityData(); const tokenId = pubStatus?.token.id; const itemType = pubStatus?.draftInPublication ? "Draft" : "Leaflet"; + // Check if this is a published post/document and if user is the owner + const isPublishedPostOwner = + !!identity?.atp_did && !!pubStatus?.documentUri?.includes(identity.atp_did); + const canDelete = !pubStatus?.documentUri || isPublishedPostOwner; + return ( <> @@ -133,12 +139,14 @@ const DefaultOptions = (props: { {!props.archived ? " Archive" : "Unarchive"} {itemType} - { - e.preventDefault(); - props.setState("areYouSure"); - }} - /> + {canDelete && ( + { + e.preventDefault(); + props.setState("areYouSure"); + }} + /> + )} ); }; -- 2.51.2 From 76114016051316cb47c5cc902e0682a127524a17 Mon Sep 17 00:00:00 2001 From: celine Date: Wed, 3 Dec 2025 14:57:51 -0500 Subject: [PATCH 2/2] fixing a big ol oopsie in our pub empty state in the sidebar --- components/ActionBar/Publications.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ActionBar/Publications.tsx b/components/ActionBar/Publications.tsx index 4299146c..304f9ad4 100644 --- a/components/ActionBar/Publications.tsx +++ b/components/ActionBar/Publications.tsx @@ -151,7 +151,7 @@ export const PubListEmptyContent = (props: { compact?: boolean }) => {
Publish on AT Proto
- {identity && !identity.atp_did ? ( + {identity && identity.atp_did ? ( // has ATProto account and no pubs <>