GETSSH Logo
GETSSH

Changelog

Explore the evolution and iterations of every GETSSH release.

📝 GETSSH Changelog

All notable changes, new features, security updates, and bug fixes will be documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.


🏗️ Infrastructure Overhaul Phase 1: React 19 Core Engine Hot-Swap

A landmark milestone for GETSSH's technology stack modernization. We have fully migrated the frontend runtime from React 18 to React 19, adopting all new concurrent rendering features and upgrading the UI component library and type system to ensure every future feature ships on the most cutting-edge foundation possible.

⚛️ React 19 Core Migration

  • Full React 19.0.0 Upgrade: react, react-dom, @types/react, and @types/react-dom all promoted to 19.0.0+. The application now runs entirely on the React 19 concurrent rendering model.
  • forwardRef Removal Pre-check: A global codebase scan confirmed zero React.forwardRef wrappers remain — the project naturally adapts to React 19's native ref-as-prop paradigm with no migration work required.
  • Entry File Compliance Verified: Confirmed main.tsx uses ReactDOM.createRoot, fully compliant with React 19's mandatory API. No legacy ReactDOM.render calls remain.
  • React 19 Strict Type Tightening Fix: Fixed a useRef<NodeJS.Timeout>() error in ConnectForm.tsx triggered by React 19's stricter generic inference rules. Updated to the canonical useRef<NodeJS.Timeout | null>(null) form.
  • Lucide React Latest Upgrade: Upgraded lucide-react to the latest version. All icon import names were validated for compatibility with the new API spec — zero naming conflicts or deprecation warnings.
  • @testing-library/react React 19 Alignment: Simultaneously upgraded the testing library to the latest version, ensuring full API compatibility with React 19.

🌪️ Infrastructure Overhaul Phase 2: Tailwind CSS v4 & Vite 8 Upgrade

  • Tailwind v4 Engine Upgrade: Upgraded from Tailwind CSS v3 to v4. Eliminated the bulky tailwind.config.js and transitioned to pure CSS configuration via @import "tailwindcss"; and @theme blocks, unleashing the next-generation lightning-fast styling engine.
  • Vite 8 Integration: Elevated the build toolchain to Vite 8.0, migrating flawlessly to the new @tailwindcss/vite plugin and vite.config.mts configuration format, achieving extreme development server boot speeds.

🚀 Infrastructure Overhaul Phase 3: Electron 42 & Node 22 Ultimate Leap

  • Next-Gen Electron Kernel: Upgraded the core framework from the legacy Electron 32 branch directly to the bleeding-edge Electron 42.3.0.
  • Node 22 Backend Environment: Upgraded native backend types to Node 22, unlocking the latest V8 features and robust security patches.
  • IPC API Modernization: Remapped and resolved deprecation warnings introduced by Electron 42, ensuring window frame controls, system event listeners, and inter-process communications remain perfectly intact.

📟 Xterm.js Architecture Cleanup & Hardening

  • N-API PTY Resurrection: Completely eradicated the obsolete @homebridge/node-pty-prebuilt-multiarch branch and returned to the official node-pty mainstream, directly leveraging N-API prebuilds for maximum stability.
  • Unified Xterm Ecosystem: Scanned and wiped all legacy xterm-addon-* stray dependencies. Standardized the entire terminal rendering engine on the official @xterm/ namespace (e.g., @xterm/addon-fit, @xterm/addon-search, @xterm/addon-webgl, @xterm/addon-canvas).
  • WebGL/Canvas Failover: Forged an intelligent rendering failover mechanism in Terminal.tsx. The terminal automatically attempts high-performance WebGL rendering, and elegantly falls back to Canvas on context loss or unsupported transparent environments.

🛡️ TypeScript 6.0 Strict Defense

  • ES2023 Target Enforced: Elevated the global TypeScript target and module system to ESNext/ES2023, enforcing strict module resolution with isolatedModules and allowImportingTsExtensions.
  • Zero-Tolerance Type Checks: Fixed implicit any leaks in sftpHandler.ts native callbacks, and cemented critical null pointer exceptions in cryptoHandler.ts (Rust N-API decryption boundary) and sshHandler.ts (Proxy connection fallback), achieving absolute zero compiler errors under strict: true.

