Skip to content

feat(desktop): unlock with Touch ID, and copy secrets from the main process - #24

Merged
pyramation merged 1 commit into
mainfrom
feat/touch-id-unlock
Aug 9, 2026
Merged

feat(desktop): unlock with Touch ID, and copy secrets from the main process#24
pyramation merged 1 commit into
mainfrom
feat/touch-id-unlock

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Two things: Copy is fixed — it never worked in a packaged build — and the vault can now be unlocked by fingerprint instead of the master password.

Copy. copyWithTimeout used the renderer's navigator.clipboard, which needs a secure context (a packaged build serves the UI from file://, where the API is simply absent) and a read permission Electron never grants, so the clear-after-30s half always threw. It now runs in the main process:

// renderer
copyWithTimeout = (value, seconds = 30) => void dcrypt.clipboard.copy(value, seconds)

// main
clipboard.writeText(value)
setTimeout(() => { if (clipboard.readText() === value) clipboard.clear() }, seconds * 1000)

Still clears only if it is still ours, so a shopping list copied since survives; a second copy supersedes the first timer; locking the vault cancels it.

Touch ID. What is stored is the master password, sealed by the OS credential store via safeStorage — Keychain, DPAPI, libsecret — and released only after systemPreferences.promptTouchID(). The vault file is untouched and still opens with the password anywhere else, so this changes who is asked, not what protects the vault. enrol refuses when safeStorage.isEncryptionAvailable() is false (no keyring on Linux) rather than falling back to anything weaker, and the IPC handler unlocks the vault with the password before promising it works, so a typo cannot enrol a password that fails at the doors.

macOS is the only platform Electron gives a biometric prompt for, so elsewhere biometricStatus().biometric is false and the same stored password is released without one — labelled "Unlock with Credential Manager" / "the system keyring" rather than Touch ID.

Three places keep the remembered password honest, since one that no longer opens the vault is a dead end:

  • changing the master password re-enrols the new one;
  • restoring a backup forgets it (that vault may have a different password);
  • erase-all already removes everything under ~/.dcrypt, which is where config/unlock.bin lives.

On the unlock screen the fingerprint prompt fires as soon as the doors appear when one is enrolled, with the password field still there behind it; a cancelled prompt is treated as a choice, not an error.

Link to Devin session: https://app.devin.ai/sessions/04636534e07048089ffb6b78142e12cd
Requested by: @pyramation

@pyramation pyramation self-assigned this Aug 9, 2026
@devin-ai-integration

Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit 978142c into main Aug 9, 2026
5 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.

1 participant