From 748de04248ba70457c15b91059d453be69cec544 Mon Sep 17 00:00:00 2001 From: Bruno Bernardino Date: Wed, 20 Jul 2022 12:18:58 +0100 Subject: [PATCH] Desktop lock on suspend Related to #211 Note that this attempt doesn't quite work as the app doesn't load properly in Electron, and I eventually stopped trying to, since it's turning into a lot of effort. I just wanted it "documented". There are to options to close #211: 1. When we detect the system is suspending/locking, shutdown/quit the app. This won't require any communication with the PWA. 2. We implement something like [`electron-safe-ipc`](https://www.npmjs.com/package/electron-safe-ipc) directly in the PWA, so electron can send the lock event to it. Option 1 is not a great UX, but does handle the security aspect. Option 2 is a much better UX, but introduces a new dependency that is only _relevant_ when the app's used via Electron. --- packages/app/src/mixins/auto-lock.ts | 1 + packages/electron/src/main.ts | 37 ++++++++++++++++++++++------ packages/electron/src/platform.ts | 11 ++++++++- packages/electron/webpack.config.js | 5 ++++ 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/packages/app/src/mixins/auto-lock.ts b/packages/app/src/mixins/auto-lock.ts index 324683ec..d3b9bd5a 100644 --- a/packages/app/src/mixins/auto-lock.ts +++ b/packages/app/src/mixins/auto-lock.ts @@ -18,6 +18,7 @@ export function AutoLock>(baseClass: B) { document.addEventListener("keydown", () => this._startTimer()); document.addEventListener("pause", () => this._pause()); document.addEventListener("resume", () => this._resume()); + document.addEventListener("lock-app", () => this._doLock()); } _cancelAutoLock() { diff --git a/packages/electron/src/main.ts b/packages/electron/src/main.ts index 6eb665f5..0c178733 100644 --- a/packages/electron/src/main.ts +++ b/packages/electron/src/main.ts @@ -1,10 +1,10 @@ -import { app, BrowserWindow, Menu, dialog, shell } from "electron"; +import { app, BrowserWindow, Menu, dialog, shell, powerMonitor, ipcMain } from "electron"; import { autoUpdater, UpdateInfo } from "electron-updater"; // import * as os from "os"; import ElectronStore from "electron-store"; -const debug = process.argv.includes("--dbg"); -const pwaUrl = process.env.PL_PWA_URL!.replace(/(\/*)$/, ""); +const debug = true; //process.argv.includes("--dbg"); +// const pwaUrl = process.env.PL_PWA_URL!.replace(/(\/*)$/, ""); const appName = process.env.PL_APP_NAME!; const appScheme = process.env.PL_APP_SCHEME!; @@ -125,6 +125,8 @@ function createWindow(path: string = "") { autoHideMenuBar: true, webPreferences: { devTools: debug, + nodeIntegration: true, + contextIsolation: false, }, minWidth, minHeight, @@ -134,8 +136,8 @@ function createWindow(path: string = "") { win.webContents.openDevTools(); } - // win.loadFile("index.html"); - win.loadURL(`${pwaUrl}/${path}`); + win.loadFile("index.html"); + // win.loadURL(`${pwaUrl}/${path}`); win.once("ready-to-show", () => { win.show(); @@ -298,7 +300,7 @@ async function start() { }); app.on("open-url", async (_event, url) => { - console.log("opening via custome scheme. url: ", url); + console.log("opening via custom scheme. url: ", url); await app.whenReady(); goToUrl(url); }); @@ -308,9 +310,30 @@ async function start() { const startUrl = process.argv.find((arg) => arg.startsWith(`${appScheme}:`)); const path = startUrl?.replace(/\w+:(\/*)/, ""); - createWindow(path); + const window = createWindow(path); createApplicationMenu(); + // Lock app on suspend system event + powerMonitor.on("suspend", async () => { + console.log("suspending"); + ipcMain.emit("electron-lock-app"); + window.webContents.send("electron-lock-app"); + }); + + // Lock app on lock system event + powerMonitor.on("lock-screen", async () => { + console.log("locking screen"); + ipcMain.emit("electron-lock-app"); + window.webContents.send("electron-lock-app"); + }); + + // TODO: Remove this + setTimeout(() => { + console.log("fake lock"); + // ipcMain.emit("electron-lock-app"); + window.webContents.send("electron-lock-app"); + }, 10000); + app.setAsDefaultProtocolClient(appScheme); // Quit when all windows are closed. diff --git a/packages/electron/src/platform.ts b/packages/electron/src/platform.ts index c9077d2e..cf4b03d7 100644 --- a/packages/electron/src/platform.ts +++ b/packages/electron/src/platform.ts @@ -1,4 +1,13 @@ +import { ipcRenderer } from "electron"; import { Platform } from "@padloc/core/src/platform"; import { WebPlatform } from "@padloc/app/src/lib/platform"; -export class ElectronPlatform extends WebPlatform implements Platform {} +export class ElectronPlatform extends WebPlatform implements Platform { + constructor() { + super(); + + ipcRenderer.on("electron-lock-app", () => { + window.document.dispatchEvent(new CustomEvent("lock-app")); + }); + } +} diff --git a/packages/electron/webpack.config.js b/packages/electron/webpack.config.js index 51479c31..f803bdcb 100644 --- a/packages/electron/webpack.config.js +++ b/packages/electron/webpack.config.js @@ -1,5 +1,6 @@ const { resolve, join } = require("path"); const { EnvironmentPlugin } = require("webpack"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); const rootDir = resolve(__dirname, "../.."); const assetsDir = resolve(rootDir, process.env.PL_ASSETS_DIR || "assets"); @@ -39,6 +40,10 @@ module.exports = [ PL_VENDOR_VERSION: version, PL_TERMS_OF_SERVICE: terms_of_service, }), + new HtmlWebpackPlugin({ + title: name, + template: resolve(__dirname, "src/index.html"), + }), { apply(compiler) { const package = JSON.stringify({