278 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			278 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| {
 | ||
|   stdenv,
 | ||
|   lib,
 | ||
|   nodejs_22,
 | ||
|   pnpm_10,
 | ||
|   electron_36,
 | ||
|   python3,
 | ||
|   makeWrapper,
 | ||
|   callPackage,
 | ||
|   fetchFromGitHub,
 | ||
|   jq,
 | ||
|   makeDesktopItem,
 | ||
|   copyDesktopItems,
 | ||
|   replaceVars,
 | ||
|   noto-fonts-color-emoji,
 | ||
|   nixosTests,
 | ||
| 
 | ||
|   # command line arguments which are always set e.g "--password-store=kwallet6"
 | ||
|   commandLineArgs ? "",
 | ||
| 
 | ||
|   withAppleEmojis ? false,
 | ||
| }:
 | ||
| let
 | ||
|   nodejs = nodejs_22;
 | ||
|   pnpm = pnpm_10.override { inherit nodejs; };
 | ||
|   electron = electron_36;
 | ||
| 
 | ||
|   libsignal-node = callPackage ./libsignal-node.nix { inherit nodejs; };
 | ||
|   signal-sqlcipher = callPackage ./signal-sqlcipher.nix { inherit pnpm nodejs; };
 | ||
| 
 | ||
|   webrtc = callPackage ./webrtc.nix { };
 | ||
|   ringrtc = callPackage ./ringrtc.nix { inherit webrtc; };
 | ||
| 
 | ||
|   # Noto Color Emoji PNG files for emoji replacement; see below.
 | ||
|   noto-fonts-color-emoji-png = noto-fonts-color-emoji.overrideAttrs (prevAttrs: {
 | ||
|     pname = "noto-fonts-color-emoji-png";
 | ||
| 
 | ||
|     # The build produces 136×128 PNGs by default for arcane font
 | ||
|     # reasons, but we want square PNGs.
 | ||
|     buildFlags = prevAttrs.buildFlags or [ ] ++ [ "BODY_DIMENSIONS=128x128" ];
 | ||
| 
 | ||
|     makeTargets = [ "compressed" ];
 | ||
| 
 | ||
|     installPhase = ''
 | ||
|       runHook preInstall
 | ||
| 
 | ||
|       mkdir -p $out/share
 | ||
|       mv build/compressed_pngs $out/share/noto-fonts-color-emoji-png
 | ||
|       python3 add_aliases.py --srcdir=$out/share/noto-fonts-color-emoji-png
 | ||
| 
 | ||
|       runHook postInstall
 | ||
|     '';
 | ||
|   });
 | ||
| 
 | ||
|   version = "7.61.0";
 | ||
| 
 | ||
|   src = fetchFromGitHub {
 | ||
|     owner = "signalapp";
 | ||
|     repo = "Signal-Desktop";
 | ||
|     tag = "v${version}";
 | ||
|     hash = "sha256-foMzSKm2BROZ8ATCdYx/0sl+4tQfhgoPA4AWSHEKL0Y=";
 | ||
|   };
 | ||
| 
 | ||
|   sticker-creator = stdenv.mkDerivation (finalAttrs: {
 | ||
|     pname = "signal-desktop-sticker-creator";
 | ||
|     inherit version;
 | ||
|     src = src + "/sticker-creator";
 | ||
| 
 | ||
|     pnpmDeps = pnpm.fetchDeps {
 | ||
|       inherit (finalAttrs) pname src version;
 | ||
|       hash = "sha256-cT7Ixl/V/mesPHvJUsG63Y/wXwKjbjkjdjP3S7uEOa0=";
 | ||
|     };
 | ||
| 
 | ||
|     strictDeps = true;
 | ||
|     nativeBuildInputs = [
 | ||
|       nodejs
 | ||
|       pnpm.configHook
 | ||
|     ];
 | ||
| 
 | ||
|     buildPhase = ''
 | ||
|       runHook preBuild
 | ||
|       pnpm run build
 | ||
|       runHook postBuild
 | ||
|     '';
 | ||
| 
 | ||
|     installPhase = ''
 | ||
|       runHook preInstall
 | ||
|       cp -r dist $out
 | ||
|       runHook postInstall
 | ||
|     '';
 | ||
|   });
 | ||
| in
 | ||
