Unverified Commit 821c95bc authored by Sandro Jäckel's avatar Sandro Jäckel Committed by GitHub
Browse files

bitwarden-desktop: add darwin support and do minor refactor (#369559)

parents 63e31591 de0b5d91
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
diff --git a/apps/desktop/desktop_native/napi/index.js b/apps/desktop/desktop_native/napi/index.js
index acfd0df..31a0c6a 100644
--- a/apps/desktop/desktop_native/napi/index.js
+++ b/apps/desktop/desktop_native/napi/index.js
@@ -17,6 +17,7 @@ function loadFirstAvailable(localFiles, nodeModule) {
   require(nodeModule);
 }
 
+/*
 switch (platform) {
   case "android":
     switch (arch) {
@@ -121,6 +122,8 @@ switch (platform) {
   default:
     throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`);
 }
+*/
+nativeBinding = require('./desktop_napi.node')
 
 if (!nativeBinding) {
   if (loadError) {
diff --git a/apps/desktop/desktop_native/napi/package.json b/apps/desktop/desktop_native/napi/package.json
index d557ccf..2e47c79 100644
--- a/apps/desktop/desktop_native/napi/package.json
+++ b/apps/desktop/desktop_native/napi/package.json
@@ -3,7 +3,7 @@
   "version": "0.1.0",
   "description": "",
   "scripts": {
-    "build": "napi build --platform --js false",
+    "build": "napi build --js false",
     "test": "cargo test"
   },
   "author": "",
diff --git a/apps/desktop/electron-builder.json b/apps/desktop/electron-builder.json
index 2922035..6497a38 100644
--- a/apps/desktop/electron-builder.json
+++ b/apps/desktop/electron-builder.json
@@ -18,7 +18,7 @@
     "**/*",
     "!**/node_modules/@bitwarden/desktop-napi/**/*",
     "**/node_modules/@bitwarden/desktop-napi/index.js",
-    "**/node_modules/@bitwarden/desktop-napi/desktop_napi.${platform}-${arch}*.node"
+    "**/node_modules/@bitwarden/desktop-napi/desktop_napi.node"
   ],
   "electronVersion": "34.0.0",
   "generateUpdatesFilesForAllChannels": true,
@@ -67,7 +67,6 @@
       ],
       "CFBundleDevelopmentRegion": "en"
     },
