Graphical PDS migrator for AT Protocol
1import { getSessionAgent } from "../../../lib/sessions.ts";
2import { define } from "../../../utils.ts";
3import * as plc from "@did-plc/lib";
4
5/**
6 * Verify if a rotation key exists in the PLC document
7 * Body must contain:
8 * - key: The rotation key to verify
9 * @param ctx - The context object containing the request and response
10 * @returns A response object with the verification result
11 */
12export const handler = define.handlers({
13 async POST(ctx) {
14 const res = new Response();
15 try {
16 const body = await ctx.req.json();
17 const { key: newKey } = body;
18 console.log("Request body:", { newKey });
19
20 if (!newKey) {
21 console.log("Missing key in request");
22 return new Response("Missing param key in request body", {
23 status: 400,
24 });
25 }
26
27 const agent = await getSessionAgent(ctx.req, res);
28 if (!agent) {
29 console.log("No agent found");
30 return new Response("Unauthorized", { status: 401 });
31 }
32
33 const session = await agent.com.atproto.server.getSession();
34 const did = session.data.did;
35 if (!did) {
36 console.log("No DID found in session");
37 return new Response(
38 JSON.stringify({
39 success: false,
40 message: "No DID found in your session",
41 }),
42 {
43 status: 400,
44 headers: { "Content-Type": "application/json" },
45 },
46 );
47 }
48 console.log("Using agent DID:", did);
49
50 // Fetch the PLC document to check rotation keys
51 console.log("Getting did:plc document...");
52 const plcClient = new plc.Client("https://plc.directory");
53 const didDoc = await plcClient.getDocumentData(did);
54 if (!didDoc) {
55 console.log("No DID document found for agent DID");
56 return new Response(
57 JSON.stringify({
58 success: false,
59 message: "No DID document found for your account",
60 }),
61 {
62 status: 400,
63 headers: { "Content-Type": "application/json" },
64 },
65 );
66 }
67 console.log("Got DID document:", didDoc);
68
69 const rotationKeys = didDoc.rotationKeys ?? [];
70 if (!rotationKeys.length) {
71 console.log("No existing rotation keys found");
72 throw new Error("No rotation keys found in did:plc document");
73 }
74
75 // Check if the key exists in rotation keys
76 if (rotationKeys.includes(newKey)) {
77 return new Response(
78 JSON.stringify({
79 success: true,
80 message: "Rotation key exists in PLC document",
81 }),
82 {
83 status: 200,
84 headers: {
85 "Content-Type": "application/json",
86 ...Object.fromEntries(res.headers), // Include session cookie headers
87 },
88 },
89 );
90 }
91
92 // If we get here, the key was not found
93 return new Response(
94 JSON.stringify({
95 success: false,
96 message: "Rotation key not found in PLC document",
97 }),
98 {
99 status: 404,
100 headers: { "Content-Type": "application/json" },
101 },
102 );
103 } catch (error) {
104 console.error("PLC verification error:", error);
105 const errorMessage = error instanceof Error
106 ? error.message
107 : "Failed to verify rotation key";
108 console.log("Sending error response:", errorMessage);
109
110 return new Response(
111 JSON.stringify({
112 success: false,
113 message: errorMessage,
114 error: error instanceof Error
115 ? {
116 name: error.name,
117 message: error.message,
118 stack: error.stack,
119 }
120 : String(error),
121 }),
122 {
123 status: 400,
124 headers: { "Content-Type": "application/json" },
125 },
126 );
127 }
128 },
129});