diff --git a/src/state/queries/deer-verification.ts b/src/state/queries/deer-verification.ts index ac98065a1..1a7170020 100644 --- a/src/state/queries/deer-verification.ts +++ b/src/state/queries/deer-verification.ts @@ -23,6 +23,7 @@ import { constellationLinks, } from './constellation' import {LRU} from './direct-fetch-record' +import {resolvePdsServiceUrl} from './resolve-identity' import {useCurrentAccountProfile} from './useCurrentAccountProfile' const RQKEY_ROOT = 'deer-verification' @@ -37,9 +38,6 @@ type LinkedRecord = { record: AppBskyGraphVerification.Record } -// TODO: lift this into direct fetch to share cache -const serviceCache = new LRU<`did:${string}`, string>() - const verificationCache = new LRU() export function getTrustedConstellationVerifications( @@ -82,26 +80,7 @@ async function getDeerVerificationLinkedRecords( async link => { const {did, rkey} = link - let service = await serviceCache.getOrTryInsertWith(did, async () => { - const docUrl = did.startsWith('did:plc:') - ? `https://plc.directory/${did}` - : `https://${did.substring(8)}/.well-known/did.json` - - // TODO: validate! - const doc: { - service: { - serviceEndpoint: string - type: string - }[] - } = await (await fetch(docUrl)).json() - const service = doc.service.find( - s => s.type === 'AtprotoPersonalDataServer', - )?.serviceEndpoint - - if (service === undefined) - throw new Error(`could not find a service for ${did}`) - return service - }) + let service = await resolvePdsServiceUrl(did) const request = `${service}/xrpc/com.atproto.repo.getRecord?repo=${did}&collection=app.bsky.graph.verification&rkey=${rkey}` const record = await verificationCache.getOrTryInsertWith( diff --git a/src/state/queries/resolve-identity.ts b/src/state/queries/resolve-identity.ts new file mode 100644 index 000000000..74fb92404 --- /dev/null +++ b/src/state/queries/resolve-identity.ts @@ -0,0 +1,26 @@ +import {LRU} from './direct-fetch-record' + +const serviceCache = new LRU<`did:${string}`, string>() + +export async function resolvePdsServiceUrl(did: `did:${string}`) { + return await serviceCache.getOrTryInsertWith(did, async () => { + const docUrl = did.startsWith('did:plc:') + ? `https://plc.directory/${did}` + : `https://${did.substring(8)}/.well-known/did.json` + + // TODO: validate! + const doc: { + service: { + serviceEndpoint: string + type: string + }[] + } = await (await fetch(docUrl)).json() + const service = doc.service.find( + s => s.type === 'AtprotoPersonalDataServer', + )?.serviceEndpoint + + if (service === undefined) + throw new Error(`could not find a service for ${did}`) + return service + }) +} diff --git a/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx b/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx index 5d461329f..6d58f0669 100644 --- a/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx +++ b/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx @@ -52,6 +52,7 @@ import { useProfileBlockMutationQueue, useProfileMuteMutationQueue, } from '#/state/queries/profile' +import {resolvePdsServiceUrl} from '#/state/queries/resolve-identity' import {useToggleReplyVisibilityMutation} from '#/state/queries/threadgate' import {useSession} from '#/state/session' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' @@ -396,7 +397,9 @@ let PostDropdownMenuItems = ({ const video = post.embed as AppBskyEmbedVideo.View const did = post.author.did const cid = video.cid - const uri = `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${did}&cid=${cid}` + if (!did.startsWith('did:')) return + const pdsUrl = await resolvePdsServiceUrl(did as `did:${string}`) + const uri = `${pdsUrl}/xrpc/com.atproto.sync.getBlob?did=${did}&cid=${cid}` Toast.show('Downloading video...', 'download') @@ -427,7 +430,7 @@ let PostDropdownMenuItems = ({ const embed = post.embed as AppBskyEmbedExternal.View // Janky workaround by checking if the domain is tenor.com const url = new URL(embed.external.uri) - return url.host == 'media.tenor.com' + return url.host === 'media.tenor.com' }, [post]) const onBlockAuthor = useCallback(async () => {