Skip to content

Feat/keepass integration#125

Open
rederyk wants to merge 3 commits into
snowarch:mainfrom
rederyk:feat/keepass-integration
Open

Feat/keepass integration#125
rederyk wants to merge 3 commits into
snowarch:mainfrom
rederyk:feat/keepass-integration

Conversation

@rederyk

@rederyk rederyk commented Apr 20, 2026

Copy link
Copy Markdown

Ciao! I am an Italian user. I've used AI to help me with the English translation and to refine some of the QML logic, but I have tested everything extensively on my own system to make sure it's solid and fits the iNiR aesthetic.


Summary

Improved the KeePass integration with a focus on security, automation, and visual consistency.

Key Improvements:

  • Security: Migrated the vault password cache from plain files to the system keyring via secret-tool (Secret Service API).
  • Background Timer: Implemented a real background countdown timer that automatically locks the database and clears the cache when it expires.
  • Enhanced Generator: Completely overhauled the password generation logic:
    • Standard passwords now guarantee at least one character of each selected type (upper, lower, number, symbol).
    • Word-based generator now mixes full-word casing (ALL CAPS vs lowercase) and interleaves symbols/numbers between words for better entropy and security.
  • Live UI: Added a live countdown badge in the title bar with a progress bar. The timer turns red when close to locking (< 30s).
  • Quick Extension: The timer badge is clickable to instantly reset/extend the unlock duration.
  • Aesthetic Alignment: Refactored the UI to match the 'Pill' style used in iNiR settings, including proper high-contrast text inversion for readability.
  • Documentation: Added a new guide in docs/KEEPASS.md.

Testing

  • inir restart && inir logs — checked, no critical errors.
  • Tested the specific feature path that changed — verified unlocking, background timer, live badge, manual reset, and the new generation rules.
  • Both panel families checked — KeePass is currently used only in the ii panel family, but the underlying service is shared.

I hope this helps other KeePass users in the community!

@snowarch

Copy link
Copy Markdown
Owner

hey this is cool and i appreciate the effort, but it needs some work before it can go in. a few things:

  • the hardcoded vault path ($HOME/Nextcloud/secrets/end4dot-keepass.kdbx) needs to be configurable, probably a config key
  • the italian wordlist (_KP_WORDS_IT) should be english or pulled from the translation system
  • squash the 12 commits into something clean
  • GlobalStates.keepassOpen adds surface area to a singleton with 129+ consumers, worth thinking about whether this needs its own state management
  • the keepassxc-cli dependency should be optional, not required — feature should gracefully degrade if it's not installed

no rush, take your time cleaning it up and ping when it's ready for another look

@rederyk rederyk force-pushed the feat/keepass-integration branch 4 times, most recently from c7cf669 to f87a842 Compare April 28, 2026 08:10
@rederyk rederyk force-pushed the feat/keepass-integration branch from f87a842 to 2a2dc64 Compare May 12, 2026 11:52
@rederyk

rederyk commented May 12, 2026

Copy link
Copy Markdown
Author

Hi @snowarch, I've addressed all the points from your review:

  • Configurable vault path: moved to a keepass.vaultDir config key, no hardcoded paths.
  • Wordlist: removed the Italian hardcoded list, now pulled from the translation system via Translation.tr("keepass_wordlist").
  • Commits: squashed and cleaned up — now 4 logical commits.
  • GlobalStates: removed keepassOpen from GlobalStates, state is managed locally in the panel.
  • Graceful degrade: if keepassxc-cli is not installed, the panel shows an install banner instead of failing; keepassxc is listed in optdepends in the PKGBUILD.

Ready for another look whenever you have time, thanks!

@snowarch

Copy link
Copy Markdown
Owner

hey, thanks for addressing the previous points. i went through the updated diff more carefully and there are still some things that need fixing before this can go in.

