Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions frontend/src/components/AccountMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,14 @@ export function AccountMenu() {
sessionStorage.removeItem("maple_billing_token");
}

// Stop proxy and reset config so it doesn't auto-start on next launch
try {
const { proxyService } = await import("@/services/proxyService");
await proxyService.stopAndResetProxy();
} catch (error) {
console.error("Error clearing proxy config:", error);
}

// Sign out from OpenSecret
await os.signOut();

Expand Down
8 changes: 8 additions & 0 deletions frontend/src/components/DeleteAccountDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ export function DeleteAccountDialog({ open, onOpenChange }: DeleteAccountDialogP
sessionStorage.removeItem("maple_billing_token");
}

// Stop proxy and reset config so it doesn't auto-start on next launch
try {
const { proxyService } = await import("@/services/proxyService");
await proxyService.stopAndResetProxy();
} catch (error) {
console.error("Error clearing proxy config:", error);
}

// Sign out
await os.signOut();

Expand Down
8 changes: 8 additions & 0 deletions frontend/src/components/GuestPaymentWarningDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ export function GuestPaymentWarningDialog({ open, onOpenChange }: GuestPaymentWa
};

const handleLogout = async () => {
// Stop proxy and reset config so it doesn't auto-start on next launch
try {
const { proxyService } = await import("@/services/proxyService");
await proxyService.stopAndResetProxy();
} catch (error) {
console.error("Error clearing proxy config:", error);
}

await os.signOut();
};

Expand Down
14 changes: 13 additions & 1 deletion frontend/src/components/VerificationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ export function VerificationModal() {
}
};

const handleSignOut = async () => {
// Stop proxy and reset config so it doesn't auto-start on next launch
try {
const { proxyService } = await import("@/services/proxyService");
await proxyService.stopAndResetProxy();
} catch (error) {
console.error("Error clearing proxy config:", error);
}

await os.signOut();
};

return (
<Dialog open={isOpen} onOpenChange={handleOpenChange}>
<DialogContent className="max-w-[calc(100vw-2rem)] sm:max-w-[425px] [&>button]:hidden">
Expand Down Expand Up @@ -148,7 +160,7 @@ export function VerificationModal() {
)}
</Button>
)}
<Button variant="outline" onClick={() => os.signOut()} className="gap-2">
<Button variant="outline" onClick={handleSignOut} className="gap-2">
<LogOut className="w-4 h-4" />
Log Out
</Button>
Expand Down
27 changes: 27 additions & 0 deletions frontend/src/services/proxyService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,33 @@ class ProxyService {
}
}

// Stop proxy if running and reset saved config (used on logout)
async stopAndResetProxy(): Promise<void> {
try {
// Check if proxy is running and stop it
const status = await this.getProxyStatus();
if (status.running) {
await this.stopProxy();
}
} catch {
// Proxy may not be running, that's fine
}
Comment on lines +97 to +99
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Do not silently swallow cleanup failures in stopAndResetProxy.

At Line 97, all status/stop errors are ignored. If stopProxy() fails while running, logout can complete with the proxy still active.
Surface cleanup failures to callers (they already catch) so failures are observable while sign-out still proceeds.

Proposed fix
   async stopAndResetProxy(): Promise<void> {
+    let cleanupError: unknown = null;
     try {
       // Check if proxy is running and stop it
       const status = await this.getProxyStatus();
       if (status.running) {
         await this.stopProxy();
       }
-    } catch {
-      // Proxy may not be running, that's fine
+    } catch (error) {
+      cleanupError ??= error;
+      console.error("Failed to stop proxy during sign-out cleanup:", error);
     }
 
     try {
       // Save default config to clear auto_start and API key
       await this.saveProxySettings({
@@
         auto_start: false
       });
     } catch (error) {
+      cleanupError ??= error;
       console.error("Failed to reset proxy config:", error);
     }
+
+    if (cleanupError) {
+      throw cleanupError;
+    }
   }

Also applies to: 111-113

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/services/proxyService.ts` around lines 97 - 99, The cleanup code
in stopAndResetProxy is silently swallowing errors from stopProxy(), so failures
are hidden; change the try/catch blocks around stopProxy() (and the other
similar block) to let errors propagate to callers instead of ignoring
them—either remove the empty catch or rethrow the caught error (optionally log
it via the existing logger before rethrowing) so callers can observe cleanup
failures while sign-out continues; target the stopAndResetProxy function and the
explicit stopProxy() invocation(s) to implement this change.


try {
// Save default config to clear auto_start and API key
await this.saveProxySettings({
host: "127.0.0.1",
port: 8080,
api_key: "",
enabled: false,
enable_cors: true,
auto_start: false
});
} catch (error) {
console.error("Failed to reset proxy config:", error);
}
}

// Helper to check if we're in Tauri desktop environment
async isTauriDesktop(): Promise<boolean> {
try {
Expand Down
Loading