Skip to content

OnlyKey App 6.0.0 - #245

Merged
onlykey merged 132 commits into
masterfrom
release/6.0.0-modern-rewrite
Oct 23, 2026
Merged

onlykey merged 132 commits into
masterfrom
release/6.0.0-modern-rewrite

Conversation

@rodgolpe

Copy link
Copy Markdown
Contributor

Summary

OnlyKey App 6.0.0 replaces the Chrome-app tree (app/, tasks/) with a React desktop app. The HID protocol is unchanged. Device I/O goes through OnlyKeyDevice only.

132 commits. 1,397 files, +37,141 / −15,757 vs master.

npm ci is clean. npm audit and npm audit --omit=optional report no vulnerabilities. Lockfile is follow-redirects 1.16.1 and vite 7.3.7. master's lockfile commit is merged; this branch's lockfile and .gitignore are the ones kept.

Stack

  • React 19, TypeScript, Zustand, Tailwind 4, Vite 7
  • NW.js 0.104.1, pinned. 0.105+ breaks Windows tray menu clicks
  • package-lock.json is committed

App

  • Setup, Slots, Keys (PGP/SSH), Backup/Restore, Firmware, Preferences, Advanced, Tools
  • Light and dark theme
  • 50-message history
  • Clipboard-free password generator
  • Shared config-mode instructions on Keys, Setup, Backup, and Firmware
  • Session state is wiped on lock and unplug
  • Classic vs Duo comes from device status

Desktop

  • Tray lives in the main window (desktopInject.js → desktopBg.cjs). Close hides to the tray
  • Autostart opens minimized. A later launch (Start menu, Dock, taskbar, CLI) shows the window
  • Linux: udev prompt, onlykey-launch, tray menu is rebuilt rather than mutated
  • macOS: universal DMG via hdiutil (no appdmg). Tray paths resolve inside the bundle
  • Windows: NSIS. The updater hashes the signed installer

Updates

  • Firmware: check, SHA-256, download, and load for OnlyKey and Duo, including bootloader. In-app dialog. Timeouts and errors are shown. Auto-check is on the Firmware page and stays in sync with the tray
  • App: check, streamed download, sha256 required, then Install now or Later. A package with no sha256 is rejected. Auto-check follows the preference
  • npm run release writes per-OS manifest fragments (sha256 and size)

Firmware 3.1.0 preferences

Included from #244:

  • Fields 21, 22, and 30 (challenge, button, or none) save together
  • Field 31 is one Webcrypt choice: stored and derived, derived only, or off
  • Nothing starts selected. Save writes only the families the user picked, and names any family already written if a later write fails
  • Fields 30 and 31 show only on firmware 3.1.0 or later
  • Help icons sit beside the controls

Protocol fixes

Behavior aligned with the 5.6 app:

  • PIN setup, wrong PIN, self-destruct offset, keypad timeout
  • Label slot IDs, Classic/Duo classification, config mode, hot-plug
  • Key import layout, ECC vs RSA slots, curve tag, backup-key bit
  • TOTP clock, Base32, OTP type bytes
  • Firmware handshake, block pacing, bootloader entry. A disconnect is not treated as success

CI

  • Typecheck, lint, audit (fails on high/critical; optional deps omitted), unit tests
  • Desktop tests on Ubuntu, Windows, and macOS
  • Installer builds for those three OSes on this branch

Test plan

  • npm ci and npm audit --omit=optional
  • npm test
  • npm start on OnlyKey and Duo: unlock, slots, keys, backup, preferences
  • Firmware check and load, including bootloader
  • Tray: hide, autostart, second launch shows the window (Windows, macOS, Linux)
  • App update check against a manifest with sha256
  • On firmware 3.1.0, save user-input modes and Webcrypt access. On older firmware, those two controls stay hidden

