fix: comprehensive bug fixes, security improvements, and feature additions
CI / Build & Test (push) Successful in 3m21s

Critical fixes:
- Fix wrong registry key (com.bridgeswarm → com.holesail.browser) in
  update-native-manifest-extension-id.ps1 — script was always failing on Windows
- Create missing wrong-domain.html redirect page for .host.test URLs
- Remove options_ui pointing to non-existent options.html from manifest

High-priority bug fixes:
- ssh-manager: track and kill orphaned printf FIFO writer when key auth succeeds
- ssh-manager: fix uncancelled 2000ms fallback password timer (assign to fallbackTimer,
  clear in cancelPasswordWatch); fix null-check before removeAllListeners
- ssh-manager: add 30s Promise.race timeout to holesailInst.ready()
- backup-manager: fix macOS cp -R nesting bug by removing destination before copy;
  add tar -tzf integrity check after archive creation
- host.js: restoreBackup now stops running tunnels before restore and re-starts them
- holesail-manager: fix stale closure bug in virtual host and service tunnel
  error/close handlers (guard with v.holesail === hs check)
- dashboard.js: remove dead setText('dashTabs', ...) call referencing non-existent element

Medium improvements:
- manifest: remove unused storage and scripting permissions; restrict
  web_accessible_resources match from <all_urls> to chrome-extension://*/*
- background.js: fix self-referential browser alias (globalThis.browser ?? chrome);
  add 30s per-request timeout to send(); clean up dashboardTabs on tab close
- holesail-manager: gate saveStateSync stderr log behind DEBUG flag; updateSettings
  now returns requiresRestart:true when proxy port changes; add backupRetention field
- host.js: pass requiresRestart through in updateSettings response
- dashboard.js: remove dead loadSettings() function; add requiresRestart warning toast;
  add chrome.runtime.lastError guards in fetchState and refreshBackups;
  set dynamic version from chrome.runtime.getManifest()
- dashboard.html: remove stray </button> tag; add id="sidebarVersion" for dynamic version
- install.sh/install.ps1: fetch version from RELEASE_BASE/VERSION instead of hardcoded 1.0.0
- install.ps1: add Firefox .xpi download and Firefox registry key
- update-native-manifest-extension-id.sh: add optional Firefox manifest update
- certificate-authority.js: defer RSA key generation to setImmediate to avoid blocking
  startup; expose caReady promise
- host.js: await caReady before starting HTTPS proxy

Documentation:
- REMOTE-DESKTOP.md: correct RDP WebSocket protocol field names to match rdp-manager.js
  (destLeft/destTop/destRight/destBottom, mouseMove/mouseButton/keyEvent/keyUnicode)