📦 "Small & Beautiful" DMG Ultimate Compression

  • Locale Eradication: Injected electronLanguages: ["en-US", "zh-CN"] into the electron-builder config, surgically slicing away over 50 unnecessary .pak and .lproj language binaries from the Electron Framework.
  • Pure JS Tree-Shaking: Transferred pure JavaScript node modules (dompurify, p-limit, socks, http-proxy-agent) to devDependencies. The Vite/esbuild bundler now absorbs them natively into the final index.js, permanently banishing thousands of disjointed files from app.asar.
  • N-API Dev Bloat Excluded: Excluded rust-core/**/node_modules/** from the packaging scope, preventing ~17MB of useless @napi-rs compile-time binaries from leaking into the production app.
  • Result: The fully compressed ARM64 .dmg size plunged to a historical 101 MB — practically the physical limit for a full-scale Electron 42 environment.

🧹 Physical Dependency Purge & Tree Rebuild

  • Ghost Dependency Extermination: Completely destroyed the mixed node_modules directory and cross-contaminated package-lock.json, then executed npm cache clean --force to purge OS-level NPM cache — eliminating every last React 18 fragment from the root.
  • Critical pnpm node-linker=hoisted Fix: Diagnosed and resolved a critical runtime crash caused by pnpm's default symlink storage strategy conflicting with Electron's CJS native require hook. The ssh2 internal dependency path resolution was failing (Cannot find module './constants.js'). Enforcing node-linker=hoisted in .npmrc forces pnpm to physically hoist packages, perfectly resolving native CJS module path resolution in Electron.
  • Clean Dependency Tree Sealed: Ran a fresh pnpm install from the finalized package.json, completing the pure rebuild and sealing the dependency ecosystem.

🔒 Plugin SDK v2.0 — Full Security Sandbox Deployment

  • ctx.net.fetch Network Bridge: Safely injected ctx.net.fetch(url, options) into the backend plugin Node VM sandbox Context. Plugins must explicitly declare "net:fetch" in their package.json capabilities array — any undeclared call is immediately blocked with a SecurityError.
  • Ultimate SSRF Defense Wall: The underlying fetch interceptor enforces strict DNS/regex dual defense, absolutely blocking any requests to loopback addresses (127.0.0.1, localhost, 0.0.0.0) and private IP ranges (192.168.x.x, 10.x.x.x, 172.16.x.x).
  • ctx.ui.registerSettings No-Code Settings Form: Injected a schema registration API into the controlled ctx.ui namespace. Backend plugins can register typed config schemas (string, number, boolean, password) during activate. The main process syncs schemas to the frontend Zustand Store via sync-plugin-settings-schema IPC, dynamically rendering host-styled form components in a dedicated "Plugin Settings" tab in Settings.tsx — with live hot-reload on schema updates.
  • ctx.host.clipboard Audited Clipboard Access: Injected clipboard.writeText and clipboard.readText into the controlled ctx.host namespace, bridging directly to Electron's native clipboard module. Any readText call forces an OS-native notification (containing the plugin name) to prevent silent data exfiltration, alongside a full audit log in the main process.
  • window.GETSSH.registerPanel / openPanel Immersive Panel Views: Exposed panel registration and open APIs to frontend plugins via the preload script. Added PluginPanelTab route type to sessionStore.ts and introduced <webview> sandboxed full-screen rendering in the SessionManager.tsx render tree — enabling plugins to take over the entire main workspace view from the sidebar.

🛡️ Full Codebase Security Audit & Bug Fixes

  • IPC Path Traversal Sealed: Implemented strict file path boundary validation on the getssh-plugin:// custom protocol handler in electron/main/index.ts, intercepting ../../ backtracking attacks and ensuring plugins can only read assets within their authorized directory.
  • Plugin Arbitrary Install Path Vulnerability Fixed: Added OS-level temp directory legitimacy checks to the plugin install commit path in PluginManager.ts, blocking unauthorized directory tampering.
  • SFTP Write Privilege Escalation Defense: Enforced write path locking in the sftpHandler.ts download interface to only allow writes within Downloads or Desktop directories, preventing malicious plugins from injecting auto-start trojans via the SFTP bridge.
  • TypeScript Zero-Error Seal: Systematically cleared 70+ legacy TypeScript type errors across src/types.d.ts (completing missing electronAPI interface definitions), LeafPane.tsx, PluginPane.tsx, TerminalPane.tsx, SplitPane.tsx, App.tsx, and more core components — achieving a confirmed zero-error npx tsc --noEmit output.

🦀 Four-Zone Rust Native Core Refactoring — 100% Complete

This is a monumental Preview release marking the complete Rust-ification of GETSSH's performance-critical code paths. All four security & performance zones have been fully migrated from Node.js/V8 to Rust N-API native extensions, making GETSSH one of the most security-hardened Electron SSH clients in existence.

🦀 Zone 1: Watchdog Process Guardian

  • Rust Standalone Daemon: rust-core/watchdog is a fully independent Rust binary that runs outside the Electron main process, communicating via Unix Domain Sockets (macOS/Linux) and Named Pipes (Windows).
  • 60-Second Physical Kill: If the Watchdog receives no heartbeat within 60 seconds (e.g., the process is frozen or injected), it issues a physical-level SIGKILL against the parent process via OS APIs and displays a desktop notification, preventing the app from running in a hijacked state.
  • SAFE MODE Awareness: If the main process boots in SAFE MODE (post-crash recovery), the Watchdog automatically enters silent mode and will not trigger the kill sequence.
  • Production Path Bridging: Full app.isPackaged dual-path resolution ensures the Watchdog binary is accurately located in both development and packaged production environments.

🦀 Zone 2: Vault Local Credential Encryption Engine

  • getssh-vault N-API Extension: Rust encryption logic compiled into a .node native extension via @napi-rs, loaded directly by the Electron main process.
  • AES-256-GCM Hardware-Grade Encryption: Uses the Rust aes-gcm crate to perform physical-level encryption and decryption of local profiles.enc, eliminating potential vulnerabilities in Node.js's crypto module.
  • Master Password + Biometric Dual Gate: cryptoHandler.ts integrates full master password validation and systemPreferences.promptTouchID biometric authentication.

🦀 Zone 3: Sysprobe System Metrics Probe

  • getssh-sysprobe N-API Extension: Uses Rust's sysinfo crate to collect CPU, memory, network, and disk metrics directly at the OS level.
  • Eliminated node:os Dependency: Ended systemHandler.ts's reliance on node:os polling. System metrics no longer pass through the V8 string serialization layer — throughput efficiency is massively improved with zero UI jank.

🦀 Zone 4: Hybrid SFTP Engine

  • sftp-stream Zero-Copy N-API Engine: rust-core/sftp-stream takes over the heaviest disk I/O during file uploads and downloads.
  • Node-Rust Pipeline Bridge: Network Buffer data from ssh2 is consumed directly in Rust and streamed to disk, completely bypassing V8 string parsing — a true "Node handles networking, Rust handles heavy I/O" dual-engine architecture.
  • Large File Download Confirmation: Before initiating a pure-download, the user is shown the file's size and must confirm, preventing accidental downloads of large files.

🔥 Exterminating the adm-zip Memory Tumor (getssh-unarchive)

  • New getssh-unarchive Rust N-API Extension: Completely replaces the pure-JS adm-zip library in PluginManager.ts, whose full in-memory approach was a time-bomb OOM waiting to detonate.
  • Zero-Copy Streaming Extraction: Uses Rust's zip crate and std::io::copy to stream files from archives directly to disk, never touching JavaScript/V8 heap memory. Memory peak stays under 10MB regardless of archive size.
  • Military-Grade Zip Slip Defense: Every archive entry path is rigorously validated in Rust. If any path traversal sequence (../) or absolute root prefix is detected, the extraction immediately trips a circuit breaker, physically destroys all already-extracted debris files, and throws a hard error — completely sealing the Zip Slip attack vector.
  • tokio Async Non-Blocking Extraction: Extraction runs inside tokio::task::spawn_blocking, keeping the Electron main process and renderer completely responsive throughout.

🔒 Security & Lock UX Improvements

  • CommandCenter One-Tap Lock Button: Added a "Lock Profile" button to the WelcomePane command center. Users can now manually trigger a lock at any time without waiting for the timeout timer.
  • Smart Disabled State: When no master password is set, the "Lock Profile" button is automatically grayed out with a tooltip guiding the user to configure their security settings.
  • CryptoModal Full i18n: The lock and unlock screens in CryptoModal now fully integrate react-i18next, supporting seamless Chinese/English switching with zero hardcoded English strings remaining.
  • Gaussian Blur Privacy Shield on Lock: When the lock screen is triggered, the background is immediately overlaid with a 40px-strength Gaussian blur (applied via inline styles to reliably bypass Tailwind JIT thermal behavior), protecting sensitive server information from bystander view.
  • Global Crypto State (Single Source of Truth): cryptoMode, masterPassword, and related state have been migrated from App.tsx local state into the useCryptoStore Zustand global store, ensuring all UI components (CommandCenter, CryptoModal) share a consistent, real-time view of authentication state.

📦 Cross-Platform Production Packaging

  • ASAR Physical Ejection: Added "asarUnpack": ["**/*.node"] to electron-builder config, ensuring all Rust N-API native extensions are ejected from the app.asar virtual filesystem into the physical app.asar.unpacked directory, permanently eliminating dynamic library loading failures in packaged builds.
  • Watchdog Binary Injection: extraResources config ensures the pre-compiled watchdog binary is injected verbatim into the final package's resources directory.
  • macOS Hardened Runtime & Signing Prep: Enabled hardenedRuntime: true and created build/entitlements.mac.plist with com.apple.security.cs.allow-unsigned-executable-memory (V8 JIT compatibility) and com.apple.security.cs.disable-library-validation (allows loading self-compiled Rust .node extensions), perfectly circumventing macOS 10.15+ Gatekeeper crashes.
  • Dependency Cleanup: Completely removed adm-zip and @types/adm-zip from the project root, further purifying the dependency tree.