Skip to content

Commit

Permalink
Update checking feature (#2648)
Browse files Browse the repository at this point in the history
* Check on startup (toggleable setting) and manually
* Option to check for pre-releases (eg, 2.4.0-beta1)
* Only included if WITH_XC_NETWORKING is enabled
  • Loading branch information
weslly authored and droidmonkey committed Jan 30, 2019
1 parent 5c9b062 commit 779b529
Show file tree
Hide file tree
Showing 17 changed files with 677 additions and 5 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ if(WITH_XC_ALL)
set(WITH_XC_YUBIKEY ON)
set(WITH_XC_SSHAGENT ON)
set(WITH_XC_KEESHARE ON)
if(APPLE)
set(WITH_XC_TOUCHID ON)
endif()
if(APPLE)
set(WITH_XC_TOUCHID ON)
endif()
endif()

if(WITH_XC_KEESHARE_SECURE)
Expand Down
2 changes: 0 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,7 @@ These steps place the compiled KeePassXC binary inside the `./build/src/` direct
-DWITH_XC_KEESHARE=[ON|OFF] Enable/Disable KeeShare group syncronization extension (default: OFF)
-DWITH_XC_TOUCHID=[ON|OFF] (macOS Only) Enable/Disable Touch ID unlock (default:OFF)
-DWITH_XC_ALL=[ON|OFF] Enable/Disable compiling all plugins above (default: OFF)
-DWITH_XC_KEESHARE_SECURE=[ON|OFF] Enable/Disable KeeShare secure containers, requires libquazip5 (default: OFF)
-DWITH_TESTS=[ON|OFF] Enable/Disable building of unit tests (default: ON)
-DWITH_GUI_TESTS=[ON|OFF] Enable/Disable building of GUI tests (default: OFF)
-DWITH_DEV_BUILD=[ON|OFF] Enable/Disable deprecated method warnings (default: OFF)
Expand Down
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ else()
list(APPEND keepassx_SOURCES keys/drivers/YubiKey.h keys/drivers/YubiKeyStub.cpp)
endif()

if(WITH_XC_NETWORKING)
list(APPEND keepassx_SOURCES updatecheck/UpdateChecker.cpp gui/UpdateCheckDialog.cpp)
endif()

if(WITH_XC_TOUCHID)
list(APPEND keepassx_SOURCES touchid/TouchID.mm)
endif()
Expand Down
5 changes: 5 additions & 0 deletions src/gui/ApplicationSettingsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent)
// clang-format on

#ifndef WITH_XC_NETWORKING
m_generalUi->checkForUpdatesOnStartupCheckBox->setVisible(false);
m_secUi->privacy->setVisible(false);
#endif

Expand Down Expand Up @@ -174,6 +175,8 @@ void ApplicationSettingsWidget::loadSettings()
m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get("GUI/MinimizeToTray").toBool());
m_generalUi->minimizeOnCloseCheckBox->setChecked(config()->get("GUI/MinimizeOnClose").toBool());
m_generalUi->systrayMinimizeOnStartup->setChecked(config()->get("GUI/MinimizeOnStartup").toBool());
m_generalUi->checkForUpdatesOnStartupCheckBox->setChecked(config()->get("GUI/CheckForUpdates").toBool());
m_generalUi->checkForUpdatesIncludeBetasCheckBox->setChecked(config()->get("GUI/CheckForUpdatesIncludeBetas").toBool());
m_generalUi->autoTypeAskCheckBox->setChecked(config()->get("security/autotypeask").toBool());

