diff --git a/src/components/common/overall-layout/mobile-wrappers/logout-wrapper.tsx b/src/components/common/overall-layout/mobile-wrappers/logout-wrapper.tsx index 41550ee4..2c2d3e88 100644 --- a/src/components/common/overall-layout/mobile-wrappers/logout-wrapper.tsx +++ b/src/components/common/overall-layout/mobile-wrappers/logout-wrapper.tsx @@ -1,4 +1,5 @@ import { LogOut } from "lucide-react"; +import { clearClientWalletState } from "@/lib/auth/clearClientWalletState"; import { useWallet } from "@meshsdk/react"; import { useRouter } from "next/router"; import { useUserStore } from "@/lib/zustand/user"; @@ -39,6 +40,8 @@ export default function LogoutWrapper({ mode, onAction }: LogoutWrapperProps) { } setPastWallet(undefined); + setPastUtxosEnabled(false); + clearClientWalletState(); router.push("/"); setTimeout(() => { router.reload(); diff --git a/src/components/common/overall-layout/mobile-wrappers/user-dropdown-wrapper.tsx b/src/components/common/overall-layout/mobile-wrappers/user-dropdown-wrapper.tsx index e83f43c8..3c5201a6 100644 --- a/src/components/common/overall-layout/mobile-wrappers/user-dropdown-wrapper.tsx +++ b/src/components/common/overall-layout/mobile-wrappers/user-dropdown-wrapper.tsx @@ -1,4 +1,5 @@ import { CircleUser, Copy, Unlink, LogOut, User } from "lucide-react"; +import { clearClientWalletState } from "@/lib/auth/clearClientWalletState"; import { Button } from "@/components/ui/button"; import { DropdownMenu, @@ -199,6 +200,8 @@ export default function UserDropDownWrapper({ } setPastWallet(undefined); + setPastUtxosEnabled(false); + clearClientWalletState(); router.push("/"); setTimeout(() => { router.reload(); diff --git a/src/components/common/overall-layout/user-drop-down.tsx b/src/components/common/overall-layout/user-drop-down.tsx index 152f3608..b5b78344 100644 --- a/src/components/common/overall-layout/user-drop-down.tsx +++ b/src/components/common/overall-layout/user-drop-down.tsx @@ -1,4 +1,5 @@ import { CircleUser } from "lucide-react"; +import { clearClientWalletState } from "@/lib/auth/clearClientWalletState"; import { Button } from "@/components/ui/button"; import { DropdownMenu, @@ -23,6 +24,7 @@ export default function UserDropDown() { const { toast } = useToast(); const router = useRouter(); const setPastWallet = useUserStore((state) => state.setPastWallet); + const setPastUtxosEnabled = useUserStore((state) => state.setPastUtxosEnabled); const userAddress = useUserStore((state) => state.userAddress); const unlinkDiscordMutation = api.user.unlinkDiscord.useMutation({ @@ -151,6 +153,8 @@ export default function UserDropDown() { } disconnect(); setPastWallet(undefined); + setPastUtxosEnabled(false); + clearClientWalletState(); router.push("/"); setTimeout(() => { router.reload(); diff --git a/src/lib/auth/clearClientWalletState.ts b/src/lib/auth/clearClientWalletState.ts new file mode 100644 index 00000000..26f8d099 --- /dev/null +++ b/src/lib/auth/clearClientWalletState.ts @@ -0,0 +1,15 @@ +/** + * Remove browser-side traces of the last connected wallet so that, after + * logout, nothing auto-reconnects and the user has to authorize again. + * Mesh persists the connected wallet under `mesh-wallet-persist`; the UTXOS + * store persists its network id under `utxos-state`. + */ +export function clearClientWalletState() { + if (typeof window === "undefined") return; + try { + localStorage.removeItem("mesh-wallet-persist"); + localStorage.removeItem("utxos-state"); + } catch (error) { + console.error("[Logout] Failed to clear persisted wallet state:", error); + } +} diff --git a/src/pages/api/auth/wallet-session.ts b/src/pages/api/auth/wallet-session.ts index f381ebe3..103b070b 100644 --- a/src/pages/api/auth/wallet-session.ts +++ b/src/pages/api/auth/wallet-session.ts @@ -4,6 +4,7 @@ import { cors, addCorsCacheBustingHeaders } from "@/lib/cors"; import { DataSignature } from "@meshsdk/core"; import { checkSignature } from "@meshsdk/core-cst"; import { + clearWalletSessionCookie, getWalletSessionFromReq, setWalletSessionCookie, type WalletSessionPayload, @@ -17,6 +18,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) return res.status(200).end(); } + // Logout: drop the session cookie so the next connect must re-authorize. + if (req.method === "DELETE") { + clearWalletSessionCookie(res); + return res.status(200).json({ ok: true }); + } + if (req.method !== "POST") { return res.status(405).json({ error: "Method Not Allowed" }); }