Skip to content

Release 2.2.0: note import, duress PIN, editor upgrades and dependency updates - #65

Merged
pasichDev merged 19 commits into
mainfrom
feat/next-version-issues-59-60-61-63
Oct 15, 2026
Merged

pasichDev merged 19 commits into
mainfrom
feat/next-version-issues-59-60-61-63

Conversation

@pasichDev

@pasichDev pasichDev commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

✅ Ready: this is release 2.2.0. After the merge, tag v2.2.0 on main to run release.yml. From #64 only Milestone I is included; Milestones II and III are for a later release.

What

Why

The next release: the pending dependency and security updates, and issues #59–#63.

Behaviour changes

  • New store entries pin.decoy.slot, decoy.key and pin.strikes are added at startup to existing vaults (random bytes, no PIN needed); pin.slot is 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).
  • Changing the PIN to the duress PIN, or setting a wipe PIN equal to it, is refused; each such refusal counts as a missed PIN, and the wipe and duress PIN cannot be set during a lockout.
  • From the 10th missed PIN since the real PIN was last entered, every miss is locked out, even right after the duress PIN opened the decoy vault.
  • Pasting several lines of plain text now keeps paragraphs (a blank line starts a new block) instead of creating one block per line. Pasted after existing text, the first line stays plain text.