Feature additions:
- dashboard.js: add Reconnect button for service tunnels in error/closed state
- https-proxy.js: add WebSocket upgrade handler to support ws:// over *.hole.sail
- connect-proxy.js: add 10s header-read timeout to protect against idle connections
- native-host: add bare-fs as explicit dependency
This commit is contained in:
Raven Scott
2026-02-28 19:00:13 -05:00
parent a03f45a439
commit e5a1fa71fe
19 changed files with 436 additions and 110 deletions
+36 -2
View File
@@ -11,7 +11,14 @@ $Downloads = "$env:USERPROFILE\Downloads"
$ManifestName = "com.holesail.browser"
$HostZip = "holesail-browser-host-win32-x64.zip"
$ExtZip = "Holesail-Browser-1.0.0.zip"
# Resolve the current release version from the server so filenames stay accurate
try {
$ExtVersion = (Invoke-WebRequest "$ReleaseBase/VERSION" -UseBasicParsing -ErrorAction Stop).Content.Trim()
} catch {
$ExtVersion = "latest"
}
$ExtZip = "Holesail-Browser-$ExtVersion.zip"
$ExtXpi = "Holesail-Browser-$ExtVersion.xpi"
Write-Host ""
Write-Host "Holesail Browser Installer" -ForegroundColor Cyan
@@ -97,6 +104,13 @@ Get-ChildItem -Path $Downloads -Filter "Holesail-Browser-*.xpi" -ErrorAction Sil
Write-Host "Downloading extension..."
Invoke-WebRequest "$ReleaseBase/$ExtZip" -OutFile "$Downloads\$ExtZip"
Write-Host " Saved: $Downloads\$ExtZip"
# Also grab the .xpi for Firefox
try {
Invoke-WebRequest "$ReleaseBase/$ExtXpi" -OutFile "$Downloads\$ExtXpi" -ErrorAction Stop
Write-Host " Saved: $Downloads\$ExtXpi"
} catch {
Write-Host " Note: Firefox .xpi not available for this release" -ForegroundColor Yellow
}
# ── Native messaging manifest ──────────────────────────────────────────────────
Write-Host "Installing native messaging manifest..."
@@ -112,12 +126,27 @@ $Manifest = @{
} | ConvertTo-Json -Depth 4
Set-Content $ManifestFile -Value $Manifest -Encoding UTF8
foreach ($p in $RegPaths) {
# Chrome / Chromium registry keys
$ChromeRegPaths = @(
"HKCU:\Software\Google\Chrome\NativeMessagingHosts\$ManifestName",
"HKCU:\Software\Chromium\NativeMessagingHosts\$ManifestName"
)
foreach ($p in $ChromeRegPaths) {
New-Item -Path $p -Force | Out-Null
Set-ItemProperty -Path $p -Name "(Default)" -Value $ManifestFile
Write-Host " Registry: $p"
}
# Firefox registry key (native messaging on Windows)
$FirefoxRegPath = "HKCU:\Software\Mozilla\NativeMessagingHosts\$ManifestName"
try {
New-Item -Path $FirefoxRegPath -Force | Out-Null
Set-ItemProperty -Path $FirefoxRegPath -Name "(Default)" -Value $ManifestFile
Write-Host " Registry: $FirefoxRegPath"
} catch {
Write-Host " Note: Could not write Firefox registry key: $_" -ForegroundColor Yellow
}
# ── Done ───────────────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "==========================" -ForegroundColor Green
@@ -131,5 +160,10 @@ Write-Host " 2. Enable Developer mode"
Write-Host " 3. Drag & drop $Downloads\$ExtZip onto the page"
Write-Host " (or click 'Load unpacked' after extracting)"
Write-Host ""
Write-Host " Firefox Developer Edition / Nightly (permanent install):"
Write-Host " 1. Open about:config -> set xpinstall.signatures.required = false"
Write-Host " 2. Open about:addons -> gear icon -> Install Add-on From File"
Write-Host " 3. Select $Downloads\$ExtXpi"
Write-Host ""
Write-Host " Then restart your browser."
Write-Host ""
+4 -2
View File
@@ -24,8 +24,10 @@ if [[ -z "${PLATFORM:-}" ]]; then
fi
HOST_ZIP="holesail-browser-host-${PLATFORM}-${ARCH}.zip"
EXT_ZIP="Holesail-Browser-1.0.0.zip"
EXT_XPI="Holesail-Browser-1.0.0.xpi"
# Resolve the current release version from the server so filenames stay accurate
EXT_VERSION="$(curl -fsSL "${RELEASE_BASE}/VERSION" 2>/dev/null || echo "latest")"
EXT_ZIP="Holesail-Browser-${EXT_VERSION}.zip"
EXT_XPI="Holesail-Browser-${EXT_VERSION}.xpi"
echo ""
echo "Holesail Browser Installer"
@@ -3,7 +3,7 @@
param([Parameter(Mandatory=$true)] [string] $ExtensionId)
$ExtensionId = $ExtensionId -replace '^chrome-extension://', '' -replace '/$', ''
$Origin = "chrome-extension://$ExtensionId/"
$manifestFile = (Get-ItemProperty -Path "HKCU:\Software\Google\Chrome\NativeMessagingHosts\com.bridgeswarm" -ErrorAction SilentlyContinue).'(Default)'
$manifestFile = (Get-ItemProperty -Path "HKCU:\Software\Google\Chrome\NativeMessagingHosts\com.holesail.browser" -ErrorAction SilentlyContinue).'(Default)'
if (-not $manifestFile -or -not (Test-Path $manifestFile)) { Write-Host "Run scripts/install.ps1 first."; exit 1 }
$m = Get-Content $manifestFile -Raw | ConvertFrom-Json
$m.allowed_origins = @($Origin)
+38 -7
View File
@@ -1,15 +1,29 @@
#!/usr/bin/env bash
# Update native host manifest with your Chrome extension ID (fix "Access forbidden").
# Usage: ./scripts/update-native-manifest-extension-id.sh YOUR_EXTENSION_ID
# Also accepts a Firefox extension ID as a second argument to update allowed_extensions.
# Usage: ./scripts/update-native-manifest-extension-id.sh CHROME_EXT_ID [FIREFOX_EXT_ID]
set -e
[[ -z "$1" ]] && echo "Usage: $0 YOUR_CHROME_EXTENSION_ID (from chrome://extensions)" && exit 1
[[ -z "$1" ]] && echo "Usage: $0 CHROME_EXT_ID [FIREFOX_EXT_ID]" && exit 1
EXT_ID="${1#chrome-extension://}"; EXT_ID="${EXT_ID%/}"
ORIGIN="chrome-extension://${EXT_ID}/"
CHROME_DIR="$HOME/.config/google-chrome/NativeMessagingHosts"
CHROMIUM_DIR="$HOME/.config/chromium/NativeMessagingHosts"
[[ "$OSTYPE" == "darwin"* ]] && CHROME_DIR="$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts" && CHROMIUM_DIR="$HOME/Library/Application Support/Chromium/NativeMessagingHosts"
FIREFOX_EXT_ID="${2:-}"
MANIFEST_NAME="com.holesail.browser"
# Chrome / Chromium manifest directories
if [[ "$OSTYPE" == "darwin"* ]]; then
CHROME_DIR="$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts"
CHROMIUM_DIR="$HOME/Library/Application Support/Chromium/NativeMessagingHosts"
FIREFOX_DIR="$HOME/Library/Application Support/Mozilla/NativeMessagingHosts"
else
CHROME_DIR="$HOME/.config/google-chrome/NativeMessagingHosts"
CHROMIUM_DIR="$HOME/.config/chromium/NativeMessagingHosts"
FIREFOX_DIR="$HOME/.mozilla/native-messaging-hosts"
fi
updated=0
# Update Chrome / Chromium manifests (allowed_origins)
for dir in "$CHROME_DIR" "$CHROMIUM_DIR"; do
f="$dir/${MANIFEST_NAME}.json"
[[ ! -f "$f" ]] && continue
@@ -18,8 +32,25 @@ for dir in "$CHROME_DIR" "$CHROMIUM_DIR"; do
else
sed -i.bak "s|\"chrome-extension://[^\"]*/\"|\"$ORIGIN\"|g" "$f" && rm -f "${f}.bak"
fi
echo "Updated $f"
echo "Updated $f (allowed_origins)"
updated=1
done
# Update Firefox manifest (allowed_extensions) if a Firefox extension ID was provided
if [[ -n "$FIREFOX_EXT_ID" ]]; then
f="$FIREFOX_DIR/${MANIFEST_NAME}.json"
if [[ -f "$f" ]]; then
if command -v node >/dev/null 2>&1; then
node -e "const fs=require('fs');const j=JSON.parse(fs.readFileSync('$f','utf8'));j.allowed_extensions=['$FIREFOX_EXT_ID'];fs.writeFileSync('$f',JSON.stringify(j,null,2));"
else
sed -i.bak "s|\"holesail-browser[^\"]*@[^\"]*\"|\"$FIREFOX_EXT_ID\"|g" "$f" && rm -f "${f}.bak"
fi
echo "Updated $f (allowed_extensions)"
updated=1
else
echo "Note: Firefox manifest not found at $f — skipping Firefox update"
fi
fi
[[ $updated -eq 0 ]] && echo "No manifest found. Run scripts/install.sh first." && exit 1
echo "Done. Restart Chrome."
echo "Done. Restart your browser."