From 7bf95d713ee39ab90c8ef52343528d236b57bb16 Mon Sep 17 00:00:00 2001 From: saknarajapakshe Date: Thu, 16 Jul 2026 18:17:34 +0530 Subject: [PATCH] feat: implement account removal and logoutAll functionality in AccountContext --- src/nonview/core/AccountContext.tsx | 42 +++++++++++++++++++++++++---- src/nonview/core/accountStorage.ts | 10 +------ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/nonview/core/AccountContext.tsx b/src/nonview/core/AccountContext.tsx index d964c22..2ead060 100644 --- a/src/nonview/core/AccountContext.tsx +++ b/src/nonview/core/AccountContext.tsx @@ -9,6 +9,7 @@ import React, { } from "react"; import { useAuth } from "./AuthContext"; import { APIClient, APIError, defaultBaseURL } from "../api/client"; +import { clearAccount } from "../cache/db"; import { type AccountSession, type LinkedAccount, @@ -17,6 +18,7 @@ import { getAccounts, getSession, getSessions, + removeAccountFromStorage, removeSession, saveAccount, saveSession, @@ -186,13 +188,43 @@ export const AccountProvider: React.FC = ({ children }) => [authContext], ); - const removeAccount = useCallback(async (_id: string): Promise => { - throw new Error("removeAccount is not implemented yet — see Parent Issue 5"); - }, []); + const removeAccount = useCallback( + async (id: string): Promise => { + const account = getAccount(id); + if (!account) return; + + const session = getSession(id); + if (session) { + await authContext.logout(session); + } + removeSession(id); + await clearAccount(account.id); + removeAccountFromStorage(id); + + const remaining = getAccounts(); + setAccounts(remaining); + setSessions(getSessions()); + + if (activeAccountId === id) { + if (remaining.length > 0) { + switchAccount(remaining[0].id); + } else { + sessionStorage.removeItem(STORAGE_ACTIVE_ACCOUNT); + setActiveAccountId(null); + } + } + }, + [authContext, activeAccountId, switchAccount], + ); const logoutAll = useCallback(async (): Promise => { - throw new Error("logoutAll is not implemented yet — see Parent Issue 5"); - }, []); + const allSessions = getSessions(); + await Promise.all(allSessions.map((s) => authContext.logout(s))); + allSessions.forEach((s) => removeSession(s.accountId)); + setSessions(getSessions()); + sessionStorage.removeItem(STORAGE_ACTIVE_ACCOUNT); + setActiveAccountId(null); + }, [authContext]); const value: AccountContextValue = { accounts, diff --git a/src/nonview/core/accountStorage.ts b/src/nonview/core/accountStorage.ts index 95b57ce..fbacf5a 100644 --- a/src/nonview/core/accountStorage.ts +++ b/src/nonview/core/accountStorage.ts @@ -1,11 +1,3 @@ -// Multi-account storage layer. Replaces the single-profile model (see -// AuthContext.tsx's MailProfile) with a list of linked accounts and a -// separate list of their sessions — accounts and sessions have different -// lifecycles (a 401 invalidates a session, not the linked account). -// -// Nothing consumes this module yet; it's additive groundwork for the -// upcoming AccountContext. - import type { LoginRequest } from "../api/types"; export interface LinkedAccount { @@ -109,7 +101,7 @@ export function updateAccount( return updated; } -export function removeAccount(id: string): void { +export function removeAccountFromStorage(id: string): void { writeList( STORAGE_ACCOUNTS, getAccounts().filter((a) => a.id !== id),