if (autoType()->isAvailable()) {
Expand Down Expand Up @@ -256,6 +259,8 @@ void ApplicationSettingsWidget::saveSettings()
config()->set("GUI/MinimizeToTray", m_generalUi->systrayMinimizeToTrayCheckBox->isChecked());
config()->set("GUI/MinimizeOnClose", m_generalUi->minimizeOnCloseCheckBox->isChecked());
config()->set("GUI/MinimizeOnStartup", m_generalUi->systrayMinimizeOnStartup->isChecked());
config()->set("GUI/CheckForUpdates", m_generalUi->checkForUpdatesOnStartupCheckBox->isChecked());
config()->set("GUI/CheckForUpdatesIncludeBetas", m_generalUi->checkForUpdatesIncludeBetasCheckBox->isChecked());

config()->set("security/autotypeask", m_generalUi->autoTypeAskCheckBox->isChecked());

Expand Down
14 changes: 14 additions & 0 deletions src/gui/ApplicationSettingsWidgetGeneral.ui
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkForUpdatesOnStartupCheckBox">
<property name="text">
<string>Check for updates at application startup</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -179,6 +186,13 @@
<string>General</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QCheckBox" name="checkForUpdatesIncludeBetasCheckBox">
<property name="text">
<string>Include pre-releases when checking for updates</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="toolbarHideCheckBox">
<property name="text">
Expand Down
58 changes: 58 additions & 0 deletions src/gui/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
#include "keys/FileKey.h"
#include "keys/PasswordKey.h"

#ifdef WITH_XC_NETWORKING
#include "updatecheck/UpdateChecker.h"
#include "gui/MessageBox.h"
#include "gui/UpdateCheckDialog.h"
#endif

#ifdef WITH_XC_SSHAGENT
#include "sshagent/AgentSettingsPage.h"
#include "sshagent/SSHAgent.h"
Expand Down Expand Up @@ -282,6 +288,7 @@ MainWindow::MainWindow()
m_ui->actionPasswordGenerator->setIcon(filePath()->icon("actions", "password-generator"));

m_ui->actionAbout->setIcon(filePath()->icon("actions", "help-about"));
m_ui->actionCheckForUpdates->setIcon(filePath()->icon("actions", "system-software-update"));

m_actionMultiplexer.connect(
SIGNAL(currentModeChanged(DatabaseWidget::Mode)), this, SLOT(setMenuActionState(DatabaseWidget::Mode)));
Expand Down Expand Up @@ -364,6 +371,15 @@ MainWindow::MainWindow()
#ifdef Q_OS_MACOS
setUnifiedTitleAndToolBarOnMac(true);
#endif

#ifdef WITH_XC_NETWORKING
connect(m_ui->actionCheckForUpdates, SIGNAL(triggered()), SLOT(showUpdateCheckDialog()));
connect(UpdateChecker::instance(), SIGNAL(updateCheckFinished(bool, QString, bool)), SLOT(hasUpdateAvailable(bool, QString, bool)));
QTimer::singleShot(3000, this, SLOT(showUpdateCheckStartup()));
#else
m_ui->actionCheckForUpdates->setVisible(false);
#endif

// clang-format off
connect(m_ui->tabWidget,
SIGNAL(messageGlobal(QString,MessageWidget::MessageType)),
Expand Down Expand Up @@ -661,6 +677,48 @@ void MainWindow::showAboutDialog()
aboutDialog->open();
}

void MainWindow::showUpdateCheckStartup()
{
#ifdef WITH_XC_NETWORKING
if (!config()->get("UpdateCheckMessageShown", false).toBool()) {
auto result = MessageBox::question(this,
tr("Check for updates on startup?"),
tr("Would you like KeePassXC to check for updates on startup?") + "\n\n" +
tr("You can always check for updates manually from the application menu."),
MessageBox::Yes | MessageBox::No,
MessageBox::Yes);

config()->set("GUI/CheckForUpdates", (result == MessageBox::Yes));
config()->set("UpdateCheckMessageShown", true);
}

if (config()->get("GUI/CheckForUpdates", false).toBool()) {
updateCheck()->checkForUpdates(false);
}

#endif
}

void MainWindow::hasUpdateAvailable(bool hasUpdate, const QString& version, bool isManuallyRequested)
{
#ifdef WITH_XC_NETWORKING
if (hasUpdate && !isManuallyRequested) {
auto* updateCheckDialog = new UpdateCheckDialog(this);
updateCheckDialog->showUpdateCheckResponse(hasUpdate, version);
updateCheckDialog->show();
}
#endif
}

void MainWindow::showUpdateCheckDialog()
{
#ifdef WITH_XC_NETWORKING
updateCheck()->checkForUpdates(true);
auto* updateCheckDialog = new UpdateCheckDialog(this);
updateCheckDialog->show();
#endif
}

void MainWindow::openDonateUrl()
{
QDesktopServices::openUrl(QUrl("https://keepassxc.org/donate"));
Expand Down
3 changes: 3 additions & 0 deletions src/gui/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ private slots:
void setMenuActionState(DatabaseWidget::Mode mode = DatabaseWidget::Mode::None);
void updateWindowTitle();
void showAboutDialog();
void showUpdateCheckStartup();
void showUpdateCheckDialog();
void hasUpdateAvailable(bool hasUpdate, const QString& version, bool isManuallyRequested);
void openDonateUrl();
void openBugReportUrl();
void switchToDatabases();
Expand Down
9 changes: 9 additions & 0 deletions src/gui/MainWindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@
<string>&amp;Help</string>
</property>
<addaction name="actionAbout"/>
<addaction name="actionCheckForUpdates"/>
<addaction name="actionDonate"/>
<addaction name="actionBugReport"/>
</widget>
Expand Down Expand Up @@ -348,6 +349,14 @@
<enum>QAction::AboutRole</enum>
</property>
</action>
<action name="actionCheckForUpdates">
<property name="text">
<string>Check for Updates...</string>
</property>
<property name="menuRole">
<enum>QAction::ApplicationSpecificRole</enum>
</property>
</action>
<action name="actionDatabaseOpen">
<property name="text">
<string>&amp;Open database...</string>
Expand Down
68 changes: 68 additions & 0 deletions src/gui/UpdateCheckDialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "UpdateCheckDialog.h"
#include "ui_UpdateCheckDialog.h"
#include "updatecheck/UpdateChecker.h"
#include "core/FilePath.h"

UpdateCheckDialog::UpdateCheckDialog(QWidget* parent)
: QDialog(parent)
, m_ui(new Ui::UpdateCheckDialog())
{
m_ui->setupUi(this);
setWindowFlags(Qt::Window);
setAttribute(Qt::WA_DeleteOnClose);

m_ui->iconLabel->setPixmap(filePath()->applicationIcon().pixmap(48));

connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close()));
connect(UpdateChecker::instance(), SIGNAL(updateCheckFinished(bool, QString, bool)), SLOT(showUpdateCheckResponse(bool, QString)));
}

