electron-windows-hello
v0.1.0
Published
Window-owned Windows Hello verification for Electron, with x64 and ARM64 prebuilds
Maintainers
Readme
electron-windows-hello
Windows Hello verification associated with an Electron BrowserWindow.
Independent Node-API implementation for Windows x64 and ARM64, with no runtime npm dependencies.
npm install electron-windows-helloAPI
import {
Availability,
VerificationResult,
allowSetForegroundWindow,
checkAvailability,
requestVerification,
} from "electron-windows-hello";
const availability = await checkAvailability();
const result = await requestVerification({
windowHandle: mainWindow.getNativeWindowHandle(),
message: "OneKey requests verification to unlock your wallet",
});
const verified = result === VerificationResult.Verified;checkAvailability() resolves to a value in Availability: Available, DeviceNotPresent, NotConfiguredForUser, DisabledByPolicy, or DeviceBusy.
It first probes the window-owned IUserConsentVerifierInterop interface at runtime, without showing a verification dialog. It returns DeviceNotPresent on unsupported operating systems and architectures, without loading a native binary. An unavailable interop interface or Windows API failure rejects the promise; applications should offer their normal password authentication instead.
requestVerification({ windowHandle, message }) requires a fresh, 8-byte Buffer from BrowserWindow.getNativeWindowHandle() and a non-empty message. It resolves to a value in VerificationResult: Verified, Canceled, DeviceBusy, DeviceNotPresent, NotConfiguredForUser, DisabledByPolicy, or RetriesExhausted.
Only Verified authorizes the operation. An overlapping request returns DeviceBusy and does not share another request's authorization.
Invalid or destroyed owner windows and Windows API errors reject the promise. Native errors retain the Windows HRESULT in the error message.
allowSetForegroundWindow(processId) grants a specific process permission to set the foreground window, when Windows permits the caller to grant it. It returns whether Windows accepted the grant. Call it from the foreground Electron main process before dispatching verification to a utility process. Zero, wildcard, and non-integer process IDs are rejected.
Electron utility process and focus
In the main process, restore and activate the actual owner window before dispatching:
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.show();
mainWindow.focus();
allowSetForegroundWindow(helloProcess.pid);
helloProcess.postMessage({
message: "OneKey requests verification to unlock your wallet",
windowHandle: Array.from(mainWindow.getNativeWindowHandle()),
});Wait for the owner to be focused before dispatching. If mainWindow.isFocused() is false, defer verification until a user-initiated window activation. show() and focus() alone do not guarantee that Windows grants foreground permission.
In the utility process, reconstruct the handle with Buffer.from(data.windowHandle) and call requestVerification with that buffer. Always send a result or error back to the caller.
Do not convert the handle to a JavaScript number or discover the owner by querying an unrelated foreground window.
WinRT is initialized and awaited on a libuv worker, so verification does not block Electron's JavaScript thread. Windows controls foreground policy, title, icon, taskbar presentation, and the authentication method. An owner handle and foreground grant do not guarantee a particular icon or force focus against operating-system policy.
Support
- Windows x64 and ARM64; both native binaries ship in the same package and are selected using
process.arch. - Node.js 20.17 or later, including Electron runtimes with Node-API 8 support.
- Windows 10 and 11 use the same window-owned
IUserConsentVerifierInterop::RequestVerificationForWindowAsyncpath, selected by runtime interface availability rather than an OS version check. Microsoft's method documentation lists build 22000, while its CsWinRT implementation and Electron sample indicate Windows 10 support. Windows 11 interaction has been manually verified; Windows 10 interaction testing is still pending, so no minimum Windows 10 build is claimed. - There is no silent fallback to an unowned verification dialog. If availability fails, offer the application's normal password authentication. Cancellation, unsuccessful verification, and native errors never cause an automatic retry; a new Hello attempt must be explicitly initiated by the user.
- No credential storage, account management, key generation, signing, PIN collection, or custom authentication UI.
Development and release
Install Rust 1.88 or later and the Windows MSVC toolchain, then run:
npm ci --ignore-scripts
npm run build
npm test
npm run test:typesBuild a specific target with npm run build -- x86_64-pc-windows-msvc or npm run build -- aarch64-pc-windows-msvc.
CI builds and tests each architecture on a native Windows runner, then checks and packs the combined npm package. npm pack refuses missing binaries or a PE machine type that does not match the advertised architecture. Only the runtime entrypoint, declarations, native binaries, README, license, and package metadata are published.
With Electron installed in the development environment, npm run test:electron checks the real HWND and utility-process path without an authentication prompt. npm run test:electron -- --interactive opens a visible owner window and requests Windows Hello; verify focus, cancellation, multi-monitor placement, and taskbar presentation in a logged-in desktop session. Headless CI cannot establish those interaction results.
The publish workflow supports npm trusted publishing with provenance after configuring this repository and .github/workflows/publish.yml as a trusted publisher in npm. Alternatively, configure an npm publish token as the repository's NPM_TOKEN secret. Release tags must match the package version. Initial publication may require an authenticated local npm session.
References
The API choice was informed by Microsoft's desktop interoperability documentation and investigation of passport-desktop. This project has its own source, API, tests, and release pipeline; it does not include Passport account or cryptographic APIs.
