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

handle checks

Changed files
+130 -14
+130 -14
index.html
··· 8 <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> 9 10 <script type="module"> 11 - import { Client, ClientResponseError, ok, simpleFetchHandler } from 'https://esm.sh/@atcute/client@4.1.1'; 12 window.SimpleQuery = service => { 13 const client = new Client({ handler: simpleFetchHandler({ service }) }); 14 return (...args) => ok(client.get(...args)); ··· 18 return (...args) => ok(client.post(...args)); 19 }; 20 window.isXrpcErr = e => e instanceof ClientResponseError; 21 window.slingshot = window.SimpleQuery('https://slingshot.microcosm.blue'); 22 window.relays = [ 23 { ··· 67 this.identifierError = null; 68 this.pds = null; 69 this.did = null; 70 if (this.identifier.startsWith('https://')) { 71 this.pds = this.identifier; 72 } else { ··· 76 if (this.identifier.startsWith('did:')) { 77 this.did = this.identifier; 78 } else { 79 let data; 80 try { 81 data = await window.slingshot('com.bad-example.identity.resolveMiniDoc', { ··· 101 Alpine.data('pdsCheck', pds => ({ 102 loading: false, 103 error: null, 104 - status: null, 105 106 async init() { 107 this.loading = true; 108 this.error = null; 109 - this.status = null; 110 let query = window.SimpleQuery(pds); 111 try { 112 - await query('com.atproto.server.describeServer'); 113 - this.status = 'online'; 114 } catch (e) { 115 if (window.isXrpcErr(e)) { 116 this.error = e.error; ··· 121 } 122 this.loading = false; 123 } 124 - })) 125 126 Alpine.data('relayCheckHost', (pds, relay) => ({ 127 loading: false, ··· 178 } 179 this.reqCrawlStatus = "done"; 180 }, 181 - })) 182 }) 183 </script> 184 </head> ··· 234 <span x-text="pds"></span> 235 </h2> 236 237 - <h3 class="text-lg">Server</h3> 238 <div x-data="pdsCheck(pds)"> 239 - <div 240 - x-show="status !== null" 241 - x-text="`status: ${status}`" 242 - ></div> 243 </div> 244 245 <h3 class="text-lg">Relay host status</h3> ··· 301 </template> 302 303 <template x-if="did != null"> 304 - <div class="card bg-base-100 w-full max-w-sm shrink-0 shadow-2xl"> 305 <div class="card-body"> 306 - <p x-text="`DID: ${did}`"></p> 307 </div> 308 </div> 309 </template>
··· 8 <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> 9 10 <script type="module"> 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 + 22 window.SimpleQuery = service => { 23 const client = new Client({ handler: simpleFetchHandler({ service }) }); 24 return (...args) => ok(client.get(...args)); ··· 28 return (...args) => ok(client.post(...args)); 29 }; 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 + 37 window.slingshot = window.SimpleQuery('https://slingshot.microcosm.blue'); 38 window.relays = [ 39 { ··· 83 this.identifierError = null; 84 this.pds = null; 85 this.did = null; 86 + this.handle = null; 87 if (this.identifier.startsWith('https://')) { 88 this.pds = this.identifier; 89 } else { ··· 93 if (this.identifier.startsWith('did:')) { 94 this.did = this.identifier; 95 } else { 96 + this.handle = this.identifier; 97 let data; 98 try { 99 data = await window.slingshot('com.bad-example.identity.resolveMiniDoc', { ··· 119 Alpine.data('pdsCheck', pds => ({ 120 loading: false, 121 error: null, 122 + description: null, 123 124 async init() { 125 this.loading = true; 126 this.error = null; 127 + this.description = null; 128 let query = window.SimpleQuery(pds); 129 try { 130 + this.description = await query('com.atproto.server.describeServer'); 131 } catch (e) { 132 if (window.isXrpcErr(e)) { 133 this.error = e.error; ··· 138 } 139 this.loading = false; 140 } 141 + })); 142 143 Alpine.data('relayCheckHost', (pds, relay) => ({ 144 loading: false, ··· 195 } 196 this.reqCrawlStatus = "done"; 197 }, 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 + })); 229 }) 230 </script> 231 </head> ··· 281 <span x-text="pds"></span> 282 </h2> 283 284 <div x-data="pdsCheck(pds)"> 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> 307 </div> 308 309 <h3 class="text-lg">Relay host status</h3> ··· 365 </template> 366 367 <template x-if="did != null"> 368 + <div class="card bg-base-100 w-full max-w-lg shrink-0 shadow-2xl"> 369 <div class="card-body"> 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> 423 </div> 424 </div> 425 </template>