Graphical PDS migrator for AT Protocol
at main 5.3 kB view raw
1import { checkDidsMatch } from "../../../lib/check-dids.ts"; 2import { getSessionAgent } from "../../../lib/sessions.ts"; 3import { define } from "../../../utils.ts"; 4 5export const handler = define.handlers({ 6 async GET(ctx) { 7 console.log("Status check: Starting"); 8 const url = new URL(ctx.req.url); 9 const params = new URLSearchParams(url.search); 10 const step = params.get("step"); 11 console.log("Status check: Step", step); 12 13 console.log("Status check: Getting agents"); 14 const oldAgent = await getSessionAgent(ctx.req); 15 const newAgent = await getSessionAgent(ctx.req, new Response(), true); 16 17 if (!oldAgent || !newAgent) { 18 console.log("Status check: Unauthorized - missing agents", { 19 hasOldAgent: !!oldAgent, 20 hasNewAgent: !!newAgent, 21 }); 22 return new Response("Unauthorized", { status: 401 }); 23 } 24 25 const didsMatch = await checkDidsMatch(ctx.req); 26 27 console.log("Status check: Fetching account statuses"); 28 const oldStatus = await oldAgent.com.atproto.server.checkAccountStatus(); 29 const newStatus = await newAgent.com.atproto.server.checkAccountStatus(); 30 31 if (!oldStatus.data || !newStatus.data) { 32 console.error("Status check: Failed to verify status", { 33 hasOldStatus: !!oldStatus.data, 34 hasNewStatus: !!newStatus.data, 35 }); 36 return new Response("Could not verify status", { status: 500 }); 37 } 38 39 console.log("Status check: Account statuses", { 40 old: oldStatus.data, 41 new: newStatus.data, 42 }); 43 44 const readyToContinue = () => { 45 if (!didsMatch) { 46 return { 47 ready: false, 48 reason: "Invalid state, original and target DIDs do not match", 49 }; 50 } 51 if (step) { 52 console.log("Status check: Evaluating step", step); 53 switch (step) { 54 case "1": { 55 if (newStatus.data) { 56 console.log("Status check: Step 1 ready"); 57 return { ready: true }; 58 } 59 console.log( 60 "Status check: Step 1 not ready - new account status not available", 61 ); 62 return { ready: false, reason: "New account status not available" }; 63 } 64 case "2": { 65 const isReady = newStatus.data.repoCommit && 66 newStatus.data.indexedRecords === oldStatus.data.indexedRecords && 67 newStatus.data.privateStateValues === 68 oldStatus.data.privateStateValues && 69 newStatus.data.expectedBlobs === newStatus.data.importedBlobs && 70 newStatus.data.importedBlobs === oldStatus.data.importedBlobs; 71 72 if (isReady) { 73 console.log("Status check: Step 2 ready"); 74 return { ready: true }; 75 } 76 77 const reasons = []; 78 if (!newStatus.data.repoCommit) { 79 reasons.push("Repository not imported."); 80 } 81 if (newStatus.data.indexedRecords < oldStatus.data.indexedRecords) { 82 reasons.push("Not all records imported."); 83 } 84 if ( 85 newStatus.data.privateStateValues < 86 oldStatus.data.privateStateValues 87 ) { 88 reasons.push("Not all private state values imported."); 89 } 90 if (newStatus.data.expectedBlobs !== newStatus.data.importedBlobs) { 91 reasons.push("Expected blobs not fully imported."); 92 } 93 if (newStatus.data.importedBlobs < oldStatus.data.importedBlobs) { 94 reasons.push("Not all blobs imported."); 95 } 96 97 console.log("Status check: Step 2 not ready", { reasons }); 98 return { ready: false, reason: reasons.join(", ") }; 99 } 100 case "3": { 101 if (newStatus.data.validDid) { 102 console.log("Status check: Step 3 ready"); 103 return { ready: true }; 104 } 105 console.log("Status check: Step 3 not ready - DID not valid"); 106 return { ready: false, reason: "DID not valid" }; 107 } 108 case "4": { 109 if ( 110 newStatus.data.activated === true && 111 oldStatus.data.activated === false 112 ) { 113 console.log("Status check: Step 4 ready"); 114 return { ready: true }; 115 } 116 console.log( 117 "Status check: Step 4 not ready - Account not activated", 118 ); 119 return { ready: false, reason: "Account not activated" }; 120 } 121 } 122 } else { 123 console.log("Status check: No step specified, returning ready"); 124 return { ready: true }; 125 } 126 }; 127 128 const status = { 129 activated: newStatus.data.activated, 130 validDid: newStatus.data.validDid, 131 repoCommit: newStatus.data.repoCommit, 132 repoRev: newStatus.data.repoRev, 133 repoBlocks: newStatus.data.repoBlocks, 134 expectedRecords: oldStatus.data.indexedRecords, 135 indexedRecords: newStatus.data.indexedRecords, 136 privateStateValues: newStatus.data.privateStateValues, 137 expectedBlobs: newStatus.data.expectedBlobs, 138 importedBlobs: newStatus.data.importedBlobs, 139 ...readyToContinue(), 140 }; 141 142 console.log("Status check: Complete", status); 143 return Response.json(status); 144 }, 145});