Address PR review: fix Bluesky host routing
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
import {BSKY_SERVICE} from '#/lib/constants'
|
import {BSKY_SERVICE} from '#/lib/constants'
|
||||||
import {Agent} from '#/state/session/agent'
|
import {Agent} from '#/state/session/agent'
|
||||||
|
|
||||||
|
// Cap the DID-doc fetch so a slow/hanging host can't keep a resolution pending.
|
||||||
|
const DID_DOC_FETCH_TIMEOUT_MS = 5e3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves an atproto handle (or DID) to the user's PDS service URL.
|
* Resolves an atproto handle (or DID) to the user's PDS service URL.
|
||||||
*
|
*
|
||||||
@@ -65,8 +68,13 @@ async function fetchDidDoc(did: string): Promise<DidDoc> {
|
|||||||
`Unsupported DID method: ${did}`,
|
`Unsupported DID method: ${did}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
// Bound the fetch - the background query has no other timeout, so a did:web
|
||||||
|
// (or plc.directory) host that hangs would otherwise keep the resolution
|
||||||
|
// pending indefinitely.
|
||||||
|
const controller = new AbortController()
|
||||||
|
const timer = setTimeout(() => controller.abort(), DID_DOC_FETCH_TIMEOUT_MS)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(url)
|
const res = await fetch(url, {signal: controller.signal})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw new Error(`HTTP ${res.status}`)
|
throw new Error(`HTTP ${res.status}`)
|
||||||
}
|
}
|
||||||
@@ -77,6 +85,8 @@ async function fetchDidDoc(did: string): Promise<DidDoc> {
|
|||||||
`Failed to fetch DID doc from ${url}`,
|
`Failed to fetch DID doc from ${url}`,
|
||||||
e,
|
e,
|
||||||
)
|
)
|
||||||
|
} finally {
|
||||||
|
clearTimeout(timer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -162,8 +162,12 @@ export const LoginForm = ({
|
|||||||
// Fire analytics on resolve success/failure.
|
// Fire analytics on resolve success/failure.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (resolveQuery.isSuccess && resolveQuery.data) {
|
if (resolveQuery.isSuccess && resolveQuery.data) {
|
||||||
|
// Only count duration when a fetch actually ran (a cache hit leaves the
|
||||||
|
// ref at 0); reset after so a re-render can't re-emit a stale delta.
|
||||||
|
const start = resolveStartRef.current
|
||||||
|
resolveStartRef.current = 0
|
||||||
ax.metric('signin:pdsResolve:success', {
|
ax.metric('signin:pdsResolve:success', {
|
||||||
durationMs: Date.now() - resolveStartRef.current,
|
durationMs: start ? Date.now() - start : 0,
|
||||||
isBlueskySocial: isBlueskyHostedPds(resolveQuery.data.pds),
|
isBlueskySocial: isBlueskyHostedPds(resolveQuery.data.pds),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -262,7 +266,15 @@ export const LoginForm = ({
|
|||||||
let service = customServerOverride ?? serviceUrl
|
let service = customServerOverride ?? serviceUrl
|
||||||
if (!customServerOverride && looksResolvable(fullIdent)) {
|
if (!customServerOverride && looksResolvable(fullIdent)) {
|
||||||
const resolvedPds = await resolvePdsOnSubmit(queryClient, fullIdent)
|
const resolvedPds = await resolvePdsOnSubmit(queryClient, fullIdent)
|
||||||
if (resolvedPds) service = resolvedPds
|
// Only reroute to the resolved PDS for non-Bluesky hosts. A normal
|
||||||
|
// Bluesky account resolves to a sharded *.host.bsky.network endpoint,
|
||||||
|
// but must keep signing in through the bsky.social entryway
|
||||||
|
// (serviceUrl) - using the shard as account.service would flip
|
||||||
|
// downstream isSelfHosted / isBskyPds checks and suppress email
|
||||||
|
// verification. The resolution still drives the status UI either way.
|
||||||
|
if (resolvedPds && !isBlueskyHostedPds(resolvedPds)) {
|
||||||
|
service = resolvedPds
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove double login
|
// TODO remove double login
|
||||||
|
|||||||
Reference in New Issue
Block a user