From a5e4623b5a2f33875d44dde2289313cb9491d18a Mon Sep 17 00:00:00 2001 From: snekxs <26660858+snekxs@users.noreply.github.com> Date: Mon, 26 Oct 2026 16:57:48 -0600 Subject: [PATCH 1/3] feat(macos): ship Bridge as a signed .app in a styled DMG; make the updater bundle-aware - packaging/macos: build OpenMouse Bridge.app (tray-only, icon, bundled native-hid) and a dmgbuild installer window - updater: replace the whole .app in a locked, rolling-back transaction; bare-binary installs keep the existing zip - updater: open archives with a known zero offset so the metadata budget no longer rejects every real (>16 MiB) release archive - release workflow: build, optionally Developer ID sign and notarize, and publish the DMG plus app update archive --- .github/workflows/release.yml | 61 ++++++- .gitignore | 1 + README.md | 9 + packaging/macos/Info.plist | 34 ++++ packaging/macos/build-app.sh | 67 ++++++++ packaging/macos/build-dmg.sh | 23 +++ packaging/macos/dmg-background.tiff | Bin 0 -> 72666 bytes packaging/macos/dmg-settings.py | 27 +++ packaging/macos/entitlements.plist | 14 ++ packaging/macos/icon-1024.png | Bin 0 -> 68784 bytes packaging/macos/make-assets.py | 175 +++++++++++++++++++ src/drivers/native_hid.rs | 11 +- src/platform/macos.rs | 35 +++- src/platform/mod.rs | 6 +- src/updater.rs | 250 ++++++++++++++++++++++++---- src/updater/tests.rs | 199 ++++++++++++++++++++++ 16 files changed, 870 insertions(+), 42 deletions(-) create mode 100644 packaging/macos/Info.plist create mode 100755 packaging/macos/build-app.sh create mode 100755 packaging/macos/build-dmg.sh create mode 100644 packaging/macos/dmg-background.tiff create mode 100644 packaging/macos/dmg-settings.py create mode 100644 packaging/macos/entitlements.plist create mode 100644 packaging/macos/icon-1024.png create mode 100644 packaging/macos/make-assets.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a5c4b3b..1ddad41 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,6 +72,15 @@ jobs: macos: name: macOS universal runs-on: macos-14 + # Signing and notarization are automatic when these secrets exist; + # without them the app is ad-hoc signed. + env: + MACOS_CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE_BASE64 }} + MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} + MACOS_SIGN_IDENTITY: ${{ secrets.MACOS_SIGN_IDENTITY }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }} steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable @@ -105,7 +114,7 @@ jobs: "node-$NATIVE_HID_NODE_VERSION-darwin-x64/bin/node" \ -output native-hid/node/bin/node chmod +x native-hid/node/bin/node - - name: Package universal binary + - name: Package universal binary (existing bare-binary installs) run: | lipo -create \ target/aarch64-apple-darwin/release/openmouse-bridge \ @@ -115,12 +124,62 @@ jobs: cp assets/fonts/DM-Sans-OFL.txt ./DM-Sans-OFL.txt zip -r openmouse-bridge-macos-universal.zip openmouse-bridge README.md DM-Sans-OFL.txt native-hid shasum -a 256 openmouse-bridge-macos-universal.zip > openmouse-bridge-macos-universal.zip.sha256 + - name: Import signing certificate + if: env.MACOS_CERTIFICATE_BASE64 != '' + run: | + set -euo pipefail + keychain="$RUNNER_TEMP/openmouse-signing.keychain-db" + keychain_password="$(uuidgen)" + echo "$MACOS_CERTIFICATE_BASE64" | base64 --decode > "$RUNNER_TEMP/certificate.p12" + security create-keychain -p "$keychain_password" "$keychain" + security set-keychain-settings -lut 21600 "$keychain" + security unlock-keychain -p "$keychain_password" "$keychain" + security import "$RUNNER_TEMP/certificate.p12" -P "$MACOS_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$keychain" + security set-key-partition-list -S apple-tool:,apple: -s -k "$keychain_password" "$keychain" + security list-keychains -d user -s "$keychain" login.keychain-db + echo "MACOS_SIGN_IDENTITY=$MACOS_SIGN_IDENTITY" >> "$GITHUB_ENV" + - name: Build OpenMouse Bridge.app + run: | + version="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)" + mkdir -p dist + packaging/macos/build-app.sh openmouse-bridge native-hid "$version" dist + - name: Notarize app + if: env.MACOS_CERTIFICATE_BASE64 != '' && env.APPLE_ID != '' + run: | + set -euo pipefail + ditto -c -k --keepParent "dist/OpenMouse Bridge.app" notarize-app.zip + xcrun notarytool submit notarize-app.zip --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" --password "$APPLE_APP_PASSWORD" --wait + xcrun stapler staple "dist/OpenMouse Bridge.app" + - name: Package DMG and app update archive + run: | + set -euo pipefail + python3 -m pip install --quiet dmgbuild + packaging/macos/build-dmg.sh "dist/OpenMouse Bridge.app" OpenMouse-Bridge-macos-universal.dmg + # Plain Info-ZIP (not ditto): the updater's strict extractor expects ordinary zip entries. + (cd dist && zip -r -X -q "../openmouse-bridge-macos-app.zip" "OpenMouse Bridge.app") + shasum -a 256 openmouse-bridge-macos-app.zip > openmouse-bridge-macos-app.zip.sha256 + - name: Notarize DMG + if: env.MACOS_CERTIFICATE_BASE64 != '' && env.APPLE_ID != '' + run: | + set -euo pipefail + xcrun notarytool submit OpenMouse-Bridge-macos-universal.dmg --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" --password "$APPLE_APP_PASSWORD" --wait + xcrun stapler staple OpenMouse-Bridge-macos-universal.dmg + - name: Verify DMG + run: | + set -euo pipefail + hdiutil attach OpenMouse-Bridge-macos-universal.dmg -nobrowse -readonly -mountpoint "$RUNNER_TEMP/dmg" + test -d "$RUNNER_TEMP/dmg/OpenMouse Bridge.app" + codesign --verify --deep --strict "$RUNNER_TEMP/dmg/OpenMouse Bridge.app" + hdiutil detach "$RUNNER_TEMP/dmg" - uses: actions/upload-artifact@v4 with: name: bridge-macos path: | openmouse-bridge-macos-universal.zip openmouse-bridge-macos-universal.zip.sha256 + openmouse-bridge-macos-app.zip + openmouse-bridge-macos-app.zip.sha256 + OpenMouse-Bridge-macos-universal.dmg linux: name: Linux x64 runs-on: ubuntu-24.04 diff --git a/.gitignore b/.gitignore index 1ca09c9..65bfcab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target native-hid/node_modules .DS_Store +__pycache__/ diff --git a/README.md b/README.md index 0c203ad..6bbe239 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,15 @@ cargo test cargo clippy --all-targets -- -D warnings ``` +## Install on macOS + +Download `OpenMouse-Bridge-macos-universal.dmg` from the latest release, open +it, and drag OpenMouse Bridge to Applications. It runs as a menu bar app with +no Terminal window. `packaging/macos/` holds the scripts that build the app +bundle and DMG; the release workflow signs and notarizes them when the +`MACOS_CERTIFICATE_BASE64`, `MACOS_CERTIFICATE_PASSWORD`, `MACOS_SIGN_IDENTITY`, +`APPLE_ID`, `APPLE_TEAM_ID` and `APPLE_APP_PASSWORD` secrets are set. + ## Install on Linux One-line install from the latest stable release (detects missing system diff --git a/packaging/macos/Info.plist b/packaging/macos/Info.plist new file mode 100644 index 0000000..38621b3 --- /dev/null +++ b/packaging/macos/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + openmouse-bridge + CFBundleIconFile + OpenMouse + CFBundleIdentifier + io.OpenMouse.OpenMouse-Bridge + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + OpenMouse Bridge + CFBundleDisplayName + OpenMouse Bridge + CFBundlePackageType + APPL + CFBundleShortVersionString + @VERSION@ + CFBundleVersion + @BUILD@ + LSMinimumSystemVersion + 11.0 + LSUIElement + + NSHighResolutionCapable + + NSHumanReadableCopyright + MIT License + + diff --git a/packaging/macos/build-app.sh b/packaging/macos/build-app.sh new file mode 100755 index 0000000..b66d1fe --- /dev/null +++ b/packaging/macos/build-app.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# Assembles "OpenMouse Bridge.app" from a built Bridge binary and a prepared +# native-hid directory (deps + bundled Node.js, see release.yml). +# +# build-app.sh +# +# Signs ad-hoc by default. Set MACOS_SIGN_IDENTITY to a Developer ID +# Application identity for a distributable (notarizable) build. +set -euo pipefail + +binary="$1" +native_hid="$2" +version="$3" +out_dir="$4" +identity="${MACOS_SIGN_IDENTITY:--}" + +here="$(cd "$(dirname "$0")" && pwd)" +repo="$(cd "$here/../.." && pwd)" +app="$out_dir/OpenMouse Bridge.app" + +rm -rf "$app" +mkdir -p "$app/Contents/MacOS" "$app/Contents/Resources" + +cp "$binary" "$app/Contents/MacOS/openmouse-bridge" +chmod +x "$app/Contents/MacOS/openmouse-bridge" + +ditto "$native_hid" "$app/Contents/Resources/native-hid" +# Bridge's updater refuses packages that omit the bundled font's license. +cp "$repo/assets/fonts/DM-Sans-OFL.txt" "$app/Contents/Resources/DM-Sans-OFL.txt" +# npm's .bin entries are symlinks, which the update zip cannot carry. +find "$app/Contents/Resources/native-hid" -name .bin -type d -prune -exec rm -rf {} + +if [ -n "$(find "$app" -type l)" ]; then + echo "bundle contains symlinks:" >&2 + find "$app" -type l >&2 + exit 1 +fi + +# 1.0.0-beta.19 -> short version as-is, build number numeric. +build="${version%%-*}" +sed -e "s/@VERSION@/$version/" -e "s/@BUILD@/$build/" \ + "$here/Info.plist" > "$app/Contents/Info.plist" + +iconset="$(mktemp -d)/OpenMouse.iconset" +mkdir -p "$iconset" +icon="$here/icon-1024.png" # regenerate with make-assets.py +for size in 16 32 128 256 512; do + sips -z "$size" "$size" "$icon" --out "$iconset/icon_${size}x${size}.png" >/dev/null + double=$((size * 2)) + sips -z "$double" "$double" "$icon" --out "$iconset/icon_${size}x${size}@2x.png" >/dev/null +done +iconutil -c icns "$iconset" -o "$app/Contents/Resources/OpenMouse.icns" + +sign_flags=(--force --sign "$identity" --entitlements "$here/entitlements.plist") +if [ "$identity" != "-" ]; then + sign_flags+=(--options runtime --timestamp) +fi + +# Inside-out: nested Mach-O (Node, node-hid addon) first, then the app. +while IFS= read -r -d '' file; do + if file -b "$file" | grep -q "Mach-O"; then + codesign "${sign_flags[@]}" "$file" + fi +done < <(find "$app/Contents/Resources" -type f -print0) +codesign "${sign_flags[@]}" "$app" + +codesign --verify --deep --strict "$app" +echo "$app" diff --git a/packaging/macos/build-dmg.sh b/packaging/macos/build-dmg.sh new file mode 100755 index 0000000..c261ba2 --- /dev/null +++ b/packaging/macos/build-dmg.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Wraps the app in a styled drag-to-Applications disk image. Needs dmgbuild +# (pip install dmgbuild). +# +# build-dmg.sh +set -euo pipefail + +app="$1" +dmg="$2" +identity="${MACOS_SIGN_IDENTITY:--}" +here="$(cd "$(dirname "$0")" && pwd)" + +rm -f "$dmg" +dmgbuild -s "$here/dmg-settings.py" \ + -D app="$app" \ + -D icon="$app/Contents/Resources/OpenMouse.icns" \ + -D background="$here/dmg-background.tiff" \ + "OpenMouse Bridge" "$dmg" + +if [ "$identity" != "-" ]; then + codesign --force --sign "$identity" --timestamp "$dmg" +fi +echo "$dmg" diff --git a/packaging/macos/dmg-background.tiff b/packaging/macos/dmg-background.tiff new file mode 100644 index 0000000000000000000000000000000000000000..3cffb16ff39d522807973b14645edee0c46846c2 GIT binary patch literal 72666 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�|)Ea6WYvN+ES3(27YJr7YAm3 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 literal 0 HcmV?d00001 diff --git a/packaging/macos/dmg-settings.py b/packaging/macos/dmg-settings.py new file mode 100644 index 0000000..4906c97 --- /dev/null +++ b/packaging/macos/dmg-settings.py @@ -0,0 +1,27 @@ +# dmgbuild settings for the installer window; see build-dmg.sh. +# defines: app (path to the .app), icon (volume icon .icns), background (.tiff) +import os + +app = defines["app"] +app_name = os.path.basename(app) + +format = "UDZO" +files = [app] +symlinks = {"Applications": "/Applications"} +background = defines["background"] +icon = defines["icon"] + +show_status_bar = False +show_tab_view = False +show_toolbar = False +show_pathbar = False +show_sidebar = False +default_view = "icon-view" + +# Frame = 32pt title bar + 400pt content + 28pt path bar (bg is 660x428 so it +# also fills the frame when the path bar is hidden). Icon y matches make-assets.py. +window_rect = ((200, 120), (660, 460)) +icon_size = 112 +text_size = 13 +arrange_by = None +icon_locations = {app_name: (170, 185), "Applications": (490, 185)} diff --git a/packaging/macos/entitlements.plist b/packaging/macos/entitlements.plist new file mode 100644 index 0000000..f83db85 --- /dev/null +++ b/packaging/macos/entitlements.plist @@ -0,0 +1,14 @@ + + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + + diff --git a/packaging/macos/icon-1024.png b/packaging/macos/icon-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..e29283cafebae50bc0a60f21adc31134a21ccc3f GIT binary patch literal 68784 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μm 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 1: + continue + span = (1 - dy**n) ** (1 / n) + x0 = int(center - half * span) + x1 = int(center + half * span) + for x in range(max(x0, 0), min(x1, big)): + pixels[x, y] = 255 + return mask.resize((size, size), Image.LANCZOS) + + +def make_icon(): + size = 1024 + tile = superellipse_mask(size, margin=100) + + gradient = Image.new("RGB", (size, size)) + draw = ImageDraw.Draw(gradient) + for y in range(size): + t = y / (size - 1) + draw.line( + [(0, y), (size, y)], + fill=(int(34 - 16 * t), int(38 - 18 * t), int(46 - 22 * t)), + ) + + icon = Image.new("RGBA", (size, size), (0, 0, 0, 0)) + + shadow = Image.new("L", (size, size), 0) + shadow.paste(tile, (0, 12)) + shadow = shadow.filter(ImageFilter.GaussianBlur(14)).point(lambda v: v * 0.45) + icon.paste(Image.new("RGBA", (size, size), (0, 0, 0, 255)), mask=shadow) + icon.paste(gradient, mask=tile) + + mouse = Image.open(SOURCE).convert("RGBA") + mouse = mouse.crop(mouse.getbbox()) + height = 520 + mouse = mouse.resize((round(mouse.width * height / mouse.height), height), Image.LANCZOS) + icon.alpha_composite(mouse, ((size - mouse.width) // 2, (size - mouse.height) // 2)) + icon.save(HERE / "icon-1024.png") + return icon + + +BANNER = r""" + ___ __ __ + / _ \ _ __ ___ _ _ | \/ |___ _ _ ___ ___ +| (_) | '_ \/ -_) ' \| |\/| / _ \ || (_-", f) + gap = 8 * scale + count = 5 + total = count * chevron + (count - 1) * gap + x = ((APP_X + APPS_X) * scale - total) / 2 + for i in range(count): + t = (i + 1) / count + color = tuple(int(DIM[c] + (GREEN[c] - DIM[c]) * t) for c in range(3)) + draw.text((x + i * (chevron + gap), (ICON_Y - 19) * scale), ">", font=f, fill=color) + + # Finder always draws DMG icon labels in black over a picture background, + # so give them light chips to sit on (label centre is ~74pt below the icon). + chip_w, chip_h, chip_y = 140, 22, ICON_Y + 74 + for cx in (APP_X, APPS_X): + draw.rounded_rectangle( + [(cx - chip_w / 2) * scale, (chip_y - chip_h / 2) * scale, + (cx + chip_w / 2) * scale, (chip_y + chip_h / 2) * scale], + radius=chip_h / 2 * scale, + fill=(226, 231, 238), + ) + + # Terminal-style caption with a cursor block. + f = mono(12) + caption = "drag OpenMouse Bridge.app -> /Applications" + prompt = "$ " + cursor = 8 * scale + total = text_width(prompt + caption, f) + 6 * scale + cursor + x = (width - total) / 2 + y = 330 * scale + draw.text((x, y), prompt, font=f, fill=GREEN) + draw.text((x + text_width(prompt, f), y), caption, font=f, fill=TEXT) + cx = x + text_width(prompt + caption, f) + 6 * scale + draw.rectangle([cx, y + 1 * scale, cx + cursor, y + 15 * scale], fill=GREEN) + return image + + +def main(): + make_icon() + one, two = background(1), background(2) + one.save(HERE / "bg.png", dpi=(72, 72)) + two.save(HERE / "bg@2x.png", dpi=(144, 144)) + subprocess.run( + ["tiffutil", "-cathidpicheck", HERE / "bg.png", HERE / "bg@2x.png", + "-out", HERE / "dmg-background.tiff"], + check=True, + ) + (HERE / "bg.png").unlink() + (HERE / "bg@2x.png").unlink() + + +if __name__ == "__main__": + main() diff --git a/src/drivers/native_hid.rs b/src/drivers/native_hid.rs index 8a0514f..d94417a 100644 --- a/src/drivers/native_hid.rs +++ b/src/drivers/native_hid.rs @@ -312,10 +312,15 @@ fn locate_node_binary() -> Option { } /// The `native-hid/` directory a packaged Bridge release ships next to its -/// executable, if the executable's location can be determined at all (it's -/// an `Option` rather than a hard error because the fallback paths this -/// module's callers use don't need it to succeed). +/// executable (or, in a macOS `.app`, under `Contents/Resources/`), if the +/// executable's location can be determined at all (it's an `Option` rather +/// than a hard error because the fallback paths this module's callers use +/// don't need it to succeed). fn installed_native_hid_dir() -> Option { + #[cfg(target_os = "macos")] + if let Some(bundle) = crate::platform::bundle_root() { + return Some(bundle.join("Contents/Resources/native-hid")); + } Some(std::env::current_exe().ok()?.parent()?.join("native-hid")) } diff --git a/src/platform/macos.rs b/src/platform/macos.rs index b970da8..f60d388 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -1,4 +1,7 @@ -use std::{env, fs, path::PathBuf}; +use std::{ + env, fs, + path::{Path, PathBuf}, +}; use anyhow::{Context, Result}; use directories::BaseDirs; @@ -13,6 +16,22 @@ pub fn linux_distribution() -> Option { None } +/// The `.app` directory the running executable lives in, if it was launched +/// from a bundle (`X.app/Contents/MacOS/`) rather than as a bare binary. +pub fn bundle_root() -> Option { + bundle_root_of(&env::current_exe().ok()?) +} + +fn bundle_root_of(executable: &Path) -> Option { + let macos_dir = executable.parent()?; + let contents = macos_dir.parent()?; + let bundle = contents.parent()?; + (macos_dir.file_name()? == "MacOS" + && contents.file_name()? == "Contents" + && bundle.extension()? == "app") + .then(|| bundle.to_path_buf()) +} + pub fn autostart_enabled() -> bool { launch_agent_path().is_ok_and(|path| path.exists()) } @@ -72,6 +91,20 @@ fn xml_escape(value: &str) -> String { mod tests { use super::*; + #[test] + fn bundle_root_is_found_only_inside_an_app() { + assert_eq!( + bundle_root_of(Path::new( + "/Applications/OpenMouse Bridge.app/Contents/MacOS/openmouse-bridge" + )), + Some(PathBuf::from("/Applications/OpenMouse Bridge.app")) + ); + assert_eq!( + bundle_root_of(Path::new("/tmp/openmouse-bridge/openmouse-bridge")), + None + ); + } + #[test] fn executable_paths_are_escaped_for_plists() { assert_eq!(xml_escape("A&B "), "A&B <Bridge>"); diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 9452878..04477d4 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -21,7 +21,7 @@ pub use windows::{ }; #[cfg(target_os = "macos")] -pub use macos::{autostart_enabled, linux_distribution, platform_name, set_autostart}; +pub use macos::{autostart_enabled, bundle_root, linux_distribution, platform_name, set_autostart}; #[cfg(target_os = "linux")] pub use linux::{autostart_enabled, linux_distribution, platform_name, set_autostart}; @@ -158,9 +158,7 @@ pub fn notify(summary: &str, body: &str) -> Result<()> { #[cfg(target_os = "macos")] fn macos_is_bundled() -> bool { - std::env::current_exe() - .map(|path| path.to_string_lossy().contains(".app/Contents/MacOS/")) - .unwrap_or(false) + bundle_root().is_some() } #[cfg(target_os = "macos")] diff --git a/src/updater.rs b/src/updater.rs index 282d4cb..6c84f67 100644 --- a/src/updater.rs +++ b/src/updater.rs @@ -22,6 +22,9 @@ const UPDATE_URL_ENV: &str = "OPENMOUSE_BRIDGE_UPDATE_API_URL"; const USER_AGENT: &str = "OpenMouse-Bridge-Updater"; const CHECK_TIMEOUT: Duration = Duration::from_secs(8); const DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10 * 60); +/// The bundle a macOS app-update archive carries at its root. +#[cfg(any(target_os = "macos", test))] +const MACOS_APP_NAME: &str = "OpenMouse Bridge.app"; #[derive(Clone, Debug)] pub struct UpdateInfo { @@ -153,8 +156,14 @@ fn asset_url(assets: &[ReleaseAsset], name: &str) -> Result { } fn platform_archive_name() -> Result<&'static str> { + // Installs from the DMG run as a signed .app and are replaced as a whole + // bundle; bare-binary installs keep following the original zip. #[cfg(target_os = "macos")] - return Ok("openmouse-bridge-macos-universal.zip"); + return Ok(if crate::platform::bundle_root().is_some() { + "openmouse-bridge-macos-app.zip" + } else { + "openmouse-bridge-macos-universal.zip" + }); #[cfg(target_os = "windows")] return Ok("openmouse-bridge-windows-x64.zip"); #[cfg(target_os = "linux")] @@ -232,22 +241,80 @@ fn stage_archive(archive: &[u8], version: &str) -> Result<()> { verify_package(&staging.path)?; let current_executable = env::current_exe().context("could not locate the Bridge executable")?; - let install_directory = current_executable - .parent() - .context("Bridge executable has no parent directory")?; ensure!( current_executable.file_name() == Some(std::ffi::OsStr::new(platform_binary_name())), "Bridge executable has an unexpected name" ); + // A bundled install replaces the whole .app so its code signature stays + // intact; the directory that must be writable is the one holding it. + #[cfg(target_os = "macos")] + if let Some(bundle) = crate::platform::bundle_root() { + let install_directory = bundle + .parent() + .context("Bridge bundle has no parent directory")?; + let bundle_name = bundle + .file_name() + .context("Bridge bundle has no file name")?; + verify_install_targets(install_directory, &[bundle_name])?; + spawn_bundle_install_helper(&staging.path, install_directory, bundle_name)?; + staging.handed_off = true; + return Ok(()); + } + let install_directory = current_executable + .parent() + .context("Bridge executable has no parent directory")?; verify_install_directory(install_directory)?; spawn_install_helper(&staging.path, install_directory, ¤t_executable)?; staging.handed_off = true; Ok(()) } +/// Where an update package keeps the files Bridge needs, relative to the +/// extracted archive: flat next to the executable, or inside a macOS bundle. +struct PackageLayout { + binary: std::path::PathBuf, + license: std::path::PathBuf, + native_hid: std::path::PathBuf, + extra: Vec, +} + +impl PackageLayout { + fn flat() -> Self { + Self { + binary: platform_binary_name().into(), + license: "DM-Sans-OFL.txt".into(), + native_hid: "native-hid".into(), + extra: Vec::new(), + } + } + + #[cfg(any(target_os = "macos", test))] + fn macos_bundle() -> Self { + let app = Path::new(MACOS_APP_NAME); + Self { + binary: app.join("Contents/MacOS/openmouse-bridge"), + license: app.join("Contents/Resources/DM-Sans-OFL.txt"), + native_hid: app.join("Contents/Resources/native-hid"), + extra: vec![app.join("Contents/Info.plist")], + } + } + + fn current() -> Self { + #[cfg(target_os = "macos")] + if crate::platform::bundle_root().is_some() { + return Self::macos_bundle(); + } + Self::flat() + } +} + fn verify_package(staging: &Path) -> Result<()> { + verify_package_with(staging, &PackageLayout::current()) +} + +fn verify_package_with(staging: &Path, layout: &PackageLayout) -> Result<()> { verify_tree(staging)?; - let license = staging.join("DM-Sans-OFL.txt"); + let license = staging.join(&layout.license); let expected = include_bytes!("../assets/fonts/DM-Sans-OFL.txt"); ensure!( reject_link(&license)?.is_file() && fs::metadata(&license)?.len() == expected.len() as u64, @@ -258,36 +325,41 @@ fn verify_package(staging: &Path) -> Result<()> { "update package contains an incomplete DM Sans license" ); let node = if cfg!(windows) { - "native-hid/node/node.exe" + layout.native_hid.join("node/node.exe") } else { - "native-hid/node/bin/node" + layout.native_hid.join("node/bin/node") }; - for name in [ - platform_binary_name(), - "native-hid/src/apply.mjs", - "native-hid/src/brands.mjs", - "native-hid/src/hid-device-adapter.mjs", - "native-hid/src/attack-shark-x11.mjs", - "native-hid/package.json", - node, - "native-hid/node_modules/node-hid/package.json", - "native-hid/node_modules/@openmouse/protocol/package.json", - "native-hid/node_modules/@openmouse/keyboard-protocol/package.json", - ] { + let hid = &layout.native_hid; + let mut required = vec![ + layout.binary.clone(), + hid.join("src/apply.mjs"), + hid.join("src/brands.mjs"), + hid.join("src/hid-device-adapter.mjs"), + hid.join("src/attack-shark-x11.mjs"), + hid.join("package.json"), + node.clone(), + hid.join("node_modules/node-hid/package.json"), + hid.join("node_modules/@openmouse/protocol/package.json"), + hid.join("node_modules/@openmouse/keyboard-protocol/package.json"), + ]; + required.extend(layout.extra.iter().cloned()); + for name in &required { let path = staging.join(name); verify_directory_chain(path.parent().context("missing package parent")?)?; - let metadata = - reject_link(&path).with_context(|| format!("update package is missing {name}"))?; + let metadata = reject_link(&path) + .with_context(|| format!("update package is missing {}", name.display()))?; ensure!( metadata.is_file() && metadata.len() > 0, - "update package file is empty or invalid: {name}" + "update package file is empty or invalid: {}", + name.display() ); #[cfg(unix)] - if name == platform_binary_name() || name == node { + if *name == layout.binary || *name == node { use std::os::unix::fs::PermissionsExt; ensure!( metadata.permissions().mode() & 0o500 == 0o500, - "update executable requires owner read and execute access: {name}" + "update executable requires owner read and execute access: {}", + name.display() ); } } @@ -458,8 +530,17 @@ fn extract_archive_with_limits( inner: Cursor::new(archive), metadata_budget: &metadata_budget, }; - let mut zip = zip::ZipArchive::new(reader) - .context("update archive is invalid or exceeds metadata budget")?; + // Update archives never carry prepended data. Without a known offset the + // zip crate scans the whole file forward looking for the central + // directory, which spends the entire metadata budget on any archive + // larger than it - that is, every real release. + let mut zip = zip::ZipArchive::with_config( + zip::read::Config { + archive_offset: zip::read::ArchiveOffset::Known(0), + }, + reader, + ) + .context("update archive is invalid or exceeds metadata budget")?; metadata_budget.set(None); ensure!(zip.len() <= entries, "update archive has too many entries"); let mut declared_total = 0u64; @@ -566,25 +647,34 @@ fn extract_archive_with_limits( } } ensure!( - reject_link(&staging.join(platform_binary_name()))?.is_file(), + reject_link(&staging.join(&PackageLayout::current().binary))?.is_file(), "update archive does not contain the Bridge executable" ); Ok(()) } fn verify_install_directory(directory: &Path) -> Result<()> { + verify_install_targets( + directory, + &[ + std::ffi::OsStr::new(platform_binary_name()), + std::ffi::OsStr::new("native-hid"), + std::ffi::OsStr::new("openmouse-app-icon.png"), + std::ffi::OsStr::new("DM-Sans-OFL.txt"), + ], + ) +} + +/// Checks that `directory` is a plain, unlocked, writable directory and that +/// every existing entry named in `names` is a link-free tree. +fn verify_install_targets(directory: &Path, names: &[&std::ffi::OsStr]) -> Result<()> { verify_directory_chain(directory)?; match fs::symlink_metadata(directory.join(".openmouse-update.lock")) { Ok(_) => anyhow::bail!("Bridge update lock already exists"), Err(error) if error.kind() == io::ErrorKind::NotFound => {} Err(error) => return Err(error).context("could not inspect Bridge update lock"), } - for name in [ - platform_binary_name(), - "native-hid", - "openmouse-app-icon.png", - "DM-Sans-OFL.txt", - ] { + for name in names { let path = directory.join(name); match fs::symlink_metadata(&path) { Ok(_) => verify_tree(&path)?, @@ -741,6 +831,100 @@ fn spawn_install_helper(staging: &Path, destination: &Path, executable: &Path) - Ok(()) } +/// Replaces one directory (a macOS `.app`) as a unit. Same lock, backup and +/// rollback discipline as `UNIX_TRANSACTION`: status 2 means nothing changed. +#[cfg(any(target_os = "macos", test))] +const BUNDLE_TRANSACTION: &str = r#"install_bundle() ( +set -eu +stage="$1" +destination="$2" +staged="$3" +installed="$4" +[ -d "$stage/$staged/Contents/MacOS" ] || exit 1 +for tree_root in "$stage" "$destination"; do + parent="$tree_root" + while [ "$parent" != / ]; do + [ -d "$parent" ] && [ ! -L "$parent" ] || exit 1 + parent=$(dirname "$parent") || exit 1 + done +done +special=$(find "$stage" ! -type f ! -type d -print) || exit 1 +[ -z "$special" ] || exit 1 +lock="$destination/.openmouse-update.lock" +(umask 077; mkdir "$lock") || exit 2 +transaction=$(umask 077; mktemp -d "$destination/.openmouse-update.XXXXXXXX") || { rmdir "$lock" || :; exit 2; } +committed=no +rollback() { + status=$? + trap - 0 1 2 15 + failed=no + if [ "$committed" != yes ]; then + if [ -e "$transaction/old/$installed" ]; then + rm -rf "$destination/$installed" && mv "$transaction/old/$installed" "$destination/$installed" || failed=yes + elif [ -f "$transaction/installed/marker" ]; then + rm -rf "$destination/$installed" || failed=yes + fi + fi + if [ "$failed" = yes ]; then + printf '%s\n' "Update rollback failed; backups retained at $transaction" >&2 + exit 1 + fi + rm -rf "$transaction" + rmdir "$lock" + if [ "$committed" != yes ]; then exit 2; fi + exit "$status" +} +trap rollback 0 +trap 'exit 1' 1 2 15 +mkdir "$transaction/new" "$transaction/old" "$transaction/installed" || exit 1 +if [ -e "$destination/$installed" ] || [ -L "$destination/$installed" ]; then + special=$(find "$destination/$installed" ! -type f ! -type d -print) || exit 1 + [ -z "$special" ] || exit 1 +fi +cp -R "$stage/$staged" "$transaction/new/$installed" || exit 1 +chmod u+x "$transaction/new/$installed/Contents/MacOS/openmouse-bridge" || exit 1 +if [ -e "$destination/$installed" ]; then mv "$destination/$installed" "$transaction/old/$installed" || exit 1; fi +: > "$transaction/installed/marker" || exit 1 +mv "$transaction/new/$installed" "$destination/$installed" || exit 1 +committed=yes +) +"#; + +#[cfg(any(target_os = "macos", test))] +const BUNDLE_COMPLETION: &str = r#"complete_bundle_update() { + if install_bundle "$1" "$2" "$3" "$4"; then + : + else + status=$? + [ "$status" -eq 2 ] || return 1 + fi + "$5" "$2" "$4" +} +"#; + +#[cfg(target_os = "macos")] +fn spawn_bundle_install_helper( + staging: &Path, + destination: &Path, + installed: &std::ffi::OsStr, +) -> Result<()> { + let script = staging.join("install-update.sh"); + let contents = format!( + "#!/bin/sh\n{BUNDLE_TRANSACTION}\n{BUNDLE_COMPLETION}\npid=\"$1\"\nstage=\"$2\"\ndestination=\"$3\"\nstaged=\"$4\"\ninstalled=\"$5\"\ntrap 'rm -rf \"$stage\"' 0\nwhile kill -0 \"$pid\" 2>/dev/null; do sleep 1; done\nlaunch_bundle() {{ open \"$1/$2\"; }}\ncomplete_bundle_update \"$stage\" \"$destination\" \"$staged\" \"$installed\" launch_bundle\n" + ); + write_helper(&script, &contents)?; + Command::new("/bin/sh") + .arg(&script) + .arg(std::process::id().to_string()) + .arg(staging) + .arg(destination) + .arg(MACOS_APP_NAME) + .arg(installed) + .spawn() + .context("could not launch the update helper")?; + Ok(()) +} + #[cfg(windows)] const WINDOWS_TRANSACTION: &str = r#"function Assert-CleanTree([string]$Path) { $Pending = [System.Collections.Generic.Stack[string]]::new() diff --git a/src/updater/tests.rs b/src/updater/tests.rs index 09c1849..2b9d016 100644 --- a/src/updater/tests.rs +++ b/src/updater/tests.rs @@ -720,3 +720,202 @@ fn checksum_must_match_archive() { .is_err() ); } + +#[test] +fn macos_bundle_package_layout_requires_every_bundled_file() { + let root = fixture(); + let layout = PackageLayout::macos_bundle(); + let node = layout.native_hid.join("node/bin/node"); + let mut names = vec![ + layout.binary.clone(), + layout.native_hid.join("src/apply.mjs"), + layout.native_hid.join("src/brands.mjs"), + layout.native_hid.join("src/hid-device-adapter.mjs"), + layout.native_hid.join("src/attack-shark-x11.mjs"), + layout.native_hid.join("package.json"), + node, + layout.native_hid.join("node_modules/node-hid/package.json"), + layout + .native_hid + .join("node_modules/@openmouse/protocol/package.json"), + layout + .native_hid + .join("node_modules/@openmouse/keyboard-protocol/package.json"), + ]; + names.extend(layout.extra.iter().cloned()); + for name in &names { + let path = root.join(name); + fs::create_dir_all(path.parent().unwrap()).unwrap(); + fs::write(&path, b"inert-fixture").unwrap(); + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + fs::set_permissions(path, fs::Permissions::from_mode(0o700)).unwrap(); + } + } + assert!( + verify_package_with(&root, &layout).is_err(), + "font license is mandatory inside the bundle" + ); + fs::write( + root.join(&layout.license), + include_bytes!("../../assets/fonts/DM-Sans-OFL.txt"), + ) + .unwrap(); + verify_package_with(&root, &layout).unwrap(); + assert!( + verify_package_with(&root, &PackageLayout::flat()).is_err(), + "a bundle is not a flat package" + ); + for name in &names { + let path = root.join(name); + fs::remove_file(&path).unwrap(); + assert!( + verify_package_with(&root, &layout).is_err(), + "accepted a bundle missing {}", + name.display() + ); + fs::write(&path, b"inert-fixture").unwrap(); + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + fs::set_permissions(path, fs::Permissions::from_mode(0o700)).unwrap(); + } + } + fs::remove_dir_all(root).unwrap(); +} + +#[test] +fn bundle_archive_paths_are_accepted_by_the_extractor() { + let bytes = archive(&[ + // The extractor's executable check follows the running install's + // layout, which is flat under test. + (platform_binary_name(), b"flat"), + ("OpenMouse Bridge.app/Contents/Info.plist", b"plist"), + ( + "OpenMouse Bridge.app/Contents/MacOS/openmouse-bridge", + b"bin", + ), + ]); + let root = fixture(); + extract_archive(&bytes, &root).unwrap(); + assert!( + root.join("OpenMouse Bridge.app/Contents/MacOS/openmouse-bridge") + .is_file() + ); + fs::remove_dir_all(root).unwrap(); +} + +#[cfg(unix)] +#[test] +fn generated_bundle_transaction_replaces_or_restores_the_app() { + for case in [ + "success", + "existing-lock", + "copy-failure", + "commit-failure", + "rollback-failure", + ] { + let root = fixture(); + let stage = root.join("stage"); + let destination = root.join("install"); + let staged_exe = stage.join("OpenMouse Bridge.app/Contents/MacOS"); + let installed_exe = destination.join("Renamed Bridge.app/Contents/MacOS"); + for directory in [&staged_exe, &installed_exe] { + fs::create_dir_all(directory).unwrap(); + } + fs::write(root.join("sandbox-marker"), b"bridge-update-fixture-only").unwrap(); + fs::write(staged_exe.join("openmouse-bridge"), b"new-binary").unwrap(); + fs::write(installed_exe.join("openmouse-bridge"), b"old-binary").unwrap(); + fs::write(destination.join("sentinel"), b"untouched").unwrap(); + if case == "existing-lock" { + fs::create_dir(destination.join(".openmouse-update.lock")).unwrap(); + } + let script = root.join("sandbox.sh"); + let contents = format!( + "{BUNDLE_TRANSACTION}\n{BUNDLE_COMPLETION}\n{}", + r#" +root="$1" +fixture_case="$2" +[ "$(cat "$root/sandbox-marker")" = bridge-update-fixture-only ] || exit 90 +cp() { + if [ "$fixture_case" = copy-failure ]; then return 1; fi + command cp "$@" +} +mv() { + case "$1" in */new/*) if [ "$fixture_case" = commit-failure ] || [ "$fixture_case" = rollback-failure ]; then return 1; fi ;; esac + case "$1" in */old/*) if [ "$fixture_case" = rollback-failure ]; then return 1; fi ;; esac + command mv "$@" +} +record_launch() { cat "$1/$2/Contents/MacOS/openmouse-bridge" > "$root/launch-record"; } +complete_bundle_update "$root/stage" "$root/install" "OpenMouse Bridge.app" "Renamed Bridge.app" record_launch +"# + ); + write_helper(&script, &contents).unwrap(); + let output = Command::new("/bin/sh") + .arg(&script) + .arg(root.to_string_lossy().as_ref()) + .arg(case) + .output() + .unwrap(); + assert_eq!( + output.status.success(), + case != "rollback-failure", + "{case}: {}", + String::from_utf8_lossy(&output.stderr) + ); + assert_eq!( + root.join("launch-record").exists(), + case != "rollback-failure", + "{case}: relaunch eligibility" + ); + if case == "rollback-failure" { + assert!(destination.join(".openmouse-update.lock").exists()); + fs::remove_dir_all(root).unwrap(); + continue; + } + let expected: &[u8] = if case == "success" { + b"new-binary" + } else { + b"old-binary" + }; + assert_eq!(fs::read(root.join("launch-record")).unwrap(), expected); + assert_eq!( + fs::read(installed_exe.join("openmouse-bridge")).unwrap(), + expected, + "{case}: installed app" + ); + assert_eq!( + fs::read(destination.join("sentinel")).unwrap(), + b"untouched" + ); + assert!(!destination.join("OpenMouse Bridge.app").exists()); + assert_eq!( + fs::read_dir(&destination).unwrap().count(), + if case == "existing-lock" { 3 } else { 2 }, + "{case}: no transaction leftovers" + ); + fs::remove_dir_all(root).unwrap(); + } +} + +#[test] +fn archives_larger_than_the_metadata_budget_still_open() { + use std::io::Write; + let mut writer = zip::ZipWriter::new(Cursor::new(Vec::new())); + let stored = + zip::write::SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored); + writer.start_file(platform_binary_name(), stored).unwrap(); + // Real release archives are tens of megabytes; opening one must not read + // the whole file as "metadata". + let block = vec![0x5a; 1024 * 1024]; + for _ in 0..(MAX_ZIP_METADATA_READ_BYTES / block.len() + 4) { + writer.write_all(&block).unwrap(); + } + let bytes = writer.finish().unwrap().into_inner(); + assert!(bytes.len() > MAX_ZIP_METADATA_READ_BYTES); + let root = fixture(); + extract_archive(&bytes, &root).unwrap(); + assert!(root.join(platform_binary_name()).is_file()); + fs::remove_dir_all(root).unwrap(); +} From 4f52c2c2673d33babe7c26c083bc41a1983c8eae Mon Sep 17 00:00:00 2001 From: snekxs <26660858+snekxs@users.noreply.github.com> Date: Mon, 26 Oct 2026 17:04:28 -0600 Subject: [PATCH 2/3] test(updater): use the platform's Node path in the bundle layout test --- src/updater/tests.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/updater/tests.rs b/src/updater/tests.rs index 2b9d016..331c2c8 100644 --- a/src/updater/tests.rs +++ b/src/updater/tests.rs @@ -725,7 +725,11 @@ fn checksum_must_match_archive() { fn macos_bundle_package_layout_requires_every_bundled_file() { let root = fixture(); let layout = PackageLayout::macos_bundle(); - let node = layout.native_hid.join("node/bin/node"); + let node = layout.native_hid.join(if cfg!(windows) { + "node/node.exe" + } else { + "node/bin/node" + }); let mut names = vec![ layout.binary.clone(), layout.native_hid.join("src/apply.mjs"), From 603e679a594687ef3606f43ba05ca1d9b396cc5e Mon Sep 17 00:00:00 2001 From: snekxs <26660858+snekxs@users.noreply.github.com> Date: Mon, 26 Oct 2026 17:09:43 -0600 Subject: [PATCH 3/3] fix(updater): compile the bundle transaction scripts only where they are used --- src/updater.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/updater.rs b/src/updater.rs index 6c84f67..321b429 100644 --- a/src/updater.rs +++ b/src/updater.rs @@ -833,7 +833,7 @@ fn spawn_install_helper(staging: &Path, destination: &Path, executable: &Path) - /// Replaces one directory (a macOS `.app`) as a unit. Same lock, backup and /// rollback discipline as `UNIX_TRANSACTION`: status 2 means nothing changed. -#[cfg(any(target_os = "macos", test))] +#[cfg(any(target_os = "macos", all(unix, test)))] const BUNDLE_TRANSACTION: &str = r#"install_bundle() ( set -eu stage="$1" @@ -890,7 +890,7 @@ committed=yes ) "#; -#[cfg(any(target_os = "macos", test))] +#[cfg(any(target_os = "macos", all(unix, test)))] const BUNDLE_COMPLETION: &str = r#"complete_bundle_update() { if install_bundle "$1" "$2" "$3" "$4"; then :