Repository navigation
Release 2.2.0: note import, duress PIN, editor upgrades and dependency updates - #65
Merged
Merged
Conversation
Coverage (core/security)
|
Apply compact spacing to textual list and quote blocks, and document the visible changes in the Unreleased changelog.
pasichDev
force-pushed
the
feat/next-version-issues-59-60-61-63
branch
from
October 14, 2026 11:22
c971500 to
57b060c
Compare
This was referenced Oct 14, 2026
A third PIN, typed on the usual lock screen, opens a decoy vault with its own random DEK and SQLCipher database. The duress slot and the decoy key always exist with the same size, every attempt tries all three slots in one KDF run, and a decoy session cannot touch the real vault's key slots, backups or settings. Refs: #61
This was referenced Oct 14, 2026
Imports exports of Google Keep (Takeout), Standard Notes (decrypted backup), Joplin (JEX, RAW), Notesnook (Markdown, TXT) and plain Markdown/TXT folders such as an Obsidian vault. Files are read from the system picker into memory only, with bounded ZIP and TAR readers, detected by content, reviewed note by note before saving, and merged in one transaction into the open vault. Parsers are tested against real exports of each app. Refs: #62
29 of 33 tasks
Comfortable reading density, a slash command picker for empty paragraphs, Markdown-aware smart paste (one undo step, paragraphs kept), block duplication, find in note, and optional templates for new notes. The stored note format is unchanged; opening a note never rewrites it. Refs: #64
…ues-59-60-61-63 # Conflicts: # CONTRIBUTING.md
…ecoy - Keep a second miss counter (pin.strikes) that only the real PIN, a new PIN slot and the erase clear: typing the duress PIN between guesses ends a running lockout but no longer resets the guess budget. From the 10th miss since the PIN was last right every miss is locked out. - Charge a miss when Settings refuses a PIN for being another PIN, and refuse setting the wipe or duress PIN during a lockout. - Record a turned-off duress PIN inside decoy.key (another AAD) instead of the pin.decoy.notice entry, so the store never shows a decoy vault and Settings reports the duress PIN as off after any new PIN salt. - Show the same Settings in the decoy vault; every real-vault action fails like a storage error. Backup decrypt and import are refused by BackupManager, and wipeAndReset reports whether it erased. - Write the SQLite header magic as an escape instead of a raw NUL byte. Refs: #61
Import: - Count media and attachments by name without keeping them: picked files are never opened, TAR members are discarded and ZIP members are inflated against a separate 2 GiB cap, so a Takeout full of photos imports and a bomb named photo.jpg still stops. - Key Markdown notes by path and content, accept front matter only with a key line, strip only known HTML tags, keep Lexical code and tables as text, make the wiki-link match linear, treat unknown ZIP signatures as errors, read backslash paths and CP437 names, count every archive entry and too-deep file, and apply Notesnook rules per file. Editor: - Keep the first pasted line as plain text after existing text, paste empty checklist items, keep a heading or quote tail's kind, stop offering templates once a new note is saved, and observe the slash menu only in the paragraph that owns it. SECURITY.md and CHANGELOG.md cover these and the duress PIN lockout. Refs: #61 Refs: #62 Refs: #64
- Add tests for PIN slots, Keystore and biometric failures, the vault store format, SecurityManager lifecycle, SecureDatabaseManager, dialogs, unlock effects, clipboard and formatting helpers. - Gate the whole app at 85% line coverage in Kover, generated code (Hilt, R, BuildConfig, Room _Impl, ComposableSingletons) excluded, instead of core/security alone at 40%. - Fail the INTERNET manifest check when no fdroidRelease manifest is found, and use the stable configuration-cache property name.
Navigation 2.10 shrinks the leaving screen into the middle of the window during a predictive back gesture. Use the same motion as a tap on Back.
Each app gets its own card with a short mark, its name and what to pick. How to export and what is not imported unfold on a tap.
Bumps the version to 2.2.0 (versionCode 20200), moves the Unreleased notes under 2.2.0 with a Changed and a Compatibility section, and adds the 2.2.0 release notes for the stores in all nine store languages. Neither the database nor the backup format changes, so 2.1.0 still opens the vault and its backups.
pasichDev
marked this pull request as ready for review
October 15, 2026 17:11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
version.properties2.2.0 (versionCode 20200), CHANGELOG section with Changed and Compatibility, store notes20200.txtin all nine store languages. No database or backup format change, so 2.1.0 still opens the vault.compileSdk37 for SQLCipher; target and min SDK unchanged. compose-rules for detekt stays on 0.4.28 (0.5 needs detekt 2).vault_b.db). Every attempt runs one KDF and tries all three slots (PIN, duress, wipe); the duress slot and decoy key always exist with the same size. A decoy session cannot touch the real vault's key slots, biometrics, recovery phrase, backups or "erase all data": Settings looks the same as in the real vault and each of those actions fails like a storage error, refused by the security layer. A second miss counter (pin.strikes) bounds guesses at the real PIN when the duress PIN is typed between them. The wipe PIN erases the decoy vault too. Repositories reach Room only through a per-opening lease.core/securityat 40%; the INTERNET manifest check fails when it finds no release manifest.TranslationCompletenessTestnow also coversstrings_handoff.xmlandstrings_import.xml.Why
The next release: the pending dependency and security updates, and issues #59–#63.
Behaviour changes
pin.decoy.slot,decoy.keyandpin.strikesare added at startup to existing vaults (random bytes, no PIN needed);pin.slotis not touched. Older builds ignore them and keep opening the real vault; a PIN changed in an older build turns the duress PIN off (documented in SECURITY.md → Duress PIN).Testing
spotlessCheck,:app:testFdroidDebugUnitTest,:app:koverVerifyFdroidDebug,:app:detekt,:app:lintFdroidRelease,:app:lintPlayReleaseand:app:compileFdroidDebugAndroidTestKotlinpass locally (JDK 21).core/security89.6%).DuressPinTest(store shape after every lifecycle step with and without a decoy vault, three-slot dispatch, lockout and strikes, collisions, PIN-key reset, wipe interaction, decoy-session restrictions, epoch on vault switch); decoy Settings parity and failure paths inSecurityScreensTest.app/src/test/resources/import-fixtures/, synthetic notes only) plus malformed, bomb (including media-named), traversal and limit cases.fdroidDebuginstalled over a 2.0.1 vault with notes and a task):efdb390): unlock; auto-lock (open after 5 s in the background, locked after 20 s with the 15 s delay); slash menu, heading and task saved; import cards unfold, Notesnook zip adds 5; duress PIN set, opens an empty decoy, the main PIN opens the real vault; no crashes in logcat.Not verified: backup export after the dependency update, Material 3 1.4 visuals (FLAG_SECURE blocks screenshots), an upgrade from a 2.1.0 install (tested from 2.0.1 only), Markdown paste of lists or headings from the clipboard (unit tests only), note spacing, find in note, templates, TalkBack; instrumented tests not run.
References
#59 #60 #61 #62 #63 #64 #66