Something went wrong. Try again.
a tiny oauth browser client for atproto using a service worker
Something went wrong. Try again.
2.1 kB · 72 lines
HTML
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273<!doctype html><html> <head> <meta charset="utf-8" /> <title>atproto oauth</title> <style> :root { color-scheme: light dark; font-family: system-ui, sans-serif; } </style> </head> <body> <div id="app"> <h1>atproto oauth</h1> <form id="login"> <input name="handle" placeholder="you.bsky.social" /> <button>Login</button> </form> <pre id="out"></pre> </div> <script type="module"> import { logIn, listSessions, logOut } from "./atsw.js";
// register the service worker that handles the callback and authenticates PDS requests await navigator.serviceWorker.register("./atsw.js", { type: "module" }); await navigator.serviceWorker.ready;
const config = { clientId: "https://jake.tngl.io/atsw/client-metadata.json", redirectUri: "https://jake.tngl.io/atsw/", scope: "atproto repo?collection=com.atproto.server.getSession", }; const out = (msg) => (document.getElementById("out").textContent = msg);
document.getElementById("login").onsubmit = async (e) => { const data = new FormData(e.target); const handle = data.get("handle").trim(); if (!handle) return; e.preventDefault(); try { out("Logging in..."); await logIn(config, handle); } catch (e) { out(e.message); } };
// Show any sessions the service worker has stored. const sessions = await listSessions(); if (sessions.length) { document.getElementById("login").hidden = true; const session = sessions[0]; out(`Logged in as ${session.did} @ ${session.pds}\n\nVerifying session...`);
// the service worker intercepts this request and signs it with DPoP + auth headers const res = await fetch(`${session.pds}/xrpc/com.atproto.server.getSession`); const data = await res.json();
out(`Session verified:\n${JSON.stringify(data, null, 2)}`);
const btn = document.createElement("button"); btn.textContent = "Log out"; btn.onclick = async () => { await logOut(session.did); location.reload(); }; document.getElementById("app").appendChild(btn); } </script> </body></html>