a tool for shared writing and social publishing
at refactor/pub-settings 122 lines 3.8 kB view raw
1"use server"; 2 3import { cookies } from "next/headers"; 4import { supabaseServerClient } from "supabase/serverClient"; 5import { cache } from "react"; 6import { deduplicateByUri } from "src/utils/deduplicateRecords"; 7import { AtUri } from "@atproto/syntax"; 8import { TID } from "@atproto/common"; 9export const getIdentityData = cache(uncachedGetIdentityData); 10export async function uncachedGetIdentityData() { 11 let cookieStore = await cookies(); 12 let auth_token = 13 cookieStore.get("auth_token")?.value || 14 cookieStore.get("external_auth_token")?.value; 15 let auth_res = auth_token 16 ? await supabaseServerClient 17 .from("email_auth_tokens") 18 .select( 19 `*, 20 identities( 21 *, 22 bsky_profiles(*), 23 notifications(count), 24 publication_subscriptions(*), 25 custom_domains!custom_domains_identity_id_fkey(publication_domains(*, publications(name)), custom_domain_routes(*), *), 26 home_leaflet:permission_tokens!identities_home_page_fkey(*, permission_token_rights(*, 27 entity_sets(entities(facts(*))) 28 )), 29 permission_token_on_homepage( 30 archived, 31 created_at, 32 permission_tokens!inner( 33 id, 34 root_entity, 35 permission_token_rights(*), 36 leaflets_to_documents(*, documents(*)), 37 leaflets_in_publications(*, publications(*), documents(*)) 38 ) 39 ), 40 user_subscriptions(plan, status, current_period_end), 41 user_entitlements(entitlement_key, granted_at, expires_at, source, metadata) 42 )`, 43 ) 44 .eq("identities.notifications.read", false) 45 .eq("id", auth_token) 46 .eq("confirmed", true) 47 .single() 48 : null; 49 if (!auth_res?.data?.identities) return null; 50 51 // Transform embedded entitlements into a keyed record, filtering expired 52 const now = new Date().toISOString(); 53 const entitlements: Record< 54 string, 55 { 56 granted_at: string; 57 expires_at: string | null; 58 source: string | null; 59 metadata: unknown; 60 } 61 > = {}; 62 for (const row of auth_res.data.identities.user_entitlements || []) { 63 if (row.expires_at && row.expires_at < now) continue; 64 entitlements[row.entitlement_key] = { 65 granted_at: row.granted_at, 66 expires_at: row.expires_at, 67 source: row.source, 68 metadata: row.metadata, 69 }; 70 } 71 72 const subscription = auth_res.data.identities.user_subscriptions ?? null; 73 74 if (auth_res.data.identities.atp_did) { 75 //I should create a relationship table so I can do this in the above query 76 let { data: rawPublications } = await supabaseServerClient 77 .from("publications") 78 .select("*") 79 .eq("identity_did", auth_res.data.identities.atp_did); 80 // Deduplicate records that may exist under both pub.leaflet and site.standard namespaces, 81 // then filter to only publications created by Leaflet 82 const publications = deduplicateByUri(rawPublications || []).filter( 83 isLeafletPublication, 84 ); 85 return { 86 ...auth_res.data.identities, 87 publications, 88 entitlements, 89 subscription, 90 }; 91 } 92 93 return { 94 ...auth_res.data.identities, 95 publications: [], 96 entitlements, 97 subscription, 98 }; 99} 100 101function isLeafletPublication(p: { uri: string; record: unknown }): boolean { 102 try { 103 const rkey = new AtUri(p.uri).rkey; 104 if (!TID.is(rkey)) return false; 105 } catch { 106 return false; 107 } 108 109 const record = p.record as Record<string, any> | null; 110 if (!record) return true; 111 112 if (record.preferences?.greengale) return false; 113 114 if ( 115 record.theme && 116 record.theme.$type && 117 record.theme.$type !== "pub.leaflet.publication#theme" 118 ) 119 return false; 120 121 return true; 122}