From f75d0f80998322c208fe3d7fe098091e543f4919 Mon Sep 17 00:00:00 2001
From: Michael Clark <5285928+MikesGlitch@users.noreply.github.com>
Date: Wed, 17 Jul 2024 22:31:09 +0100
Subject: [PATCH] =?UTF-8?q?:electron:=20security.js=20and=20preload.js=20?=
 =?UTF-8?q?=E2=9E=A1=EF=B8=8F=20.ts=20=20(#3066)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/desktop-electron/index.ts            | 48 ++++++++++++++-----
 .../{preload.js => preload.ts}                | 37 +++++++++-----
 .../{security.js => security.ts}              | 14 ++----
 upcoming-release-notes/3066.md                |  6 +++
 4 files changed, 72 insertions(+), 33 deletions(-)
 rename packages/desktop-electron/{preload.js => preload.ts} (51%)
 rename packages/desktop-electron/{security.js => security.ts} (65%)
 create mode 100644 upcoming-release-notes/3066.md

diff --git a/packages/desktop-electron/index.ts b/packages/desktop-electron/index.ts
index 049e79c35..c7d9df812 100644
--- a/packages/desktop-electron/index.ts
+++ b/packages/desktop-electron/index.ts
@@ -13,6 +13,8 @@ import {
   protocol,
   utilityProcess,
   UtilityProcess,
+  OpenDialogSyncOptions,
+  SaveDialogOptions,
 } from 'electron';
 import isDev from 'electron-is-dev';
 // @ts-strict-ignore
@@ -269,11 +271,18 @@ app.on('activate', () => {
   }
 });
 
