Graphical PDS migrator for AT Protocol
at main 3.6 kB view raw
1import { setCredentialSession } from "../../../lib/cred/sessions.ts"; 2import { resolver } from "../../../lib/id-resolver.ts"; 3import { define } from "../../../utils.ts"; 4import { Agent } from "npm:@atproto/api"; 5 6/** 7 * Handle credential login 8 * Save iron session to cookies 9 * Save credential session state to database 10 * @param ctx - The context object containing the request and response 11 * @returns A response object with the login result 12 */ 13export const handler = define.handlers({ 14 async POST(ctx) { 15 try { 16 const body = await ctx.req.json(); 17 const { handle, password } = body; 18 19 if (!handle || !password) { 20 return new Response( 21 JSON.stringify({ 22 success: false, 23 message: "Handle and password are required", 24 }), 25 { 26 status: 400, 27 headers: { "Content-Type": "application/json" }, 28 }, 29 ); 30 } 31 32 console.log("Resolving handle:", handle); 33 const did = typeof handle == "string" && handle.startsWith("did:") 34 ? handle 35 : await resolver.resolveHandleToDid(handle); 36 const service = await resolver.resolveDidToPdsUrl(did); 37 console.log("Resolved service:", service); 38 39 if (!service) { 40 return new Response( 41 JSON.stringify({ 42 success: false, 43 message: "Invalid handle", 44 }), 45 { 46 status: 400, 47 }, 48 ); 49 } 50 51 try { 52 // Create agent and get session 53 console.log("Creating agent with service:", service); 54 const agent = new Agent({ service }); 55 const sessionRes = await agent.com.atproto.server.createSession({ 56 identifier: handle, 57 password: password, 58 }); 59 console.log("Created ATProto session:", { 60 did: sessionRes.data.did, 61 handle: sessionRes.data.handle, 62 hasAccessJwt: !!sessionRes.data.accessJwt, 63 }); 64 65 // Create response for setting cookies 66 const response = new Response( 67 JSON.stringify({ 68 success: true, 69 did, 70 handle, 71 }), 72 { 73 status: 200, 74 headers: { "Content-Type": "application/json" }, 75 }, 76 ); 77 78 // Create and save our client session with tokens 79 await setCredentialSession(ctx.req, response, { 80 did, 81 service, 82 password, 83 handle, 84 accessJwt: sessionRes.data.accessJwt, 85 }); 86 87 // Log the response headers 88 console.log("Response headers:", { 89 cookies: response.headers.get("Set-Cookie"), 90 allHeaders: Object.fromEntries(response.headers.entries()), 91 }); 92 93 return response; 94 } catch (err) { 95 const message = err instanceof Error ? err.message : String(err); 96 console.error("Login failed:", message); 97 return new Response( 98 JSON.stringify({ 99 success: false, 100 message: "Invalid credentials", 101 }), 102 { 103 status: 401, 104 headers: { "Content-Type": "application/json" }, 105 }, 106 ); 107 } 108 } catch (error) { 109 const message = error instanceof Error ? error.message : String(error); 110 console.error("Login error:", message); 111 return new Response( 112 JSON.stringify({ 113 success: false, 114 message: error instanceof Error ? error.message : "An error occurred", 115 }), 116 { 117 status: 500, 118 headers: { "Content-Type": "application/json" }, 119 }, 120 ); 121 } 122 }, 123});