diff --git a/surfsense_desktop/src/main.ts b/surfsense_desktop/src/main.ts index aaf59292e..74fd7ba4e 100644 --- a/surfsense_desktop/src/main.ts +++ b/surfsense_desktop/src/main.ts @@ -1,4 +1,4 @@ -import { app, BrowserWindow, shell, ipcMain } from 'electron'; +import { app, BrowserWindow, shell, ipcMain, session } from 'electron'; import path from 'path'; import { spawn, ChildProcess } from 'child_process'; import { resolveEnv } from './resolve-env'; @@ -10,6 +10,12 @@ let deepLinkUrl: string | null = null; const SERVER_PORT = 3000; const PROTOCOL = 'surfsense'; +// TODO: Hardcoded URL is fragile — production domain may change and +// self-hosted users have their own. Two options: +// 1. Load from .env file using dotenv — users edit the file to change it. +// 2. Backend endpoint (GET /api/v1/config/frontend-url) that returns +// the backend's NEXT_FRONTEND_URL — automatic, no file to manage. +const HOSTED_FRONTEND_URL = 'https://surfsense.net'; function getStandalonePath(): string { if (isDev) { @@ -104,6 +110,14 @@ function createWindow() { return { action: 'deny' }; }); + // Intercept backend OAuth redirects targeting the hosted web frontend + // and rewrite them to localhost so the user stays in the desktop app. + const filter = { urls: [`${HOSTED_FRONTEND_URL}/*`] }; + session.defaultSession.webRequest.onBeforeRequest(filter, (details, callback) => { + const rewritten = details.url.replace(HOSTED_FRONTEND_URL, `http://localhost:${SERVER_PORT}`); + callback({ redirectURL: rewritten }); + }); + if (isDev) { mainWindow.webContents.openDevTools(); } diff --git a/surfsense_web/app/(home)/login/page.tsx b/surfsense_web/app/(home)/login/page.tsx index 08c191335..8b3be3805 100644 --- a/surfsense_web/app/(home)/login/page.tsx +++ b/surfsense_web/app/(home)/login/page.tsx @@ -35,15 +35,6 @@ function LoginContent() { localStorage.setItem("surfsense_redirect_path", decodeURIComponent(returnUrl)); } - // Desktop app: persist login source so TokenHandler can redirect to - // the surfsense:// deep link after the OAuth round-trip completes. - const source = searchParams.get("source"); - if (source === "desktop") { - sessionStorage.setItem("surfsense_login_source", "desktop"); - } else { - sessionStorage.removeItem("surfsense_login_source"); - } - // Show registration success message if (registered === "true") { toast.success(t("register_success"), { diff --git a/surfsense_web/components/TokenHandler.tsx b/surfsense_web/components/TokenHandler.tsx index 6b5e10d8e..230cda81a 100644 --- a/surfsense_web/components/TokenHandler.tsx +++ b/surfsense_web/components/TokenHandler.tsx @@ -60,15 +60,6 @@ const TokenHandler = ({ setRefreshToken(refreshToken); } - // Desktop app: redirect tokens to the Electron deep link handler - const loginSource = sessionStorage.getItem("surfsense_login_source"); - if (loginSource === "desktop") { - sessionStorage.removeItem("surfsense_login_source"); - const deepLink = `surfsense://auth/callback?token=${token}${refreshToken ? `&refresh_token=${refreshToken}` : ""}`; - window.location.href = deepLink; - return; - } - // Check if there's a saved redirect path from before the auth flow const savedRedirectPath = getAndClearRedirectPath();