diff --git a/service/index.js b/service/index.js index 6b3d861..b038b18 100644 --- a/service/index.js +++ b/service/index.js @@ -21,25 +21,47 @@ const main = async () => { checkHandleRoute(pds, req, res); }); - pds.app.get("/.well-known/webfinger", (req, res) => { - const resource = req.query.resource; - if (!resource) { - return res.status(400).json({ error: "missing resource parameter" }); - } + pds.app.get("/.well-known/webfinger", async (req, res) => { + try { + const resource = req.query.resource; + if (!resource || typeof resource !== "string") { + return res.status(400).json({ error: "missing resource parameter" }); + } - const issuerUrl = process.env.PDS_OIDC_ISSUER_URL; - if (!issuerUrl) { - return res.status(404).json({ error: "webfinger not configured" }); - } + const issuerUrl = process.env.PDS_OIDC_ISSUER_URL; + if (!issuerUrl) { + return res.status(404).json({ error: "webfinger not configured" }); + } - res.setHeader("Content-Type", "application/jrd+json"); - res.json({ - subject: resource, - links: [{ - rel: "http://openid.net/specs/connect/1.0/issuer", - href: issuerUrl - }] - }); + // Parse acct: URI to extract the AT Proto handle. + // Supports two formats: + // acct:alice.bsky.social@pds.example.com — handle is "alice.bsky.social" + // acct:alice.com — handle is "alice.com" (bare domain handle) + const match = resource.match(/^acct:(.+)$/); + if (!match) { + return res.status(400).json({ error: "invalid resource format, expected acct: URI" }); + } + + const acct = match[1]; + const handle = acct.includes("@") ? acct.split("@")[0] : acct; + + const account = await pds.ctx.accountManager.getAccount(handle); + if (!account) { + return res.status(404).json({ error: "account not found" }); + } + + res.setHeader("Content-Type", "application/jrd+json"); + res.json({ + subject: resource, + links: [{ + rel: "http://openid.net/specs/connect/1.0/issuer", + href: issuerUrl + }] + }); + } catch (err) { + httpLogger.error({ err }, "webfinger lookup failed"); + return res.status(500).json({ error: "internal server error" }); + } }); // Graceful shutdown (see also https://aws.amazon.com/blogs/containers/graceful-shutdowns-with-ecs/)