Testing

  • spotlessCheck, :app:testFdroidDebugUnitTest, :app:koverVerifyFdroidDebug, :app:detekt, :app:lintFdroidRelease, :app:lintPlayRelease and :app:compileFdroidDebugAndroidTestKotlin pass locally (JDK 21).
  • 1700 unit tests; app line coverage 91% with generated code excluded (core/security 89.6%).
  • Duress PIN: 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 in SecurityScreensTest.
  • Import: parsers tested against real exports made with each app (app/src/test/resources/import-fixtures/, synthetic notes only) plus malformed, bomb (including media-named), traversal and limit cases.
  • Device (Pixel 7a, Android 16, fdroidDebug installed over a 2.0.1 vault with notes and a task):
    • Upgrade: the 2.0.1 vault opens with its PIN on this branch (SQLCipher 4.19.0); notes, task and subtask intact.
    • Editor: slash menu opens on an empty paragraph and inserts a heading; plain multi-line paste after existing text continues the line.
    • Duress PIN: set; equal to the PIN refused; decoy opens empty; decoy Settings/Security match the real vault; duress PIN change, backup export and Erase are refused with the generic message; the real vault is intact afterwards.
    • Lockout: 30 s from the 5th miss; the duress PIN does not open the decoy during a lockout; after two rounds of 4 misses + duress unlock, the next round locks out on its 2nd miss (strikes survive the decoy unlock).
    • Import (synthetic fixtures): Keep 5, Joplin JEX 5, Standard Notes 6, Notesnook 5, Obsidian folder 4 (attachment counted, not read); re-importing Keep skips all 5 as duplicates; an encrypted Notesnook backup gives its guidance.
    • Backup: export and re-import with the recovery phrase (27 notes, 1 task, 6 tags), merge.
    • Wipe PIN: equal to the duress PIN refused; typed on the lock screen it erases silently and opens an empty vault; the old PIN and the duress PIN no longer open anything.
    • After the dependency update (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

@pasichDev pasichDev changed the title Нова версія: залежності та задачі #59, #60, #61, #63 Next release: dependency updates and issues #59, #60, #61, #63 Oct 14, 2026
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Coverage (core/security)

Overall Project 78.82% -0.72% 🍏
Files changed 96.9% 🍏

File Coverage
AutoLock.kt 100% 🍏
DuressSlots.kt 99.48% -0.52% 🍏
PinSlots.kt 99.45% -0.55% 🍏
AuthenticationManager.kt 97.99% -1.08% 🍏
SessionLockManager.kt 91.74% -0.59% 🍏
SecurityManager.kt 85.7% -2.09% 🍏

Apply compact spacing to textual list and quote blocks, and document the visible changes in the Unreleased changelog.
@pasichDev
pasichDev force-pushed the feat/next-version-issues-59-60-61-63 branch from c971500 to 57b060c Compare October 14, 2026 11:22
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
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
@pasichDev pasichDev changed the title Next release: dependency updates and issues #59, #60, #61, #63 Next release: dependency updates and issues #59–#63 Oct 14, 2026
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.
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Coverage

Overall Project 89.76% -1.65% 🍏
Files changed 90.6% 🍏

File Coverage
InlineHtml.kt 100% 🍏
EnclySpacing.kt 100% 🍏
SQLCipherUtils.kt 100% 🍏
ImportNotesActions.kt 100% 🍏
DatabaseProvider.kt 100% 🍏
ActionBlockDialog.kt 100% 🍏
DocumentTree.kt 100% 🍏
ImportBlocks.kt 100% 🍏
SmartPaste.kt 100% 🍏
AutoLock.kt 100% 🍏
DuressSlots.kt 100% 🍏
PinSlots.kt 100% 🍏
NavRoutes.kt 100% 🍏
NoteLineSpacing.kt 100% 🍏
NotesRepositoryImpl.kt 100% 🍏
TasksRepositoryImpl.kt 100% 🍏
SettingsLocalDataSource.kt 99.82% 🍏
ImportSourceCard.kt 99.56% -0.44% 🍏
PasteEditing.kt 99.55% -0.45% 🍏
MarkdownBlockMapper.kt 99.39% -0.61% 🍏
ImportMapper.kt 99.37% -0.63% 🍏
BackupManager.kt 99.23% 🍏
SlashCommands.kt 99.12% -0.88% 🍏
SessionLockManager.kt 99.12% -0.59% 🍏
FormatDetector.kt 99% -1% 🍏
NoteFind.kt 98.89% -1.11% 🍏
BlockDuplicate.kt 98.83% -1.17% 🍏
BlockEditorState.kt 98.65% 🍏
PreloadedViewModelOwner.kt 98.57% -1.43% 🍏
AuthenticationManager.kt 98.45% -1% 🍏
BlockEditRows.kt 98.44% 🍏
TextBlock.kt 98.14% 🍏
ImportReader.kt 98.04% -1.96% 🍏
SecuritySettingsViewModel.kt 97.99% -1.17% 🍏
NoteCardBottomSheet.kt 97.94% 🍏
JoplinParser.kt 97.66% -2.34% 🍏
NoteTemplates.kt 97.56% -2.44% 🍏
Editor.kt 97.47% -1.2% 🍏
HomeTaskWidget.kt 97.45% 🍏
KeepParser.kt 97.37% -2.63% 🍏
TagsRepositoryImpl.kt 97.13% -2.87% 🍏
Frontmatter.kt 97.09% -2.91% 🍏
ImportTypes.kt 96.95% -3.05% 🍏
SlashMenuPopup.kt 96.78% -3.22% 🍏
CommandMenuItem.kt 96.75% -3.25% 🍏
ImportReviewScreen.kt 96.73% -3.27% 🍏
DuressPinScreen.kt 96.48% -3.52% 🍏
MarkdownNotesParser.kt 95.97% -4.03% 🍏
StandardNotesParser.kt 95.78% -4.22% 🍏
TextFields.kt 95.27% -1.52% 🍏
PinCodeConfigScreen.kt 95.19% 🍏
PinFlow.kt 95.11% -4.89% 🍏
SettingsRepositoryImpl.kt 94.85% -5.15% 🍏
SubtaskEditor.kt 94.83% 🍏
TrashScreen.kt 94.73% 🍏
BlockEditing.kt 94.62% 🍏
SettingsScreen.kt 94.51% -0.95% 🍏
SecuritySettingsScreen.kt 94.32% -0.55% 🍏
SecurityManager.kt 93.88% -1.39% 🍏
SettingsBuilder.kt 93.87% -1.72% 🍏
BackupScreen.kt 93.71% 🍏
LexicalBlocks.kt 93.62% -6.38% 🍏
EditNoteBottomSheet.kt 93.59% -1.48% 🍏
TemplateChooser.kt 93.35% -6.65% 🍏
EditorFindBar.kt 93.22% -6.78% 🍏
ImportText.kt 93.19% -6.81% 🍏
ImportNotesViewModel.kt 93% -7% 🍏
LockScreen.kt 92.73% -0.63% 🍏
HBlock.kt 92.62% 🍏
AppearanceScreen.kt 92.31% 🍏
Shortcut.kt 91.81% 🍏
EditNoteScreen.kt 91.67% -2% 🍏
TasksScreen.kt 91.64% 🍏
EditNoteViewModel.kt 90.71% -3.86% 🍏
ImportTime.kt 90.34% -9.66% 🍏
NoteBottomBar.kt 90.09% 🍏
EditorBlocksHost.kt 90.02% -0.72% 🍏
EditTagScreen.kt 89.98% 🍏
NotesSortBottomSheet.kt 89.76% -2% 🍏
Theme.kt 89.7% -3.12% 🍏
WipePinScreen.kt 89.64% -1.59% 🍏
BackupViewModel.kt 88.99% 🍏
MainDrawer.kt 88.94% 🍏
QuoteBlock.kt 88.76% 🍏
ImportPages.kt 87.19% -12.81% 🍏
SubtaskTree.kt 87.18% -0.51% 🍏
SecuritySections.kt 86.04% -1.25% 🍏
VaultDataStore.kt 85.71% -14.29% 🍏
ListBlock.kt 84.39% 🍏
EditorEffects.kt 84.23% -5.99% 🍏
ZipStreamReader.kt 83.76% -16.24% 🍏
EditNoteLocalProvider.kt 83.7% 🍏
MainScreen.kt 83.23% 🍏
TagsListScreen.kt 82.85% -2.72% 🍏
DataFormater.kt 80.79% -1.32% 🍏
NotesListScreen.kt 80.76% 🍏
OnboardingScreen.kt 79.79% 🍏
TrashNotesList.kt 77.61% 🍏
ImportReview.kt 74.14% -25.86% 🍏
BlockInput.kt 72.82% -0.51% 🍏
NoteSpacing.kt 71.43% -28.57% 🍏
TarReader.kt 71.25% -28.75% 🍏
EditorSheets.kt 68.51% -0.48% 🍏
FieldHighlight.kt 66.79% -33.21% 🍏
ImportFromMyNotesScreen.kt 54.12% 🍏
SecureDatabaseManager.kt 50.09% -17.2% 🍏
TextBlockKeys.kt 49.35% -42.21% 🍏
NavHost.kt 44.31% -2.9% 🍏
BlockActionsImpl.kt 44.03% -4.1% 🍏
ImportNotesScreen.kt 40.56% -59.44% 🍏
AutoLockSetting.kt 27.27% -10.52% 🍏
FindHighlights.kt 14.71% -85.29% 🍏
RoomVaultDataStore.kt 4.6% -83.91% 🍏
SafImportFiles.kt 1.79% -98.21% 🍏

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 pasichDev changed the title Next release: dependency updates and issues #59–#63 Release 2.2.0: note import, duress PIN, editor upgrades and dependency updates Oct 15, 2026
@pasichDev
pasichDev marked this pull request as ready for review October 15, 2026 17:11
@pasichDev
pasichDev merged commit 849ed73 into main Oct 15, 2026
1 check 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