+export type GetBootstrapDataPayload = {
+  version: string;
+  isDev: boolean;
+};
+
 ipcMain.on('get-bootstrap-data', event => {
-  event.returnValue = {
+  const payload: GetBootstrapDataPayload = {
     version: app.getVersion(),
     isDev,
   };
+
+  event.returnValue = payload;
 });
 
 ipcMain.handle('relaunch', () => {
@@ -281,16 +290,33 @@ ipcMain.handle('relaunch', () => {
   app.exit();
 });
 
-ipcMain.handle('open-file-dialog', (event, { filters, properties }) => {
-  return dialog.showOpenDialogSync({
-    properties: properties || ['openFile'],
-    filters,
-  });
-});
+export type OpenFileDialogPayload = {
+  properties: OpenDialogSyncOptions['properties'];
+  filters?: OpenDialogSyncOptions['filters'];
+};
+
+ipcMain.handle(
+  'open-file-dialog',
+  (_event, { filters, properties }: OpenFileDialogPayload) => {
+    return dialog.showOpenDialogSync({
+      properties: properties || ['openFile'],
+      filters,
+    });
+  },
+);
+
+export type SaveFileDialogPayload = {
+  title: SaveDialogOptions['title'];
+  defaultPath?: SaveDialogOptions['defaultPath'];
+  fileContents: string | NodeJS.ArrayBufferView;
+};
 
 ipcMain.handle(
   'save-file-dialog',
-  async (event, { title, defaultPath, fileContents }) => {
+  async (
+    _event,
+    { title, defaultPath, fileContents }: SaveFileDialogPayload,
+  ) => {
     const fileLocation = await dialog.showSaveDialog({ title, defaultPath });
 
     return new Promise<void>((resolve, reject) => {
@@ -327,15 +353,15 @@ ipcMain.on('screenshot', () => {
   }
 });
 
-ipcMain.on('update-menu', (event, budgetId?: string) => {
+ipcMain.on('update-menu', (_event, budgetId?: string) => {
   updateMenu(budgetId);
 });
 
-ipcMain.on('set-theme', theme => {
+ipcMain.on('set-theme', (_event, theme: string) => {
   const obj = { theme };
   if (clientWin) {
     clientWin.webContents.executeJavaScript(
-      `window.__actionsForMenu && window.__actionsForMenu.saveGlobalPrefs(${obj})`,
+      `window.__actionsForMenu && window.__actionsForMenu.saveGlobalPrefs(${JSON.stringify(obj)})`,
     );
   }
 });
diff --git a/packages/desktop-electron/preload.js b/packages/desktop-electron/preload.ts
similarity index 51%
rename from packages/desktop-electron/preload.js
rename to packages/desktop-electron/preload.ts
index e4c75c0ff..832bd6a50 100644
--- a/packages/desktop-electron/preload.js
+++ b/packages/desktop-electron/preload.ts
@@ -1,16 +1,25 @@
-const { ipcRenderer, contextBridge } = require('electron');
+import { ipcRenderer, contextBridge, IpcRenderer } from 'electron';
 
-const { version: VERSION, isDev: IS_DEV } =
+import {
+  GetBootstrapDataPayload,
+  OpenFileDialogPayload,
+  SaveFileDialogPayload,
+} from './index';
+
+const { version: VERSION, isDev: IS_DEV }: GetBootstrapDataPayload =
   ipcRenderer.sendSync('get-bootstrap-data');
 
 contextBridge.exposeInMainWorld('Actual', {
   IS_DEV,
   ACTUAL_VERSION: VERSION,
-  logToTerminal: (...args) => {
-    require('console').log(...args);
-  },
+  logToTerminal: console.log,
 
-  ipcConnect: func => {
+  ipcConnect: (
+    func: (payload: {
+      on: IpcRenderer['on'];
+      emit: (name: string, data: unknown) => void;
+    }) => void,
+  ) => {
     func({
       on(name, handler) {
         return ipcRenderer.on(name, (_event, value) => handler(value));
@@ -25,11 +34,15 @@ contextBridge.exposeInMainWorld('Actual', {
     ipcRenderer.invoke('relaunch');
   },
 
-  openFileDialog: opts => {
+  openFileDialog: (opts: OpenFileDialogPayload) => {
     return ipcRenderer.invoke('open-file-dialog', opts);
   },
 
-  saveFile: async (contents, filename, dialogTitle) => {
+  saveFile: async (
+    contents: SaveFileDialogPayload['fileContents'],
+    filename: SaveFileDialogPayload['defaultPath'],
+    dialogTitle: SaveFileDialogPayload['title'],
+  ) => {
     await ipcRenderer.invoke('save-file-dialog', {
       title: dialogTitle,
       defaultPath: filename,
@@ -37,15 +50,15 @@ contextBridge.exposeInMainWorld('Actual', {
     });
   },
 
-  openURLInBrowser: url => {
+  openURLInBrowser: (url: string) => {
     ipcRenderer.invoke('open-external-url', url);
   },
 
-  onEventFromMain: (type, handler) => {
+  onEventFromMain: (type: string, handler: (...args: unknown[]) => void) => {
     ipcRenderer.on(type, handler);
   },
 
-  updateAppMenu: budgetId => {
+  updateAppMenu: (budgetId?: string) => {
     ipcRenderer.send('update-menu', budgetId);
   },
 
@@ -53,7 +66,7 @@ contextBridge.exposeInMainWorld('Actual', {
     return null;
   },
 
-  setTheme: theme => {
+  setTheme: (theme: string) => {
     ipcRenderer.send('set-theme', theme);
   },
 });
diff --git a/packages/desktop-electron/security.js b/packages/desktop-electron/security.ts
similarity index 65%
rename from packages/desktop-electron/security.js
rename to packages/desktop-electron/security.ts
index 8e8a9934d..6bc3e2006 100644
--- a/packages/desktop-electron/security.js
+++ b/packages/desktop-electron/security.ts
@@ -1,15 +1,13 @@
-const electron = require('electron');
+import { app, session } from 'electron';
 
-electron.app.on('web-contents-created', function (event, contents) {
+app.on('web-contents-created', function (event, contents) {
   contents.on('will-attach-webview', function (event, webPreferences) {
-    delete webPreferences.preloadURL;
     delete webPreferences.preload;
 
     webPreferences.nodeIntegration = false;
     webPreferences.webSecurity = true;
     webPreferences.allowRunningInsecureContent = false;
     webPreferences.experimentalFeatures = false;
-    webPreferences.enableBlinkFeatures = false;
 
     // For now, we never use <webview>. Just disable it entirely.
     event.preventDefault();
@@ -18,14 +16,10 @@ electron.app.on('web-contents-created', function (event, contents) {
   contents.on('will-navigate', event => {
     event.preventDefault();
   });
-
-  contents.on('new-window', event => {
-    event.preventDefault();
-  });
 });
 
-electron.app.on('ready', function () {
-  electron.session.defaultSession.setPermissionRequestHandler(
+app.on('ready', function () {
+  session.defaultSession.setPermissionRequestHandler(
     function (webContents, permission, callback) {
       const url = webContents.getURL();
       if (url.startsWith('file://')) {
diff --git a/upcoming-release-notes/3066.md b/upcoming-release-notes/3066.md
new file mode 100644
index 000000000..ff417ba49
--- /dev/null
+++ b/upcoming-release-notes/3066.md
@@ -0,0 +1,6 @@
+---
+category: Maintenance
+authors: [MikesGlitch]
+---
+
+Updated security.js and preload.js to Typescript and fixed Theme not setting correctly when set via dev console
-- 
GitLab