at://Press
at main 49 lines 1.3 kB view raw
1import { DID, BLOG_URL } from "./constants"; 2 3const GATEWAY_URL = process.env.ATAUTH_GATEWAY_URL; 4const ATAUTH_PUBLIC_URL = process.env.ATAUTH_PUBLIC_URL; 5 6interface ProxyUser { 7 did: string; 8 handle: string; 9} 10 11export function getLoginUrl(): string | null { 12 if (!ATAUTH_PUBLIC_URL) return null; 13 return `${ATAUTH_PUBLIC_URL}/auth/proxy/login?rd=${encodeURIComponent(`${BLOG_URL}/write`)}`; 14} 15 16export async function verifyProxyTicket( 17 ticket: string 18): Promise<ProxyUser | null> { 19 if (!GATEWAY_URL) return null; 20 try { 21 const verifyUrl = `${GATEWAY_URL}/auth/verify`; 22 const originalUrl = `${BLOG_URL}/write?_atauth_ticket=${encodeURIComponent(ticket)}`; 23 24 const res = await fetch(verifyUrl, { 25 headers: { 26 "X-Original-URL": originalUrl, 27 "X-Forwarded-Proto": "https", 28 "X-Forwarded-Host": new URL(BLOG_URL).host, 29 }, 30 }); 31 32 if (res.status !== 200) return null; 33 34 const did = res.headers.get("x-auth-did"); 35 const handle = res.headers.get("x-auth-handle"); 36 if (!did || !handle) return null; 37 38 // Validate handle format (alphanumeric, dots, hyphens) 39 if (!/^[a-zA-Z0-9.-]+$/.test(handle)) return null; 40 41 return { did, handle }; 42 } catch { 43 return null; 44 } 45} 46 47export function isOwner(did: string): boolean { 48 return did === DID; 49}