a a vibe-coded abomination experiment of a fragrance review platform built on the atmosphere. drydown.social
at main 109 lines 3.2 kB view raw
1/** 2 * Service Detection Utilities 3 * 4 * Detects which AT Protocol service a user is using based on OAuth issuer or PDS URL. 5 * Falls back to Bluesky for unknown/custom PDS instances. 6 */ 7 8import { KNOWN_SERVICES, DEFAULT_SERVICE, type ServiceConfig } from '../config/services' 9 10/** 11 * Detect which service a user is using based on OAuth issuer or PDS URL 12 * 13 * @param issuer - OAuth issuer from session.server.serverMetadata.issuer 14 * @param pdsUrl - Personal Data Server URL 15 * @returns ServiceConfig for the detected service (defaults to Bluesky) 16 */ 17export function detectService(issuer?: string, pdsUrl?: string): ServiceConfig { 18 // Try issuer first (most reliable indicator) 19 if (issuer) { 20 for (const service of KNOWN_SERVICES) { 21 if (service.issuerPatterns.some(pattern => issuer.includes(pattern))) { 22 return service 23 } 24 } 25 } 26 27 // Fallback to PDS URL if issuer didn't match 28 if (pdsUrl) { 29 for (const service of KNOWN_SERVICES) { 30 if (service.pdsPatterns.some(pattern => pdsUrl.includes(pattern))) { 31 return service 32 } 33 } 34 } 35 36 // Default to Bluesky for unknown/custom services 37 return DEFAULT_SERVICE 38} 39 40/** 41 * Detect service for a specific DID by fetching their DID document 42 * 43 * @param did - AT Protocol DID (e.g., "did:plc:...") 44 * @returns ServiceConfig for the user's service 45 */ 46export async function detectServiceForDid(did: string): Promise<ServiceConfig> { 47 try { 48 // Fetch DID document to get PDS URL 49 const didDoc = await fetch(`https://plc.directory/${did}`) 50 const didDocData = await didDoc.json() 51 52 // Look for PDS service endpoint 53 const pdsService = didDocData.service?.find( 54 (s: any) => s.type === 'AtprotoPersonalDataServer' 55 ) 56 57 if (pdsService?.serviceEndpoint) { 58 return detectService(undefined, pdsService.serviceEndpoint) 59 } 60 } catch (error) { 61 console.warn('Failed to detect service for DID:', did, error) 62 } 63 64 return DEFAULT_SERVICE 65} 66 67/** 68 * Detect service for a specific handle by resolving their DID document 69 * 70 * @param handle - AT Protocol handle (e.g., "user.bsky.social") 71 * @returns ServiceConfig for the user's service 72 */ 73export async function detectServiceForHandle(handle: string): Promise<ServiceConfig> { 74 try { 75 // Try multiple resolvers for better cross-service compatibility 76 const resolvers = [ 77 `https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=${handle}`, 78 `https://blacksky.app/xrpc/com.atproto.identity.resolveHandle?handle=${handle}`, 79 ] 80 81 let did: string | null = null 82 83 for (const resolver of resolvers) { 84 try { 85 const didResolution = await fetch(resolver) 86 if (didResolution.ok) { 87 const didData = await didResolution.json() 88 if (didData.did) { 89 did = didData.did 90 break 91 } 92 } 93 } catch { 94 // Try next resolver 95 continue 96 } 97 } 98 99 if (!did) { 100 return DEFAULT_SERVICE 101 } 102 103 return await detectServiceForDid(did) 104 } catch (error) { 105 console.warn('Failed to detect service for handle:', handle, error) 106 } 107 108 return DEFAULT_SERVICE 109}