Merge branch 'master' into develop

This commit is contained in:
Janek Bevendorff 2019-10-26 21:36:13 +02:00
commit 9b5a46f4b0
No known key found for this signature in database
GPG Key ID: 2FDEB0D40BCA5E11
68 changed files with 66306 additions and 16395 deletions

View File

@ -1,73 +1,131 @@
# Changelog
## 2.5.0 (2019-07-05)
## 2.5.0 (2019-10-26)
### Added
- Group sorting feature [#3282](https://github.com/keepassxreboot/keepassxc/issues/3282)
- CLI: Add 'flatten' option to the 'ls' command [#3276](https://github.com/keepassxreboot/keepassxc/issues/3276)
- CLI: Add password generation options to `Add` and `Edit` commands [#3275](https://github.com/keepassxreboot/keepassxc/issues/3275)
- CLI: Add CSV export to the 'export' command [#3277]
- CLI: Add `-y --yubikey` option for YubiKey [#3416](https://github.com/keepassxreboot/keepassxc/issues/3416)
- Add 'Monospaced font' option to the Notes field [#3321](https://github.com/keepassxreboot/keepassxc/issues/3321)
- CLI: Add group commands (mv, mkdir and rmdir) [#3313].
- CLI: Add interactive shell mode command `open` [#3224](https://github.com/keepassxreboot/keepassxc/issues/3224)
- Add "Paper Backup" aka "Export to HTML file" to the "Database" menu [#3277](https://github.com/keepassxreboot/keepassxc/pull/3277)
- Add statistics panel with information about the database (number of entries, number of unique passwords, etc.) to the Database Settings dialog [#2034](https://github.com/keepassxreboot/keepassxc/issues/2034)
- Add 'Paper Backup' aka 'Export to HTML file' to the 'Database' menu [[#3277](https://github.com/keepassxreboot/keepassxc/pull/3277)]
- Add statistics panel with information about the database (number of entries, number of unique passwords, etc.) to the Database Settings dialog [[#2034](https://github.com/keepassxreboot/keepassxc/issues/2034)]
- Add offline user manual accessible via the 'Help' menu [[#3274](https://github.com/keepassxreboot/keepassxc/issues/3274)]
- Add support for importing 1Password OpVault files [[#2292](https://github.com/keepassxreboot/keepassxc/issues/2292)]
- Implement Freedesktop.org secret storage DBus protocol so that KeePassXC can be used as a vault service by libsecret [[#2726](https://github.com/keepassxreboot/keepassxc/issues/2726)]
- Add support for OnlyKey as an alternative to YubiKeys (requires yubikey-personalization >= 1.20.0) [[#3352](https://github.com/keepassxreboot/keepassxc/issues/3352)]
- Add group sorting feature [[#3282](https://github.com/keepassxreboot/keepassxc/issues/3282)]
- Add feature to download favicons for all entries at once [[#3169](https://github.com/keepassxreboot/keepassxc/issues/3169)]
- Add word case option to passphrase generator [[#3172](https://github.com/keepassxreboot/keepassxc/issues/3172)]
- Add support for RFC6238-compliant TOTP hashes [[#2972](https://github.com/keepassxreboot/keepassxc/issues/2972)]
- Add UNIX man page for main program [[#3665](https://github.com/keepassxreboot/keepassxc/issues/3665)]
- Add 'Monospaced font' option to the notes field [[#3321](https://github.com/keepassxreboot/keepassxc/issues/3321)]
- Add support for key files in auto open [[#3504](https://github.com/keepassxreboot/keepassxc/issues/3504)]
- Add search field for filtering entries in Auto-Type dialog [[#2955](https://github.com/keepassxreboot/keepassxc/issues/2955)]
- Complete usernames based on known usernames from other entries [[#3300](https://github.com/keepassxreboot/keepassxc/issues/3300)]
- Parse hyperlinks in the notes field of the entry preview pane [[#3596](https://github.com/keepassxreboot/keepassxc/issues/3596)]
- Allow abbreviation of field names in entry search [[#3440](https://github.com/keepassxreboot/keepassxc/issues/3440)]
- Allow setting group icons recursively [[#3273](https://github.com/keepassxreboot/keepassxc/issues/3273)]
- Add copy context menu for username and password in Auto-Type dialog [[#3038](https://github.com/keepassxreboot/keepassxc/issues/3038)]
- Drop to background after copying a password to the clipboard [[#3253](https://github.com/keepassxreboot/keepassxc/issues/3253)]
- Add 'Lock databases' entry to tray icon menu [[#2896](https://github.com/keepassxreboot/keepassxc/issues/2896)]
- Add option to minimize window after unlocking [[#3439](https://github.com/keepassxreboot/keepassxc/issues/3439)]
- Add option to minimize window after opening a URL [[#3302](https://github.com/keepassxreboot/keepassxc/issues/3302)]
- Request accessibility permissions for Auto-Type on macOS [[#3624](https://github.com/keepassxreboot/keepassxc/issues/3624)]
- Browser: Add initial support for multiple URLs [[#3558](https://github.com/keepassxreboot/keepassxc/issues/3558)]
- Browser: Add entry-specific browser integration settings [[#3444](https://github.com/keepassxreboot/keepassxc/issues/3444)]
- CLI: Add offline HIBP checker (requires a downloaded HIBP dump) [[#2707](https://github.com/keepassxreboot/keepassxc/issues/2707)]
- CLI: Add 'flatten' option to the 'ls' command [[#3276](https://github.com/keepassxreboot/keepassxc/issues/3276)]
- CLI: Add password generation options to `Add` and `Edit` commands [[#3275](https://github.com/keepassxreboot/keepassxc/issues/3275)]
- CLI: Add XML import [[#3572](https://github.com/keepassxreboot/keepassxc/issues/3572)]
- CLI: Add CSV export to the 'export' command [[#3278](https://github.com/keepassxreboot/keepassxc/issues/3278)]
- CLI: Add `-y --yubikey` option for YubiKey [[#3416](https://github.com/keepassxreboot/keepassxc/issues/3416)]
- CLI: Add `--dry-run` option for merging databases [[#3254](https://github.com/keepassxreboot/keepassxc/issues/3254)]
- CLI: Add group commands (mv, mkdir and rmdir) [[#3313](https://github.com/keepassxreboot/keepassxc/issues/3313)].
- CLI: Add interactive shell mode command `open` [[#3224](https://github.com/keepassxreboot/keepassxc/issues/3224)]
### Changed
- CLI: The password length option `-l` for the CLI commands
`Add` and `Edit` is now `-L` [#3275](https://github.com/keepassxreboot/keepassxc/issues/3275)
- CLI: the `-u` shorthand for the `--upper` password generation option has been renamed `-U` [#3275](https://github.com/keepassxreboot/keepassxc/issues/3275)
- CLI: Renamed command `extract` -> `export`. [#3277]
- Rework the Entry Preview panel [#3306](https://github.com/keepassxreboot/keepassxc/issues/3306)
- Move notes to General tab on Group Preview Panel [#3336](https://github.com/keepassxreboot/keepassxc/issues/3336)
- Drop to background when copy feature [#3253](https://github.com/keepassxreboot/keepassxc/issues/3253)
- Redesign database unlock dialog [ [#3287](https://github.com/keepassxreboot/keepassxc/issues/3287)]
- Rework the entry preview panel [ [#3306](https://github.com/keepassxreboot/keepassxc/issues/3306)]
- Move notes to General tab on Group Preview Panel [[#3336](https://github.com/keepassxreboot/keepassxc/issues/3336)]
- Enable entry actions when editing an entry and cleanup entry context menu [[#3641](https://github.com/keepassxreboot/keepassxc/issues/3641)]
- Improve detection of external database changes [[#2389](https://github.com/keepassxreboot/keepassxc/issues/2389)]
- Warn if user is trying to use a KDBX file as a key file [[#3625](https://github.com/keepassxreboot/keepassxc/issues/3625)]
- Add option to disable KeePassHTTP settings migrations prompt [[#3349](https://github.com/keepassxreboot/keepassxc/issues/3349), [#3344](https://github.com/keepassxreboot/keepassxc/issues/3344)]
- Re-enabled Wayland support (no Auto-Type yet) [[#3520](https://github.com/keepassxreboot/keepassxc/issues/3520), [#3341](https://github.com/keepassxreboot/keepassxc/issues/3341)]
- Add icon to 'Toggle Window' action in tray icon menu [[3244](https://github.com/keepassxreboot/keepassxc/issues/3244)]
- Merge custom data between databases only when necessary [[#3475](https://github.com/keepassxreboot/keepassxc/issues/3475)]
- Improve various file-handling related issues when picking files using the system's file dialog [[#3473](https://github.com/keepassxreboot/keepassxc/issues/3473)]
- Add 'New Entry' context menu when no entries are selected [[#3671](https://github.com/keepassxreboot/keepassxc/issues/3671)]
- Reduce default Argon2 settings from 128 MiB and one thread per CPU core to 64 MiB and two threads to account for lower-spec mobile hardware [ [#3672](https://github.com/keepassxreboot/keepassxc/issues/3672)]
- Browser: Remove unused 'Remember' checkbox for HTTP Basic Auth [[#3371](https://github.com/keepassxreboot/keepassxc/issues/3371)]
- Browser: Show database name when pairing with a new browser [[#3638](https://github.com/keepassxreboot/keepassxc/issues/3638)]
- Browser: Show URL in allow access dialog [[#3639](https://github.com/keepassxreboot/keepassxc/issues/3639)]
- CLI: The password length option `-l` for the CLI commands `Add` and `Edit` is now `-L` [[#3275](https://github.com/keepassxreboot/keepassxc/issues/3275)]
- CLI: The `-u` shorthand for the `--upper` password generation option has been renamed to `-U` [[#3275](https://github.com/keepassxreboot/keepassxc/issues/3275)]
- CLI: Rename command `extract` to `export`. [[#3277](https://github.com/keepassxreboot/keepassxc/issues/3277)]
### Fixed
- Fix password generator issues with special characters [#3303](https://github.com/keepassxreboot/keepassxc/issues/3303)
- Improve accessibility for assistive technologies [[#3409](https://github.com/keepassxreboot/keepassxc/issues/3409)]
- Correctly unlock all databases if `--pw-stdin` is provided [[#2916](https://github.com/keepassxreboot/keepassxc/issues/2916)]
- Fix password generator issues with special characters [[#3303](https://github.com/keepassxreboot/keepassxc/issues/3303)]
- Fix KeePassXC interrupting shutdown procedure [[#3666](https://github.com/keepassxreboot/keepassxc/issues/3666)]
- Fix password visibility toggle button state on unlock dialog [[#3312](https://github.com/keepassxreboot/keepassxc/issues/3312)]
- Fix potential data loss if database is reloaded while user is editing an entry [[#3656](https://github.com/keepassxreboot/keepassxc/issues/3656)]
- Fix hard-coded background color in search help popup [[#3001](https://github.com/keepassxreboot/keepassxc/issues/3001)]
- Fix font choice for password preview [[#3425](https://github.com/keepassxreboot/keepassxc/issues/3425)]
- Fix handling of read-only files when autosave is enabled [[#3408](https://github.com/keepassxreboot/keepassxc/issues/3408)]
- Handle symlinks correctly when atomic saves are disabled [[#3463](https://github.com/keepassxreboot/keepassxc/issues/3463)]
- Enable HighDPI icon scaling on Linux [[#3332](https://github.com/keepassxreboot/keepassxc/issues/3332)]
- Make Auto-Type on macOS more robust and remove old Carbon API calls [[#3634](https://github.com/keepassxreboot/keepassxc/issues/3634), [[#3347](https://github.com/keepassxreboot/keepassxc/issues/3347))]
- Hide Share tab if KeePassXC is compiled without KeeShare support and other minor KeeShare improvements [[#3654](https://github.com/keepassxreboot/keepassxc/issues/3654), [[#3291](https://github.com/keepassxreboot/keepassxc/issues/3291), [#3029](https://github.com/keepassxreboot/keepassxc/issues/3029), [#3031](https://github.com/keepassxreboot/keepassxc/issues/3031), [#3236](https://github.com/keepassxreboot/keepassxc/issues/3236)]
- Correctly bring window to the front when clicking tray icon on macOS [[#3576](https://github.com/keepassxreboot/keepassxc/issues/3576)]
- Correct application shortcut created by MSI Installer on Windows [[#3296](https://github.com/keepassxreboot/keepassxc/issues/3296)]
- Fix crash when removing custom data [[#3508](https://github.com/keepassxreboot/keepassxc/issues/3508)]
- Fix placeholder resolution in URLs [[#3281](https://github.com/keepassxreboot/keepassxc/issues/3281)]
- Fix various inconsistencies and platform-dependent compilation bugs [[#3664](https://github.com/keepassxreboot/keepassxc/issues/3664), [#3662](https://github.com/keepassxreboot/keepassxc/issues/3662), [#3660](https://github.com/keepassxreboot/keepassxc/issues/3660), [#3655](https://github.com/keepassxreboot/keepassxc/issues/3655), [#3649](https://github.com/keepassxreboot/keepassxc/issues/3649), [#3417](https://github.com/keepassxreboot/keepassxc/issues/3417), [#3357](https://github.com/keepassxreboot/keepassxc/issues/3357), [#3319](https://github.com/keepassxreboot/keepassxc/issues/3319), [#3318](https://github.com/keepassxreboot/keepassxc/issues/3318), [#3304](https://github.com/keepassxreboot/keepassxc/issues/3304)]
- Browser: Fix potential leaking of entries through the browser integration API if multiple databases are opened [[#3480](https://github.com/keepassxreboot/keepassxc/issues/3480)]
- Browser: Fix password entropy calculation [[#3107](https://github.com/keepassxreboot/keepassxc/issues/3107)]
- Browser: Fix Windows registry settings for portable installation [[#3603](https://github.com/keepassxreboot/keepassxc/issues/3603)]
## 2.4.3 (2019-06-12)
### Added
- Add documentation for keyboard shortcuts to source code distribution [#3215](https://github.com/keepassxreboot/keepassxc/issues/3215)
- Add documentation for keyboard shortcuts to source code distribution [[#3215](https://github.com/keepassxreboot/keepassxc/issues/3215)]
### Fixed
- Fix library loading issues in the Snap and macOS releases [#3247](https://github.com/keepassxreboot/keepassxc/issues/3247)
- Fix various keyboard navigation issues [#3248](https://github.com/keepassxreboot/keepassxc/issues/3248)
- Fix main window toggling regression when clicking the tray icon on KDE [#3258](https://github.com/keepassxreboot/keepassxc/issues/3258)
- Fix library loading issues in the Snap and macOS releases [[#3247](https://github.com/keepassxreboot/keepassxc/issues/3247)]
- Fix various keyboard navigation issues [[#3248](https://github.com/keepassxreboot/keepassxc/issues/3248)]
- Fix main window toggling regression when clicking the tray icon on KDE [[#3258](https://github.com/keepassxreboot/keepassxc/issues/3258)]
## 2.4.2 (2019-05-31)
- Improve resilience against memory attacks - overwrite memory before free [#3020](https://github.com/keepassxreboot/keepassxc/issues/3020)
- Prevent infinite save loop when location is unavailable [#3026](https://github.com/keepassxreboot/keepassxc/issues/3026)
- Attempt to fix quitting application when shutdown or logout issued [#3199](https://github.com/keepassxreboot/keepassxc/issues/3199)
- Support merging database custom data [#3002](https://github.com/keepassxreboot/keepassxc/issues/3002)
- Fix opening URL's with non-http schemes [#3153](https://github.com/keepassxreboot/keepassxc/issues/3153)
- Fix data loss due to not reading all database attachments if duplicates exist [#3180](https://github.com/keepassxreboot/keepassxc/issues/3180)
- Fix entry context menu disabling when using keyboard navigation [#3199](https://github.com/keepassxreboot/keepassxc/issues/3199)
- Fix behaviors when canceling an entry edit [#3199](https://github.com/keepassxreboot/keepassxc/issues/3199)
- Fix processing of tray icon click and doubleclick [#3112](https://github.com/keepassxreboot/keepassxc/issues/3112)
- Update group in preview widget when focused [#3199](https://github.com/keepassxreboot/keepassxc/issues/3199)
- Prefer DuckDuckGo service over direct icon download (increases resolution) [#2996](https://github.com/keepassxreboot/keepassxc/issues/2996)
- Remove apply button in application settings [#3019](https://github.com/keepassxreboot/keepassxc/issues/3019)
- Use winqtdeploy on Windows to correct deployment issues [#3025](https://github.com/keepassxreboot/keepassxc/issues/3025)
- Don't mark entry edit as modified when attribute selection changes [#3041](https://github.com/keepassxreboot/keepassxc/issues/3041)
- Use console code page CP_UTF8 on Windows if supported [#3050](https://github.com/keepassxreboot/keepassxc/issues/3050)
- Snap: Fix locking database with session lock [#3046](https://github.com/keepassxreboot/keepassxc/issues/3046)
- Snap: Fix theming across Linux distributions [#3057](https://github.com/keepassxreboot/keepassxc/issues/3057)
- Snap: Use SNAP_USER_COMMON and SNAP_USER_DATA directories [#3131](https://github.com/keepassxreboot/keepassxc/issues/3131)
- KeeShare: Automatically enable WITH_XC_KEESHARE_SECURE if quazip is found [#3088](https://github.com/keepassxreboot/keepassxc/issues/3088)
- macOS: Fix toolbar text when in dark mode [#2998](https://github.com/keepassxreboot/keepassxc/issues/2998)
- macOS: Lock database on switching user [#3097](https://github.com/keepassxreboot/keepassxc/issues/3097)
- macOS: Fix global Auto-Type when the database is locked [#3138](https://github.com/keepassxreboot/keepassxc/issues/3138)
- Browser: Close popups when database is locked [#3093](https://github.com/keepassxreboot/keepassxc/issues/3093)
- Browser: Add tests [#3016](https://github.com/keepassxreboot/keepassxc/issues/3016)
- Browser: Don't create default group if custom group is enabled [#3127](https://github.com/keepassxreboot/keepassxc/issues/3127)
- Improve resilience against memory attacks - overwrite memory before free [[#3020](https://github.com/keepassxreboot/keepassxc/issues/3020)]
- Prevent infinite save loop when location is unavailable [[#3026](https://github.com/keepassxreboot/keepassxc/issues/3026)]
- Attempt to fix quitting application when shutdown or logout issued [[#3199](https://github.com/keepassxreboot/keepassxc/issues/3199)]
- Support merging database custom data [[#3002](https://github.com/keepassxreboot/keepassxc/issues/3002)]
- Fix opening URL's with non-http schemes [[#3153](https://github.com/keepassxreboot/keepassxc/issues/3153)]
- Fix data loss due to not reading all database attachments if duplicates exist [[#3180](https://github.com/keepassxreboot/keepassxc/issues/3180)]
- Fix entry context menu disabling when using keyboard navigation [[#3199](https://github.com/keepassxreboot/keepassxc/issues/3199)]
- Fix behaviors when canceling an entry edit [[#3199](https://github.com/keepassxreboot/keepassxc/issues/3199)]
- Fix processing of tray icon click and doubleclick [[#3112](https://github.com/keepassxreboot/keepassxc/issues/3112)]
- Update group in preview widget when focused [[#3199](https://github.com/keepassxreboot/keepassxc/issues/3199)]
- Prefer DuckDuckGo service over direct icon download (increases resolution) [#2996](https://github.com/keepassxreboot/keepassxc/issues/2996)]
- Remove apply button in application settings [[#3019](https://github.com/keepassxreboot/keepassxc/issues/3019)]
- Use winqtdeploy on Windows to correct deployment issues [[#3025](https://github.com/keepassxreboot/keepassxc/issues/3025)]
- Don't mark entry edit as modified when attribute selection changes [[#3041](https://github.com/keepassxreboot/keepassxc/issues/3041)]
- Use console code page CP_UTF8 on Windows if supported [[#3050](https://github.com/keepassxreboot/keepassxc/issues/3050)]
- Snap: Fix locking database with session lock [[#3046](https://github.com/keepassxreboot/keepassxc/issues/3046)]
- Snap: Fix theming across Linux distributions [[#3057](https://github.com/keepassxreboot/keepassxc/issues/3057)]
- Snap: Use SNAP_USER_COMMON and SNAP_USER_DATA directories [[#3131](https://github.com/keepassxreboot/keepassxc/issues/3131)]
- KeeShare: Automatically enable WITH_XC_KEESHARE_SECURE if quazip is found [[#3088](https://github.com/keepassxreboot/keepassxc/issues/3088)]
- macOS: Fix toolbar text when in dark mode [[#2998](https://github.com/keepassxreboot/keepassxc/issues/2998)]
- macOS: Lock database on switching user [[#3097](https://github.com/keepassxreboot/keepassxc/issues/3097)]
- macOS: Fix global Auto-Type when the database is locked[ [#3138](https://github.com/keepassxreboot/keepassxc/issues/3138)]
- Browser: Close popups when database is locked [[#3093](https://github.com/keepassxreboot/keepassxc/issues/3093)]
- Browser: Add tests [[#3016](https://github.com/keepassxreboot/keepassxc/issues/3016)]
- Browser: Don't create default group if custom group is enabled [[#3127](https://github.com/keepassxreboot/keepassxc/issues/3127)]
## 2.4.1 (2019-04-12)

View File

@ -1,5 +1,5 @@
KeePassXC - http://www.keepassxc.org/
Copyright (C) 2016-2017 KeePassXC Team <team@keepassxc.org>
Copyright (C) 2016-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
@ -27,7 +27,7 @@ Copyright: 2010-2012, Felix Geyer <debfx@fobos.de>
2000-2008, Tom Sato <VEF00200@nifty.ne.jp>
2013, Laszlo Papp <lpapp@kde.org>
2013, David Faure <faure@kde.org>
2016-2018, KeePassXC Team <team@keepassxc.org>
2016-2019, KeePassXC Team <team@keepassxc.org>
License: GPL-2 or GPL-3
Comment: The "KeePassXC Team" in every copyright notice is formed by the following people:

View File

@ -22,7 +22,7 @@ so please check out your distribution's package list to see if KeePassXC is avai
- YubiKey challenge-response support
- TOTP generation
- CSV import
- A [Command Line Interface (keepassxc-cli)](./src/cli/keepassxc-cli.1)
- A [Command Line Interface (keepassxc-cli)](./share/docs/man/keepassxc-cli.1)
- DEP and ASLR hardening
- Stand-alone password and passphrase generator
- Password strength meter

View File

@ -6,7 +6,9 @@ keepassxc-cli \- command line interface for the \fBKeePassXC\fP password manager
.SH SYNOPSIS
.B keepassxc-cli
.I command
.RI [ options ]
.B [
-I options
.B ]
.SH DESCRIPTION
\fBkeepassxc-cli\fP is the command line interface for the \fBKeePassXC\fP password manager. It provides the ability to query and modify the entries of a KeePass database, directly from the command line.

View File

@ -0,0 +1,39 @@
.TH KEEPASSXC 1 "Oct 25, 2019"
.SH NAME
keepassxc \- password manager
.SH SYNOPSIS
.B keepassxc
.B [
.I options
.B ] [
.I filename(s)
.B ]
.SH DESCRIPTION
\fBKeePassXC\fP is a free/open-source password manager or safe which helps you to manage your passwords in a secure way. The complete database is always encrypted with the industry-standard AES (alias Rijndael) encryption algorithm using a 256 bit key. KeePassXC uses a database format that is compatible with KeePass Password Safe. Your wallet works offline and requires no Internet connection.
.SH OPTIONS
.IP "-h, --help"
Displays this help.
.IP "-v, --version"
Displays version information.
.IP "--config <config>"
Path to a custom config file
.IP "--keyfile <keyfile>"
Key file of the database
.IP "--pw-stdin"
Read password of the database from stdin
.IP "--pw, --parent-window <handle>"
Parent window handle
.IP "--debug-info"
Displays debugging information.
.SH AUTHOR
This manual page is maintained by the KeePassXC Team <team@keepassxc.org>.

View File

@ -50,6 +50,87 @@
</screenshots>
<releases>
<release version="2.5.0" date="2019-10-26">
<description>
<ul>
<li>Add 'Paper Backup' aka 'Export to HTML file' to the 'Database' menu [#3277]</li>
<li>Add statistics panel with information about the database (number of entries, number of unique passwords, etc.) to the Database Settings dialog [#2034]</li>
<li>Add offline user manual accessible via the 'Help' menu [#3274]</li>
<li>Add support for importing 1Password OpVault files [#2292]</li>
<li>Implement Freedesktop.org secret storage DBus protocol so that KeePassXC can be used as a vault service by libsecret [#2726]</li>
<li>Add support for OnlyKey as an alternative to YubiKeys (requires yubikey-personalization >= 1.20.0) [#3352]</li>
<li>Add group sorting feature [#3282]</li>
<li>Add feature to download favicons for all entries at once [#3169]</li>
<li>Add word case option to passphrase generator [#3172]</li>
<li>Add support for RFC6238-compliant TOTP hashes [#2972]</li>
<li>Add UNIX man page for main program [#3665]</li>
<li>Add 'Monospaced font' option to the notes field [#3321]</li>
<li>Add support for key files in auto open [#3504]</li>
<li>Add search field for filtering entries in Auto-Type dialog [#2955]</li>
<li>Complete usernames based on known usernames from other entries [#3300]</li>
<li>Parse hyperlinks in the notes field of the entry preview pane [#3596]</li>
<li>Allow abbreviation of field names in entry search [#3440]</li>
<li>Allow setting group icons recursively [#3273]</li>
<li>Add copy context menu for username and password in Auto-Type dialog [#3038]</li>
<li>Drop to background after copying a password to the clipboard [#3253]</li>
<li>Add 'Lock databases' entry to tray icon menu [#2896]</li>
<li>Add option to minimize window after unlocking [#3439]</li>
<li>Add option to minimize window after opening a URL [#3302]</li>
<li>Request accessibility permissions for Auto-Type on macOS [#3624]</li>
<li>Browser: Add initial support for multiple URLs [#3558]</li>
<li>Browser: Add entry-specific browser integration settings [#3444]</li>
<li>Add offline HIBP checker (requires a downloaded HIBP dump) [#2707]</li>
<li>CLI: Add 'flatten' option to the 'ls' command [#3276]</li>
<li>CLI: Add password generation options to `Add` and `Edit` commands [#3275]</li>
<li>CLI: Add XML import [#3572]</li>
<li>CLI: Add CSV export to the 'export' command [#3278]</li>
<li>CLI: Add `-y --yubikey` option for YubiKey [#3416]</li>
<li>CLI: Add `--dry-run` option for merging databases [#3254]</li>
<li>CLI: Add group commands (mv, mkdir and rmdir) [#3313].</li>
<li>CLI: Add interactive shell mode command `open` [#3224]</li>
<li>Redesign database unlock dialog [ [#3287]</li>
<li>Rework the entry preview panel [ [#3306]</li>
<li>Move notes to General tab on Group Preview Panel [#3336]</li>
<li>Enable entry actions when editing an entry and cleanup entry context menu [#3641]</li>
<li>Improve detection of external database changes [#2389]</li>
<li>Warn if user is trying to use a KDBX file as a key file [#3625]</li>
<li>Add option to disable KeePassHTTP settings migrations prompt [#3349, #3344]</li>
<li>Re-enabled Wayland support (no Auto-Type yet) [#3520, #3341]</li>
<li>Add icon to 'Toggle Window' action in tray icon menu [[3244]</li>
<li>Merge custom data between databases only when necessary [#3475]</li>
<li>Improve various file-handling related issues when picking files using the system's file dialog [#3473]</li>
<li>Add 'New Entry' context menu when no entries are selected [#3671]</li>
<li>Reduce default Argon2 settings from 128 MiB and one thread per CPU core to 64 MiB and two threads to account for lower-spec mobile hardware [#3672]</li>
<li>Browser: Remove unused 'Remember' checkbox for HTTP Basic Auth [#3371]</li>
<li>Browser: Show database name when pairing with a new browser [#3638]</li>
<li>Browser: Show URL in allow access dialog [#3639]</li>
<li>CLI: The password length option `-l` for the CLI commands `Add` and `Edit` is now `-L` [#3275]</li>
<li>CLI: The `-u` shorthand for the `--upper` password generation option has been renamed to `-U` [#3275]</li>
<li>CLI: Rename command `extract` to `export`. [#3277]</li>
<li>Improve accessibility for assistive technologies [#3409]</li>
<li>Correctly unlock all databases if `--pw-stdin` is provided [#2916]</li>
<li>Fix password generator issues with special characters [#3303]</li>
<li>Fix KeePassXC interrupting shutdown procedure [#3666]</li>
<li>Fix password visibility toggle button state on unlock dialog [#3312]</li>
<li>Fix potential data loss if database is reloaded while user is editing an entry [#3656]</li>
<li>Fix hard-coded background color in search help popup [#3001]</li>
<li>Fix font choice for password preview [#3425]</li>
<li>Fix handling of read-only files when autosave is enabled [#3408]</li>
<li>Handle symlinks correctly when atomic saves are disabled [#3463]</li>
<li>Enable HighDPI icon scaling on Linux [#3332]</li>
<li>Make Auto-Type on macOS more robust and remove old Carbon API calls [#3634, #3347]</li>
<li>Hide Share tab if KeePassXC is compiled without KeeShare support and other minor KeeShare improvements [#3654, #3291, #3029, #3031, #3236]</li>
<li>Correctly bring window to the front when clicking tray icon on macOS [#3576]</li>
<li>Correct application shortcut created by MSI Installer on Windows [#3296]</li>
<li>Fix crash when removing custom data [#3508]</li>
<li>Fix placeholder resolution in URLs [#3281]</li>
<li>Fix various inconsistencies and platform-dependent compilation bugs [#3664, #3662, #3660, #3655, #3649, #3417, #3357, #3319, #3318, #3304]</li>
<li>Browser: Fix potential leaking of entries through the browser integration API if multiple databases are opened [#3480]</li>
<li>Browser: Fix password entropy calculation [#3107]</li>
<li>Browser: Fix Windows registry settings for portable installation [#3603]</li>
</ul>
</description>
</release>
<release version="2.4.3" date="2019-06-12">
<description>
<ul>

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

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

@ -389,6 +389,10 @@ install(TARGETS ${PROGNAME}
BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION ${BIN_INSTALL_DIR} COMPONENT Runtime)
if(APPLE OR UNIX)
install(FILES ../share/docs/man/keepassxc.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/)
endif()
if(MINGW)
if(${CMAKE_SIZEOF_VOID_P} EQUAL "8")
set(OUTPUT_FILE_POSTFIX "Win64")

View File

@ -304,9 +304,9 @@ QString BrowserService::storeKey(const QString& key)
QInputDialog keyDialog;
connect(m_dbTabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), &keyDialog, SLOT(reject()));
keyDialog.setWindowTitle(tr("KeePassXC: New key association request"));
keyDialog.setLabelText(tr("You have received an association request for the above key.\n\n"
"If you would like to allow it access to your KeePassXC database,\n"
"give it a unique name to identify and accept it."));
keyDialog.setLabelText(tr("You have received an association request for the following database:\n%1\n\n"
"Give the connection a unique name or ID, for example:\nchrome-laptop.")
.arg(db->metadata()->name().toHtmlEscaped()));
keyDialog.setOkButtonText(tr("Save and allow access"));
keyDialog.setWindowFlags(keyDialog.windowFlags() | Qt::WindowStaysOnTopHint);
raiseWindow();
@ -410,7 +410,7 @@ QJsonArray BrowserService::findMatchingEntries(const QString& id,
}
// Confirm entries
if (confirmEntries(pwEntriesToConfirm, url, host, submitHost, realm, httpAuth)) {
if (confirmEntries(pwEntriesToConfirm, url, host, submitUrl, realm, httpAuth)) {
pwEntries.append(pwEntriesToConfirm);
}
@ -786,7 +786,7 @@ QList<Entry*> BrowserService::sortEntries(QList<Entry*>& pwEntries, const QStrin
bool BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm,
const QString& url,
const QString& host,
const QString& submitHost,
const QString& submitUrl,
const QString& realm,
const bool httpAuth)
{
@ -797,7 +797,7 @@ bool BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm,
m_dialogActive = true;
BrowserAccessControlDialog accessControlDialog;
connect(m_dbTabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), &accessControlDialog, SLOT(reject()));
accessControlDialog.setUrl(url);
accessControlDialog.setUrl(!submitUrl.isEmpty() ? submitUrl : url);
accessControlDialog.setItems(pwEntriesToConfirm);
accessControlDialog.setHTTPAuth(httpAuth);
@ -806,6 +806,7 @@ bool BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm,
accessControlDialog.activateWindow();
accessControlDialog.raise();
const QString submitHost = QUrl(submitUrl).host();
int res = accessControlDialog.exec();
if (accessControlDialog.remember()) {
for (auto* entry : pwEntriesToConfirm) {

View File

@ -120,7 +120,7 @@ private:
bool confirmEntries(QList<Entry*>& pwEntriesToConfirm,
const QString& url,
const QString& host,
const QString& submitHost,
const QString& submitUrl,
const QString& realm,
const bool httpAuth);
QJsonObject prepareEntry(const Entry* entry);

View File

@ -78,5 +78,5 @@ void Analyze::printHibpFinding(const Entry* entry, int count, QTextStream& out)
path.prepend("/").prepend(g->name());
}
out << QObject::tr("Password for '%1' has been leaked %2 times!").arg(path).arg(count) << endl;
out << QObject::tr("Password for '%1' has been leaked %2 time(s)!", "", count).arg(path).arg(count) << endl;
}

View File

@ -119,5 +119,5 @@ if(APPLE AND WITH_APP_BUNDLE)
endif()
if(APPLE OR UNIX)
install(FILES keepassxc-cli.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/)
install(FILES ../../share/docs/man/keepassxc-cli.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/)
endif()

View File

@ -52,7 +52,11 @@ int DatabaseCommand::execute(const QStringList& arguments)
db = Utils::unlockDatabase(args.at(0),
!parser->isSet(Command::NoPasswordOption),
parser->value(Command::KeyFileOption),
#ifdef WITH_XC_YUBIKEY
parser->value(Command::YubiKeyOption),
#else
"",
#endif
parser->isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT,
Utils::STDERR);
if (!db) {

View File

@ -29,11 +29,11 @@ const QCommandLineOption Export::FormatOption =
QCommandLineOption(QStringList() << "f"
<< "format",
QObject::tr("Format to use when exporting. Available choices are xml or csv. Defaults to xml."),
QObject::tr("xml|csv"));
QStringLiteral("xml|csv"));
Export::Export()
{
name = QString("export");
name = QStringLiteral("export");
options.append(Export::FormatOption);
description = QObject::tr("Exports the content of a database to standard output in the specified format.");
}
@ -44,7 +44,7 @@ int Export::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
TextStream errorTextStream(Utils::STDERR, QIODevice::WriteOnly);
QString format = parser->value(Export::FormatOption);
if (format.isEmpty() || format == QString("xml")) {
if (format.isEmpty() || format == QStringLiteral("xml")) {
QByteArray xmlData;
QString errorMessage;
if (!database->extract(xmlData, &errorMessage)) {
@ -52,7 +52,7 @@ int Export::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
return EXIT_FAILURE;
}
outputTextStream << xmlData.constData() << endl;
} else if (format == QString("csv")) {
} else if (format == QStringLiteral("csv")) {
CsvExporter csvExporter;
outputTextStream << csvExporter.exportDatabase(database);
} else {

View File

@ -126,7 +126,7 @@ QSharedPointer<PasswordGenerator> Generate::createGenerator(QSharedPointer<QComm
passwordGenerator->setExcludedChars(parser->value(Generate::ExcludeCharsOption));
if (!passwordGenerator->isValid()) {
errorTextStream << QObject::tr("invalid password generator after applying all options") << endl;
errorTextStream << QObject::tr("Invalid password generator after applying all options") << endl;
return QSharedPointer<PasswordGenerator>(nullptr);
}

View File

@ -17,6 +17,7 @@
#include <QtGlobal>
#include <cstdint>
#include <cstdlib>
#include <sodium.h>
#if defined(Q_OS_MACOS)
#include <malloc/malloc.h>

View File

@ -585,13 +585,18 @@ QList<Entry*> Group::referencesRecursive(const Entry* entry) const
[entry](const Entry* e) { return e->hasReferencesTo(entry->uuid()); });
}
Entry* Group::findEntryByUuid(const QUuid& uuid) const
Entry* Group::findEntryByUuid(const QUuid& uuid, bool recursive) const
{
if (uuid.isNull()) {
return nullptr;
}
for (Entry* entry : entriesRecursive(false)) {
auto entries = m_entries;
if (recursive) {
entries = entriesRecursive(false);
}
for (auto entry : entries) {
if (entry->uuid() == uuid) {
return entry;
}

View File

@ -114,7 +114,7 @@ public:
static const QString RootAutoTypeSequence;
Group* findChildByName(const QString& name);
Entry* findEntryByUuid(const QUuid& uuid) const;
Entry* findEntryByUuid(const QUuid& uuid, bool recursive = true) const;
Entry* findEntryByPath(const QString& entryPath);
Entry* findEntryBySearchTerm(const QString& term, EntryReferenceType referenceType);
Group* findGroupByUuid(const QUuid& uuid);

View File

@ -37,15 +37,7 @@ bool OSEventFilter::nativeEventFilter(const QByteArray& eventType, void* message
#if defined(Q_OS_UNIX)
if (eventType == QByteArrayLiteral("xcb_generic_event_t")) {
#elif defined(Q_OS_WIN)
auto winmsg = static_cast<MSG*>(message);
if (winmsg->message == WM_QUERYENDSESSION) {
*result = 1;
return true;
} else if (winmsg->message == WM_ENDSESSION) {
getMainWindow()->appExit();
*result = 0;
return true;
} else if (eventType == QByteArrayLiteral("windows_generic_MSG")
if (eventType == QByteArrayLiteral("windows_generic_MSG")
|| eventType == QByteArrayLiteral("windows_dispatcher_MSG")) {
#endif
return autoType()->callEventFilter(message) == 1;

View File

@ -49,6 +49,14 @@ static const QString aboutContributors = R"(
<li>Igor Zinovik</li>
<li>Morgan Courbet</li>
<li>Sergiu Coroi</li>
<li>Chris Sohns</li>
<li>Kyle Kneitinger</li>
<li>Sergey Vilgelm</li>
<li>Roman Vaughan (NZSmartie)</li>
<li>Shmavon Gazanchyan</li>
<li>Riley Moses</li>
<li>Korbinian Schildmann</li>
<li>Andreas (nitrohorse)</li>
</ul>
<h3>Notable Code Contributions:</h3>
<ul>
@ -61,11 +69,15 @@ static const QString aboutContributors = R"(
<li>hifi (SSH Agent)</li>
<li>ckieschnick (KeeShare)</li>
<li>seatedscribe (CSV Import)</li>
<li>Aetf (Secret Storage Server)</li>
<li>brainplot (many improvements)</li>
<li>kneitinger (many improvements)</li>
<li>frostasm (many improvements)</li>
<li>fonic (Entry Table View)</li>
<li>kylemanna (YubiKey)</li>
<li>c4rlo (Offline HIBP Checker)</li>
<li>wolframroesler (HTML Exporter)</li>
<li>mdaniel (OpVault Importer)</li>
<li>keithbennett (KeePassHTTP)</li>
<li>Typz (KeePassHTTP)</li>
<li>denk-mal (KeePassHTTP)</li>
@ -75,7 +87,6 @@ static const QString aboutContributors = R"(
</ul>
<h3>Patreon Supporters:</h3>
<ul>
<li>Ashura</li>
<li>Alexanderjb</li>
<li>Andreas Kollmann</li>
<li>Richard Ames</li>
@ -83,77 +94,101 @@ static const QString aboutContributors = R"(
<li>Gregory Werbin</li>
<li>Nuutti Toivola</li>
<li>SLmanDR</li>
<li>Ashura</li>
<li>Tyler Gass</li>
<li>Lionel Laské</li>
<li>Dmitrii Galinskii</li>
<li>Sergei Maximov</li>
<li>John-Ivar</li>
<li>Clayton Casciato</li>
<li>John</li>
<li>Darren</li>
<li>Brad</li>
<li>Mathieu Peltier</li>
<li>Oleksii Aleksieiev</li>
<li>Daniel Epp</li>
<li>Gernot Premper</li>
<li>Julian Stier</li>
<li>gonczor</li>
<li>Ruben Schade</li>
<li>Esteban Martinez</li>
<li>turin231</li>
<li>judd</li>
<li>Niels Ganser</li>
</ul>
<h3>Translations:</h3>
<ul>
<li><strong>Arabic</strong>: AboShanab, Night1, kmutahar, muha_abdulaziz, omar.nsy</li>
<li><strong>Basque</strong>: azken_tximinoa, Hey_neken</li>
<li><strong>Bengali</strong>: codesmite</li>
<li><strong>Burmese</strong>: Phyu</li>
<li><strong>Catalan</strong>: capitantrueno, dsoms, mcus, raulua, ZJaume</li>
<li><strong>Chinese (China)</strong>: Biggulu, Brandon_c, Dy64, Felix2yu, Small_Ku, Z4HD,
carp0129, ef6, holic, kikyous, kofzhanganguo, ligyxy, remonli, slgray, umi_neko, vc5</li>
<li><strong>Chinese (Taiwan)</strong>: BestSteve, MiauLightouch, Small_Ku, flachesis, gojpdchx,
raymondtau, th3lusive, yan12125, ymhuang0808</li>
<li><strong>Czech</strong>: DanielMilde, JosefVitu, awesomevojta, pavelb, tpavelek</li>
<li><strong>Danish</strong>: nlkl, KalleDK, MannVera, alfabetacain, ebbe, thniels</li>
<li><strong>Dutch</strong>: Bubbel, Dr.Default, apie, bartlibert, evanoosten, fvw, KnooL,
srgvg, Vistaus, wanderingidea, Stephan_P, Zombaya1, e2jk, ovisicnarf, pietermj, rigrig,
theniels17</li>
<li><strong>English (UK)</strong>: YCMHARHZ, rookwood01, throne3d</li>
<li><strong>Esperanto</strong>: batisteo</li>
<li><strong>Estonian</strong>: Hermanio</li>
<li><strong>Finnish</strong>: artnay, Jarppi, MawKKe, petri, tomisalmi, hifi, varjolintu</li>
<li><strong>French</strong>: yahoe.001, A1RO, Albynton, Cabirto, Fumble, Gui13, MartialBis,
MrHeadwar, Nesousx, Raphi111, Scrat15, aghilas.messara, alexisju, b_mortgat, benoitbalon,
bisaloo, e2jk, ebrious, frgnca, ggtr1138, gilbsgilbs, gtalbot, houdini, houdini69,
iannick, jlutran, kyodev, lacnic, laetilodie, logut, mlpo, narzb, nekopep, pBouillon,
plunkets, theodex, tl_pierre, wilfriedroset</li>
<li><strong>German</strong>: origin_de, mithrial, andreas.maier, NotAName, Atalanttore,
Hativ, muellerma, mircsicz, derhagen, Wyrrrd, mbetz, kflesch, nursoda, BasicBaer,
mfernau77, for1real, joe776, waster, eth0, marcbone, mcliquid, transi_222, MarcEdinger,
DavidHamburg, jensrutschmann, codejunky, vlenzer, montilo, antsas, rgloor, Calyrx,
omnisome4, pcrcoding</li>
<li><strong>Greek</strong>: magkopian, nplatis, tassos.b, xinomilo</li>
<li><strong>Hungarian</strong>: bubu, meskobalazs, urbalazs, andras_tim</li>
<li><strong>Indonesian</strong>: zk, bora_ach</li>
<li><strong>Italian</strong>: the.sailor, VosaxAlo, tosky, seatedscribe, bovirus, Peo,
NITAL, FranzMari, Gringoarg, amaxis, salvatorecordiano, duncanmid, lucaim</li>
<li><strong>Japanese</strong>: masoo, metalic_cat, p2635, Shinichirou_Yamada,
vargas.peniel, vmemjp, yukinakato, gojpdchx, saita</li>
<li><strong>Korean</strong>: cancantun, peremen</li>
<li><strong>Lithuanian</strong>: Moo, pauliusbaulius, rookwood101</li>
<li><strong>Norweigian Bokmål</strong>: sattor, ysteinalver, jumpingmushroom,
JardarBolin, eothred, torgeirf, haarek</li>
<li><strong>Polish</strong>: keypress, konradmb, mrerexx, psobczak, SebJez, hoek</li>
<li><strong>Portuguese</strong>: weslly, xendez</li>
<li><strong>Portuguese (Brazil)</strong>: danielbibit, guilherme__sr, Havokdan, fabiom,
flaviobn, weslly, newmanisaac, rafaelnp, RockyTV, xendez, lucasjsoliveira, vitor895,
mauri.andres, andersoniop</li>
<li><strong>Portuguese (Portugal)</strong>: American_Jesus, xendez, hds, arainho, a.santos,
pfialho, smarquespt, mihai.ile, smiguel, lmagomes, xnenjm</li>
<li><strong>Russian</strong>: Mogost, alexminza, KekcuHa, NcNZllQnHVU, ruslan.denisenko,
agag11507, anm, cl0ne, JayDi85, RKuchma, Rakleed, vsvyatski, NetWormKido, DG,
Mr.GreyWolf, VictorR2007, _nomoretears_, netforhack, denoos, wkill95, Shevchuk,
talvind, artemkonenko, ShareDVI</li>
<li><strong>Slovak</strong>: l.martinicky, Slavko, crazko, pecer</li>
<li><strong>Spanish</strong>: gonrial, iglpdc, vsvyatski, Xlate1984, erinm, AndreachongB,
piegope, lupa18, e2jk, capitantrueno, LeoBeltran, antifaz, Zranz, AdrianClv,
EdwardNavarro, rodolfo.guagnini, NicolasCGN, caralu74, puchrojo, DarkHolme,
pdinoto, masanchez5000, adolfogc, systurbed, mauri.andres, Bendhet, vargas.peniel,
eliluminado, jojobrambs, pquin</li>
<li><strong>Swedish</strong>: theschitz, Anders_Bergqvist, LIINdd, krklns, henziger,
jpyllman, peron, Thelin, baxtex, zeroxfourc</li>
<li><strong>Thai</strong>: arthit, rayg</li>
<li><strong>Turkish</strong>: TeknoMobil, etc, SeLeNLeR, ethem578, cagries, N3pp</li>
<li><strong>Ukrainian</strong>: brisk022, exlevan, chulivska, cl0ne, zoresvit,
netforhack, ShareDVI</li>
<li><strong>العربية (Arabic)</strong>: AboShanab, kmutahar, muha_abdulaziz, Night1, omar.nsy</li>
<li><strong>euskara (Basque)</strong>: azken_tximinoa, Galaipa, Hey_neken</li>
<li><strong> (Bengali)</strong>: codesmite</li>
<li><strong> (Burmese)</strong>: Snooooowwwwwman</li>
<li><strong>català (Catalan)</strong>: antoniopolonio, capitantrueno, dsoms, MarcRiera, mcus, raulua, ZJaume</li>
<li><strong> (Chinese (Simplified))</strong>: Biggulu, Brandon_c, carp0129, Dy64, ef6, Felix2yu, hoilc, ivlioioilvi,
kikyous, kofzhanganguo, ligyxy, lxx4380, remonli, ShuiHuo, slgray, Small_Ku, snhun, umi_neko, vc5, Wylmer_Wang, Z4HD</li>
<li><strong> () (Chinese (Traditional))</strong>: BestSteve, flachesis, gojpdchx, ligyxy, MiauLightouch, plesry,
priv, raymondtau, Small_Ku, th3lusive, yan12125, ymhuang0808</li>
<li><strong>hrvatski jezik (Croatian)</strong>: Halberd, mladenuzelac</li>
<li><strong>čeština (Czech)</strong>: awesomevojta, DanielMilde, JosefVitu, pavelb, stps, tpavelek</li>
<li><strong>dansk (Danish)</strong>: alfabetacain, ebbe, GimliDk, JakobPP, KalleDK, MannVera, nlkl, thniels</li>
<li><strong>Nederlands (Dutch)</strong>: apie, bartlibert, Bubbel, bython, Dr.Default, e2jk, evanoosten, fourwood,
fvw, glotzbach, JCKalman, KnooL, ovisicnarf, pietermj, rigrig, srgvg, Stephan_P, stijndubrul, theniels17,
ThomasChurchman, Vistaus, wanderingidea, Zombaya1</li>
<li><strong>English (UK)</strong>: CisBetter, rookwood101, spacemanspiff, throne3d, YCMHARHZ</li>
<li><strong>English (USA)</strong>: alexandercrice, caralu74, cl0ne, DarkHolme, nguyenlekhtn, thedoctorsoad, throne3d</li>
<li><strong>Esperanto (Esperanto)</strong>: batisteo</li>
<li><strong>eesti (Estonian)</strong>: Hermanio</li>
<li><strong>suomi (Finnish)</strong>: artnay, hif1, MawKKe, petri, tomisalmi, varjolintu</li>
<li><strong>français (French)</strong>: A1RO, aghilas.messara, Albynton, alexisju, b_mortgat, Beatussum, benoitbalon,
bertranoel, bisaloo, Cabirto, Code2Mirabeau, e2jk, ebrious, frgnca, Fumble, ggtr1138, gilbsgilbs, gohuros, gtalbot,
Gui13, houdini, houdini69, iannick, jlutran, John.Mickael, kyodev, lacnic, laetilodie, logut, MartialBis, Maxime_J,
mlpo, Morgan, MrHeadwar, narzb, nekopep, Nesousx, pBouillon, Raphi111, Scrat15, TheFrenchGhosty, theodex, tl_pierre,
webafrancois, wilfriedroset, yahoe.001, zedentox</li>
<li><strong>Galego (Galician)</strong>: enfeitizador</li>
<li><strong>Deutsch (German)</strong>: andreas.maier, antsas, Atalanttore, BasicBaer, bwolkchen, Calyrx, codejunky,
DavidHamburg, derhagen, eth0, fahstat, for1real, Gyges, Hativ, hjonas, HoferJulian, janis91, jensrutschmann,
joe776, kflesch, man_at_home, marcbone, MarcEdinger, markusd112, Maxime_J, mbetz, mcliquid, mfernau77, mircsicz,
mithrial, montilo, MuehlburgPhoenix, muellerma, nautilusx, Nerzahd, Nightwriter, NotAName, nursoda, omnisome4,
origin_de, pcrcoding, PFischbeck, rgloor, rugk, ScholliYT, Silas_229, spacemanspiff, testarossa47, TheForcer,
transi_222, traschke, vlenzer, vpav, waster, wolfram.roesler, Wyrrrd</li>
<li><strong>ελληνικά (Greek)</strong>: anvo, magkopian, nplatis, tassos.b, xinomilo</li>
<li><strong>עברית (Hebrew)</strong>: shmag18</li>
<li><strong>magyar (Hungarian)</strong>: andras_tim, bubu, meskobalazs, urbalazs</li>
<li><strong>Íslenska (Icelandic)</strong>: MannVera</li>
<li><strong>Bahasa (Indonesian)</strong>: achmad, bora_ach, zk</li>
<li><strong>Italiano (Italian)</strong>: amaxis, bovirus, duncanmid, FranzMari, Gringoarg, lucaim, NITAL, Peo,
salvatorecordiano, seatedscribe, Stemby, the.sailor, tosky, VosaxAlo</li>
<li><strong> (Japanese)</strong>: gojpdchx, masoo, metalic_cat, p2635, saita, Shinichirou_Yamada, take100yen,
Umoxfo, vargas.peniel, vmemjp, WatanabeShint, yukinakato</li>
<li><strong>қазақ тілі (Kazakh)</strong>: sotrud_nik</li>
<li><strong> (Korean)</strong>: cancantun, peremen</li>
<li><strong>latine (Latin)</strong>: alexandercrice</li>
<li><strong>lietuvių kalba (Lithuanian)</strong>: Moo, pauliusbaulius, rookwood101</li>
<li><strong>Norsk Bokmål (Norwegian Bokmål)</strong>: eothred, haarek, JardarBolin, jumpingmushroom, sattor, torgeirf,
ysteinalver</li>
<li><strong>język polski (Polish)</strong>: AreYouLoco, dedal123, hoek, keypress, konradmb, mrerexx, pabli, psobczak,
SebJez</li>
<li><strong>Português (Portuguese)</strong>: weslly, xendez</li>
<li><strong>Português (Portuguese (Brazil))</strong>: andersoniop, danielbibit, fabiom, flaviobn, guilherme__sr,
Havokdan, lucasjsoliveira, mauri.andres, newmanisaac, rafaelnp, RockyTV, vitor895, weslly, xendez</li>
<li><strong>Português (Portuguese (Portugal))</strong>: a.santos, American_Jesus, arainho, hds, lmagomes, mihai.ile,
pfialho, smarquespt, smiguel, xendez, xnenjm</li>
<li><strong>Română (Romanian)</strong>: alexminza, drazvan, polearnik</li>
<li><strong>русский (Russian)</strong>: _nomoretears_, agag11507, alexminza, anm, artemkonenko, cl0ne, denoos, DG,
JayDi85, KekcuHa, Mogost, Mr.GreyWolf, MustangDSG, NcNZllQnHVU, netforhack, NetWormKido, Rakleed, RKuchma,
ruslan.denisenko, ShareDVI, Shevchuk, solodyagin, talvind, VictorR2007, vsvyatski, wkill95</li>
<li><strong>српски језик (Serbian)</strong>: ArtBIT, oros</li>
<li><strong>Slovenčina (Slovak)</strong>: Asprotes, crazko, l.martinicky, pecer, Slavko</li>
<li><strong>Español (Spanish)</strong>: adolfogc, AdrianClv, AndreachongB, AndresQ, antifaz, Bendhet, capitantrueno,
caralu74, DarkHolme, e2jk, EdwardNavarro, eliluminado, erinm, gonrial, iglpdc, jojobrambs, LeoBeltran, lupa18,
masanchez5000, mauri.andres, NicolasCGN, Pablohn, pdinoto, picodotdev, piegope, pquin, puchrojo, rcalpha,
rodolfo.guagnini, systurbed, vargas.peniel, ventolinmono, vsvyatski, Xlate1984, zmzpa, Zranz</li>
<li><strong>Svenska (Swedish)</strong>: 0x9fff00, Anders_Bergqvist, ArmanB, baxtex, eson, henziger, jpyllman, krklns,
LIINdd, malkus, peron, Thelin, theschitz, victorhggqvst, zeroxfourc</li>
<li><strong> (Thai)</strong>: arthit, ben_cm, chumaporn.t, darika, digitalthailandproject, GitJirasamatakij,
muhammadmumean, nipattra, ordinaryjane, rayg, sirawat, Socialister, Wipanee</li>
<li><strong>Türkçe (Turkish)</strong>: cagries, etc, ethem578, mcveri, N3pp, SeLeNLeR, TeknoMobil, Ven_Zallow</li>
<li><strong>Українська (Ukrainian)</strong>: brisk022, chulivska, cl0ne, exlevan, m0stik, netforhack, paul_sm, ShareDVI,
zoresvit</li>
</ul>
)";

View File

@ -80,6 +80,8 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
connect(m_ui->buttonRedetectYubikey, SIGNAL(clicked()), SLOT(pollYubikey()));
#else
m_ui->hardwareKeyLabel->setVisible(false);
m_ui->hardwareKeyLabelHelp->setVisible(false);
m_ui->buttonRedetectYubikey->setVisible(false);
m_ui->comboChallengeResponse->setVisible(false);
m_ui->yubikeyProgress->setVisible(false);

View File

@ -11,7 +11,7 @@
</rect>
</property>
<property name="accessibleName">
<string>Unlock KePassXC Database</string>
<string>Unlock KeePassXC Database</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0,2">
<item>
@ -86,7 +86,7 @@
<item>
<widget class="ElidedLabel" name="fileNameLabel">
<property name="text">
<string>filename.kdbx</string>
<string notr="true">filename.kdbx</string>
</property>
</widget>
</item>
@ -380,7 +380,7 @@
}</string>
</property>
<property name="text">
<string>?</string>
<string notr="true">?</string>
</property>
<property name="iconSize">
<size>

View File

@ -381,6 +381,12 @@ void DatabaseWidget::createEntry()
void DatabaseWidget::replaceDatabase(QSharedPointer<Database> db)
{
// Save off new parent UUID which will be valid when creating a new entry
QUuid newParentUuid;
if (m_newParent) {
newParentUuid = m_newParent->uuid();
}
// TODO: instead of increasing the ref count temporarily, there should be a clean
// break from the old database. Without this crashes occur due to the change
// signals triggering dangling pointers.
@ -390,6 +396,15 @@ void DatabaseWidget::replaceDatabase(QSharedPointer<Database> db)
m_groupView->changeDatabase(m_db);
processAutoOpen();
// Restore the new parent group pointer, if not found default to the root group
// this prevents data loss when merging a database while creating a new entry
if (!newParentUuid.isNull()) {
m_newParent = m_db->rootGroup()->findGroupByUuid(newParentUuid);
if (!m_newParent) {
m_newParent = m_db->rootGroup();
}
}
emit databaseReplaced(oldDb, m_db);
#if defined(WITH_XC_KEESHARE)
@ -1480,7 +1495,7 @@ void DatabaseWidget::restoreGroupEntryFocus(const QUuid& groupUuid, const QUuid&
auto group = m_db->rootGroup()->findGroupByUuid(groupUuid);
if (group) {
m_groupView->setCurrentGroup(group);
auto entry = group->findEntryByUuid(entryUuid);
auto entry = group->findEntryByUuid(entryUuid, false);
if (entry) {
m_entryView->setCurrentEntry(entry);
}

View File

@ -72,6 +72,10 @@ EntryPreviewWidget::EntryPreviewWidget(QWidget* parent)
m_ui->groupCloseButton->setIcon(filePath()->icon("actions", "dialog-close"));
connect(m_ui->groupCloseButton, SIGNAL(clicked()), SLOT(hide()));
connect(m_ui->groupTabWidget, SIGNAL(tabBarClicked(int)), SLOT(updateTabIndexes()), Qt::QueuedConnection);
#if !defined(WITH_XC_KEESHARE)
removeTab(m_ui->groupTabWidget, m_ui->groupShareTab);
#endif
}
EntryPreviewWidget::~EntryPreviewWidget()
@ -376,6 +380,13 @@ void EntryPreviewWidget::openEntryUrl()
}
}
void EntryPreviewWidget::removeTab(QTabWidget* tabWidget, QWidget* widget)
{
const int tabIndex = tabWidget->indexOf(widget);
Q_ASSERT(tabIndex != -1);
tabWidget->removeTab(tabIndex);
}
void EntryPreviewWidget::setTabEnabled(QTabWidget* tabWidget, QWidget* widget, bool enabled)
{
const int tabIndex = tabWidget->indexOf(widget);

View File

@ -67,6 +67,7 @@ private slots:
void openEntryUrl();
private:
void removeTab(QTabWidget* tabWidget, QWidget* widget);
void setTabEnabled(QTabWidget* tabWidget, QWidget* widget, bool enabled);
static QPixmap preparePixmap(const QPixmap& pixmap, int size);

View File

@ -100,7 +100,7 @@
</font>
</property>
<property name="text">
<string>1234567</string>
<string notr="true">1234567</string>
</property>
</widget>
</item>

View File

@ -29,7 +29,7 @@
</font>
</property>
<property name="text">
<string>Downloading favicon 0/0...</string>
<string notr="true">Downloading favicon 0/0...</string>
</property>
</widget>
</item>

View File

@ -142,10 +142,6 @@ MainWindow* getMainWindow()
MainWindow::MainWindow()
: m_ui(new Ui::MainWindow())
, m_trayIcon(nullptr)
, m_appExitCalled(false)
, m_appExiting(false)
, m_lastFocusOutTime(0)
{
g_MainWindow = this;
@ -183,6 +179,9 @@ MainWindow::MainWindow()
m_entryContextMenu->addAction(m_ui->actionEntryOpenUrl);
m_entryContextMenu->addAction(m_ui->actionEntryDownloadIcon);
m_entryNewContextMenu = new QMenu(this);
m_entryNewContextMenu->addAction(m_ui->actionEntryNew);
restoreGeometry(config()->get("GUI/MainWindowGeometry").toByteArray());
restoreState(config()->get("GUI/MainWindowState").toByteArray());
#ifdef WITH_XC_BROWSER
@ -288,6 +287,10 @@ MainWindow::MainWindow()
connect(m_ui->menuEntries, SIGNAL(aboutToShow()), SLOT(obtainContextFocusLock()));
connect(m_ui->menuEntries, SIGNAL(aboutToHide()), SLOT(releaseContextFocusLock()));
connect(m_entryContextMenu, SIGNAL(aboutToShow()), SLOT(obtainContextFocusLock()));
connect(m_entryContextMenu, SIGNAL(aboutToHide()), SLOT(releaseContextFocusLock()));
connect(m_entryNewContextMenu, SIGNAL(aboutToShow()), SLOT(obtainContextFocusLock()));
connect(m_entryNewContextMenu, SIGNAL(aboutToHide()), SLOT(releaseContextFocusLock()));
connect(m_ui->menuGroups, SIGNAL(aboutToShow()), SLOT(obtainContextFocusLock()));
connect(m_ui->menuGroups, SIGNAL(aboutToHide()), SLOT(releaseContextFocusLock()));
@ -990,31 +993,29 @@ void MainWindow::toggleUsernamesHidden()
void MainWindow::closeEvent(QCloseEvent* event)
{
// ignore double close events (happens on macOS when closing from the dock)
if (m_appExiting) {
event->accept();
return;
}
// Don't ignore close event when the app is hidden to tray.
// This can occur when the OS issues close events on shutdown.
if (config()->get("GUI/MinimizeOnClose").toBool() && !isHidden() && !m_appExitCalled) {
// Ignore event and hide to tray if this is not an actual close
// request by the system's session manager.
if (config()->get("GUI/MinimizeOnClose").toBool() && !m_appExitCalled && !isHidden() && !qApp->isSavingSession()) {
event->ignore();
hideWindow();
return;
}
bool accept = saveLastDatabases();
if (accept) {
m_appExiting = true;
m_appExiting = saveLastDatabases();
if (m_appExiting) {
saveWindowInformation();
event->accept();
QApplication::quit();
} else {
event->ignore();
return;
}
m_appExitCalled = false;
event->ignore();
}
void MainWindow::changeEvent(QEvent* event)
@ -1125,7 +1126,17 @@ void MainWindow::releaseContextFocusLock()
void MainWindow::showEntryContextMenu(const QPoint& globalPos)
{
bool entrySelected = false;
auto dbWidget = m_ui->tabWidget->currentDatabaseWidget();
if (dbWidget) {
entrySelected = dbWidget->currentEntryHasFocus();
}
if (entrySelected) {
m_entryContextMenu->popup(globalPos);
} else {
m_entryNewContextMenu->popup(globalPos);
}
}
void MainWindow::showGroupContextMenu(const QPoint& globalPos)
@ -1208,15 +1219,14 @@ void MainWindow::processTrayIconTrigger()
toggleWindow();
} else if (m_trayIconTriggerReason == QSystemTrayIcon::Trigger
|| m_trayIconTriggerReason == QSystemTrayIcon::MiddleClick) {
// Toggle window if hidden
// If on windows, check if focus switched within the last second because
// clicking the tray icon removes focus from main window
// If on Linux or macOS, check if the window is active
if (isHidden()
// Toggle window if is not in front.
#ifdef Q_OS_WIN
|| (Clock::currentSecondsSinceEpoch() - m_lastFocusOutTime) <= 1) {
// If on Windows, check if focus switched within the last second because
// clicking the tray icon removes focus from main window.
if (isHidden() || (Clock::currentSecondsSinceEpoch() - m_lastFocusOutTime) <= 1) {
#else
|| windowHandle()->isActive()) {
// If on Linux or macOS, check if the window has focus.
if (hasFocus() || isHidden() || windowHandle()->isActive()) {
#endif
toggleWindow();
} else {

View File

@ -144,24 +144,25 @@ private:
const QScopedPointer<Ui::MainWindow> m_ui;
SignalMultiplexer m_actionMultiplexer;
QAction* m_clearHistoryAction;
QAction* m_searchWidgetAction;
QMenu* m_entryContextMenu;
QActionGroup* m_lastDatabasesActions;
QActionGroup* m_copyAdditionalAttributeActions;
InactivityTimer* m_inactivityTimer;
InactivityTimer* m_touchIDinactivityTimer;
QPointer<QAction> m_clearHistoryAction;
QPointer<QAction> m_searchWidgetAction;
QPointer<QMenu> m_entryContextMenu;
QPointer<QMenu> m_entryNewContextMenu;
QPointer<QActionGroup> m_lastDatabasesActions;
QPointer<QActionGroup> m_copyAdditionalAttributeActions;
QPointer<InactivityTimer> m_inactivityTimer;
QPointer<InactivityTimer> m_touchIDinactivityTimer;
int m_countDefaultAttributes;
QSystemTrayIcon* m_trayIcon;
ScreenLockListener* m_screenLockListener;
QPointer<QSystemTrayIcon> m_trayIcon;
QPointer<ScreenLockListener> m_screenLockListener;
QPointer<SearchWidget> m_searchWidget;
Q_DISABLE_COPY(MainWindow)
bool m_appExitCalled;
bool m_appExiting;
bool m_contextMenuFocusLock;
uint m_lastFocusOutTime;
bool m_appExitCalled = false;
bool m_appExiting = false;
bool m_contextMenuFocusLock = false;
uint m_lastFocusOutTime = 0;
QTimer m_trayIconTriggerTimer;
QSystemTrayIcon::ActivationReason m_trayIconTriggerReason;
};

View File

@ -765,7 +765,7 @@
<string>&amp;Keyboard Shortcuts</string>
</property>
<property name="shortcut">
<string>Ctrl+/</string>
<string notr="true">Ctrl+/</string>
</property>
</action>
</widget>

View File

@ -171,7 +171,7 @@ QProgressBar::chunk {
<item row="0" column="2">
<widget class="QToolButton" name="togglePasswordButton">
<property name="accessibleName">
<string>Toggle password visibiity</string>
<string>Toggle password visibility</string>
</property>
<property name="accessibleDescription">
<string/>

View File

@ -232,7 +232,7 @@
</font>
</property>
<property name="accessibleName">
<string>Field seperation</string>
<string>Field separation</string>
</property>
<property name="editable">
<bool>false</bool>

View File

@ -400,8 +400,10 @@ void DatabaseSettingsWidgetEncryption::updateFormatCompatibility(int index, bool
if (kdf->uuid() == KeePass2::KDF_ARGON2) {
auto argon2Kdf = kdf.staticCast<Argon2Kdf>();
argon2Kdf->setMemory(128 * 1024);
argon2Kdf->setParallelism(static_cast<quint32>(QThread::idealThreadCount()));
// Default to 64 MiB of memory and 2 threads
// these settings are safe for desktop and mobile devices
argon2Kdf->setMemory(1 << 16);
argon2Kdf->setParallelism(2);
}
activateChangeDecryptionTime();

View File

@ -22,7 +22,7 @@
#include "core/FilePath.h"
#include "core/Group.h"
#include "core/Metadata.h"
#include "zxcvbn/zxcvbn.h"
#include "zxcvbn.h"
#include <QFileInfo>
#include <QHash>

View File

@ -129,7 +129,7 @@
<item row="9" column="0" alignment="Qt::AlignLeft|Qt::AlignTop">
<widget class="QCheckBox" name="notesEnabled">
<property name="toolTip">
<string>Toggle notes visibile</string>
<string>Toggle notes visible</string>
</property>
<property name="accessibleName">
<string>Toggle notes visible</string>

View File

@ -149,8 +149,7 @@ namespace
KeeShareSettings::Sign sign;
auto sshKey = own.key.sshKey();
sshKey.openKey(QString());
const Signature signer;
sign.signature = signer.create(bytes, sshKey);
sign.signature = Signature::create(bytes, sshKey);
sign.certificate = own.certificate;
stream << KeeShareSettings::Sign::serialize(sign);
stream.flush();

View File

@ -288,7 +288,7 @@ QList<ShareObserver::Result> ShareObserver::exportShares()
const auto& reference = it.value().first();
const QString resolvedPath = resolvePath(reference.config.path, m_db);
m_fileWatcher->ignoreFileChanges(resolvedPath);
ShareExport::intoContainer(resolvedPath, reference.config, reference.group);
results << ShareExport::intoContainer(resolvedPath, reference.config, reference.group);
m_fileWatcher->observeFileChanges(true);
}
return results;

View File

@ -0,0 +1,79 @@
#!/usr/bin/env python3
import json
import os
# Download Transifex languages dump at: https://www.transifex.com/api/2/project/keepassxc/languages
# Language information from https://www.wikiwand.com/en/List_of_ISO_639-1_codes and http://www.lingoes.net/en/translator/langcode.htm
LANGS = {
"ar" : "العربية (Arabic)",
"bn" : "বাংলা (Bengali)",
"ca" : "català (Catalan)",
"cs" : "čeština (Czech)",
"da" : "dansk (Danish)",
"de" : "Deutsch (German)",
"el" : "ελληνικά (Greek)",
"en_GB" : "English (UK)",
"en_US" : "English (USA)",
"eo" : "Esperanto (Esperanto)",
"es" : "Español (Spanish)",
"et" : "eesti (Estonian)",
"eu" : "euskara (Basque)",
"fa" : "فارسی (Farsi)",
"fa_IR" : "فارسی (Farsi (Iran))",
"fi" : "suomi (Finnish)",
"fr" : "français (French)",
"gl" : "Galego (Galician)",
"he" : "עברית (Hebrew)",
"hr_HR" : "hrvatski jezik (Croatian)",
"hu" : "magyar (Hungarian)",
"id" : "Bahasa (Indonesian)",
"is_IS" : "Íslenska (Icelandic)",
"it" : "Italiano (Italian)",
"ja" : "日本語 (Japanese)",
"kk" : "қазақ тілі (Kazakh)",
"ko" : "한국어 (Korean)",
"la" : "latine (Latin)",
"lt" : "lietuvių kalba (Lithuanian)",
"lv" : "latviešu valoda (Latvian)",
"nb" : "Norsk Bokmål (Norwegian Bokmål)",
"nl_NL" : "Nederlands (Dutch)",
"my" : "ဗမာစာ (Burmese)",
"pa" : "ਪੰਜਾਬੀ (Punjabi)",
"pa_IN" : "ਪੰਜਾਬੀ (Punjabi (India))",
"pl" : "język polski (Polish)",
"pt" : "Português (Portuguese)",
"pt_BR" : "Português (Portuguese (Brazil))",
"pt_PT" : "Português (Portuguese (Portugal))",
"ro" : "Română (Romanian)",
"ru" : "русский (Russian)",
"sk" : "Slovenčina (Slovak)",
"sl_SI" : "Slovenščina (Slovenian)",
"sr" : "српски језик (Serbian)",
"sv" : "Svenska (Swedish)",
"th" : "ไทย (Thai)",
"tr" : "Türkçe (Turkish)",
"uk" : "Українська (Ukrainian)",
"zh_CN" : "中文 (Chinese (Simplified))",
"zh_TW" : "中文 (台灣) (Chinese (Traditional))",
}
TEMPLATE = "<li><strong>{0}</strong>: {1}</li>\n"
if not os.path.exists("languages.json"):
print("Could not find 'languages.json' in current directory!")
print("Save the output from https://www.transifex.com/api/2/project/keepassxc/languages")
exit(0)
with open("languages.json") as json_file:
output = open("translators.html", "w", encoding="utf-8")
languages = json.load(json_file)
for lang in languages:
code = lang["language_code"]
if code not in LANGS:
print("WARNING: Could not find language code:", code)
continue
translators = ", ".join(sorted(lang["reviewers"] + lang["translators"], key=str.casefold))
output.write(TEMPLATE.format(LANGS[code], translators))
output.close()
print("Language translators written to 'translators.html'!")