rodgolpe and others added 30 commits November 10, 2022 01:33
React 19 + Vite + TypeScript rewrite with full 5.6 feature surface (setup, slots, keys, backup, firmware, preferences, advanced, tools), NW.js desktop shell, packaging scripts, and automated tests. Version labeled 5.7.0 (not 6.x).
Remove vulnerable nw-autoupdater, harden MockTransport for automated testing, fix NW blank UI and desktop Vitest shebang, improve multi-OS release packaging, and lock dependencies for reproducible installs.
- Package/install: world-readable NW libs, onlykey-launch, desktop Exec/Path
- Tray: rebuild menus without Linux remove/insert (empty menu fix)
- Unlock: poll lock state via OKSETTIME; default tab Slots when initialized
- Restore: silent intermediate OKRESTORE packets + progress UI (SVG spinner)
- Security: wipe store + remount session UI on unplug and lock
- deps: bump tar override to ^7.5.22 (audit clean for release)
5.7 has never shipped, so leftover aliases and experiment hosts are unused.
Drop the one-off debug/repro scripts that mutated package.json to probe
discarded tray approaches.
Rewrite agent instructions for the current tree and NW 0.104.1 pin.
Mark firmware load and app auto-update as unverified rather than done.
* Add Tier 1 CI quality gates and desktop OS-matrix tests.

Split the Ubuntu test workflow into typecheck, lint, audit, and unit/coverage jobs with concurrency and least-privilege permissions. Add a fail-fast-disabled desktop matrix on Ubuntu (Xvfb), Windows, and macOS so tray/HID regressions are caught before merging to 5.7. Ignore Dependabot bumps of the pinned NW.js 0.104.1 runtime.

* Stop tray init from using nw after test teardown.

initTray is async (auto-launch probe). Unit afterEach called stop() and deleted global.nw while that promise was still running, so buildTrayMenu logged ReferenceError: nw is not defined even though the tests passed. Abort in-flight init on stop() and talk to the mock via global.nw from the ESM test file.
rodgolpe and others added 26 commits September 10, 2026 23:46
5.6 used packages.*.size as the nw-autoupdater progress denominator (rounded MB on the live 5.3.4 channel). SHA-256 is the only payload check. Prefer Content-Length for progress when present.
Replace window.confirm with AppUpdateHost + AppUpdateDialog outside sessionEpoch. Tools checkbox and Check now; tray/React pref sync; autoUpdate defaults on (5.6 continuity). Ready state is Show in folder / OK. No installer launch.
Startup check was easy to miss (StrictMode cancel, DevTools reload + session skip, tray toggle only hydrated state). Defer the GET until after paint, start a check when autoUpdate goes from off to on, and log skip/current so the console shows what happened.
arrayBuffer() only reported 100% after the file was already in memory, so the dialog stayed at 0% until the ready modal. Read response.body when getReader exists; keep arrayBuffer as the test fallback.
applyAppUpdate verifies SHA-256 on disk, launches a detached NSIS/open/xdg-open process, then quits so files can be replaced. Spawn failure shows the folder and does not quit. Ready dialog is Install now / Show in folder / Later.
Shorten the downloaded-update copy to version plus SHA-256. Later opens the installer in the file manager and dismisses. Spawn or quit failure also reveals the file and reports apply-failed.
… size

After each OS artifact, hash it, write releases/update-manifest.d/<key>.json, and merge same-version fragments into releases/manifest.json. Packaged package.json honors ONLYKEY_UPDATE_MANIFEST_URL and ONLYKEY_UPDATE_BASE_URL. Does not upload to S3.
Authenticode/notarization changes bytes, so npm run release no longer writes the update manifest. After signing in place, npm run update-manifest hashes that file, refuses NotSigned on Windows/macOS, and reminds the operator to upload the same signed artifact.
Replace HTML scrape with GitHub API; injectable I/O; restore 5.6 load gate floor.
Host/dialog/Tools/pref events; Ready is Open Firmware tab only; no HID.
Extract kick/pending/stream; dialog Load when legal; tab Download Latest stays one-shot.
Manual check ignores pref; Setup Step 11 Download Latest / use-downloaded.
Correct firmware SHA-256 and auto-check UX; hardware remains a lab gate.
Leave Check now / load on the Firmware tab. Tools keeps the same autoUpdateFW checkbox as the tray menu.
Remove firmware prefs from Tools. The Firmware tab checkbox uses the same autoUpdateFW key as the tray and follows tray toggles.
Drop the internal feature-parity checklist from the tree and add the GitHub release note.
* Preferences: 3.1.0 user input modes and Webcrypt access

Field 30 (web and agent derived keys: challenge code, button press or
none) is saved together with fields 21 and 22, and field 31 sets what
the web app may do with the key.

