an app to share curated trails
sidetrail.app
1"use server";
2
3import "server-only";
4import { redirect } from "next/navigation";
5import { getOAuthClient, getSession } from "./index";
6
7export async function login(formData: FormData) {
8 const rawHandle = formData.get("loginHint") as string;
9 let returnUrl = (formData.get("returnUrl") as string) || "/";
10 if (!returnUrl.startsWith("/")) {
11 returnUrl = "/";
12 }
13
14 const handle = rawHandle?.trim().replace(/^@/, "");
15 if (!handle) {
16 redirect("/login?error=" + encodeURIComponent("Please enter your handle"));
17 }
18
19 let authorizationUrl: string;
20 try {
21 const client = await getOAuthClient();
22 authorizationUrl = (
23 await client.authorize(handle, {
24 scope: "atproto transition:generic",
25 state: JSON.stringify({ returnUrl }),
26 })
27 ).toString();
28 } catch (error) {
29 console.error("OAuth authorize error:", error);
30 const message = error instanceof Error ? error.message : "Unknown error";
31 redirect("/login?error=" + encodeURIComponent(`Login failed: ${message}`));
32 }
33 redirect(authorizationUrl);
34}
35
36export async function logout(returnUrl: string = "/") {
37 const session = await getSession();
38
39 if (session.did) {
40 try {
41 const client = await getOAuthClient();
42 const oauthSession = await client.restore(session.did);
43 if (oauthSession) {
44 await oauthSession.signOut();
45 }
46 } catch (err) {
47 console.error("Failed to sign out OAuth session:", err);
48 }
49 }
50
51 session.destroy();
52 redirect(returnUrl);
53}