diff --git a/packages/desktop-client/src/browser-preload.browser.js b/packages/desktop-client/src/browser-preload.browser.js index 75065ca521db9b8cbf1e6a359252a64626f95e38..2522fce90657c90e2a24bbc0693685de0cf93a70 100644 --- a/packages/desktop-client/src/browser-preload.browser.js +++ b/packages/desktop-client/src/browser-preload.browser.js @@ -51,6 +51,22 @@ global.Actual = { window.location.reload(); }, + reload: () => { + if (window.navigator.serviceWorker == null) return; + + // Unregister the service worker handling routing and then reload. This should force the reload + // to query the actual server rather than delegating to the worker + return window.navigator.serviceWorker + .getRegistration('/') + .then(registration => { + if (registration == null) return; + return registration.unregister(); + }) + .then(() => { + window.location.reload(); + }); + }, + restartElectronServer: () => {}, openFileDialog: async ({ filters = [] }) => { diff --git a/packages/desktop-client/src/global-events.ts b/packages/desktop-client/src/global-events.ts index 81de6392789c6fca08fed3ec00cad19bb4c72281..619f673b259c1ca381e89c289890a933951a93ae 100644 --- a/packages/desktop-client/src/global-events.ts +++ b/packages/desktop-client/src/global-events.ts @@ -142,4 +142,8 @@ export function handleGlobalEvents(actions: BoundActions, store: Store<State>) { actions.closeBudgetUI(); actions.setAppState({ loadingText: null }); }); + + listen('api-fetch-redirected', () => { + actions.reloadApp(); + }); } diff --git a/packages/loot-core/src/client/actions/app.ts b/packages/loot-core/src/client/actions/app.ts index 6f6ca76963714063a2a4bb7d6a3634a60dcf2739..e586f55dc69242e86256dab16e22d38e1a0a7ed5 100644 --- a/packages/loot-core/src/client/actions/app.ts +++ b/packages/loot-core/src/client/actions/app.ts @@ -46,3 +46,9 @@ export function focused() { return send('app-focused'); }; } + +export function reloadApp() { + return () => { + global.Actual.reload(); + }; +} diff --git a/packages/loot-core/src/platform/server/fetch/index.web.ts b/packages/loot-core/src/platform/server/fetch/index.web.ts index db20b9acb807998f47ca1d11451f1a08812d2129..f93196b0f5fb5e6f80c276dca760fdfc397248ef 100644 --- a/packages/loot-core/src/platform/server/fetch/index.web.ts +++ b/packages/loot-core/src/platform/server/fetch/index.web.ts @@ -1 +1,19 @@ -export const fetch = globalThis.fetch; +import * as connection from '../connection'; + +export const fetch = async ( + input: RequestInfo | URL, + options?: RequestInit, +): Promise<Response> => { + const response = await globalThis.fetch(input, options); + + // Detect if the API query has been redirected to a different origin. This may indicate that the + // request has been intercepted by an authentication proxy + const originalUrl = new URL(input instanceof Request ? input.url : input); + const responseUrl = new URL(response.url); + if (response.redirected && responseUrl.host !== originalUrl.host) { + connection.send('api-fetch-redirected'); + throw new Error(`API request redirected to ${responseUrl.host}`); + } + + return response; +}; diff --git a/packages/loot-core/src/types/server-events.d.ts b/packages/loot-core/src/types/server-events.d.ts index d256ddfd422abf4d7dd580648f434d754a3f6180..c53004a9cab5416aa947457e3d142768aa507c38 100644 --- a/packages/loot-core/src/types/server-events.d.ts +++ b/packages/loot-core/src/types/server-events.d.ts @@ -18,4 +18,5 @@ export interface ServerEvents { 'start-load': unknown; 'sync-event': { type; subtype; meta; tables; syncDisabled }; 'undo-event': UndoState; + 'api-fetch-redirected': unknown; } diff --git a/packages/loot-core/typings/window.d.ts b/packages/loot-core/typings/window.d.ts index 870114cb64bf6e620900bf009bfa81740eb645ab..9dde1c2b45b93e4d44a926a2699e2097709f4095 100644 --- a/packages/loot-core/typings/window.d.ts +++ b/packages/loot-core/typings/window.d.ts @@ -15,6 +15,7 @@ declare global { opts: Parameters<import('electron').Dialog['showOpenDialogSync']>[0], ) => Promise<string[]>; relaunch: () => void; + reload: (() => Promise<void>) | undefined; restartElectronServer: () => void; }; diff --git a/upcoming-release-notes/3286.md b/upcoming-release-notes/3286.md new file mode 100644 index 0000000000000000000000000000000000000000..d055ab0de8cde2bb12f4e37efb27941dfa9317a2 --- /dev/null +++ b/upcoming-release-notes/3286.md @@ -0,0 +1,6 @@ +--- +category: Bugfix +authors: [TimQuelch] +--- + +Forcibly reload app when API request is redirected. This fixes issue #2793