atproto pds in zig
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132#!/usr/bin/env node
const oldHandle = mustEnv("OLD_HANDLE");const password = mustEnv("OLD_PASSWORD");const newEmail = mustEnv("NEW_EMAIL");const newPds = process.env.NEW_PDS ?? "https://pds.zat.dev";const newHandle = process.env.NEW_HANDLE ?? oldHandle;const sourcePdsOverride = process.env.SOURCE_PDS;
function mustEnv(name) { const value = process.env[name]; if (!value) { console.error(`missing ${name}`); process.exit(2); } return value;}
function cleanHandle(handle) { return handle.replace("@", "").trim().replace(/[\u202A\u202C\u200E\u200F\u2066-\u2069]/g, "");}
async function requestJson(label, method, baseUrl, nsid, { params, body, token } = {}) { const url = new URL(`/xrpc/${nsid}`, baseUrl); if (params) { for (const [key, value] of Object.entries(params)) { if (value != null) url.searchParams.set(key, value); } } const headers = { accept: "application/json" }; if (body !== undefined) headers["content-type"] = "application/json"; if (token) headers.authorization = `Bearer ${token}`; const started = Date.now(); const res = await fetch(url, { method, headers, body: body === undefined ? undefined : JSON.stringify(body), }); const text = await res.text(); let data = null; if (text) { try { data = JSON.parse(text); } catch { data = { raw: text.slice(0, 200) }; } } const error = data?.error ? ` error=${data.error}` : ""; console.log(`${label}: ${method} ${url} -> ${res.status} ${res.statusText}${error} (${Date.now() - started}ms)`); if (!res.ok) { const err = new Error(data?.message ?? `${res.status} ${res.statusText}`); err.status = res.status; err.data = data; throw err; } return data;}
async function resolveMiniDoc(handle) { const url = new URL("https://slingshot.microcosm.blue/xrpc/blue.microcosm.identity.resolveMiniDoc"); url.searchParams.set("identifier", handle); const res = await fetch(url); if (!res.ok) throw new Error(`resolveMiniDoc failed: ${res.status}`); return res.json();}
async function main() { const handle = cleanHandle(oldHandle); const mini = sourcePdsOverride ? { did: null, handle, pds: sourcePdsOverride } : await resolveMiniDoc(handle);
console.log(`source handle=${handle}`); if (mini.did) console.log(`source did=${mini.did}`); console.log(`source pds=${mini.pds}`); console.log(`target pds=${newPds}`); console.log(`target handle=${newHandle}`);
const oldSession = await requestJson("old login", "POST", mini.pds, "com.atproto.server.createSession", { body: { identifier: handle, password }, }); const did = oldSession.did; console.log(`old login ok did=${did} handle=${oldSession.handle}`);
const newDesc = await requestJson("new describe", "GET", newPds, "com.atproto.server.describeServer"); console.log(`new pds did=${newDesc.did}`);
const serviceAuth = await requestJson("old service auth", "GET", mini.pds, "com.atproto.server.getServiceAuth", { token: oldSession.accessJwt, params: { aud: newDesc.did, lxm: "com.atproto.server.createAccount", }, }); console.log("old service auth ok");
try { await requestJson("new repo status before create", "GET", newPds, "com.atproto.sync.getRepoStatus", { params: { did }, }); } catch (err) { console.log(`new repo status before create expected miss: ${err.status} ${err.data?.error ?? err.message}`); }
const created = await requestJson("new create account", "POST", newPds, "com.atproto.server.createAccount", { token: serviceAuth.token, body: { did, handle: newHandle, email: newEmail, password, }, }); console.log(`new create account ok did=${created.did} handle=${created.handle}`);
const byDid = await requestJson("new login by did", "POST", newPds, "com.atproto.server.createSession", { body: { identifier: did, password }, }); console.log(`new login by did ok active=${byDid.active}`);
const byHandle = await requestJson("new login by handle", "POST", newPds, "com.atproto.server.createSession", { body: { identifier: newHandle, password }, }); console.log(`new login by handle ok active=${byHandle.active}`);}
main().catch((err) => { console.error(`trace failed: ${err.message}`); if (err.data) console.error(JSON.stringify(err.data, null, 2)); process.exit(1);});