From 3743a328e30ad7379f1b0c105d9955acd9257390 Mon Sep 17 00:00:00 2001
From: Michael Clark <5285928+MikesGlitch@users.noreply.github.com>
Date: Tue, 17 Sep 2024 08:59:33 +0100
Subject: [PATCH] :electron: Restart server silently when adding self signed
 cert and add some logs (#3431)

* restart server silently on add self signed cert and add some logging

* release notes

* fix name

* updating names to be more specific

* removing setloading

* feedback
---
 .../src/browser-preload.browser.js            |  2 ++
 .../src/components/manager/ConfigServer.tsx   | 10 ++++++--
 .../desktop-client/src/hooks/useGlobalPref.ts | 12 ++++++++--
 packages/desktop-electron/index.ts            |  6 +++++
 packages/desktop-electron/preload.ts          |  4 ++++
 .../loot-core/src/client/actions/prefs.ts     |  6 ++++-
 .../platform/server/fetch/index.electron.ts   | 24 ++++++++++++-------
 packages/loot-core/typings/window.d.ts        |  1 +
 upcoming-release-notes/3431.md                |  6 +++++
 9 files changed, 58 insertions(+), 13 deletions(-)
 create mode 100644 upcoming-release-notes/3431.md

diff --git a/packages/desktop-client/src/browser-preload.browser.js b/packages/desktop-client/src/browser-preload.browser.js
index c7e0f0b35..75065ca52 100644
--- a/packages/desktop-client/src/browser-preload.browser.js
+++ b/packages/desktop-client/src/browser-preload.browser.js
@@ -51,6 +51,8 @@ global.Actual = {
     window.location.reload();
   },
 
+  restartElectronServer: () => {},
+
   openFileDialog: async ({ filters = [] }) => {
     return new Promise(resolve => {
       let createdElement = false;
diff --git a/packages/desktop-client/src/components/manager/ConfigServer.tsx b/packages/desktop-client/src/components/manager/ConfigServer.tsx
index 66e454330..fcc619321 100644
--- a/packages/desktop-client/src/components/manager/ConfigServer.tsx
+++ b/packages/desktop-client/src/components/manager/ConfigServer.tsx
@@ -1,5 +1,5 @@
 // @ts-strict-ignore
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useCallback } from 'react';
 import { Trans, useTranslation } from 'react-i18next';
 
 import {
@@ -34,8 +34,15 @@ export function ConfigServer() {
   }, [currentUrl]);
   const [loading, setLoading] = useState(false);
   const [error, setError] = useState<string | null>(null);
+
+  const restartElectronServer = useCallback(() => {
+    globalThis.window.Actual.restartElectronServer();
+    setError(null);
+  }, []);
+
   const [_serverSelfSignedCert, setServerSelfSignedCert] = useGlobalPref(
     'serverSelfSignedCert',
+    restartElectronServer,
   );
 
   function getErrorMessage(error: string) {
@@ -101,7 +108,6 @@ export function ConfigServer() {
 
     if (selfSignedCertificateLocation) {
       setServerSelfSignedCert(selfSignedCertificateLocation[0]);
-      globalThis.window.Actual.relaunch(); // relaunch to use the certificate
     }
   }
 
diff --git a/packages/desktop-client/src/hooks/useGlobalPref.ts b/packages/desktop-client/src/hooks/useGlobalPref.ts
index 02d5773ac..4f686a2ae 100644
--- a/packages/desktop-client/src/hooks/useGlobalPref.ts
+++ b/packages/desktop-client/src/hooks/useGlobalPref.ts
@@ -11,13 +11,21 @@ type SetGlobalPrefAction<K extends keyof GlobalPrefs> = (
 
 export function useGlobalPref<K extends keyof GlobalPrefs>(
   prefName: K,
+  onSaveGlobalPrefs?: () => void,
 ): [GlobalPrefs[K], SetGlobalPrefAction<K>] {
   const dispatch = useDispatch();
   const setGlobalPref = useCallback<SetGlobalPrefAction<K>>(
     value => {
-      dispatch(saveGlobalPrefs({ [prefName]: value } as GlobalPrefs));
+      dispatch(
+        saveGlobalPrefs(
+          {
+            [prefName]: value,
+          } as GlobalPrefs,
+          onSaveGlobalPrefs,
+        ),
+      );
     },
-    [prefName, dispatch],
+    [prefName, dispatch, onSaveGlobalPrefs],
   );
   const globalPref = useSelector(
     (state: State) => state.prefs.global?.[prefName] as GlobalPrefs[K],
diff --git a/packages/desktop-electron/index.ts b/packages/desktop-electron/index.ts
index d5767d200..dda8cf774 100644
--- a/packages/desktop-electron/index.ts
+++ b/packages/desktop-electron/index.ts
@@ -297,6 +297,12 @@ ipcMain.on('get-bootstrap-data', event => {
   event.returnValue = payload;
 });
 
+ipcMain.handle('restart-server', () => {
+  serverProcess.kill();
+  serverProcess = null;
+  createBackgroundProcess();
+});
+
 ipcMain.handle('relaunch', () => {
   app.relaunch();
   app.exit();
diff --git a/packages/desktop-electron/preload.ts b/packages/desktop-electron/preload.ts
index 832bd6a50..7ede44429 100644
--- a/packages/desktop-electron/preload.ts
+++ b/packages/desktop-electron/preload.ts
@@ -34,6 +34,10 @@ contextBridge.exposeInMainWorld('Actual', {
     ipcRenderer.invoke('relaunch');
   },
 
+  restartElectronServer: () => {
+    ipcRenderer.invoke('restart-server');
+  },
+
   openFileDialog: (opts: OpenFileDialogPayload) => {
     return ipcRenderer.invoke('open-file-dialog', opts);
   },
diff --git a/packages/loot-core/src/client/actions/prefs.ts b/packages/loot-core/src/client/actions/prefs.ts
index 5dbca103f..76b9272d6 100644
--- a/packages/loot-core/src/client/actions/prefs.ts
+++ b/packages/loot-core/src/client/actions/prefs.ts
@@ -48,12 +48,16 @@ export function loadGlobalPrefs() {
   };
 }
 
-export function saveGlobalPrefs(prefs: prefs.GlobalPrefs) {
+export function saveGlobalPrefs(
+  prefs: prefs.GlobalPrefs,
+  onSaveGlobalPrefs?: () => void,
+) {
   return async (dispatch: Dispatch) => {
     await send('save-global-prefs', prefs);
     dispatch({
       type: constants.MERGE_GLOBAL_PREFS,
       globalPrefs: prefs,
     });
+    onSaveGlobalPrefs?.();
   };
 }
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 63ba01462..05a320bc0 100644
--- a/packages/loot-core/src/platform/server/fetch/index.electron.ts
+++ b/packages/loot-core/src/platform/server/fetch/index.electron.ts
@@ -1,12 +1,20 @@
 // @ts-strict-ignore
 import nodeFetch from 'node-fetch';
 
-export const fetch = (input: RequestInfo | URL, options?: RequestInit) => {
-  return nodeFetch(input, {
-    ...options,
-    headers: {
-      ...options?.headers,
-      origin: 'app://actual',
-    },
-  });
+export const fetch = async (
+  input: RequestInfo | URL,
+  options?: RequestInit,
+) => {
+  try {
+    return await nodeFetch(input, {
+      ...options,
+      headers: {
+        ...options?.headers,
+        origin: 'app://actual',
+      },
+    });
+  } catch (error) {
+    console.error(error); // log error
+    throw error;
+  }
 };
diff --git a/packages/loot-core/typings/window.d.ts b/packages/loot-core/typings/window.d.ts
index 7f9173c6a..870114cb6 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;
+      restartElectronServer: () => void;
     };
 
     __navigate?: import('react-router').NavigateFunction;
diff --git a/upcoming-release-notes/3431.md b/upcoming-release-notes/3431.md
new file mode 100644
index 000000000..a323e31a3
--- /dev/null
+++ b/upcoming-release-notes/3431.md
@@ -0,0 +1,6 @@
+---
+category: Maintenance
+authors: [MikesGlitch]
+---
+
+Restart server silently when adding self signed cert and add some logs
-- 
GitLab