* Preferences: write only the settings the user chose

The app cannot read fields 21, 22, 30 or 31 back from the key, so the
form no longer starts from assumed values. Nothing is selected until the
user picks it, and Save writes only the families picked; if a later
write fails, the error says which were already saved.

Webcrypt Access is one choice (stored and derived keys, derived keys
only, off) instead of two checkboxes, so 0x03 is no longer sent and the
legacy off state survives until the user saves a choice.

Fields 30 and 31 are shown only on firmware 3.1.0 and later; older
firmware gives no reply to them. Help icons sit beside the choices, not
inside their labels. Tests cover the OKSETSLOT bytes for fields 30 and
31, and the mock requires config mode for them.
Lockfile: follow-redirects 1.16.1 and vite 7.3.7.
…n-rewrite

# Conflicts:
#	.gitignore
#	package-lock.json
@rodgolpe

Copy link
Copy Markdown
Contributor Author

@onlykey The README on this branch still mixes the 6.0 desktop app with the old Chrome-app install steps. Proposed text is below. It is not committed.

Three calls I would like from you:

  1. ChromeOS and ARM. This repo builds the Windows, macOS, and Linux app. The install guide still sends Chromebook and some ARM users to the Chrome app, and the Linux page says Chrome Apps are deprecated. The draft drops the Web Store click-path and points those users at the guide. Should the store steps stay?
  2. The .deb signature sentence still links to an Unbound UKC article. Keep that link, or point somewhere else?
  3. Doc links stay on docs.crp.to. Say if these should be docs.onlykey.io.

OnlyKey App

This is the official app for OnlyKey.

OnlyKey can be purchased here: OnlyKey order

Getting Started

Just getting started with OnlyKey?

Start here

About

OnlyKey App is the desktop app for an OnlyKey or OnlyKey Duo. Use it to:

  • Set up a new OnlyKey (Setup)
  • Configure accounts (Slots)
  • Load keys for PGP, SSH, and secure backup (Keys)
  • Back up and restore an OnlyKey (Backup)
  • Load signed firmware (Firmware)
  • Set preferences (Preferences)
  • Set advanced options such as Yubikey AES and ECC/HMAC keys (Advanced)

The app is required on any computer where OATH-TOTP (Google Authenticator) codes are used.

Windows, macOS, and Linux installers are on the releases page. Closing the window hides the app in the system tray. The app can also start with the computer.

For how to use the app, see the OnlyKey User's Guide or the OnlyKey DUO User's Guide.

Installation

Desktop app (Windows, macOS, Linux)

Linux users installing the .deb should verify the GPG signature with debsig-verify. An outline of that process is here.

ChromeOS and some ARM systems

This repository is the Windows, macOS, and Linux desktop app. Where that app cannot be installed, the app install guide covers the Chrome app, which has a smaller feature set.

Support

Check out the OnlyKey Support Forum

Check out the OnlyKey Documentation

Developer Notes

OnlyKey App 6.0.0 is a React 19 + TypeScript app, built with Vite 7 and run in NW.js 0.104.1. NW.js stays on 0.104.1 because tray menu clicks do not work on 0.105 or later.

$ npm install
$ npm start

npm start builds the frontend and opens NW.js on dist/index.html.

To run with Vite HMR:

$ npm run dev:server

To build the project:

$ npm run build

To run tests:

$ npm test

Unit tests do not require NW.js. Desktop tests use the NW.js runtime from npm install ([email protected], normal flavor).

To create a release installer, run this on the OS you are packaging:

$ npm run release

The installer is written to the releases/ folder.

  • Windows: NSIS installed and on %PATH%
  • macOS: hdiutil, which ships with macOS
  • Linux: fakeroot and dpkg-deb

Cryptography Notice

This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software.
BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted.
See http://www.wassenaar.org/ for more information.

The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms.
The form and manner of this distribution makes it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code.

The following cryptographic software is included in this distribution:

"OpenPGP.js - OpenPGP JavaScript Implementation." - https://openpgpjs.org/

For more information on export restrictions see: http://www.apache.org/licenses/exports/

Source

OnlyKey App on Github

@rodgolpe
rodgolpe requested a review from onlykey October 21, 2026 18:30
@onlykey
onlykey merged commit 1422770 into master Oct 23, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants