From 8e077e0282dddb7fbd9ab578d8a6aaf31bfb85b2 Mon Sep 17 00:00:00 2001 From: Michael Clark <5285928+MikesGlitch@users.noreply.github.com> Date: Wed, 28 Aug 2024 21:39:14 +0100 Subject: [PATCH] :electron: Desktop app to work with self signed certificates (#3308) * solves the problem but creates a vulnerability * sake... * working but need to specify rootca.pem * works * being flexible on the cert names, as long as its a crt or pem * remove console logs * initial setup for adding cert * caps * comments * fix ts strict * rewrote it * release notes * remove unneeded * https no polyfill * removing the cert reference if it is not found * moving full stop --- .../src/components/manager/ConfigServer.tsx | 69 ++++++++++++++++--- .../platform/server/fetch/index.electron.ts | 2 +- packages/loot-core/src/server/main.ts | 26 +++++++ packages/loot-core/src/types/prefs.d.ts | 1 + .../webpack/webpack.browser.config.js | 1 + upcoming-release-notes/3308.md | 6 ++ 6 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 upcoming-release-notes/3308.md diff --git a/packages/desktop-client/src/components/manager/ConfigServer.tsx b/packages/desktop-client/src/components/manager/ConfigServer.tsx index 7ac54bc875c..66e45433042 100644 --- a/packages/desktop-client/src/components/manager/ConfigServer.tsx +++ b/packages/desktop-client/src/components/manager/ConfigServer.tsx @@ -8,11 +8,13 @@ import { } from 'loot-core/src/shared/environment'; import { useActions } from '../../hooks/useActions'; +import { useGlobalPref } from '../../hooks/useGlobalPref'; import { useNavigate } from '../../hooks/useNavigate'; import { useSetThemeColor } from '../../hooks/useSetThemeColor'; import { theme } from '../../style'; import { Button, ButtonWithLoading } from '../common/Button2'; import { BigInput } from '../common/Input'; +import { Link } from '../common/Link'; import { Text } from '../common/Text'; import { View } from '../common/View'; import { useServerURL, useSetServerURL } from '../ServerContext'; @@ -32,6 +34,9 @@ export function ConfigServer() { }, [currentUrl]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); + const [_serverSelfSignedCert, setServerSelfSignedCert] = useGlobalPref( + 'serverSelfSignedCert', + ); function getErrorMessage(error: string) { switch (error) { @@ -83,6 +88,23 @@ export function ConfigServer() { setUrl(window.location.origin); } + async function onSelectSelfSignedCertificate() { + const selfSignedCertificateLocation = await window.Actual?.openFileDialog({ + properties: ['openFile'], + filters: [ + { + name: 'Self Signed Certificate', + extensions: ['crt', 'pem'], + }, + ], + }); + + if (selfSignedCertificateLocation) { + setServerSelfSignedCert(selfSignedCertificateLocation[0]); + globalThis.window.Actual.relaunch(); // relaunch to use the certificate + } + } + async function onSkip() { await setServerUrl(null); await loggedIn(); @@ -121,16 +143,43 @@ export function ConfigServer() { {error && ( - - {getErrorMessage(error)} - + <> + + {getErrorMessage(error)} + + {isElectron() && ( + + + + If the server is using a self-signed certificate{' '} + + select it here + + . + + + + )} + )} diff --git a/packages/loot-core/src/platform/server/fetch/index.electron.ts b/packages/loot-core/src/platform/server/fetch/index.electron.ts index 5aabd6dd82b..63ba01462af 100644 --- a/packages/loot-core/src/platform/server/fetch/index.electron.ts +++ b/packages/loot-core/src/platform/server/fetch/index.electron.ts @@ -1,4 +1,4 @@ -// // @ts-strict-ignore +// @ts-strict-ignore import nodeFetch from 'node-fetch'; export const fetch = (input: RequestInfo | URL, options?: RequestInit) => { diff --git a/packages/loot-core/src/server/main.ts b/packages/loot-core/src/server/main.ts index eee8d7b7665..0a84bdbaf96 100644 --- a/packages/loot-core/src/server/main.ts +++ b/packages/loot-core/src/server/main.ts @@ -1,5 +1,8 @@ // @ts-strict-ignore import './polyfills'; +import https from 'https'; +import tls from 'tls'; + import * as injectAPI from '@actual-app/api/injected'; import * as CRDT from '@actual-app/crdt'; import { v4 as uuidv4 } from 'uuid'; @@ -1253,6 +1256,12 @@ handlers['save-global-prefs'] = async function (prefs) { if ('theme' in prefs) { await asyncStorage.setItem('theme', prefs.theme); } + if ('serverSelfSignedCert' in prefs) { + await asyncStorage.setItem( + 'server-self-signed-cert', + prefs.serverSelfSignedCert, + ); + } return 'ok'; }; @@ -2126,6 +2135,23 @@ export async function initApp(isDev, socketName) { } } + const selfSignedCertPath = await asyncStorage.getItem( + 'server-self-signed-cert', + ); + + if (selfSignedCertPath) { + try { + const selfSignedCert = await fs.readFile(selfSignedCertPath); + https.globalAgent.options.ca = [...tls.rootCertificates, selfSignedCert]; + } catch (error) { + console.error( + 'Unable to add the self signed certificate, removing its reference', + error, + ); + await asyncStorage.removeItem('server-self-signed-cert'); + } + } + const url = await asyncStorage.getItem('server-url'); if (!url) { diff --git a/packages/loot-core/src/types/prefs.d.ts b/packages/loot-core/src/types/prefs.d.ts index c1d7054ea48..29f3486313e 100644 --- a/packages/loot-core/src/types/prefs.d.ts +++ b/packages/loot-core/src/types/prefs.d.ts @@ -88,4 +88,5 @@ export type GlobalPrefs = Partial<{ keyId?: string; theme: Theme; documentDir: string; // Electron only + serverSelfSignedCert: string; // Electron only }>; diff --git a/packages/loot-core/webpack/webpack.browser.config.js b/packages/loot-core/webpack/webpack.browser.config.js index 9498880591d..096633ea009 100644 --- a/packages/loot-core/webpack/webpack.browser.config.js +++ b/packages/loot-core/webpack/webpack.browser.config.js @@ -41,6 +41,7 @@ module.exports = { process: require.resolve('process/browser'), stream: require.resolve('stream-browserify'), tls: false, + https: false, // used by memfs in a check which we can ignore I think url: false, zlib: require.resolve('browserify-zlib'), diff --git a/upcoming-release-notes/3308.md b/upcoming-release-notes/3308.md new file mode 100644 index 00000000000..e2b62d70c42 --- /dev/null +++ b/upcoming-release-notes/3308.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MikesGlitch] +--- + +Support servers with self signed certificates in the Desktop app