void UpdateCheckDialog::showUpdateCheckResponse(bool status, const QString& version) {
m_ui->progressBar->setVisible(false);
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("Close"));

if (version == QString("error")) {
setWindowTitle(tr("Update Error!"));

m_ui->statusLabel->setText(
"<strong>" + tr("Update Error!") + "</strong><br><br>" +
tr("An error occurred in retrieving update information.") + "<br>" +
tr("Please try again later."));
return;
}

if (status) {
setWindowTitle(tr("Software Update"));
m_ui->statusLabel->setText(
"<strong>" + tr("A new version of KeePassXC is available!") + "</strong><br><br>" +
tr("KeePassXC %1 is now available — you have %2.").arg(version, KEEPASSXC_VERSION) + "<br><br>" +
"<a href='https://keepassxc.org/download/'>" +
tr("Download it at keepassxc.org") +
"</a>");
} else {
setWindowTitle(tr("You're up-to-date!"));
m_ui->statusLabel->setText(tr(
"KeePassXC %1 is currently the newest version available").arg(KEEPASSXC_VERSION));
}
}

UpdateCheckDialog::~UpdateCheckDialog()
{
}
50 changes: 50 additions & 0 deletions src/gui/UpdateCheckDialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef KEEPASSXC_UPDATECHECKDIALOG_H
#define KEEPASSXC_UPDATECHECKDIALOG_H

#include <QUrl>
#include <QDialog>
#include <QScopedPointer>
#include "gui/MessageBox.h"
#include "config-keepassx.h"
#include "core/Global.h"
#include "updatecheck/UpdateChecker.h"

namespace Ui
{
class UpdateCheckDialog;
}

class UpdateCheckDialog : public QDialog
{
Q_OBJECT

public:
explicit UpdateCheckDialog(QWidget* parent = nullptr);
~UpdateCheckDialog() override;

public slots:
void showUpdateCheckResponse(bool status, const QString& version);

private:
QScopedPointer<Ui::UpdateCheckDialog> m_ui;
};


#endif //KEEPASSXC_UPDATECHECKDIALOG_H
Loading

0 comments on commit 779b529

Please sign in to comment.