first — the PR scope. this should only touch keepass-related files, but right now it also modifies SidebarRight.qml (rewrites the visibility pattern to mask-based input), adds a formatTime() function to DateTime.qml, and then changes 6 other files (CalendarEventRow, EventCard, TimeButton, CalendarWidget, AnimeService, YtMusic) to use it. those are unrelated changes that affect stable code across both panel families. if you want to propose those separately thats fine, but they cant ride along in a feature PR — especially right now during a release cycle where i need clean diffs.

second — the panel doesnt follow the design system correctly. a few concrete things:

  • Appearance.colors.colNegative does not exist. the error color token is colError.
  • Appearance.colors.colLayer1Border does not exist. borders use colOutlineVariant or colLayer0Border.
  • Appearance.font.pixelSize.tiny does not exist. smallest is the token you want.

these arent edge cases, they produce runtime warnings (Unable to assign [undefined] to QColor) every time the panel opens. i need contributors to verify their work against the actual Appearance.qml schema — the properties are all there, its just a matter of reading the file.

third — look at how ClipboardPanel.qml is structured. it uses GlassBackground for the surface (which handles all the glass/blur/transparency logic per style automatically), it has proper entry/exit animations using Appearance.animation tokens, and it handles the backdrop click-to-close pattern correctly. the keepass panel uses a bare Rectangle with hardcoded width (640px) and manual color branching in every single property (angelEverywhere/inirEverywhere/auroraEverywhere ternaries repeated 50+ times). GlassBackground exists precisely to avoid that pattern.

fourth — the translations. the PR adds keys to 16 locale files but the values are just english placeholders for everything except the wordlists. thats fine to ship as-is (the translation team can fill them in later), but just flagging it.

fifth — the service singleton (KeePass.qml) contains the IpcHandler, but since QML singletons are lazy-loaded, the IPC target only exists if the panel is loaded. if someone removes iiKeepass from their enabledPanels the whole thing goes dead silently. other services that need IPC (like Audio, Cliphist) are referenced by always-loaded components which forces their instantiation. worth thinking about how to ensure the handler is always available.

the backend script and the service logic are solid — the architecture of script + service + panel is right, the secret-tool caching is good, the timer system makes sense. its really the panel UI that needs a rewrite following the existing patterns, and the unrelated changes need to be dropped from this branch.

no rush, take your time.

@rederyk rederyk force-pushed the feat/keepass-integration branch from 3e17484 to 4e36007 Compare May 17, 2026 14:19
@snowarch

Copy link
Copy Markdown
Owner

Thanks @rederyk — solid feature and clearly tested. Two blockers before it can land:

  1. It currently conflicts with main and needs a rebase.
  2. The history has commits co-authored by an AI assistant — iNiR keeps AI attribution out of git, so please squash/re-author so the commits are yours only.

Once it's rebased and cleaned up I'll review the keyring + timer logic properly.

@rederyk rederyk force-pushed the feat/keepass-integration branch 3 times, most recently from 6089cda to 4fe29ab Compare June 24, 2026 09:59
@rederyk

rederyk commented Jun 24, 2026

Copy link
Copy Markdown
Author

Rebased onto latest main and cleaned up the history as requested 🙏

Blockers addressed

  • Rebase: rebased onto current main. Conflicts resolved in defaults/config.json, scripts/lib/ipc-registry.sh (regenerated with generate-ipc-registry.py, --check passes) and the 14 conflicting translation files (only the keepass_* strings re-applied on top of the new main). PR is now MERGEABLE / clean.
  • AI attribution: removed the Co-Authored-By trailers — the history is now 3 commits authored by me only.

Two small functional fixes I folded in while rebasing

  • Password generator (word mode): when both numbers and symbols were enabled, the per-gap separator picked one or the other at random, so a generated passphrase could miss a whole type (and the short 2-word preset has a single gap, making both impossible). It now guarantees every selected type appears at least once, matching the standard generator's behaviour. Verified across length presets.
  • Entry list UX: navigating the results with ↑/↓ now auto-selects the highlighted entry, so a single Enter copies (no more double-press) and Alt reveals the entry you're looking at.

