Merge remote-tracking branch 'origin/master' into develop

This commit is contained in:
Jonathan White 2017-06-25 20:23:05 -04:00
commit 0f2f6621b5
No known key found for this signature in database
GPG Key ID: 440FC65F2E0C6E01
36 changed files with 26585 additions and 4852 deletions

View File

@ -1,3 +1,36 @@
2.2.0 (2017-06-23)
=========================
- Added YubiKey 2FA integration for unlocking databases [#127]
- Added TOTP support [#519]
- Added CSV import tool [#146, #490]
- Added KeePassXC CLI tool [#254]
- Added diceware password generator [#373]
- Added support for entry references [#370, #378]
- Added support for Twofish encryption [#167]
- Enabled DEP and ASLR for in-memory protection [#371]
- Enabled single instance mode [#510]
- Enabled portable mode [#645]
- Enabled database lock on screensaver and session lock [#545]
- Redesigned welcome screen with common features and recent databases [#292]
- Multiple updates to search behavior [#168, #213, #374, #471, #603, #654]
- Added auto-type fields {CLEARFIELD}, {SPACE}, {{}, {}} [#267, #427, #480]
- Fixed auto-type errors on Linux [#550]
- Prompt user prior to executing a cmd:// URL [#235]
- Entry attributes can be protected (hidden) [#220]
- Added extended ascii to password generator [#538]
- Added new database icon to toolbar [#289]
- Added context menu entry to empty recycle bin in databases [#520]
- Added "apply" button to entry and group edit windows [#624]
- Added macOS tray icon and enabled minimize on close [#583]
- Fixed issues with unclean shutdowns [#170, #580]
- Changed keyboard shortcut to create new database to CTRL+SHIFT+N [#515]
- Compare window title to entry URLs [#556]
- Implemented inline error messages [#162]
- Ignore group expansion and other minor changes when making database "dirty" [#464]
- Updated license and copyright information on souce files [#632]
- Added contributors list to about dialog [#629]
2.1.4 (2017-04-09) 2.1.4 (2017-04-09)
========================= =========================

View File

@ -48,8 +48,8 @@ option(WITH_XC_YUBIKEY "Include YubiKey support." OFF)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
set(KEEPASSXC_VERSION_MAJOR "2") set(KEEPASSXC_VERSION_MAJOR "2")
set(KEEPASSXC_VERSION_MINOR "1") set(KEEPASSXC_VERSION_MINOR "2")
set(KEEPASSXC_VERSION_PATCH "4") set(KEEPASSXC_VERSION_PATCH "0")
set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION_MAJOR}.${KEEPASSXC_VERSION_MINOR}.${KEEPASSXC_VERSION_PATCH}") set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION_MAJOR}.${KEEPASSXC_VERSION_MINOR}.${KEEPASSXC_VERSION_PATCH}")
if("${CMAKE_C_COMPILER}" MATCHES "clang$" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") if("${CMAKE_C_COMPILER}" MATCHES "clang$" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")

57
share/keepassxc.ini Normal file
View File

@ -0,0 +1,57 @@
[General]
ShowToolbar=true
RememberLastDatabases=true
RememberLastKeyFiles=true
OpenPreviousDatabasesOnStartup=true
AutoSaveAfterEveryChange=false
AutoSaveOnExit=false
AutoReloadOnChange=true
MinimizeOnCopy=false
UseGroupIconOnEntryCreation=true
IgnoreGroupExpansion=false
AutoTypeEntryTitleMatch=true
GlobalAutoTypeKey=0
GlobalAutoTypeModifiers=0
LastOpenedDatabases=@Invalid()
[GUI]
Language=system
ShowTrayIcon=false
MinimizeToTray=false
MinimizeOnClose=false
MinimizeOnStartup=false
MainWindowGeometry="@ByteArray(\x1\xd9\xd0\xcb\0\x2\0\0\0\0\x2(\0\0\0\xbd\0\0\x5W\0\0\x3;\0\0\x2\x30\0\0\0\xdc\0\0\x5O\0\0\x3\x33\0\0\0\0\0\0\0\0\a\x80)"
SplitterState=@Invalid()
EntryListColumnSizes=@Invalid()
EntrySearchColumnSizes=@Invalid()
[security]
autotypeask=true
clearclipboard=true
clearclipboardtimeout=10
lockdatabaseidle=false
lockdatabaseidlesec=240
lockdatabaseminimize=false
lockdatabasescreenlock=true
passwordscleartext=false
passwordsrepeat=false
[Http]
Enabled=false
ShowNotification=true
BestMatchOnly=false
UnlockDatabase=true
MatchUrlScheme=true
SortByUsername=false
Port=19455
AlwaysAllowAccess=false
AlwaysAllowUpdate=false
SearchInAllDatabases=false
SupportKphFields=true
generator\LowerCase=true
generator\UpperCase=true
generator\Numbers=true
generator\SpecialChars=false
generator\ExcludeAlike=true
generator\EnsureEvery=true
generator\Length=16

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,4 +14,4 @@ tx push -s
echo echo
echo Pulling translations from Transifex echo Pulling translations from Transifex
tx pull -a --minimum-perc=80 tx pull -af --minimum-perc=40

View File

@ -1,5 +1,5 @@
name: keepassxc name: keepassxc
version: 2.1.4 version: 2.2.0
grade: stable grade: stable
summary: community driven port of the windows application “Keepass Password Safe” summary: community driven port of the windows application “Keepass Password Safe”
description: | description: |
@ -22,6 +22,7 @@ parts:
- -DWITH_TESTS=OFF - -DWITH_TESTS=OFF
- -DWITH_XC_AUTOTYPE=ON - -DWITH_XC_AUTOTYPE=ON
- -DWITH_XC_HTTP=ON - -DWITH_XC_HTTP=ON
- -DWITH_XC_YUBIKEY=ON
build-packages: build-packages:
- g++ - g++
- libgcrypt20-dev - libgcrypt20-dev
@ -32,4 +33,18 @@ parts:
- zlib1g-dev - zlib1g-dev
- libxi-dev - libxi-dev
- libxtst-dev - libxtst-dev
- libyubikey-dev
- libykpers-1-dev
after: [desktop-qt5] after: [desktop-qt5]
desktop-qt5:
# Redefine stage packages to work with Ubuntu 17.04
stage-packages:
- libxkbcommon0
- ttf-ubuntu-font-family
- dmz-cursor-theme
- light-themes
- shared-mime-info
- libqt5gui5
- libgdk-pixbuf2.0-0
- libqt5svg5 # for loading icon themes which are svg
- locales-all

View File

@ -290,7 +290,12 @@ if(APPLE AND WITH_APP_BUNDLE)
endif() endif()
if(MINGW) if(MINGW)
string(REPLACE "AMD" "Win" OUTPUT_FILE_POSTFIX "${CMAKE_HOST_SYSTEM_PROCESSOR}") if(${CMAKE_SIZEOF_VOID_P} EQUAL "8")
set(OUTPUT_FILE_POSTFIX "Win64")
else()
set(OUTPUT_FILE_POSTFIX "Win32")
endif()
set(CPACK_GENERATOR "ZIP;NSIS") set(CPACK_GENERATOR "ZIP;NSIS")
set(CPACK_STRIP_FILES ON) set(CPACK_STRIP_FILES ON)
set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSXC_VERSION}-${OUTPUT_FILE_POSTFIX}") set(CPACK_PACKAGE_FILE_NAME "${PROGNAME}-${KEEPASSXC_VERSION}-${OUTPUT_FILE_POSTFIX}")
@ -299,6 +304,7 @@ if(MINGW)
set(CPACK_PACKAGE_VENDOR "${PROGNAME} Team") set(CPACK_PACKAGE_VENDOR "${PROGNAME} Team")
string(REGEX REPLACE "/" "\\\\\\\\" CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/share/windows/installer-header.bmp") string(REGEX REPLACE "/" "\\\\\\\\" CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/share/windows/installer-header.bmp")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.GPL-2") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.GPL-2")
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/share/windows/keepassxc.ico") set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/share/windows/keepassxc.ico")
set(CPACK_NSIS_MUI_UNIICON "${CPACK_NSIS_MUI_ICON}") set(CPACK_NSIS_MUI_UNIICON "${CPACK_NSIS_MUI_ICON}")
set(CPACK_NSIS_INSTALLED_ICON_NAME "\\\\${PROGNAME}.exe") set(CPACK_NSIS_INSTALLED_ICON_NAME "\\\\${PROGNAME}.exe")
@ -307,6 +313,7 @@ if(MINGW)
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${PROGNAME}.lnk' '$INSTDIR\\\\${PROGNAME}.exe'") set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${PROGNAME}.lnk' '$INSTDIR\\\\${PROGNAME}.exe'")
set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\${PROGNAME}.lnk'") set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\${PROGNAME}.lnk'")
set(CPACK_NSIS_URL_INFO_ABOUT "https://keepassxc.org") set(CPACK_NSIS_URL_INFO_ABOUT "https://keepassxc.org")
set(CPACK_NSIS_DISPLAY_NAME ${PROGNAME})
set(CPACK_NSIS_PACKAGE_NAME "${PROGNAME} v${KEEPASSXC_VERSION}") set(CPACK_NSIS_PACKAGE_NAME "${PROGNAME} v${KEEPASSXC_VERSION}")
set(CPACK_NSIS_MUI_FINISHPAGE_RUN "../${PROGNAME}.exe") set(CPACK_NSIS_MUI_FINISHPAGE_RUN "../${PROGNAME}.exe")
include(CPack) include(CPack)

View File

@ -114,6 +114,7 @@ void Config::init(const QString& fileName)
m_defaults.insert("AutoReloadOnChange", true); m_defaults.insert("AutoReloadOnChange", true);
m_defaults.insert("AutoSaveOnExit", false); m_defaults.insert("AutoSaveOnExit", false);
m_defaults.insert("ShowToolbar", true); m_defaults.insert("ShowToolbar", true);
m_defaults.insert("SearchLimitGroup", false);
m_defaults.insert("MinimizeOnCopy", false); m_defaults.insert("MinimizeOnCopy", false);
m_defaults.insert("UseGroupIconOnEntryCreation", false); m_defaults.insert("UseGroupIconOnEntryCreation", false);
m_defaults.insert("AutoTypeEntryTitleMatch", true); m_defaults.insert("AutoTypeEntryTitleMatch", true);

View File

@ -187,6 +187,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
m_ignoreAutoReload = false; m_ignoreAutoReload = false;
m_searchCaseSensitive = false; m_searchCaseSensitive = false;
m_searchLimitGroup = config()->get("SearchLimitGroup", false).toBool();
setCurrentWidget(m_mainWidget); setCurrentWidget(m_mainWidget);
} }
@ -964,7 +965,9 @@ void DatabaseWidget::search(const QString& searchtext)
Qt::CaseSensitivity caseSensitive = m_searchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; Qt::CaseSensitivity caseSensitive = m_searchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
QList<Entry*> searchResult = EntrySearcher().search(searchtext, currentGroup(), caseSensitive); Group* searchGroup = m_searchLimitGroup ? currentGroup() : m_db->rootGroup();
QList<Entry*> searchResult = EntrySearcher().search(searchtext, searchGroup, caseSensitive);
m_entryView->setEntryList(searchResult); m_entryView->setEntryList(searchResult);
m_lastSearchText = searchtext; m_lastSearchText = searchtext;
@ -988,6 +991,12 @@ void DatabaseWidget::setSearchCaseSensitive(bool state)
refreshSearch(); refreshSearch();
} }
void DatabaseWidget::setSearchLimitGroup(bool state)
{
m_searchLimitGroup = state;
refreshSearch();
}
void DatabaseWidget::onGroupChanged(Group* group) void DatabaseWidget::onGroupChanged(Group* group)
{ {
// Intercept group changes if in search mode // Intercept group changes if in search mode

View File

@ -163,6 +163,7 @@ public slots:
// Search related slots // Search related slots
void search(const QString& searchtext); void search(const QString& searchtext);
void setSearchCaseSensitive(bool state); void setSearchCaseSensitive(bool state);
void setSearchLimitGroup(bool state);
void endSearch(); void endSearch();
void showMessage(const QString& text, MessageWidget::MessageType type); void showMessage(const QString& text, MessageWidget::MessageType type);
@ -221,6 +222,7 @@ private:
// Search state // Search state
QString m_lastSearchText; QString m_lastSearchText;
bool m_searchCaseSensitive; bool m_searchCaseSensitive;
bool m_searchLimitGroup;
// Autoreload // Autoreload
QFileSystemWatcher m_fileWatcher; QFileSystemWatcher m_fileWatcher;

View File

@ -24,6 +24,7 @@
#include <QShortcut> #include <QShortcut>
#include <QToolButton> #include <QToolButton>
#include "core/Config.h"
#include "core/FilePath.h" #include "core/FilePath.h"
SearchWidget::SearchWidget(QWidget* parent) SearchWidget::SearchWidget(QWidget* parent)
@ -50,6 +51,11 @@ SearchWidget::SearchWidget(QWidget* parent)
m_actionCaseSensitive->setObjectName("actionSearchCaseSensitive"); m_actionCaseSensitive->setObjectName("actionSearchCaseSensitive");
m_actionCaseSensitive->setCheckable(true); m_actionCaseSensitive->setCheckable(true);
m_actionLimitGroup = searchMenu->addAction(tr("Limit search to selected group"), this, SLOT(updateLimitGroup()));
m_actionLimitGroup->setObjectName("actionSearchLimitGroup");
m_actionLimitGroup->setCheckable(true);
m_actionLimitGroup->setChecked(config()->get("SearchLimitGroup", false).toBool());
m_ui->searchIcon->setIcon(filePath()->icon("actions", "system-search")); m_ui->searchIcon->setIcon(filePath()->icon("actions", "system-search"));
m_ui->searchIcon->setMenu(searchMenu); m_ui->searchIcon->setMenu(searchMenu);
m_ui->searchEdit->addAction(m_ui->searchIcon, QLineEdit::LeadingPosition); m_ui->searchEdit->addAction(m_ui->searchIcon, QLineEdit::LeadingPosition);
@ -102,6 +108,7 @@ void SearchWidget::connectSignals(SignalMultiplexer& mx)
{ {
mx.connect(this, SIGNAL(search(QString)), SLOT(search(QString))); mx.connect(this, SIGNAL(search(QString)), SLOT(search(QString)));
mx.connect(this, SIGNAL(caseSensitiveChanged(bool)), SLOT(setSearchCaseSensitive(bool))); mx.connect(this, SIGNAL(caseSensitiveChanged(bool)), SLOT(setSearchCaseSensitive(bool)));
mx.connect(this, SIGNAL(limitGroupChanged(bool)), SLOT(setSearchLimitGroup(bool)));
mx.connect(this, SIGNAL(copyPressed()), SLOT(copyPassword())); mx.connect(this, SIGNAL(copyPressed()), SLOT(copyPassword()));
mx.connect(this, SIGNAL(downPressed()), SLOT(setFocus())); mx.connect(this, SIGNAL(downPressed()), SLOT(setFocus()));
mx.connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(switchToEntryEdit())); mx.connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(switchToEntryEdit()));
@ -115,6 +122,7 @@ void SearchWidget::databaseChanged(DatabaseWidget* dbWidget)
// Enforce search policy // Enforce search policy
emit caseSensitiveChanged(m_actionCaseSensitive->isChecked()); emit caseSensitiveChanged(m_actionCaseSensitive->isChecked());
emit limitGroupChanged(m_actionLimitGroup->isChecked());
} else { } else {
m_ui->searchEdit->clear(); m_ui->searchEdit->clear();
} }
@ -151,6 +159,19 @@ void SearchWidget::setCaseSensitive(bool state)
updateCaseSensitive(); updateCaseSensitive();
} }
void SearchWidget::updateLimitGroup()
{
config()->set("SearchLimitGroup", m_actionLimitGroup->isChecked());
emit limitGroupChanged(m_actionLimitGroup->isChecked());
}
void SearchWidget::setLimitGroup(bool state)
{
m_actionLimitGroup->setChecked(state);
updateLimitGroup();
}
void SearchWidget::searchFocus() void SearchWidget::searchFocus()
{ {
m_ui->searchEdit->setFocus(); m_ui->searchEdit->setFocus();

View File

@ -39,6 +39,7 @@ public:
void connectSignals(SignalMultiplexer& mx); void connectSignals(SignalMultiplexer& mx);
void setCaseSensitive(bool state); void setCaseSensitive(bool state);
void setLimitGroup(bool state);
protected: protected:
bool eventFilter(QObject* obj, QEvent* event); bool eventFilter(QObject* obj, QEvent* event);
@ -46,6 +47,7 @@ protected:
signals: signals:
void search(const QString& text); void search(const QString& text);
void caseSensitiveChanged(bool state); void caseSensitiveChanged(bool state);
void limitGroupChanged(bool state);
void escapePressed(); void escapePressed();
void copyPressed(); void copyPressed();
void downPressed(); void downPressed();
@ -58,12 +60,14 @@ private slots:
void startSearchTimer(); void startSearchTimer();
void startSearch(); void startSearch();
void updateCaseSensitive(); void updateCaseSensitive();
void updateLimitGroup();
void searchFocus(); void searchFocus();
private: private:
const QScopedPointer<Ui::SearchWidget> m_ui; const QScopedPointer<Ui::SearchWidget> m_ui;
QTimer* m_searchTimer; QTimer* m_searchTimer;
QAction* m_actionCaseSensitive; QAction* m_actionCaseSensitive;
QAction* m_actionLimitGroup;
Q_DISABLE_COPY(SearchWidget) Q_DISABLE_COPY(SearchWidget)
}; };

View File

@ -577,7 +577,12 @@ void TestGui::testSearch()
QModelIndex rootGroupIndex = groupView->model()->index(0, 0); QModelIndex rootGroupIndex = groupView->model()->index(0, 0);
clickIndex(groupView->model()->index(0, 0, rootGroupIndex), groupView, Qt::LeftButton); clickIndex(groupView->model()->index(0, 0, rootGroupIndex), groupView, Qt::LeftButton);
QCOMPARE(groupView->currentGroup()->name(), QString("General")); QCOMPARE(groupView->currentGroup()->name(), QString("General"));
searchWidget->setLimitGroup(false);
QTRY_COMPARE(entryView->model()->rowCount(), 2);
searchWidget->setLimitGroup(true);
QTRY_COMPARE(entryView->model()->rowCount(), 0); QTRY_COMPARE(entryView->model()->rowCount(), 0);
// reset // reset
clickIndex(rootGroupIndex, groupView, Qt::LeftButton); clickIndex(rootGroupIndex, groupView, Qt::LeftButton);
QCOMPARE(groupView->currentGroup(), m_db->rootGroup()); QCOMPARE(groupView->currentGroup(), m_db->rootGroup());