| stdenv.mkDerivation (finalAttrs: {
 | ||
|   pname = "signal-desktop";
 | ||
|   inherit src version;
 | ||
| 
 | ||
|   strictDeps = true;
 | ||
|   nativeBuildInputs = [
 | ||
|     nodejs
 | ||
|     pnpm.configHook
 | ||
|     makeWrapper
 | ||
|     copyDesktopItems
 | ||
|     python3
 | ||
|     jq
 | ||
|   ];
 | ||
|   buildInputs = (lib.optional (!withAppleEmojis) noto-fonts-color-emoji-png);
 | ||
| 
 | ||
|   patches = lib.optional (!withAppleEmojis) (
 | ||
|     replaceVars ./replace-apple-emoji-with-noto-emoji.patch {
 | ||
|       noto-emoji-pngs = "${noto-fonts-color-emoji-png}/share/noto-fonts-color-emoji-png";
 | ||
|     }
 | ||
|   );
 | ||
| 
 | ||
|   pnpmDeps = pnpm.fetchDeps {
 | ||
|     inherit (finalAttrs)
 | ||
|       pname
 | ||
|       version
 | ||
|       src
 | ||
|       patches
 | ||
|       ;
 | ||
|     hash =
 | ||
|       if withAppleEmojis then
 | ||
|         "sha256-ry7s9fbKx4e1LR8DlI2LIJY9GQrxmU7JQt+3apJGw/M="
 | ||
|       else
 | ||
|         "sha256-AkrfugpNvk4KgesRLQbso8p5b96Dg174R9/xuP4JtJg=";
 | ||
|   };
 | ||
| 
 | ||
|   env = {
 | ||
|     ELECTRON_SKIP_BINARY_DOWNLOAD = "1";
 | ||
|     SIGNAL_ENV = "production";
 | ||
|     SOURCE_DATE_EPOCH = 1752109090;
 | ||
|   };
 | ||
| 
 | ||
|   preBuild = ''
 | ||
|     if [ "`jq -r '.engines.node' < package.json | cut -d. -f1`" != "${lib.versions.major nodejs.version}" ]
 | ||
|     then
 | ||
|       die "nodejs version mismatch"
 | ||
|     fi
 | ||
| 
 | ||
|     if [ "`jq -r '.devDependencies.electron' < package.json | cut -d. -f1`" != "${lib.versions.major electron.version}" ]
 | ||
|     then
 | ||
|       die "electron version mismatch"
 | ||
|     fi
 | ||
| 
 | ||
|     if [ "`jq -r '.dependencies."@signalapp/libsignal-client"' < package.json`" != "${libsignal-node.version}" ]
 | ||
|     then
 | ||
|       die "libsignal-client version mismatch"
 | ||
|     fi
 | ||
| 
 | ||
|     if [ "`jq -r '.dependencies."@signalapp/sqlcipher"' < package.json`" != "${signal-sqlcipher.version}" ]
 | ||
|     then
 | ||
|       die "signal-sqlcipher version mismatch"
 | ||
|     fi
 | ||
| 
 | ||
|     if [ "`jq -r '.dependencies."@signalapp/ringrtc"' < package.json`" != "${ringrtc.version}" ]
 | ||
|     then
 | ||
|       die "ringrtc version mismatch"
 | ||
|     fi
 | ||
| 
 | ||
|     install -D ${ringrtc}/lib/libringrtc${stdenv.hostPlatform.extensions.library} \
 | ||
|       node_modules/@signalapp/ringrtc/build/libringrtc.node
 | ||
| 
 | ||
|     substituteInPlace package.json \
 | ||
|       --replace-fail '"node_modules/@signalapp/ringrtc/build/''${platform}/*''${arch}*.node",' \
 | ||
|                      '"node_modules/@signalapp/ringrtc/build/libringrtc.node",'
 | ||
| 
 | ||
|     substituteInPlace node_modules/@signalapp/ringrtc/dist/ringrtc/Native.js \
 | ||
|       --replace-fail 'exports.default = require(`../../build/''${os.platform()}/libringrtc-''${process.arch}.node`);' \
 | ||
|                      'exports.default = require(`../../build/libringrtc.node`);'
 | ||
| 
 | ||
|     rm -r node_modules/@signalapp/libsignal-client/prebuilds
 | ||
|     cp -r ${libsignal-node}/lib node_modules/@signalapp/libsignal-client/prebuilds
 | ||
| 
 | ||
|     rm -r node_modules/@signalapp/sqlcipher
 | ||
|     cp -r ${signal-sqlcipher} node_modules/@signalapp/sqlcipher
 | ||
|   '';
 | ||
| 
 | ||
|   buildPhase = ''
 | ||
|     runHook preBuild
 | ||
| 
 | ||
|     export npm_config_nodedir=${electron.headers}
 | ||
|     cp -r ${electron.dist} electron-dist
 | ||
|     chmod -R u+w electron-dist
 | ||
|     cp -r ${sticker-creator} sticker-creator/dist
 | ||
| 
 | ||
|     pnpm run generate
 | ||
|     pnpm exec electron-builder \
 | ||
|       --dir \
 | ||
|       --config.extraMetadata.environment=$SIGNAL_ENV \
 | ||
|       -c.electronDist=electron-dist \
 | ||
|       -c.electronVersion=${electron.version}
 | ||
| 
 | ||
|     runHook postBuild
 | ||
|   '';
 | ||
| 
 | ||
|   installPhase = ''
 | ||
|     runHook preInstall
 | ||
| 
 | ||
|     mkdir -p $out/share/
 | ||
|     cp -r dist/*-unpacked/resources $out/share/signal-desktop
 | ||
| 
 | ||
|     for icon in build/icons/png/*
 | ||
|     do
 | ||
|       install -Dm644 $icon $out/share/icons/hicolor/`basename ''${icon%.png}`/apps/signal-desktop.png
 | ||
|     done
 | ||
| 
 | ||
|     makeWrapper '${lib.getExe electron}' "$out/bin/signal-desktop" \
 | ||
|       --add-flags "$out/share/signal-desktop/app.asar" \
 | ||
|       --set-default ELECTRON_FORCE_IS_PACKAGED 1 \
 | ||
|       --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}" \
 | ||
|       --add-flags ${lib.escapeShellArg commandLineArgs}
 | ||
| 
 | ||
|     runHook postInstall
 | ||
|   '';
 | ||
| 
 | ||
|   desktopItems = [
 | ||
|     (makeDesktopItem {
 | ||
|       name = "signal";
 | ||
|       desktopName = "Signal";
 | ||
|       exec = "${finalAttrs.meta.mainProgram} %U";
 | ||
|       type = "Application";
 | ||
|       terminal = false;
 | ||
|       icon = "signal-desktop";
 | ||
|       comment = "Private messaging from your desktop";
 | ||
|       startupWMClass = "signal";
 | ||
|       mimeTypes = [
 | ||
|         "x-scheme-handler/sgnl"
 | ||
|         "x-scheme-handler/signalcaptcha"
 | ||
|       ];
 | ||
|       categories = [
 | ||
|         "Network"
 | ||
|         "InstantMessaging"
 | ||
|         "Chat"
 | ||
|       ];
 | ||
|     })
 | ||
|   ];
 | ||
| 
 | ||
|   passthru = {
 | ||
|     inherit
 | ||
|       libsignal-node
 | ||
|       ringrtc
 | ||
|       webrtc
 | ||
|       sticker-creator
 | ||
|       signal-sqlcipher
 | ||
|       ;
 | ||
|     tests.application-launch = nixosTests.signal-desktop;
 | ||
|     updateScript.command = [ ./update.sh ];
 | ||
|   };
 | ||
| 
 | ||
|   meta = {
 | ||
|     description = "Private, simple, and secure messenger (nixpkgs build)";
 | ||
|     longDescription = ''
 | ||
|       Signal Desktop is an Electron application that links with your
 | ||
|       "Signal Android" or "Signal iOS" app.
 | ||
|     '';
 | ||
|     homepage = "https://signal.org/";
 | ||
|     changelog = "https://github.com/signalapp/Signal-Desktop/releases/tag/v${finalAttrs.version}";
 | ||
|     license =
 | ||
|       with lib.licenses;
 | ||
|       [
 | ||
|         agpl3Only
 | ||
| 
 | ||
|         # Various npm packages
 | ||
|         free
 | ||
|       ]
 | ||
|       ++ lib.optional withAppleEmojis unfree;
 | ||
|     maintainers = with lib.maintainers; [
 | ||
|       marcin-serwin
 | ||
|       teutat3s
 | ||
|     ];
 | ||
|     mainProgram = "signal-desktop";
 | ||
|     platforms = [
 | ||
|       "x86_64-linux"
 | ||
|       "aarch64-linux"
 | ||
|     ];
 | ||
|   };
 | ||
| })
 | 
