📝 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-domall promoted to19.0.0+. The application now runs entirely on the React 19 concurrent rendering model. forwardRefRemoval Pre-check: A global codebase scan confirmed zeroReact.forwardRefwrappers 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.tsxusesReactDOM.createRoot, fully compliant with React 19's mandatory API. No legacyReactDOM.rendercalls remain. - React 19 Strict Type Tightening Fix: Fixed a
useRef<NodeJS.Timeout>()error inConnectForm.tsxtriggered by React 19's stricter generic inference rules. Updated to the canonicaluseRef<NodeJS.Timeout | null>(null)form. - Lucide React Latest Upgrade: Upgraded
lucide-reactto the latest version. All icon import names were validated for compatibility with the new API spec — zero naming conflicts or deprecation warnings. @testing-library/reactReact 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.jsand transitioned to pure CSS configuration via@import "tailwindcss";and@themeblocks, 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/viteplugin andvite.config.mtsconfiguration 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-multiarchbranch and returned to the officialnode-ptymainstream, 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 withisolatedModulesandallowImportingTsExtensions. - Zero-Tolerance Type Checks: Fixed implicit
anyleaks insftpHandler.tsnative callbacks, and cemented critical null pointer exceptions incryptoHandler.ts(Rust N-API decryption boundary) andsshHandler.ts(Proxy connection fallback), achieving absolute zero compiler errors understrict: true.
📦 "Small & Beautiful" DMG Ultimate Compression
- Locale Eradication: Injected
electronLanguages: ["en-US", "zh-CN"]into theelectron-builderconfig, surgically slicing away over 50 unnecessary.pakand.lprojlanguage binaries from the Electron Framework. - Pure JS Tree-Shaking: Transferred pure JavaScript node modules (
dompurify,p-limit,socks,http-proxy-agent) todevDependencies. The Vite/esbuild bundler now absorbs them natively into the finalindex.js, permanently banishing thousands of disjointed files fromapp.asar. - N-API Dev Bloat Excluded: Excluded
rust-core/**/node_modules/**from the packaging scope, preventing ~17MB of useless@napi-rscompile-time binaries from leaking into the production app. - Result: The fully compressed ARM64
.dmgsize 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_modulesdirectory and cross-contaminatedpackage-lock.json, then executednpm cache clean --forceto purge OS-level NPM cache — eliminating every last React 18 fragment from the root. - Critical
pnpm node-linker=hoistedFix: Diagnosed and resolved a critical runtime crash caused bypnpm's default symlink storage strategy conflicting with Electron's CJS nativerequirehook. Thessh2internal dependency path resolution was failing (Cannot find module './constants.js'). Enforcingnode-linker=hoistedin.npmrcforcespnpmto physically hoist packages, perfectly resolving native CJS module path resolution in Electron. - Clean Dependency Tree Sealed: Ran a fresh
pnpm installfrom the finalizedpackage.json, completing the pure rebuild and sealing the dependency ecosystem.
🔒 Plugin SDK v2.0 — Full Security Sandbox Deployment
ctx.net.fetchNetwork Bridge: Safely injectedctx.net.fetch(url, options)into the backend plugin Node VM sandbox Context. Plugins must explicitly declare"net:fetch"in theirpackage.jsoncapabilitiesarray — any undeclared call is immediately blocked with aSecurityError.- 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.registerSettingsNo-Code Settings Form: Injected a schema registration API into the controlledctx.uinamespace. Backend plugins can register typed config schemas (string,number,boolean,password) duringactivate. The main process syncs schemas to the frontend Zustand Store viasync-plugin-settings-schemaIPC, dynamically rendering host-styled form components in a dedicated "Plugin Settings" tab inSettings.tsx— with live hot-reload on schema updates.ctx.host.clipboardAudited Clipboard Access: Injectedclipboard.writeTextandclipboard.readTextinto the controlledctx.hostnamespace, bridging directly to Electron's nativeclipboardmodule. AnyreadTextcall 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/openPanelImmersive Panel Views: Exposed panel registration and open APIs to frontend plugins via the preload script. AddedPluginPanelTabroute type tosessionStore.tsand introduced<webview>sandboxed full-screen rendering in theSessionManager.tsxrender 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 inelectron/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.tsdownload interface to only allow writes withinDownloadsorDesktopdirectories, 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 missingelectronAPIinterface definitions),LeafPane.tsx,PluginPane.tsx,TerminalPane.tsx,SplitPane.tsx,App.tsx, and more core components — achieving a confirmed zero-errornpx tsc --noEmitoutput.
🦀 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/watchdogis 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
SIGKILLagainst 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.isPackageddual-path resolution ensures the Watchdog binary is accurately located in both development and packaged production environments.
🦀 Zone 2: Vault Local Credential Encryption Engine
getssh-vaultN-API Extension: Rust encryption logic compiled into a.nodenative extension via@napi-rs, loaded directly by the Electron main process.- AES-256-GCM Hardware-Grade Encryption: Uses the Rust
aes-gcmcrate to perform physical-level encryption and decryption of localprofiles.enc, eliminating potential vulnerabilities in Node.js'scryptomodule. - Master Password + Biometric Dual Gate:
cryptoHandler.tsintegrates full master password validation andsystemPreferences.promptTouchIDbiometric authentication.
🦀 Zone 3: Sysprobe System Metrics Probe
getssh-sysprobeN-API Extension: Uses Rust'ssysinfocrate to collect CPU, memory, network, and disk metrics directly at the OS level.- Eliminated
node:osDependency: EndedsystemHandler.ts's reliance onnode:ospolling. 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-streamZero-Copy N-API Engine:rust-core/sftp-streamtakes over the heaviest disk I/O during file uploads and downloads.- Node-Rust Pipeline Bridge: Network
Bufferdata fromssh2is 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-unarchiveRust N-API Extension: Completely replaces the pure-JSadm-ziplibrary inPluginManager.ts, whose full in-memory approach was a time-bomb OOM waiting to detonate. - Zero-Copy Streaming Extraction: Uses Rust's
zipcrate andstd::io::copyto 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. tokioAsync Non-Blocking Extraction: Extraction runs insidetokio::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
CryptoModalnow fully integratereact-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 fromApp.tsxlocal state into theuseCryptoStoreZustand 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"]toelectron-builderconfig, ensuring all Rust N-API native extensions are ejected from theapp.asarvirtual filesystem into the physicalapp.asar.unpackeddirectory, permanently eliminating dynamic library loading failures in packaged builds. - Watchdog Binary Injection:
extraResourcesconfig ensures the pre-compiledwatchdogbinary is injected verbatim into the final package'sresourcesdirectory. - macOS Hardened Runtime & Signing Prep: Enabled
hardenedRuntime: trueand createdbuild/entitlements.mac.plistwithcom.apple.security.cs.allow-unsigned-executable-memory(V8 JIT compatibility) andcom.apple.security.cs.disable-library-validation(allows loading self-compiled Rust.nodeextensions), perfectly circumventing macOS 10.15+ Gatekeeper crashes. - Dependency Cleanup: Completely removed
adm-zipand@types/adm-zipfrom the project root, further purifying the dependency tree.