mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-30 17:47:44 +01:00
[PM-3996] Scaffolding for preload script (#6065)
This PR wires up a polyfill for window.ipc which allows us to progressively migrate the codebase to a format which supports context bridge. This avoids a big bang effort where every non sandboxed call has to be migrated before we can run the code. Once all calls to node modules are removed from the renderer and only exists in preload.ts. We will turn on context isolation and use the context bridge for communication instead.
This commit is contained in:
parent
77d7813742
commit
7cfa38e344
@ -19,8 +19,10 @@
|
||||
"postinstall": "electron-rebuild",
|
||||
"start": "cross-env ELECTRON_IS_DEV=0 ELECTRON_NO_UPDATER=1 electron ./build",
|
||||
"build-native": "cd desktop_native && npm run build",
|
||||
"build": "concurrently -n Main,Rend -c yellow,cyan \"npm run build:main\" \"npm run build:renderer\"",
|
||||
"build": "concurrently -n Main,Rend,Prel -c yellow,cyan \"npm run build:main\" \"npm run build:renderer\" \"npm run build:preload\"",
|
||||
"build:dev": "concurrently -n Main,Rend -c yellow,cyan \"npm run build:main:dev\" \"npm run build:renderer:dev\"",
|
||||
"build:preload": "cross-env NODE_ENV=production webpack --config webpack.preload.js",
|
||||
"build:preload:watch": "cross-env NODE_ENV=production webpack --config webpack.preload.js --watch",
|
||||
"build:main": "cross-env NODE_ENV=production webpack --config webpack.main.js",
|
||||
"build:main:dev": "npm run build-native && cross-env NODE_ENV=development webpack --config webpack.main.js",
|
||||
"build:main:watch": "npm run build-native && cross-env NODE_ENV=development webpack --config webpack.main.js --watch",
|
||||
|
@ -13,6 +13,11 @@ concurrently(
|
||||
command: "npm run build:main:watch",
|
||||
prefixColor: "yellow",
|
||||
},
|
||||
{
|
||||
name: "Prel",
|
||||
command: "npm run build:preload:watch",
|
||||
prefixColor: "magenta",
|
||||
},
|
||||
{
|
||||
name: "Rend",
|
||||
command: "npm run build:renderer:watch",
|
||||
|
@ -21,7 +21,6 @@ import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { flagEnabled } from "../../platform/flags";
|
||||
import { ElectronStateService } from "../../platform/services/electron-state.service.abstraction";
|
||||
import { isWindowsStore } from "../../utils";
|
||||
import { SetPinComponent } from "../components/set-pin.component";
|
||||
@Component({
|
||||
selector: "app-settings",
|
||||
@ -589,7 +588,7 @@ export class SettingsComponent implements OnInit {
|
||||
|
||||
this.form.controls.enableBrowserIntegration.setValue(false);
|
||||
return;
|
||||
} else if (isWindowsStore()) {
|
||||
} else if (ipc.platform.isWindowsStore) {
|
||||
await this.dialogService.openSimpleDialog({
|
||||
title: { key: "browserIntegrationUnsupportedTitle" },
|
||||
content: { key: "browserIntegrationWindowsStoreDesc" },
|
||||
|
@ -10,7 +10,6 @@ import {
|
||||
} from "@angular/core";
|
||||
import { DomSanitizer } from "@angular/platform-browser";
|
||||
import { Router } from "@angular/router";
|
||||
import { ipcRenderer } from "electron";
|
||||
import { IndividualConfig, ToastrService } from "ngx-toastr";
|
||||
import { firstValueFrom, Subject, takeUntil } from "rxjs";
|
||||
|
||||
@ -227,7 +226,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
this.systemService.cancelProcessReload();
|
||||
break;
|
||||
case "reloadProcess":
|
||||
ipcRenderer.send("reload-process");
|
||||
ipc.platform.reloadProcess();
|
||||
break;
|
||||
case "syncStarted":
|
||||
break;
|
||||
|
@ -1,8 +1,12 @@
|
||||
import { enableProdMode } from "@angular/core";
|
||||
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
|
||||
|
||||
import { ipc } from "../preload";
|
||||
import { isDev } from "../utils";
|
||||
|
||||
// Temporary polyfill for preload script
|
||||
(window as any).ipc = ipc;
|
||||
|
||||
require("../scss/styles.scss");
|
||||
require("../scss/tailwind.css");
|
||||
|
||||
|
1
apps/desktop/src/global.d.ts
vendored
1
apps/desktop/src/global.d.ts
vendored
@ -1 +1,2 @@
|
||||
declare module "forcefocus";
|
||||
declare const ipc: typeof import("./preload").ipc;
|
||||
|
@ -143,6 +143,7 @@ export class WindowMain {
|
||||
backgroundColor: await this.getBackgroundColor(),
|
||||
alwaysOnTop: this.enableAlwaysOnTop,
|
||||
webPreferences: {
|
||||
// preload: path.join(__dirname, "preload.js"),
|
||||
spellcheck: false,
|
||||
nodeIntegration: true,
|
||||
backgroundThrottling: false,
|
||||
|
26
apps/desktop/src/platform/preload.ts
Normal file
26
apps/desktop/src/platform/preload.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { ipcRenderer } from "electron";
|
||||
|
||||
import { DeviceType } from "@bitwarden/common/enums/device-type.enum";
|
||||
|
||||
import { isDev, isWindowsStore } from "../utils";
|
||||
|
||||
export default {
|
||||
versions: {
|
||||
app: (): Promise<string> => ipcRenderer.invoke("appVersion"),
|
||||
},
|
||||
deviceType: deviceType(),
|
||||
isDev: isDev(),
|
||||
isWindowsStore: isWindowsStore(),
|
||||
reloadProcess: () => ipcRenderer.send("reload-process"),
|
||||
};
|
||||
|
||||
function deviceType(): DeviceType {
|
||||
switch (process.platform) {
|
||||
case "win32":
|
||||
return DeviceType.WindowsDesktop;
|
||||
case "darwin":
|
||||
return DeviceType.MacOsDesktop;
|
||||
default:
|
||||
return DeviceType.LinuxDesktop;
|
||||
}
|
||||
}
|
@ -9,31 +9,14 @@ import {
|
||||
} from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
import { BiometricMessage, BiometricStorageAction } from "../../types/biometric-message";
|
||||
import { isDev, isMacAppStore } from "../../utils";
|
||||
import { isMacAppStore } from "../../utils";
|
||||
import { ClipboardWriteMessage } from "../types/clipboard";
|
||||
|
||||
export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
||||
private deviceCache: DeviceType = null;
|
||||
|
||||
constructor(protected i18nService: I18nService, private messagingService: MessagingService) {}
|
||||
|
||||
getDevice(): DeviceType {
|
||||
if (!this.deviceCache) {
|
||||
switch (process.platform) {
|
||||
case "win32":
|
||||
this.deviceCache = DeviceType.WindowsDesktop;
|
||||
break;
|
||||
case "darwin":
|
||||
this.deviceCache = DeviceType.MacOsDesktop;
|
||||
break;
|
||||
case "linux":
|
||||
default:
|
||||
this.deviceCache = DeviceType.LinuxDesktop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this.deviceCache;
|
||||
return ipc.platform.deviceType;
|
||||
}
|
||||
|
||||
getDeviceString(): string {
|
||||
@ -82,7 +65,7 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
||||
}
|
||||
|
||||
getApplicationVersion(): Promise<string> {
|
||||
return ipcRenderer.invoke("appVersion");
|
||||
return ipc.platform.versions.app();
|
||||
}
|
||||
|
||||
async getApplicationVersionNumber(): Promise<string> {
|
||||
@ -92,7 +75,7 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
||||
// Temporarily restricted to only Windows until https://github.com/electron/electron/pull/28349
|
||||
// has been merged and an updated electron build is available.
|
||||
supportsWebAuthn(win: Window): boolean {
|
||||
return process.platform === "win32";
|
||||
return this.getDevice() === DeviceType.WindowsDesktop;
|
||||
}
|
||||
|
||||
supportsDuo(): boolean {
|
||||
@ -114,7 +97,7 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
||||
}
|
||||
|
||||
isDev(): boolean {
|
||||
return isDev();
|
||||
return ipc.platform.isDev;
|
||||
}
|
||||
|
||||
isSelfHost(): boolean {
|
||||
|
19
apps/desktop/src/preload.ts
Normal file
19
apps/desktop/src/preload.ts
Normal file
@ -0,0 +1,19 @@
|
||||
// import { contextBridge } from "electron";
|
||||
import platform from "./platform/preload";
|
||||
|
||||
/**
|
||||
* Bitwarden Preload script.
|
||||
*
|
||||
* This file contains the "glue" between the main process and the renderer process. Please ensure
|
||||
* that you have read through the following articles before modifying any preload script.
|
||||
*
|
||||
* https://www.electronjs.org/docs/latest/tutorial/tutorial-preload
|
||||
* https://www.electronjs.org/docs/latest/api/context-bridge
|
||||
*/
|
||||
|
||||
// Each team owns a subspace of the `ipc` global variable in the renderer.
|
||||
export const ipc = {
|
||||
platform,
|
||||
};
|
||||
|
||||
// contextBridge.exposeInMainWorld("ipc", ipc);
|
@ -67,7 +67,6 @@ const main = {
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
"./src/package.json",
|
||||
|
63
apps/desktop/webpack.preload.js
Normal file
63
apps/desktop/webpack.preload.js
Normal file
@ -0,0 +1,63 @@
|
||||
const path = require("path");
|
||||
const { merge } = require("webpack-merge");
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
|
||||
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
|
||||
const configurator = require("./config/config");
|
||||
const { EnvironmentPlugin } = require("webpack");
|
||||
|
||||
const NODE_ENV = process.env.NODE_ENV == null ? "development" : process.env.NODE_ENV;
|
||||
|
||||
console.log("Preload process config");
|
||||
const envConfig = configurator.load(NODE_ENV);
|
||||
configurator.log(envConfig);
|
||||
|
||||
const common = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: "ts-loader",
|
||||
exclude: /node_modules\/(?!(@bitwarden)\/).*/,
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [],
|
||||
resolve: {
|
||||
extensions: [".tsx", ".ts", ".js"],
|
||||
plugins: [new TsconfigPathsPlugin({ configFile: "./tsconfig.json" })],
|
||||
},
|
||||
};
|
||||
|
||||
const prod = {
|
||||
output: {
|
||||
filename: "[name].js",
|
||||
path: path.resolve(__dirname, "build"),
|
||||
},
|
||||
};
|
||||
|
||||
const dev = {
|
||||
output: {
|
||||
filename: "[name].js",
|
||||
path: path.resolve(__dirname, "build"),
|
||||
devtoolModuleFilenameTemplate: "[absolute-resource-path]",
|
||||
},
|
||||
devtool: "cheap-source-map",
|
||||
};
|
||||
|
||||
const main = {
|
||||
mode: NODE_ENV,
|
||||
target: "electron-preload",
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
entry: {
|
||||
preload: "./src/preload.ts",
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = merge(common, NODE_ENV === "development" ? dev : prod, main);
|
@ -62,6 +62,8 @@ const common = {
|
||||
const renderer = {
|
||||
mode: NODE_ENV,
|
||||
devtool: "source-map",
|
||||
// TODO: Replace this with web.
|
||||
// target: "web",
|
||||
target: "electron-renderer",
|
||||
node: {
|
||||
__dirname: false,
|
||||
|
Loading…
Reference in New Issue
Block a user