decentralized and customizable links page on top of atproto

support did:web resolution

Changed files
+13 -11
src
atproto
+13 -11
src/atproto/__init__.py
··· 1 - from aiodns import DNSResolver, error as dns_error 2 - from aiohttp.client import ClientSession 3 - from asyncio import tasks 4 1 from os import getenv 5 2 from re import match as regex_match 6 3 from typing import Any 7 4 5 + from aiodns import DNSResolver 6 + from aiodns import error as dns_error 7 + from aiohttp.client import ClientResponse, ClientSession 8 + 9 + from ..security import is_safe_url 8 10 from .kv import KV, nokv 9 11 from .validator import is_valid_authserver_meta 10 - from ..security import is_safe_url 11 12 12 13 PLC_DIRECTORY = getenv("PLC_DIRECTORY_URL") or "https://plc.directory" 13 14 HANDLE_REGEX = r"^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$" ··· 163 164 ) -> dict[str, Any] | None: 164 165 """Returns the DID document""" 165 166 167 + response: ClientResponse | None = None 168 + 166 169 if did.startswith("did:plc:"): 167 170 response = await client.get(f"{PLC_DIRECTORY}/{did}") 168 - if response.ok: 169 - return await response.json() 170 - return None 171 + elif did.startswith("did:web:"): 172 + domain = did.split(":")[-1] 173 + assert is_valid_handle(domain) 174 + response = await client.get(f"https://{domain}/.well-known/did.json") 171 175 172 - if did.startswith("did:web:"): 173 - # TODO: resolve did:web 174 - raise Exception("resolve did:web") 175 - 176 + if response and response.ok: 177 + return await response.json() 176 178 return None 177 179 178 180