0

I am new to electron.js - been reading the documentation and some similar post here:

How do I make a database call from an Electron front end?

Secure Database Connection in ElectronJS Production App?

Electron require() is not defined

How to use preload.js properly in Electron

But it's still not super clear how to properly implement a secure SQL integration. Basically, I want to create a desktop database client. The app will connect to the remote db and users can run all kind of predefined queries and the results will show up in the app.

The documentation says that if you are working with a remote connection you shouldn't run node in the renderer. Should I then require the SQL module in the main process and use IPC to send data back and forth and preload IPCremote?

Thanks for the help

thenubian
  • 47
  • 5

1 Answers1

2

Short answer: yes

Long answer: Allowing node on your renderer poses a big security risk for your app. It is best practices in this case to create pass a function to your preloader. There are a few options you can use to do this:

  1. Pass a ipcRenderer.invoke function wrapped in another function to your renderer in your preload. You can then invoke a call to your main process which can either send info back via the same function or via sending it via the window.webContents.send command and listening for it on the window api on your renderer. EG:

Preload.js:

const invoke = (channel, args, cb = () => {return}) => {
  ipcRenderer.invoke(channel, args).then((res) => {
    cb(res);
  });
};

const handle = (channel, cb) => {
  ipcRenderer.on(channel, function (Event, message) {
    cb(Event, message);
  });
};

contextBridge.exposeInMainWorld("GlobalApi", {
  invoke: invoke,
  handle:handle
});

Renderer:

let users
window.GlobalApi.handle("users", (data)=>{users=data})
window.GlobalApi.invoke("get", "users")

or:

let users;
window.GlobalApi.invoke("get", "users", (data)=>{users=data})

Main:

ipcMain.handle("get", async (path) => {
 let data = dbFunctions.get(path)

   window.webContents.send(
    path,
    data
  );
}
  1. Create a DB interface in your preload script that passes certain invocations to your renderer that when called will return the value that you need from your db. E.G.

Renderer:

let users = window.myCoolApi.get("users");

Preload.js:

let get = function(path){
    let data =  dbFuncions.readSomeDatafromDB("path");
    return data; // Returning the function itself is a no-no shown below
    // return dbFuncions.readSomeDatafromDB("path"); Don't do this
}
contextBridge.exposeInMainWorld("myCoolApi", {
  get:get
});

There are more options, but these should generally ensure security as far as my knowledge goes.

mpmcintyre
  • 614
  • 5
  • 16