Diagnostics for atproto PDS hosts, DIDs, and handles: https://debug.hose.cam

handle checks

Changed files
+130 -14
+130 -14
index.html
··· 8 8 <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> 9 9 10 10 <script type="module"> 11 - import { Client, ClientResponseError, ok, simpleFetchHandler } from 'https://esm.sh/@atcute/client@4.1.1'; 11 + import { 12 + Client, 13 + ClientResponseError, 14 + ok, 15 + simpleFetchHandler, 16 + } from 'https://esm.sh/@atcute/client@4.1.1'; 17 + import { 18 + DohJsonHandleResolver, 19 + WellKnownHandleResolver, 20 + } from 'https://esm.sh/@atcute/identity-resolver@1.2.0'; 21 + 12 22 window.SimpleQuery = service => { 13 23 const client = new Client({ handler: simpleFetchHandler({ service }) }); 14 24 return (...args) => ok(client.get(...args)); ··· 18 28 return (...args) => ok(client.post(...args)); 19 29 }; 20 30 window.isXrpcErr = e => e instanceof ClientResponseError; 31 + 32 + window.dnsResolver = new DohJsonHandleResolver({ 33 + dohUrl: 'https://mozilla.cloudflare-dns.com/dns-query', 34 + }); 35 + window.httpResolver = new WellKnownHandleResolver(); 36 + 21 37 window.slingshot = window.SimpleQuery('https://slingshot.microcosm.blue'); 22 38 window.relays = [ 23 39 { ··· 67 83 this.identifierError = null; 68 84 this.pds = null; 69 85 this.did = null; 86 + this.handle = null; 70 87 if (this.identifier.startsWith('https://')) { 71 88 this.pds = this.identifier; 72 89 } else { ··· 76 93 if (this.identifier.startsWith('did:')) { 77 94 this.did = this.identifier; 78 95 } else { 96 + this.handle = this.identifier; 79 97 let data; 80 98 try { 81 99 data = await window.slingshot('com.bad-example.identity.resolveMiniDoc', { ··· 101 119 Alpine.data('pdsCheck', pds => ({ 102 120 loading: false, 103 121 error: null, 104 - status: null, 122 + description: null, 105 123 106 124 async init() { 107 125 this.loading = true; 108 126 this.error = null; 109 - this.status = null; 127 + this.description = null; 110 128 let query = window.SimpleQuery(pds); 111 129 try { 112 - await query('com.atproto.server.describeServer'); 113 - this.status = 'online'; 130 + this.description = await query('com.atproto.server.describeServer'); 114 131 } catch (e) { 115 132 if (window.isXrpcErr(e)) { 116 133 this.error = e.error; ··· 121 138 } 122 139 this.loading = false; 123 140 } 124 - })) 141 + })); 125 142 126 143 Alpine.data('relayCheckHost', (pds, relay) => ({ 127 144 loading: false, ··· 178 195 } 179 196 this.reqCrawlStatus = "done"; 180 197 }, 181 - })) 198 + })); 199 + 200 + Alpine.data('checkHandle', handle => ({ 201 + loading: false, 202 + dnsDid: null, 203 + dnsErr: null, 204 + httpDid: null, 205 + httpErr: null, 206 + 207 + async init() { 208 + await this.updateHandle(handle); 209 + }, 210 + async updateHandle(handle) { 211 + this.loading = true; 212 + this.dnsDid = null; 213 + this.dnsErr = null; 214 + this.httpDid = null; 215 + this.httpErr = null; 216 + try { 217 + this.dnsDid = await window.dnsResolver.resolve(handle); 218 + } catch (e) { 219 + this.dnsErr = e.name; 220 + } 221 + try { 222 + this.httpDid = await window.httpResolver.resolve(handle); 223 + } catch (e) { 224 + this.httpErr = e.name; 225 + } 226 + this.loading = false; 227 + }, 228 + })); 182 229 }) 183 230 </script> 184 231 </head> ··· 234 281 <span x-text="pds"></span> 235 282 </h2> 236 283 237 - <h3 class="text-lg">Server</h3> 238 284 <div x-data="pdsCheck(pds)"> 239 - <div 240 - x-show="status !== null" 241 - x-text="`status: ${status}`" 242 - ></div> 285 + <h3 class="text-lg"> 286 + Server 287 + <span 288 + x-show="description !== null" 289 + class="badge badge-sm badge-soft badge-success" 290 + >online</span> 291 + </h3> 292 + <template x-if="description !== null"> 293 + <div class="overflow-x-auto"> 294 + <table class="table table-xs"> 295 + <tbody> 296 + <tr> 297 + <td class="text-sm">Open registration</td> 298 + <td 299 + class="text-sm" 300 + x-text="!description.inviteCodeRequired" 301 + ></td> 302 + </tr> 303 + </tbody> 304 + </table> 305 + </div> 306 + </template> 243 307 </div> 244 308 245 309 <h3 class="text-lg">Relay host status</h3> ··· 301 365 </template> 302 366 303 367 <template x-if="did != null"> 304 - <div class="card bg-base-100 w-full max-w-sm shrink-0 shadow-2xl"> 368 + <div class="card bg-base-100 w-full max-w-lg shrink-0 shadow-2xl"> 305 369 <div class="card-body"> 306 - <p x-text="`DID: ${did}`"></p> 370 + <h2 class="card-title"> 371 + <span class="badge badge-secondary">DID</span> 372 + <code x-text="did"></code> 373 + </h2> 374 + <p>(wip)</p> 375 + </div> 376 + </div> 377 + </template> 378 + 379 + <template x-if="handle != null"> 380 + <div class="card bg-base-100 w-full max-w-lg shrink-0 shadow-2xl"> 381 + <div 382 + x-data="checkHandle(handle)" 383 + x-init="$watch('handle', h => updateHandle(h))" 384 + class="card-body" 385 + > 386 + <h2 class="card-title"> 387 + <span class="badge badge-secondary">Handle</span> 388 + <span x-text="handle"></span> 389 + </h2> 390 + <p x-show="loading" class="text-i">Loading&hellip;</p> 391 + <div x-show="!loading" class="overflow-x-auto"> 392 + <table class="table table-xs"> 393 + <tbody> 394 + <tr> 395 + <td class="text-sm">DNS</td> 396 + <td class="text-sm"> 397 + <code x-text="dnsDid"></code> 398 + </td> 399 + <td> 400 + <div 401 + class="badge badge-sm badge-soft badge-neutral" 402 + x-show="dnsErr !== null" 403 + x-text="dnsErr" 404 + ></div> 405 + </td> 406 + </tr> 407 + <tr> 408 + <td class="text-sm">Http</td> 409 + <td class="text-sm"> 410 + <code x-text="httpDid"></code> 411 + </td> 412 + <td> 413 + <div 414 + class="badge badge-sm badge-soft badge-neutral" 415 + x-show="httpErr !== null" 416 + x-text="httpErr" 417 + ></div> 418 + </td> 419 + </tr> 420 + </tbody> 421 + </table> 422 + </div> 307 423 </div> 308 424 </div> 309 425 </template>