Skip to content

Don't auto close database unlock dialog when underlying file is unavailable - #12200

Closed
droidmonkey with Copilot wants to merge 3 commits into
developfrom
copilot/fix-9539
Closed

Don't auto close database unlock dialog when underlying file is unavailable#12200
droidmonkey with Copilot wants to merge 3 commits into
developfrom
copilot/fix-9539

Conversation

Copilot AI commented Jun 15, 2025

Copy link
Copy Markdown
Contributor

This PR addresses the issue where KeePassXC would automatically close the database unlock dialog when the underlying database file is temporarily unavailable, preventing users from retrying once the file becomes accessible.

Problem

When KeePassXC starts automatically on user login and tries to open the most recently used database file, if that file is stored on cloud storage (like Google Drive) that hasn't finished mounting yet, the unlock dialog would never appear. This creates a race condition where users have to manually reselect their database file after the cloud storage becomes available.

Solution

The fix implements the suggestion from @droidmonkey to keep the unlock dialog open even when the file is missing, allowing users to retry when the file becomes available.

Key Changes

DatabaseTabWidget.cpp:

  • Removed early return when canonicalFilePath.isEmpty() (indicating file doesn't exist)
  • Continue to show error message but proceed with creating the database tab
  • Allow unlock dialog to be displayed even when file is missing

DatabaseOpenWidget.cpp:

  • Added proper error handling when Database::open() fails during header reading
  • Show informative warning message when file is unavailable
  • Continue to display unlock dialog instead of failing silently

Test Coverage

Added testOpenMissingDatabaseFile() test to verify:

  • Database tab is created even when file doesn't exist
  • Unlock dialog remains open and functional
  • User can retry when file becomes available

User Experience

Before this fix:

  1. KeePassXC starts before cloud storage mounts
  2. Database file is unavailable
  3. No unlock dialog appears
  4. User must manually reopen the database

After this fix:

  1. KeePassXC starts before cloud storage mounts
  2. Database file is unavailable
  3. Unlock dialog appears with warning message
  4. User can retry unlock once file becomes available

This provides a much better user experience for cloud storage scenarios and other cases where files may be temporarily unavailable.

Fixes #9539.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 224.0.0.251
  • esm.ubuntu.com
    • Triggering command: /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI changed the title [WIP] Don't auto close database unlock if underlying file is unavailable Don't auto close database unlock dialog when underlying file is unavailable Jun 15, 2025
Copilot AI requested a review from droidmonkey June 15, 2025 17:16
@droidmonkey
droidmonkey marked this pull request as ready for review June 15, 2025 17:24
Copilot AI review requested due to automatic review settings June 15, 2025 17:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an issue where the database unlock dialog would auto-close when the underlying file is unavailable by keeping the dialog open so users can retry once the file becomes accessible.

  • Continue showing the unlock dialog even when the file is missing
  • Improve error handling in the database opening process
  • Add a new GUI test to verify the unlock dialog remains open when the database file is missing

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
tests/gui/TestGui.h Added declaration for the new test case
tests/gui/TestGui.cpp Added testOpenMissingDatabaseFile() to validate dialog behavior
src/gui/DatabaseTabWidget.cpp Modified logic to avoid early exit when file is missing and fallback to the original file path for consistency
src/gui/DatabaseOpenWidget.cpp Updated error handling for database open failures to display a warning message

Comment thread src/gui/DatabaseTabWidget.cpp Outdated
Comment thread src/gui/DatabaseOpenWidget.cpp Outdated
@codecov

codecov Bot commented Jun 15, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 47.61905% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.38%. Comparing base (72308a1) to head (66ff42c).

Files with missing lines Patch % Lines
src/gui/DatabaseOpenWidget.cpp 50.00% 5 Missing ⚠️
src/gui/DatabaseTabWidget.cpp 50.00% 5 Missing ⚠️
src/gui/MainWindow.cpp 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           develop   #12200   +/-   ##
========================================
  Coverage    64.37%   64.38%           
========================================
  Files          378      378           
  Lines        39840    39850   +10     
========================================
+ Hits         25646    25654    +8     
- Misses       14194    14196    +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@phoerious phoerious added the pr: ai-assisted Pull request contains significant contributions by generative AI label Jun 30, 2025
@droidmonkey droidmonkey added this to the v2.7.11 milestone Sep 10, 2025

@phoerious phoerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like this solution. If this is only about tab restoration at startup, I have a better solution: Return a bool in addDatabaseTab() whether adding the tab is successful. The value is passed through by MainWindow::openDatabase() and in MainWindow::restoreConfigState() all failed tabs will be retried once after a certain timeout.

Comment on lines +74 to +80
connect(&m_fileExistsTimer, &QTimer::timeout, this, [this] {
if (!QFile::exists(m_filename)) {
m_ui->messageWidget->showMessage(tr("The database file does not exist or is not accessible."),
MessageWidget::Warning,
fileExistsCheckInterval + 500);
}
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure whether I like this. It's a bit confusing if such a message suddenly pops up after an arbitrary time interval. Also, what happens in between when the user tries to unlock the non-existent file?
This also causes an unnecessary check after 5sec for every database. At least the timer should be stopped when the database is loaded correctly.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A file can become unavailable at any time after being successfully detected/loaded. If network share gets severed, etc.

Perhaps that check should be moved to the open sequence and refuse to open if the file cannot be read. Technically that already happens but deep in the database code with direct file access.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment above. That'd be my preferred solution.

// The file does not exist, revert back to the cleaned path for comparison
dbFilePath = QDir::toNativeSeparators(dbWidget->database()->filePath());
}
if (dbFilePath.compare(canonicalFilePath, FILE_CASE_SENSITIVE) == 0) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're potentially comparing canonicalised to non-canonicalised paths there. This could open a database twice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yah we do a poor job of file path handling and comparison throughout the code base. Qt doesn't make that any easier.

Copilot AI and others added 3 commits November 23, 2025 18:26
…available

Co-authored-by: droidmonkey <2809491+droidmonkey@users.noreply.github.com>
@droidmonkey

Copy link
Copy Markdown
Member

Will reimpmement at a later date

@droidmonkey droidmonkey removed this from the v2.7.11 milestone Nov 23, 2025
@Neiyk

Neiyk commented Mar 17, 2026

Copy link
Copy Markdown

Hello,

the implementation was removed from milestone v2.7.11 and sadly also not not reimplemented in v2.7.12

For which version a new reimplementation is foreseen?
Will a new pull request created for the reimplementation (including target version)?

@droidmonkey

Copy link
Copy Markdown
Member

Not anytime in the near future, this is deprioritized right now

@Neiyk

Neiyk commented Mar 23, 2026

Copy link
Copy Markdown

Not anytime in the near future, this is deprioritized right now

It is really sad to read this statement, because here are many use cases impacted by this request.

For example:

  • Keepass DB NAS synchronization
  • Open Keepass DB from network drive
  • Google Drive Synchronization
  • Network Drive mounting
  • VeraCrypt container opening/mounting
  • database is saved on any other mounted or portable drive
  • manual mounting of other partitions with Keepass DB

 
You can find these use cases also in the initial Issue Request and their duplicates:
#9539

linked Issue Tickets with different use cases (marked as duplicates):
#1834
#11546
#12032
#12959

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

Labels

pr: ai-assisted Pull request contains significant contributions by generative AI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Don't auto close database unlock if underlying file is unavailable

5 participants