Ready for the keyring + timer review whenever you have time — happy to adjust anything there.

@rederyk rederyk force-pushed the feat/keepass-integration branch 2 times, most recently from 11152e9 to 8906a40 Compare June 24, 2026 11:07
@rederyk

rederyk commented Jun 24, 2026

Copy link
Copy Markdown
Author

Pushed a round of keyring + timer hardening (the area you flagged), all squashed into the existing commits — still 3 clean commits authored by me.

Keyring

  • Cache items are now scoped per vault (a path attribute), so vaults with different master passwords can't feed each other a stale password — verified live across two vaults (switching vaults forces a fresh unlock, no cross-vault reuse).
  • The cache is wiped on shell start: there's no auto-unlock from the keyring, so a lingering master password was pure risk. Now it never outlives the session that created it.
  • No-keyring fallback: if no Secret Service is reachable, the password is kept in memory for the session instead of silently failing copy/reveal (probed once at startup).
  • Optional KP_DEBUG=1 trace logs every keyring decision (cache hit/miss, store, clear, stdin fallback) so you can audit that nothing silently falls back — off by default, zero overhead, documented in docs/KEEPASS.md.

Timer / TTL

  • keepass.cacheTtl is now persisted (config + Settings → Services → KeePass), so the "stay unlocked" duration survives restarts. The unlock-panel slider updates its label live while dragging and commits the value on the actual unlock.

Also folded in earlier: the word generator now guarantees every selected character type, and the entry list auto-selects on ↑/↓ so a single Enter copies.

Tested live (Niri + gnome-keyring): unlock → copy/reveal all hit the keyring cache, lock clears the scoped item, startup wipes stale items. Happy to adjust anything.

rederyk added 3 commits June 24, 2026 13:21
Adds an overlay panel for KeePassXC with secure unlock flow, entry
search, password copy/reveal/generate, multi-vault support, and a
vault create flow. Designed as an always-mapped Wayland surface
(mask-based visibility) so the IpcHandler stays reachable even when
the panel is closed.

Key design points:
- Backend: quickshell-keepass script handles all keepassxc-cli calls;
  KeePass.qml singleton manages state, processes, and an IPC handler
  (toggle / add) that is always active via a _keepassReady binding in
  ShellIiPanels.qml.
- Panel: GlassBackground surface, no ExclusionMode (defaults to Normal
  so the compositor auto-positions below the bar's exclusive zone),
  WlrKeyboardFocus.Exclusive only while open. Focus is bound
  declaratively (focus: KeePass.open) and vault-list focus is restored
  after the async scan via an onAvailableVaultsChanged handler.
- Config: keepass.vaultDir is the only user-settable key; vault path
  is runtime-only. Panel registered as iiKeepass in enabledPanels.
- Graceful degrade: if keepassxc-cli is absent the panel shows an
  install banner instead of crashing on every action.
- Translations: keepass_* strings added to all 15 locale files.
Adds a KeePass section to the Services settings page allowing users
to configure keepass.vaultDir and the cache TTL from the shell UI.
Documents the panel features (vault management, entry search, password
operations, generation), all IPC commands, configuration options
(keepass.vaultDir, keepass.cacheTtl), and the quickshell-keepass
script interface.
@rederyk rederyk force-pushed the feat/keepass-integration branch from 8906a40 to a6b91b2 Compare June 24, 2026 11:22
@rederyk

rederyk commented Jun 24, 2026

Copy link
Copy Markdown
Author

One more fix folded into the feat commit: add could report "Failed to add entry" even though the entry was saved.

cmd_add ended its success branch with [[ -z "$(read_cache)" ]] && write_cache …. When the cache already exists (the normal case — DB unlocked), the test is false, so that && list (the function's last statement) returned exit 1, making a successful add look like a failure — which also flipped the UI back to the locked state. Replaced it with an explicit if … fi + return 0. Verified the entry is added and the panel stays unlocked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants