a tool for shared writing and social publishing
at update/looseleafs 161 lines 4.9 kB view raw
1"use server"; 2import { refresh } from "next/cache"; 3 4import { drizzle } from "drizzle-orm/node-postgres"; 5import { 6 entities, 7 permission_tokens, 8 permission_token_rights, 9} from "drizzle/schema"; 10import { eq } from "drizzle-orm"; 11import { PermissionToken } from "src/replicache"; 12import { pool } from "supabase/pool"; 13import { getIdentityData } from "./getIdentityData"; 14import { supabaseServerClient } from "supabase/serverClient"; 15 16export async function deleteLeaflet(permission_token: PermissionToken) { 17 const client = await pool.connect(); 18 const db = drizzle(client); 19 20 // Get the current user's identity 21 let identity = await getIdentityData(); 22 23 // Check publication and document ownership in one query 24 let { data: tokenData } = await supabaseServerClient 25 .from("permission_tokens") 26 .select( 27 ` 28 id, 29 leaflets_in_publications(publication, publications!inner(identity_did)), 30 leaflets_to_documents(document, documents!inner(uri)) 31 `, 32 ) 33 .eq("id", permission_token.id) 34 .single(); 35 36 if (tokenData) { 37 // Check if leaflet is in a publication 38 const leafletInPubs = tokenData.leaflets_in_publications || []; 39 if (leafletInPubs.length > 0) { 40 if (!identity) { 41 throw new Error( 42 "Unauthorized: You must be logged in to delete a leaflet in a publication", 43 ); 44 } 45 const isOwner = leafletInPubs.some( 46 (pub: any) => pub.publications.identity_did === identity.atp_did, 47 ); 48 if (!isOwner) { 49 throw new Error( 50 "Unauthorized: You must own the publication to delete this leaflet", 51 ); 52 } 53 } 54 55 // Check if there's a standalone published document 56 const leafletDoc = tokenData.leaflets_to_documents; 57 if (leafletDoc && leafletDoc.document) { 58 if (!identity || !identity.atp_did) { 59 throw new Error( 60 "Unauthorized: You must be logged in to delete a published leaflet", 61 ); 62 } 63 const docUri = leafletDoc.documents?.uri; 64 // Extract the DID from the document URI (format: at://did:plc:xxx/...) 65 if (docUri && !docUri.includes(identity.atp_did)) { 66 throw new Error( 67 "Unauthorized: You must own the published document to delete this leaflet", 68 ); 69 } 70 } 71 } 72 73 await db.transaction(async (tx) => { 74 let [token] = await tx 75 .select() 76 .from(permission_tokens) 77 .leftJoin( 78 permission_token_rights, 79 eq(permission_tokens.id, permission_token_rights.token), 80 ) 81 .where(eq(permission_tokens.id, permission_token.id)); 82 83 if (!token?.permission_token_rights?.write) return; 84 const entitySet = token.permission_token_rights.entity_set; 85 if (!entitySet) return; 86 await tx.delete(entities).where(eq(entities.set, entitySet)); 87 await tx 88 .delete(permission_tokens) 89 .where(eq(permission_tokens.id, permission_token.id)); 90 }); 91 client.release(); 92 93 refresh(); 94 return; 95} 96 97export async function archivePost(token: string) { 98 let identity = await getIdentityData(); 99 if (!identity) throw new Error("No Identity"); 100 101 // Archive on homepage 102 await supabaseServerClient 103 .from("permission_token_on_homepage") 104 .update({ archived: true }) 105 .eq("token", token) 106 .eq("identity", identity.id); 107 108 // Check if leaflet is in any publications where user is the creator 109 let { data: leafletInPubs } = await supabaseServerClient 110 .from("leaflets_in_publications") 111 .select("publication, publications!inner(identity_did)") 112 .eq("leaflet", token); 113 114 if (leafletInPubs) { 115 for (let pub of leafletInPubs) { 116 if (pub.publications.identity_did === identity.atp_did) { 117 await supabaseServerClient 118 .from("leaflets_in_publications") 119 .update({ archived: true }) 120 .eq("leaflet", token) 121 .eq("publication", pub.publication); 122 } 123 } 124 } 125 126 refresh(); 127 return; 128} 129 130export async function unarchivePost(token: string) { 131 let identity = await getIdentityData(); 132 if (!identity) throw new Error("No Identity"); 133 134 // Unarchive on homepage 135 await supabaseServerClient 136 .from("permission_token_on_homepage") 137 .update({ archived: false }) 138 .eq("token", token) 139 .eq("identity", identity.id); 140 141 // Check if leaflet is in any publications where user is the creator 142 let { data: leafletInPubs } = await supabaseServerClient 143 .from("leaflets_in_publications") 144 .select("publication, publications!inner(identity_did)") 145 .eq("leaflet", token); 146 147 if (leafletInPubs) { 148 for (let pub of leafletInPubs) { 149 if (pub.publications.identity_did === identity.atp_did) { 150 await supabaseServerClient 151 .from("leaflets_in_publications") 152 .update({ archived: false }) 153 .eq("leaflet", token) 154 .eq("publication", pub.publication); 155 } 156 } 157 } 158 159 refresh(); 160 return; 161}