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 + );