From e7be58f01d81b871165385654ab5844acc144757 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Fri, 3 Apr 2026 02:43:55 +0200 Subject: [PATCH] feat: implement deleteIdentity with S2S relay for soft/full modes --- .../components/modals/ConnectedInstances.tsx | 2 +- packages/web/src/stores/instanceStore.ts | 29 +++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/web/src/components/modals/ConnectedInstances.tsx b/packages/web/src/components/modals/ConnectedInstances.tsx index 3a4a6c28..ebfccc85 100644 --- a/packages/web/src/components/modals/ConnectedInstances.tsx +++ b/packages/web/src/components/modals/ConnectedInstances.tsx @@ -427,7 +427,7 @@ function DeleteIdentityDialog({ const [scope, setScope] = useState('this'); const handleConfirm = () => { - deleteIdentity(origin); + deleteIdentity([origin]); onClose(); }; diff --git a/packages/web/src/stores/instanceStore.ts b/packages/web/src/stores/instanceStore.ts index 0e9d21e8..0653cffe 100644 --- a/packages/web/src/stores/instanceStore.ts +++ b/packages/web/src/stores/instanceStore.ts @@ -157,7 +157,7 @@ interface InstanceState { registry: Map; registryUpdatedAt: number; syncRegistry: () => Promise; - deleteIdentity: (origin: string) => void; + deleteIdentity: (origins: string[], mode?: 'leave' | 'soft' | 'full') => Promise>; forceRemoveEntry: (origin: string) => void; probeInstance: (url: string) => Promise; @@ -703,8 +703,31 @@ export const useInstanceStore = create((set, get) => ({ await Promise.all([homePromise, ...remotePromises]); }, - deleteIdentity: (_origin: string) => { - useUIStore.getState().addToast('Identity deletion is not yet implemented', 'info', 3000); + deleteIdentity: async (origins: string[], mode: 'leave' | 'soft' | 'full' = 'leave') => { + // Leave mode: client-only cleanup, no server call + if (mode === 'leave') { + for (const origin of origins) { + get().forceRemoveEntry(origin); + } + return Object.fromEntries(origins.map(o => [o, { success: true as const }])); + } + + // Soft/full mode: S2S relay via home instance + try { + const { results } = await api.users.deleteFederationIdentity({ origins, mode }); + + // Clean up client-side state for successful deletions + for (const [origin, result] of Object.entries(results)) { + if (result.success) { + get().forceRemoveEntry(origin); + } + } + + return results; + } catch (err) { + const error = err instanceof Error ? err.message : 'Unknown error'; + return Object.fromEntries(origins.map(o => [o, { success: false as const, error }])); + } }, forceRemoveEntry: (origin: string) => {