-    "singleArchFiles": "node_modules/@bitwarden/desktop-napi/desktop_napi.darwin-*.node",
     "extraFiles": [
       {
         "from": "desktop_native/dist/desktop_proxy.${platform}-${arch}",
+100 −72
Original line number Diff line number Diff line
{
  lib,
  apple-sdk_14,
  buildNpmPackage,
  cargo,
  copyDesktopItems,
  darwin,
  electron_34,
  fetchFromGitHub,
  gnome-keyring,
  jq,
  llvmPackages_18,
  makeDesktopItem,
  makeWrapper,
  napi-rs-cli,
  nix-update-script,
  nodejs_20,
  patchutils_0_4_2,
  pkg-config,
  runCommand,
  rustc,
  rustPlatform,
  stdenv,
  xcbuild,
}:

let
@@ -25,16 +27,12 @@ let
  icon = "bitwarden";
  electron = electron_34;

  bitwardenDesktopNativeArch =
    {
      aarch64 = "arm64";
      x86_64 = "x64";
    }
    .${stdenv.hostPlatform.parsed.cpu.name}
      or (throw "bitwarden-desktop: unsupported CPU family ${stdenv.hostPlatform.parsed.cpu.name}");

  # argon2 npm dependency is using `std::basic_string<uint8_t>`, which is no longer allowed in LLVM 19
  buildNpmPackage' = buildNpmPackage.override {
    stdenv = if stdenv.hostPlatform.isDarwin then llvmPackages_18.stdenv else stdenv;
  };
in
buildNpmPackage rec {
buildNpmPackage' rec {
  pname = "bitwarden-desktop";
  version = "2025.2.0";

@@ -49,7 +47,8 @@ buildNpmPackage rec {
    ./electron-builder-package-lock.patch
    ./dont-auto-setup-biometrics.patch
    ./set-exe-path.patch # ensures `app.getPath("exe")` returns our wrapper, not ${electron}/bin/electron
    ./skip-afterpack.diff # this modifies bin/electron etc., but we wrap read-only bin/electron ourselves
    ./skip-afterpack-and-aftersign.patch # on linux: don't flip fuses, don't create wrapper script, on darwin: don't try copying safari extensions, don't try re-signing app
    ./dont-use-platform-triple.patch # since out arch doesn't match upstream, we'll generate and use desktop_napi.node instead of desktop_napi.${platform}-${arch}.node
  ];

  postPatch = ''
@@ -57,6 +56,11 @@ buildNpmPackage rec {
    rm -r bitwarden_license

    substituteInPlace apps/desktop/src/main.ts --replace-fail '%%exePath%%' "$out/bin/bitwarden"

    # force canUpdate to false
    # will open releases page instead of trying to update files
    substituteInPlace apps/desktop/src/main/updater.main.ts \
      --replace-fail 'this.canUpdate =' 'this.canUpdate = false; let _dummy ='
  '';

  nodejs = nodejs_20;
@@ -75,24 +79,25 @@ buildNpmPackage rec {
  npmDepsHash = "sha256-fYZJA6qV3mqxO2g+yxD0MWWQc9QYmdWJ7O7Vf88Qpbs=";

  cargoDeps = rustPlatform.fetchCargoVendor {
    inherit pname version src;
    patches = map (
      patch:
      runCommand (builtins.baseNameOf patch) { nativeBuildInputs = [ patchutils_0_4_2 ]; } ''
        < ${patch} filterdiff -p1 --include=${lib.escapeShellArg cargoRoot}'/*' > $out
      ''
    ) patches;
    patchFlags = [ "-p4" ];
    sourceRoot = "${src.name}/${cargoRoot}";
    inherit
      pname
      version
      src
      cargoRoot
      patches
      ;
    hash = "sha256-OldVFMI+rcGAbpDg7pHu/Lqbw5I6/+oXULteQ9mXiFc=";
  };
  cargoRoot = "apps/desktop/desktop_native";

  env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1";

  nativeBuildInputs = [
  # make electron-builder not attempt to codesign the app on darwin
  env.CSC_IDENTITY_AUTO_DISCOVERY = "false";

  nativeBuildInputs =
    [
      cargo
    copyDesktopItems
      jq
      makeWrapper
      napi-rs-cli
@@ -100,6 +105,17 @@ buildNpmPackage rec {
      rustc
      rustPlatform.cargoCheckHook
      rustPlatform.cargoSetupHook
    ]
    ++ lib.optionals stdenv.hostPlatform.isLinux [
      copyDesktopItems
    ]
    ++ lib.optionals stdenv.hostPlatform.isDarwin [
      xcbuild
      darwin.autoSignDarwinBinariesHook
    ];

  buildInputs = lib.optionals stdenv.hostPlatform.isDarwin [
    apple-sdk_14
  ];

  preBuild = ''
@@ -116,25 +132,31 @@ buildNpmPackage rec {
  postBuild = ''
    pushd apps/desktop

    # desktop_native/index.js loads a file of that name regardless of the libc being used
    mv desktop_native/napi/desktop_napi.* desktop_native/napi/desktop_napi.linux-${bitwardenDesktopNativeArch}-musl.node
    # electron-dist needs to be writable on darwin or when using fuses
    cp -r ${electron.dist} electron-dist
    chmod -R u+w electron-dist

    npm exec electron-builder -- \
      --dir \
      -c.electronDist=${electron.dist} \
      -c.electronDist=electron-dist \
      -c.electronVersion=${electron.version}

    popd
  '';

  doCheck = true;
  # there seem to be issues with missing libs on darwin when running tests
  doCheck = !stdenv.hostPlatform.isDarwin;

  nativeCheckInputs = [
  nativeCheckInputs = lib.optionals stdenv.hostPlatform.isLinux [
    (gnome-keyring.override { useWrappedDaemon = false; })
  ];

  checkFlags = [
  checkFlags =
    [
      "--skip=password::password::tests::test"
    ]
    ++ lib.optionals stdenv.hostPlatform.isDarwin [
      "--skip=clipboard::tests::test_write_read"
    ];

  preCheck = ''
@@ -147,15 +169,18 @@ buildNpmPackage rec {
    popd
  '';

  installPhase = ''
  installPhase =
    ''
      runHook preInstall

    mkdir $out

    pushd apps/desktop/dist/linux-${lib.optionalString stdenv.hostPlatform.isAarch64 "arm64-"}unpacked
    ''
    + lib.optionalString stdenv.hostPlatform.isDarwin ''
      mkdir -p $out/Applications
      cp -r apps/desktop/dist/mac*/Bitwarden.app $out/Applications
      makeWrapper $out/Applications/Bitwarden.app/Contents/MacOS/Bitwarden $out/bin/bitwarden
    ''
    + lib.optionalString stdenv.hostPlatform.isLinux ''
      mkdir -p $out/opt/Bitwarden
    cp -r locales resources{,.pak} $out/opt/Bitwarden
    popd
      cp -r apps/desktop/dist/linux-*unpacked/{locales,resources{,.pak}} $out/opt/Bitwarden

      makeWrapper '${lib.getExe electron}' "$out/bin/bitwarden" \
        --add-flags $out/opt/Bitwarden/resources/app.asar \
@@ -177,7 +202,8 @@ buildNpmPackage rec {
        cp "$icon" "$dir"/${icon}.png
      done
      popd

    ''
    + ''
      runHook postInstall
    '';

@@ -212,6 +238,8 @@ buildNpmPackage rec {
    platforms = [
      "x86_64-linux"
      "aarch64-linux"
      "x86_64-darwin"
      "aarch64-darwin"
    ];
    mainProgram = "bitwarden";
  };
+28 −0
Original line number Diff line number Diff line
diff --git a/apps/desktop/scripts/after-pack.js b/apps/desktop/scripts/after-pack.js
index 45b79c0..65a6fd5 100644
--- a/apps/desktop/scripts/after-pack.js
+++ b/apps/desktop/scripts/after-pack.js
@@ -13,6 +13,9 @@ async function run(context) {
   console.log("## After pack");
   // console.log(context);
 
+  // skip after-pack
+  return;
+
   if (context.packager.platform.nodeName !== "darwin" || context.arch === builder.Arch.universal) {
     await addElectronFuses(context);
   }
diff --git a/apps/desktop/scripts/after-sign.js b/apps/desktop/scripts/after-sign.js
index 20c24c8..acaf867 100644
--- a/apps/desktop/scripts/after-sign.js
+++ b/apps/desktop/scripts/after-sign.js
@@ -12,6 +12,9 @@ async function run(context) {
   console.log("## After sign");
   // console.log(context);
 
+  // skip after-sign
+  return;
+
   const appName = context.packager.appInfo.productFilename;
   const appPath = `${context.appOutDir}/${appName}.app`;
   const macBuild = context.electronPlatformName === "darwin";
+0 −39
Original line number Diff line number Diff line
diff --git a/apps/desktop/scripts/after-pack.js b/apps/desktop/scripts/after-pack.js
index fd16cd5ffb..05a2325ee1 100644
--- a/apps/desktop/scripts/after-pack.js
+++ b/apps/desktop/scripts/after-pack.js
@@ -13,25 +13,6 @@ async function run(context) {
   console.log("## After pack");
   // console.log(context);
 
-  if (context.packager.platform.nodeName !== "darwin" || context.arch === builder.Arch.universal) {
-    await addElectronFuses(context);
-  }
-
-  if (context.electronPlatformName === "linux") {
-    console.log("Creating memory-protection wrapper script");
-    const appOutDir = context.appOutDir;
-    const oldBin = path.join(appOutDir, context.packager.executableName);
-    const newBin = path.join(appOutDir, "bitwarden-app");
-    fse.moveSync(oldBin, newBin);
-    console.log("Moved binary to bitwarden-app");
-
-    const wrapperScript = path.join(__dirname, "../resources/memory-dump-wrapper.sh");
-    const wrapperBin = path.join(appOutDir, context.packager.executableName);
-    fse.copyFileSync(wrapperScript, wrapperBin);
-    fse.chmodSync(wrapperBin, "755");
-    console.log("Copied memory-protection wrapper script");
-  }
-
   if (["darwin", "mas"].includes(context.electronPlatformName)) {
     const is_mas = context.electronPlatformName === "mas";
     const is_mas_dev = context.targets.some((e) => e.name === "mas-dev");
@@ -140,6 +121,8 @@ function getIdentities() {
  * @param {import("electron-builder").AfterPackContext} context
  */
 async function addElectronFuses(context) {
+  return;
+
   const platform = context.packager.platform.nodeName;
 
   const ext = {