Something went wrong. Try again.
leaflet fork for copy edit / bug fixes forked from leaflet.pub/leaflet
Something went wrong. Try again.
2.8 kB · 78 lines
TypeScript
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879import { cache } from "react";
import { getAuthIdentity } from "src/auth";import { isPro, PRO_ENTITLEMENT_KEY } from "src/entitlements";import { isUuid } from "src/utils/isUuid";import { supabaseServerClient } from "supabase/serverClient";
// Versioning is a Leaflet Pro feature, but it's the *document* that carries the// entitlement: a doc owned by a Pro user keeps its history visible to every// collaborator, while the writes (save, restore, fork) stay with Pro viewers.// Resolved server-side because nothing in the editor's client payload carries// anyone else's entitlements. Deliberately not a "use server" module.export type VersionAccess = { // Whether this document has a version history at all. enabled: boolean; // Whether the viewer may save, restore, or fork versions of it. canModify: boolean;};
export const NO_VERSION_ACCESS: VersionAccess = { enabled: false, canModify: false,};
export const getVersionAccess = cache(uncachedGetVersionAccess);async function uncachedGetVersionAccess( tokenId: string,): Promise<VersionAccess> { if (!isUuid(tokenId)) return NO_VERSION_ACCESS; let identity = await getAuthIdentity(); if (isPro(identity?.entitlements)) return { enabled: true, canModify: true }; return { enabled: await documentHasProOwner(tokenId), canModify: false };}async function documentHasProOwner(tokenId: string) { let [homepage, inPublication, draftOf] = await Promise.all([ supabaseServerClient .from("permission_token_on_homepage") .select("identity") .eq("token", tokenId), supabaseServerClient .from("leaflets_in_publications") .select( "publications!leaflets_in_publications_publication_fkey(identity_did)", ) .eq("leaflet", tokenId), supabaseServerClient .from("publications") .select("identity_did") .eq("draft_leaflet", tokenId), ]);
let identityIds = new Set((homepage.data ?? []).map((row) => row.identity)); let dids = new Set([ ...(inPublication.data ?? []).flatMap((row) => row.publications ? [row.publications.identity_did] : [], ), ...(draftOf.data ?? []).map((row) => row.identity_did), ]);
if (dids.size > 0) { let { data } = await supabaseServerClient .from("identities") .select("id") .in("atp_did", [...dids]); for (let row of data ?? []) identityIds.add(row.id); } if (identityIds.size === 0) return false;
let { data: grants } = await supabaseServerClient .from("user_entitlements") .select("expires_at") .eq("entitlement_key", PRO_ENTITLEMENT_KEY) .in("identity_id", [...identityIds]);
// Mirrors keyEntitlements' expiry handling, which is what isPro sees. let now = new Date().toISOString(); return (grants ?? []).some((g) => !g.expires_at || g.expires_at >= now);}