From 92e8dfb6d7437627f5d9f80b51f44d4c4add2fda Mon Sep 17 00:00:00 2001 From: 18alantom <2.alan.tom@gmail.com> Date: Mon, 10 Jul 2023 14:42:20 +0530 Subject: [PATCH] incr: enable context isolation --- backend/database/types.ts | 1 + fyo/demux/auth.ts | 4 +-- fyo/demux/config.ts | 24 ++------------ fyo/demux/db.ts | 30 +++-------------- fyo/index.ts | 2 +- main.ts | 7 ++-- main/preload.ts | 69 ++++++++++++++++++++++++++++++++++++--- 7 files changed, 78 insertions(+), 59 deletions(-) diff --git a/backend/database/types.ts b/backend/database/types.ts index 8318271d..bc7380c7 100644 --- a/backend/database/types.ts +++ b/backend/database/types.ts @@ -50,6 +50,7 @@ export type BespokeFunction = ( db: DatabaseCore, ...args: unknown[] ) => Promise; + export type SingleValue = { fieldname: string; parent: string; diff --git a/fyo/demux/auth.ts b/fyo/demux/auth.ts index 9a9df527..31458634 100644 --- a/fyo/demux/auth.ts +++ b/fyo/demux/auth.ts @@ -1,7 +1,5 @@ import { AuthDemuxBase } from 'utils/auth/types'; -import { IPC_ACTIONS } from 'utils/messages'; import { Creds } from 'utils/types'; -const { ipcRenderer } = require('electron'); export class AuthDemux extends AuthDemuxBase { #isElectron = false; @@ -12,7 +10,7 @@ export class AuthDemux extends AuthDemuxBase { async getCreds(): Promise { if (this.#isElectron) { - return (await ipcRenderer.invoke(IPC_ACTIONS.GET_CREDS)) as Creds; + return await ipc.getCreds(); } else { return { errorLogUrl: '', tokenString: '', telemetryUrl: '' }; } diff --git a/fyo/demux/config.ts b/fyo/demux/config.ts index 22691c08..04c78497 100644 --- a/fyo/demux/config.ts +++ b/fyo/demux/config.ts @@ -1,26 +1,12 @@ -import type Store from 'electron-store'; import { ConfigMap } from 'fyo/core/types'; +import type { IPC } from 'main/preload'; export class Config { - config: Map | Store; + config: Map | IPC['store']; constructor(isElectron: boolean) { this.config = new Map(); if (isElectron) { - const Config = require('electron-store') as typeof Store; - this.config = new Config(); - } - } - - get store() { - if (this.config instanceof Map) { - const store: Record = {}; - for (const key of this.config.keys()) { - store[key] = this.config.get(key); - } - - return store; - } else { - return this.config; + this.config = ipc.store; } } @@ -39,8 +25,4 @@ export class Config { delete(key: keyof ConfigMap) { this.config.delete(key); } - - clear() { - this.config.clear(); - } } diff --git a/fyo/demux/db.ts b/fyo/demux/db.ts index 959903b0..8a72f85a 100644 --- a/fyo/demux/db.ts +++ b/fyo/demux/db.ts @@ -1,9 +1,7 @@ -const { ipcRenderer } = require('electron'); import { DatabaseError, NotImplemented } from 'fyo/utils/errors'; import { SchemaMap } from 'schemas/types'; import { DatabaseDemuxBase, DatabaseMethod } from 'utils/db/types'; import { BackendResponse } from 'utils/ipc/types'; -import { IPC_ACTIONS } from 'utils/messages'; export class DatabaseDemux extends DatabaseDemuxBase { #isElectron = false; @@ -32,9 +30,7 @@ export class DatabaseDemux extends DatabaseDemuxBase { } return (await this.#handleDBCall(async () => { - return (await ipcRenderer.invoke( - IPC_ACTIONS.DB_SCHEMA - )) as BackendResponse; + return await ipc.db.getSchema(); })) as SchemaMap; } @@ -47,11 +43,7 @@ export class DatabaseDemux extends DatabaseDemuxBase { } return (await this.#handleDBCall(async () => { - return (await ipcRenderer.invoke( - IPC_ACTIONS.DB_CREATE, - dbPath, - countryCode - )) as BackendResponse; + return ipc.db.create(dbPath, countryCode); })) as string; } @@ -64,11 +56,7 @@ export class DatabaseDemux extends DatabaseDemuxBase { } return (await this.#handleDBCall(async () => { - return (await ipcRenderer.invoke( - IPC_ACTIONS.DB_CONNECT, - dbPath, - countryCode - )) as BackendResponse; + return ipc.db.connect(dbPath, countryCode); })) as string; } @@ -78,11 +66,7 @@ export class DatabaseDemux extends DatabaseDemuxBase { } return await this.#handleDBCall(async () => { - return (await ipcRenderer.invoke( - IPC_ACTIONS.DB_CALL, - method, - ...args - )) as BackendResponse; + return await ipc.db.call(method, ...args); }); } @@ -92,11 +76,7 @@ export class DatabaseDemux extends DatabaseDemuxBase { } return await this.#handleDBCall(async () => { - return (await ipcRenderer.invoke( - IPC_ACTIONS.DB_BESPOKE, - method, - ...args - )) as BackendResponse; + return await ipc.db.bespoke(method, ...args); }); } } diff --git a/fyo/index.ts b/fyo/index.ts index 1b41b672..fe3e0710 100644 --- a/fyo/index.ts +++ b/fyo/index.ts @@ -96,7 +96,7 @@ export class Fyo { setIsElectron() { try { - this.isElectron = Boolean(require('electron')); + this.isElectron = !!window?.ipc; } catch { this.isElectron = false; } diff --git a/main.ts b/main.ts index 7a6a7106..c288f628 100644 --- a/main.ts +++ b/main.ts @@ -4,6 +4,7 @@ require('source-map-support').install({ environment: 'node', }); +import { emitMainProcessError } from 'backend/helpers'; import { app, BrowserWindow, @@ -12,7 +13,6 @@ import { ProtocolRequest, ProtocolResponse, } from 'electron'; -import Store from 'electron-store'; import { autoUpdater } from 'electron-updater'; import fs from 'fs'; import path from 'path'; @@ -21,7 +21,6 @@ import registerAutoUpdaterListeners from './main/registerAutoUpdaterListeners'; import registerIpcMainActionListeners from './main/registerIpcMainActionListeners'; import registerIpcMainMessageListeners from './main/registerIpcMainMessageListeners'; import registerProcessListeners from './main/registerProcessListeners'; -import { emitMainProcessError } from 'backend/helpers'; export class Main { title = 'Frappe Books'; @@ -54,8 +53,6 @@ export class Main { 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0', }; - Store.initRenderer(); - this.registerListeners(); if (this.isMac && this.isDevelopment) { app.dock.setIcon(this.icon); @@ -95,7 +92,7 @@ export class Main { titleBarStyle: 'hidden', trafficLightPosition: { x: 16, y: 16 }, webPreferences: { - contextIsolation: false, // TODO: Switch this off + contextIsolation: true, nodeIntegration: true, preload, }, diff --git a/main/preload.ts b/main/preload.ts index 4d946624..679f62b2 100644 --- a/main/preload.ts +++ b/main/preload.ts @@ -4,11 +4,15 @@ import type { SaveDialogOptions, SaveDialogReturnValue, } from 'electron'; -import { ipcRenderer } from 'electron'; -import { BackendResponse } from 'utils/ipc/types'; +import { contextBridge, ipcRenderer } from 'electron'; +import type { ConfigMap } from 'fyo/core/types'; +import config from 'utils/config'; +import type { DatabaseMethod } from 'utils/db/types'; +import type { BackendResponse } from 'utils/ipc/types'; import { IPC_ACTIONS, IPC_CHANNELS, IPC_MESSAGES } from 'utils/messages'; import type { ConfigFilesWithModified, + Creds, LanguageMap, SelectFileOptions, SelectFileReturn, @@ -23,6 +27,10 @@ const ipc = { return ipcRenderer.send(IPC_MESSAGES.RELOAD_MAIN_WINDOW); }, + async getCreds() { + return (await ipcRenderer.invoke(IPC_ACTIONS.GET_CREDS)) as Creds; + }, + async getLanguageMap(code: string) { return (await ipcRenderer.invoke(IPC_ACTIONS.GET_LANGUAGE_MAP, code)) as { languageMap: LanguageMap; @@ -136,8 +144,61 @@ const ipc = { registerConsoleLogListener(listener: IPCRendererListener) { ipcRenderer.on(IPC_CHANNELS.CONSOLE_LOG, listener); }, + + db: { + async getSchema() { + return (await ipcRenderer.invoke( + IPC_ACTIONS.DB_SCHEMA + )) as BackendResponse; + }, + + async create(dbPath: string, countryCode?: string) { + return (await ipcRenderer.invoke( + IPC_ACTIONS.DB_CREATE, + dbPath, + countryCode + )) as BackendResponse; + }, + + async connect(dbPath: string, countryCode?: string) { + return (await ipcRenderer.invoke( + IPC_ACTIONS.DB_CONNECT, + dbPath, + countryCode + )) as BackendResponse; + }, + + async call(method: DatabaseMethod, ...args: unknown[]) { + return (await ipcRenderer.invoke( + IPC_ACTIONS.DB_CALL, + method, + ...args + )) as BackendResponse; + }, + + async bespoke(method: string, ...args: unknown[]) { + return (await ipcRenderer.invoke( + IPC_ACTIONS.DB_BESPOKE, + method, + ...args + )) as BackendResponse; + }, + }, + + store: { + get(key: K) { + return config.get(key); + }, + + set(key: K, value: ConfigMap[K]) { + return config.set(key, value); + }, + + delete(key: keyof ConfigMap) { + return config.delete(key); + }, + }, } as const; -// contextBridge.exposeInMainWorld('api', ipc); -window.ipc = ipc; +contextBridge.exposeInMainWorld('ipc', ipc); export type IPC = typeof ipc;