From 84c66dd461330ce169fe7da14e2045e4b3efe729 Mon Sep 17 00:00:00 2001
From: Gabriel Kaszewski
Date: Thu, 28 May 2026 02:01:56 +0200
Subject: [PATCH] feat: add alsoKnownAs field to federation settings
---
.../app/settings/federation/page.tsx | 2 +
.../federation/migration-settings.tsx | 57 +++++++++++++++++++
thoughts-frontend/lib/api.ts | 8 +++
3 files changed, 67 insertions(+)
create mode 100644 thoughts-frontend/components/federation/migration-settings.tsx
diff --git a/thoughts-frontend/app/settings/federation/page.tsx b/thoughts-frontend/app/settings/federation/page.tsx
index 0d03082..9b0cbdd 100644
--- a/thoughts-frontend/app/settings/federation/page.tsx
+++ b/thoughts-frontend/app/settings/federation/page.tsx
@@ -1,6 +1,7 @@
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { FederationPanel } from "@/components/federation/federation-panel";
+import { MigrationSettings } from "@/components/federation/migration-settings";
export default async function FederationSettingsPage() {
const token = (await cookies()).get("auth_token")?.value;
@@ -18,6 +19,7 @@ export default async function FederationSettingsPage() {
+
);
}
diff --git a/thoughts-frontend/components/federation/migration-settings.tsx b/thoughts-frontend/components/federation/migration-settings.tsx
new file mode 100644
index 0000000..9499fc4
--- /dev/null
+++ b/thoughts-frontend/components/federation/migration-settings.tsx
@@ -0,0 +1,57 @@
+"use client";
+
+import { useState } from "react";
+import { setAlsoKnownAs } from "@/lib/api";
+import { useAuth } from "@/hooks/use-auth";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { toast } from "sonner";
+
+export function MigrationSettings() {
+ const { token } = useAuth();
+ const [value, setValue] = useState("");
+ const [saving, setSaving] = useState(false);
+
+ const handleSave = async () => {
+ if (!token) return;
+ setSaving(true);
+ try {
+ await setAlsoKnownAs(value.trim() || null, token);
+ toast.success(value.trim() ? "Also known as saved." : "Also known as cleared.");
+ } catch {
+ toast.error("Failed to save.");
+ } finally {
+ setSaving(false);
+ }
+ };
+
+ return (
+
+
+
Account migration
+
+ Set your new actor URL before broadcasting a Move. This lets remote
+ servers verify the migration is legitimate.
+
+
+
+
+
+ The full actor URL on your new server, e.g.{" "}
+ https://newdomain.com/users/<uuid>
+
+
+ setValue(e.target.value)}
+ placeholder="https://newdomain.com/users/…"
+ className="font-mono text-sm"
+ />
+
+
+
+
+ );
+}
diff --git a/thoughts-frontend/lib/api.ts b/thoughts-frontend/lib/api.ts
index 0769dd5..c94b390 100644
--- a/thoughts-frontend/lib/api.ts
+++ b/thoughts-frontend/lib/api.ts
@@ -487,3 +487,11 @@ export const unfollowRemoteActor = (handle: string, token: string) =>
z.null(),
token
);
+
+export const setAlsoKnownAs = (value: string | null, token: string) =>
+ apiFetch(
+ "/federation/me/also-known-as",
+ { method: "PATCH", body: JSON.stringify({ also_known_as: value || null }) },
+ z.null(),
+ token
+ );