Compare commits
439 Commits
fix/cli-sh
...
2.7.10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b342be4571 | ||
|
|
8aec6fb9ad | ||
|
|
55d75fbd53 | ||
|
|
4f552ba3ed | ||
|
|
9b1ee4b476 | ||
|
|
c3e32a9502 | ||
|
|
ea2f17b9a9 | ||
|
|
3d8dac0c53 | ||
|
|
beb314d7c7 | ||
|
|
903b8f189e | ||
|
|
941c1f5d7f | ||
|
|
f0c5c2ad3f | ||
|
|
43205995c6 | ||
|
|
bb4c957144 | ||
|
|
4034c68e67 | ||
|
|
089d0ca2b7 | ||
|
|
6197893e01 | ||
|
|
8d1898bd0b | ||
|
|
3af68b1d3f | ||
|
|
3b2f54daff | ||
|
|
3083626bda | ||
|
|
5ad6562578 | ||
|
|
14ee702b09 | ||
|
|
f48dcb3dba | ||
|
|
1a11a55a42 | ||
|
|
57235219f2 | ||
|
|
0b32cf348d | ||
|
|
c3214f6776 | ||
|
|
4e40a7fd79 | ||
|
|
d655d18a79 | ||
|
|
2c76a370c2 | ||
|
|
6cc6e42542 | ||
|
|
e82e9dad3b | ||
|
|
4df16fa501 | ||
|
|
048f4c45b3 | ||
|
|
0cb89a03ec | ||
|
|
fbad1b51f0 | ||
|
|
abf5a2ef8b | ||
|
|
99c8936568 | ||
|
|
ef2b5e7c26 | ||
|
|
09e47d3731 | ||
|
|
f14c256b44 | ||
|
|
080e315a09 | ||
|
|
8a3de7334b | ||
|
|
8b24e48fde | ||
|
|
bb6950433d | ||
|
|
12b2360855 | ||
|
|
2364e4cd4a | ||
|
|
84b064b743 | ||
|
|
c5e1fbfafc | ||
|
|
998569234d | ||
|
|
98e671fdc6 | ||
|
|
ecf2e2da5a | ||
|
|
ca68031795 | ||
|
|
789f91ba39 | ||
|
|
b85675f4a7 | ||
|
|
e210faa097 | ||
|
|
be862b7a07 | ||
|
|
241155e64d | ||
|
|
18cdbb3f5a | ||
|
|
da606923e9 | ||
|
|
9348ecdc27 | ||
|
|
1e6486ae17 | ||
|
|
bd4bdc6a3f | ||
|
|
2836364e1a | ||
|
|
c6800bf705 | ||
|
|
1df561ee07 | ||
|
|
c12b0c5568 | ||
|
|
6f42041837 | ||
|
|
383c6d05d1 | ||
|
|
b68775e9d8 | ||
|
|
7de453b838 | ||
|
|
ae28ff6833 | ||
|
|
70c024f7f5 | ||
|
|
06699c6692 | ||
|
|
0731a64957 | ||
|
|
36ec1aa35b | ||
|
|
53bbc4717e | ||
|
|
3c26709da9 | ||
|
|
413eec9b8c | ||
|
|
94eb3ffa7a | ||
|
|
673bdbcf3c | ||
|
|
b671070c0d | ||
|
|
aeee40048c | ||
|
|
518947e3aa | ||
|
|
defb5f027d | ||
|
|
292046ff7f | ||
|
|
5a3bde7676 | ||
|
|
05167e7b21 | ||
|
|
ad9ef88e15 | ||
|
|
0ae88131f6 | ||
|
|
0e59f2745e | ||
|
|
78cff4b6d9 | ||
|
|
8bdbccf13f | ||
|
|
4317e9d829 | ||
|
|
e565f89d47 | ||
|
|
41de1dff2d | ||
|
|
3d66618818 | ||
|
|
12cd224f42 | ||
|
|
2b5ab7db82 | ||
|
|
3e90f1b4d8 | ||
|
|
8599f0903c | ||
|
|
182bcd4ef7 | ||
|
|
8dd2377765 | ||
|
|
bfa64aa8f0 | ||
|
|
d883ca26a9 | ||
|
|
249e71fe88 | ||
|
|
ed31da0021 | ||
|
|
59bd71ddca | ||
|
|
29feb5da79 | ||
|
|
ff89a05743 | ||
|
|
fe7f1e0a51 | ||
|
|
a0b8abecb8 | ||
|
|
1de0da3d44 | ||
|
|
8f6dd13b0a | ||
|
|
809fb0d457 | ||
|
|
3ab7166e63 | ||
|
|
ee08ef421d | ||
|
|
48bf993ac5 | ||
|
|
b7e6679a58 | ||
|
|
071145dd19 | ||
|
|
22811471ac | ||
|
|
ed3f7f5a16 | ||
|
|
f83cd81ad7 | ||
|
|
c3259b2610 | ||
|
|
54afbe6a2f | ||
|
|
0aba77ee55 | ||
|
|
cf023253a0 | ||
|
|
c464f2bfe9 | ||
|
|
f19d254a0c | ||
|
|
e7f9d58541 | ||
|
|
8cbbe7cdfc | ||
|
|
8bdc7c4702 | ||
|
|
018686afeb | ||
|
|
abcff25e57 | ||
|
|
64eb3d0c82 | ||
|
|
e26dbc5608 | ||
|
|
42a2443d62 | ||
|
|
6fbab25478 | ||
|
|
2f43ca42be | ||
|
|
95b91a0890 | ||
|
|
6f77d98642 | ||
|
|
1b3abf8ab0 | ||
|
|
1bdf1bbbed | ||
|
|
1125a02d1e | ||
|
|
6e362ee637 | ||
|
|
388b4a736a | ||
|
|
87bf232e97 | ||
|
|
f6757d35ad | ||
|
|
235015cb56 | ||
|
|
75de62327d | ||
|
|
8f98d390e3 | ||
|
|
c9d71e7781 | ||
|
|
505f338d28 | ||
|
|
ffc72c896c | ||
|
|
8c91836038 | ||
|
|
d14821fb16 | ||
|
|
2dfc0e540c | ||
|
|
30d4e36a8b | ||
|
|
43ca4e7dfe | ||
|
|
49fd85c975 | ||
|
|
94df540ffe | ||
|
|
96fcc2ce89 | ||
|
|
c4e27d431a | ||
|
|
3e9fba7283 | ||
|
|
d7c054e9b2 | ||
|
|
485c446013 | ||
|
|
9dd90c95a7 | ||
|
|
a8b60b7b02 | ||
|
|
3b8dc028c1 | ||
|
|
bab48b42f7 | ||
|
|
775efc65ed | ||
|
|
d8006e0b76 | ||
|
|
651bcfc904 | ||
|
|
029ccefe22 | ||
|
|
9d714d5b4d | ||
|
|
b5827aa25f | ||
|
|
8f03f2f59e | ||
|
|
417bc29bc8 | ||
|
|
381eb76f7b | ||
|
|
dbc7f020fd | ||
|
|
50eec240b4 | ||
|
|
d87f0030a3 | ||
|
|
8723b7f6a4 | ||
|
|
4b87a3e58e | ||
|
|
bd5984ca82 | ||
|
|
969d3f9b23 | ||
|
|
f61f55fff7 | ||
|
|
305fd24a8e | ||
|
|
a5c3bf6d9d | ||
|
|
97cf35c993 | ||
|
|
eeea299187 | ||
|
|
6875851892 | ||
|
|
ff6c3d7d9a | ||
|
|
deb0926497 | ||
|
|
0b71cb1dad | ||
|
|
caece405fb | ||
|
|
3a86381df8 | ||
|
|
68e2dd8d22 | ||
|
|
bbd1604894 | ||
|
|
976c6914a6 | ||
|
|
cde88546f3 | ||
|
|
fff1b49f73 | ||
|
|
18cfbf729c | ||
|
|
6f112b11e4 | ||
|
|
ee1268c518 | ||
|
|
d78a6b6095 | ||
|
|
63b18084ac | ||
|
|
7d0dc67180 | ||
|
|
f20b531430 | ||
|
|
28d096a89a | ||
|
|
350931b707 | ||
|
|
b7a1c620e4 | ||
|
|
067deb9bd7 | ||
|
|
99e42b1fce | ||
|
|
53d06f127d | ||
|
|
3094302bcc | ||
|
|
b504c72563 | ||
|
|
b1168d0233 | ||
|
|
3ca757883f | ||
|
|
c76d9e45e7 | ||
|
|
a23b4f4dc0 | ||
|
|
e6d2e5fe6e | ||
|
|
c9b0cbaa4e | ||
|
|
762fd9462f | ||
|
|
394c0375b7 | ||
|
|
4cf5e83c38 | ||
|
|
cb5d3ed21d | ||
|
|
4bd9fdd7a4 | ||
|
|
fe739578ab | ||
|
|
3f77678b5c | ||
|
|
c477f43c40 | ||
|
|
7371589955 | ||
|
|
1cbbcff259 | ||
|
|
416581b179 | ||
|
|
82c1bf4ddb | ||
|
|
7f33868d14 | ||
|
|
c5312d63f2 | ||
|
|
e401e8f4bc | ||
|
|
159c7cf153 | ||
|
|
5686776e53 | ||
|
|
05ab5b1700 | ||
|
|
be873c83d6 | ||
|
|
87c24222b8 | ||
|
|
dd21defcf3 | ||
|
|
25d46fbc03 | ||
|
|
742a4f8980 | ||
|
|
e84d6c0b06 | ||
|
|
636d013557 | ||
|
|
3e6b118267 | ||
|
|
eee4ca9a26 | ||
|
|
aecd154399 | ||
|
|
f293aad74f | ||
|
|
5804e63559 | ||
|
|
fb2664b54a | ||
|
|
10f4704724 | ||
|
|
ea77ee686d | ||
|
|
09bda6a882 | ||
|
|
6fb498648d | ||
|
|
5b47190fcc | ||
|
|
663d4d99ae | ||
|
|
4ea0a1058c | ||
|
|
55ca5ca34c | ||
|
|
cdf6cd7cd2 | ||
|
|
4c1105f968 | ||
|
|
a81771207f | ||
|
|
2fe647fd7a | ||
|
|
33b740ddd0 | ||
|
|
f30604c6f6 | ||
|
|
e9ea5b43ec | ||
|
|
76a7dc79f4 | ||
|
|
1594e5f4e3 | ||
|
|
13a71ff1c8 | ||
|
|
fa73f100f7 | ||
|
|
b8da5e0577 | ||
|
|
6165975bdc | ||
|
|
10891a403d | ||
|
|
37dabd2561 | ||
|
|
9d0537bdab | ||
|
|
063bf4a58d | ||
|
|
d5d9a4c08c | ||
|
|
eddd97fbab | ||
|
|
53f88b93fb | ||
|
|
59042563b3 | ||
|
|
74d96fc06f | ||
|
|
9c1a01ffe8 | ||
|
|
4b92838b4f | ||
|
|
b225b85644 | ||
|
|
ebc0b3ff5f | ||
|
|
64281b508b | ||
|
|
6c9078c870 | ||
|
|
6b51c66c68 | ||
|
|
d04a6c4eb7 | ||
|
|
28e2806e07 | ||
|
|
6182b605c0 | ||
|
|
8077cd028d | ||
|
|
761e1aed58 | ||
|
|
ee44a7fd70 | ||
|
|
058e6d15c1 | ||
|
|
83720e6960 | ||
|
|
86550f2253 | ||
|
|
881e6b5a8b | ||
|
|
102ce04b2d | ||
|
|
90bbb66409 | ||
|
|
df40742223 | ||
|
|
f7920c12d5 | ||
|
|
51a08fc85e | ||
|
|
655202a35a | ||
|
|
cbbabf477a | ||
|
|
0167ce60bd | ||
|
|
d362b51450 | ||
|
|
95aaa96fb8 | ||
|
|
fa53c79ecf | ||
|
|
27668b81a5 | ||
|
|
f1a5e1c899 | ||
|
|
ae55d88544 | ||
|
|
25fc69dcd4 | ||
|
|
1bb215156e | ||
|
|
758d6f0c8d | ||
|
|
798fee338b | ||
|
|
9253a59f05 | ||
|
|
18857cb60b | ||
|
|
7bdcf05fc3 | ||
|
|
32d115d22e | ||
|
|
2e0d66039d | ||
|
|
acb37db6f1 | ||
|
|
0e1b32adcd | ||
|
|
c20104e67c | ||
|
|
32f2710430 | ||
|
|
605f13ed4a | ||
|
|
a6a4ed6ed4 | ||
|
|
c3bd31c51b | ||
|
|
90c63483c1 | ||
|
|
3383882b95 | ||
|
|
d5adf7592c | ||
|
|
9ba88e2f13 | ||
|
|
772964886e | ||
|
|
70b73524c6 | ||
|
|
a459344078 | ||
|
|
63b2394ed0 | ||
|
|
cdb10dce0c | ||
|
|
9b5b1d6dce | ||
|
|
c231abe13d | ||
|
|
d81f6ea1c0 | ||
|
|
1012d715b2 | ||
|
|
a1a5e21834 | ||
|
|
bc147070b6 | ||
|
|
9176ddc3e1 | ||
|
|
4f07a6592c | ||
|
|
3ad205f733 | ||
|
|
f01608f2bb | ||
|
|
fa4837c67b | ||
|
|
af466b120e | ||
|
|
ce790dcd3a | ||
|
|
e1d9a4fb53 | ||
|
|
d8483d3350 | ||
|
|
2d13588c95 | ||
|
|
acf1d6b1ac | ||
|
|
2ac1e0ed49 | ||
|
|
0a0389ad56 | ||
|
|
9d2f3d53d6 | ||
|
|
9bd4c785e6 | ||
|
|
c203ee7f09 | ||
|
|
047251a07f | ||
|
|
a6db8ba2db | ||
|
|
71b1df39eb | ||
|
|
82f056e5d0 | ||
|
|
edae652d6f | ||
|
|
b1f868cd6c | ||
|
|
08f7c6f863 | ||
|
|
7fa3e6ef90 | ||
|
|
035c99896b | ||
|
|
b56cc62942 | ||
|
|
3e3990934a | ||
|
|
faa4c07095 | ||
|
|
245dccf91c | ||
|
|
c6d4fd6d31 | ||
|
|
14d0732e1d | ||
|
|
dc07f01418 | ||
|
|
3fa513a78d | ||
|
|
0480c45d5c | ||
|
|
44fa40ca72 | ||
|
|
285f8981f8 | ||
|
|
00c019c8c2 | ||
|
|
3746452b88 | ||
|
|
643ab4e95d | ||
|
|
4978184480 | ||
|
|
d80be4c459 | ||
|
|
31924fcd89 | ||
|
|
87cd9c6fb9 | ||
|
|
8654b25e80 | ||
|
|
f95019964e | ||
|
|
59d20cb7ae | ||
|
|
e83c9734e0 | ||
|
|
f4510c64ec | ||
|
|
64dda09565 | ||
|
|
de168959a5 | ||
|
|
ee55143c4a | ||
|
|
5b923aee1a | ||
|
|
f3d448485a | ||
|
|
28328a7080 | ||
|
|
fab76c04cc | ||
|
|
74e1e7c9d1 | ||
|
|
7de9ab25ab | ||
|
|
233be1fc10 | ||
|
|
bad015115d | ||
|
|
e7e75c1277 | ||
|
|
e245701533 | ||
|
|
0cbfbc08f3 | ||
|
|
731c89cc1c | ||
|
|
b75abaad08 | ||
|
|
40316ac7b9 | ||
|
|
c4f625a3d1 | ||
|
|
d954519e10 | ||
|
|
f0a7c636a4 | ||
|
|
bfeb75c900 | ||
|
|
19bd6069d7 | ||
|
|
60d4e06531 | ||
|
|
9150febd02 | ||
|
|
d8d5ddcab6 | ||
|
|
8190b20efe | ||
|
|
989348bbfb | ||
|
|
679b93b601 | ||
|
|
d1d191e2b0 | ||
|
|
6f619271c4 | ||
|
|
3163547096 | ||
|
|
6da7188ecf | ||
|
|
35285d72bb | ||
|
|
07755c324a | ||
|
|
8711d31f24 | ||
|
|
a3c24b4bbc | ||
|
|
4d20cb1654 | ||
|
|
7e8a672de4 | ||
|
|
107dcae26c | ||
|
|
121d54c96a | ||
|
|
6f28b5e2ba | ||
|
|
dca70f809d | ||
|
|
750a3383ca | ||
|
|
dda70e1453 |
@@ -81,7 +81,7 @@ SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: c++17
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
...
|
||||
|
||||
2
.github/CONTRIBUTING.md
vendored
@@ -38,7 +38,7 @@ We will accept contributions of good code that we can use from anyone.
|
||||
- “contributions”: This means just about anything you wish to contribute to the project, as long as it is good code we can use. The easier you make it for us to accept your contribution, the happier we are, but if it’s good enough, we will do a reasonable amount of work to use it.
|
||||
- “of good code”: This means that we will accept contributions that work well and efficiently, that fit in with the goals of the project, that match the project’s coding style, and that do not impose an undue maintenance workload on us going forward. This does not mean just program code, either, but documentation and artistic works as appropriate to the project.
|
||||
- “that we can use”: This means that your contribution must be given freely and irrevocably, that you must have the right to contribute it for our unrestricted use, and that your contribution is made under a license that is compatible with the license the project has chosen and that permits us to include, distribute, and modify your work without restriction.
|
||||
- “from anyone”: This means exactly that. We don’t care about anything but your code. We don’t care about your race, religion, national origin, biological gender, perceived gender, sexual orientation, lifestyle, political viewpoint, or anything extraneous like that. We will neither reject your contribution nor grant it preferential treatment on any basis except the code itself. We do, however, reserve the right to limit your access to our community if you violate our [Code of Conduct](../CODE-OF-CONDUCT.md).
|
||||
- “from anyone”: This means exactly that. We don’t care about anything but your code. We don’t care about your race, religion, national origin, biological gender, perceived gender, sexual orientation, lifestyle, political viewpoint, or anything extraneous like that. We will neither reject your contribution nor grant it preferential treatment on any basis except the code itself. We do, however, reserve the right to tell you to go away if you behave too obnoxiously toward us.
|
||||
|
||||
#### If Your Contribution Is Rejected
|
||||
|
||||
|
||||
39
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: provide information about a problem
|
||||
title:
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
## Overview
|
||||
[TIP]: # ( DO NOT include screenshots of your actual database! )
|
||||
[NOTE]: # ( Give a BRIEF summary about your problem )
|
||||
|
||||
|
||||
## Steps to Reproduce
|
||||
[NOTE]: # ( Provide a simple set of steps to reproduce this bug. )
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
## Expected Behavior
|
||||
[NOTE]: # ( Tell us what you expected to happen )
|
||||
|
||||
|
||||
## Actual Behavior
|
||||
[NOTE]: # ( Tell us what actually happens )
|
||||
|
||||
|
||||
## Context
|
||||
[NOTE]: # ( Give us any additional information you may have. )
|
||||
|
||||
|
||||
[NOTE]: # ( Paste debug info from Help → About here )
|
||||
KeePassXC - VERSION
|
||||
Revision: REVISION
|
||||
|
||||
[NOTE]: # ( Pick choices based on your environment )
|
||||
Operating System: Windows/Linux/macOS
|
||||
Desktop Env: Gnome/KDE/XFCE/Mate/Cinnamon
|
||||
Windowing System: X11/Wayland
|
||||
83
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,83 +0,0 @@
|
||||
name: Bug Report
|
||||
description: Provide information about a problem you are experiencing.
|
||||
type: Bug
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Have you searched for an existing issue?
|
||||
description: |
|
||||
Use the issue search box to see if one already exists for the bug you encountered.
|
||||
Also take a moment to review our pinned issues.
|
||||
options:
|
||||
- label: Yes, I tried searching and reviewed the pinned issues
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: Brief Summary
|
||||
description: |
|
||||
Provide an overview of the problem, include any information that may help us triage this issue.
|
||||
Provide screenshots if possible, but do NOT show sensitive data (use View -> Allow Screen Capture).
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: Provide a simple set of steps to reproduce this bug.
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected_vs_actual
|
||||
attributes:
|
||||
label: Expected Versus Actual Behavior
|
||||
description: Tell us what you expected to happen and what actually happened.
|
||||
|
||||
- type: textarea
|
||||
id: debug_info
|
||||
attributes:
|
||||
label: KeePassXC Debug Information
|
||||
placeholder: "Paste the output of: Help -> About -> Debug Info"
|
||||
render: Text
|
||||
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: Select your operating system.
|
||||
options:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
- Other (BSD, Haiku, etc)
|
||||
|
||||
- type: dropdown
|
||||
id: desktop_env
|
||||
attributes:
|
||||
label: Linux Desktop Environment
|
||||
description: If on Linux, please select your desktop environment.
|
||||
options:
|
||||
- Gnome
|
||||
- KDE
|
||||
- XFCE
|
||||
- Mate / Cinnamon
|
||||
- Sway
|
||||
- i3
|
||||
- Other
|
||||
|
||||
- type: dropdown
|
||||
id: window_system
|
||||
attributes:
|
||||
label: Linux Windowing System
|
||||
description: If on Linux, please select your windowing system.
|
||||
options:
|
||||
- X11
|
||||
- Wayland
|
||||
19
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: tell us about a new feature you want
|
||||
title:
|
||||
labels: new feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
## Summary
|
||||
[TIP]: # ( DO NOT include screenshots of your actual database! )
|
||||
[NOTE]: # ( Provide a brief overview of what the new feature is all about )
|
||||
|
||||
|
||||
## Examples
|
||||
[NOTE]: # ( Show us a picture or mock-up of your proposal )
|
||||
|
||||
|
||||
## Context
|
||||
[NOTE]: # ( Why does this feature matter to you? What unique circumstances do you have? )
|
||||
34
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,34 +0,0 @@
|
||||
name: Feature Request
|
||||
description: Tell us about a new feature you want.
|
||||
type: Feature
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Have you searched for an existing feature request?
|
||||
description: Use the issue search box to see if one already exists for the feature you want.
|
||||
options:
|
||||
- label: Yes, I tried searching
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: Brief Summary
|
||||
description: |
|
||||
Provide an overview of the feature you are interested in adding.
|
||||
Provide screenshots if possible, but do NOT show sensitive data (use View -> Allow Screen Capture).
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: example
|
||||
attributes:
|
||||
label: Example
|
||||
description: Provide an example of how this feature would be used.
|
||||
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Context
|
||||
description: Why does this feature matter to you? What unique circumstances do you have?
|
||||
85
.github/ISSUE_TEMPLATE/prerelease_bug_report.yml
vendored
@@ -1,85 +0,0 @@
|
||||
name: Pre-Release Bug Report
|
||||
description: Report an issue with pre-release code (e.g. snapshot builds).
|
||||
type: Bug
|
||||
labels: PRE-RELEASE BUG
|
||||
assignees: droidmonkey
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Have you searched for an existing issue?
|
||||
description: |
|
||||
Use the issue search box to see if one already exists for the bug you encountered.
|
||||
Also take a moment to review our pinned issues.
|
||||
options:
|
||||
- label: Yes, I tried searching and reviewed the pinned issues
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: Brief Summary
|
||||
description: |
|
||||
Provide an overview of the problem, include any information that may help us triage this issue.
|
||||
Provide screenshots if possible, but do NOT show sensitive data (use View -> Allow Screen Capture).
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: Provide a simple set of steps to reproduce this bug.
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected_vs_actual
|
||||
attributes:
|
||||
label: Expected Versus Actual Behavior
|
||||
description: Tell us what you expected to happen and what actually happened.
|
||||
|
||||
- type: textarea
|
||||
id: debug_info
|
||||
attributes:
|
||||
label: KeePassXC Debug Information
|
||||
placeholder: "Paste the output of: Help -> About -> Debug Info"
|
||||
render: Text
|
||||
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: Select your operating system.
|
||||
options:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
- Other (BSD, Haiku, etc)
|
||||
|
||||
- type: dropdown
|
||||
id: desktop_env
|
||||
attributes:
|
||||
label: Linux Desktop Environment
|
||||
description: If on Linux, please select your desktop environment.
|
||||
options:
|
||||
- Gnome
|
||||
- KDE
|
||||
- XFCE
|
||||
- Mate / Cinnamon
|
||||
- Sway
|
||||
- i3
|
||||
- Other
|
||||
|
||||
- type: dropdown
|
||||
id: window_system
|
||||
attributes:
|
||||
label: Linux Windowing System
|
||||
description: If on Linux, please select your windowing system.
|
||||
options:
|
||||
- X11
|
||||
- Wayland
|
||||
39
.github/ISSUE_TEMPLATE/release-preview-bug-report.md
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: Release Preview Bug report
|
||||
about: report a bug with a release preview (e.g., 2.6.0-beta1)
|
||||
title:
|
||||
labels: PRE-RELEASE BUG
|
||||
assignees: droidmonkey
|
||||
|
||||
---
|
||||
## Overview
|
||||
[TIP]: # ( DO NOT include screenshots of your actual database! )
|
||||
[NOTE]: # ( Give a BRIEF summary about your problem )
|
||||
|
||||
|
||||
## Steps to Reproduce
|
||||
[NOTE]: # ( Provide a simple set of steps to reproduce this bug. )
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
## Expected Behavior
|
||||
[NOTE]: # ( Tell us what you expected to happen )
|
||||
|
||||
|
||||
## Actual Behavior
|
||||
[NOTE]: # ( Tell us what actually happens )
|
||||
|
||||
|
||||
## Context
|
||||
[NOTE]: # ( Give us any additional information you may have. )
|
||||
|
||||
|
||||
[NOTE]: # ( Paste debug info from Help → About here )
|
||||
KeePassXC - VERSION
|
||||
Revision: REVISION
|
||||
|
||||
[NOTE]: # ( Pick choices based on your environment )
|
||||
Operating System: Windows/Linux/macOS
|
||||
Desktop Env: Gnome/KDE/XFCE/Mate/Cinnamon
|
||||
Windowing System: X11/Wayland
|
||||
8
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,15 +1,15 @@
|
||||
[NOTE]: # ( Describe your changes in detail, why is this change required? )
|
||||
[NOTE]: # ( Explain large or complex code modifications. )
|
||||
[NOTE]: # ( If it fixes an open issue, please add "Fixes #XXX". )
|
||||
[NOTE]: # ( If it fixes an open issue, please add "Fixes #XXX" )
|
||||
|
||||
|
||||
## Screenshots
|
||||
[NOTE]: # ( Do not include screenshots of your actual database! )
|
||||
[TIP]: # ( Use View -> Allow Screen Capture )
|
||||
[TIP]: # ( Do not include screenshots of your actual database! )
|
||||
|
||||
|
||||
## Testing strategy
|
||||
[NOTE]: # ( Please describe in detail how you tested your changes. )
|
||||
[TIP]: # ( We expect new code to be covered by unit tests and include helpful comments. )
|
||||
[TIP]: # ( We expect new code to be covered by unit tests and documented with doc blocks! )
|
||||
|
||||
|
||||
## Type of change
|
||||
|
||||
1
.gitignore
vendored
@@ -24,7 +24,6 @@ desktop.ini
|
||||
# MSVC Files
|
||||
CMakeSettings.json
|
||||
CMakePresets.json
|
||||
CMakeUserPresets.json
|
||||
.vs/
|
||||
out/
|
||||
|
||||
|
||||
24
.tx/config
@@ -1,19 +1,17 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
host = https://app.transifex.com
|
||||
|
||||
[o:keepassxc:p:keepassxc:r:share-translations-keepassxc-en-ts--develop]
|
||||
file_filter = share/translations/keepassxc_<lang>.ts
|
||||
source_file = share/translations/keepassxc_en.ts
|
||||
source_lang = en
|
||||
type = QT
|
||||
replace_edited_strings = false
|
||||
keep_translations = false
|
||||
file_filter = share/translations/keepassxc_<lang>.ts
|
||||
source_file = share/translations/keepassxc_en.ts
|
||||
type = QT
|
||||
minimum_perc = 0
|
||||
resource_name = keepassxc_en.ts (develop)
|
||||
|
||||
[o:keepassxc:p:keepassxc:r:share-translations-keepassxc-en-ts--master]
|
||||
file_filter = share/translations/keepassxc_<lang>.ts
|
||||
source_file = share/translations/keepassxc_en.ts
|
||||
source_lang = en
|
||||
type = QT
|
||||
replace_edited_strings = false
|
||||
keep_translations = false
|
||||
file_filter = share/translations/keepassxc_<lang>.ts
|
||||
source_file = share/translations/keepassxc_en.ts
|
||||
type = QT
|
||||
minimum_perc = 0
|
||||
resource_name = keepassxc_en.ts (2.7.x stable)
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## 2.8.0 (Pending)
|
||||
* Placeholder for future release notes
|
||||
|
||||
## 2.7.10 (2025-03-02)
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -120,8 +120,8 @@ if(UNIX AND NOT APPLE AND NOT WITH_XC_X11)
|
||||
endif()
|
||||
|
||||
set(KEEPASSXC_VERSION_MAJOR "2")
|
||||
set(KEEPASSXC_VERSION_MINOR "8")
|
||||
set(KEEPASSXC_VERSION_PATCH "0")
|
||||
set(KEEPASSXC_VERSION_MINOR "7")
|
||||
set(KEEPASSXC_VERSION_PATCH "10")
|
||||
set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION_MAJOR}.${KEEPASSXC_VERSION_MINOR}.${KEEPASSXC_VERSION_PATCH}")
|
||||
set(OVERRIDE_VERSION "" CACHE STRING "Override the KeePassXC Version for Snapshot builds")
|
||||
|
||||
@@ -310,7 +310,7 @@ if(CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
|
||||
check_add_gcc_compiler_flag("-Wshadow-compatible-local")
|
||||
check_add_gcc_compiler_flag("-Wshadow-local")
|
||||
add_gcc_compiler_flags("-Werror")
|
||||
# This is needed since compiling against Botan3 requires compiling against C++20
|
||||
# This is needed since compiling aginst Botan3 requires compiling against C++20
|
||||
if(WITH_XC_BOTAN3)
|
||||
add_gcc_compiler_cxxflags("-Wno-error=deprecated-enum-enum-conversion -Wno-error=deprecated")
|
||||
endif()
|
||||
@@ -512,8 +512,14 @@ else()
|
||||
find_package(Qt5 COMPONENTS ${QT_COMPONENTS} REQUIRED)
|
||||
endif()
|
||||
|
||||
if(Qt5Core_VERSION VERSION_LESS "5.2.0")
|
||||
message(FATAL_ERROR "Qt version 5.2.0 or higher is required")
|
||||
endif()
|
||||
|
||||
# CBOR for Passkeys requires Qt 5.12
|
||||
if(Qt5Core_VERSION VERSION_LESS "5.12.0")
|
||||
message(FATAL_ERROR "Qt version 5.12.0 or higher is required")
|
||||
message(STATUS "Qt version 5.12.0 or higher is required for Passkeys support")
|
||||
set(WITH_XC_BROWSER_PASSKEYS OFF)
|
||||
endif()
|
||||
|
||||
get_filename_component(Qt5_PREFIX ${Qt5_DIR}/../../.. REALPATH)
|
||||
|
||||
1
COPYING
@@ -207,7 +207,6 @@ Files: share/icons/application/scalable/actions/application-exit.svg
|
||||
share/icons/application/scalable/actions/password-show-on.svg
|
||||
share/icons/application/scalable/actions/qrcode.svg
|
||||
share/icons/application/scalable/actions/refresh.svg
|
||||
share/icons/application/scalable/actions/remote-sync.svg
|
||||
share/icons/application/scalable/actions/reports.svg
|
||||
share/icons/application/scalable/actions/reports-exclude.svg
|
||||
share/icons/application/scalable/actions/sort-alphabetical-ascending.svg
|
||||
|
||||
@@ -67,9 +67,9 @@ Note: These steps place the compiled KeePassXC binary inside the `./build/src/`
|
||||
|
||||
## MacOS Build Notes
|
||||
|
||||
If you installed Qt@5 via Homebrew and CMake fails to find your Qt installation, you can specify it manually by adding the following parameter:
|
||||
If you installed Qt5 via Homebrew and CMake fails to find your Qt installation, you can specify it manually by adding the following parameter:
|
||||
|
||||
`-DCMAKE_PREFIX_PATH=$(brew --prefix qt@5)/lib/cmake`
|
||||
`-DCMAKE_PREFIX_PATH=$(brew --prefix qt5)/lib/cmake`
|
||||
|
||||
When building with ASAN support on macOS, you need to use `export ASAN_OPTIONS=detect_leaks=0` before running the tests (LSAN is no supported on macOS).
|
||||
|
||||
|
||||
46
SECURITY.md
@@ -1,46 +0,0 @@
|
||||
### Reporting Security Issues
|
||||
|
||||
The KeePassXC team takes security vulnerabilities very seriously and appreciates your responsible disclosure efforts. We will make every effort to acknowledge your contributions and handle them promptly.
|
||||
|
||||
To report a security issue, please use one of the following methods:
|
||||
|
||||
- **GitHub Security Advisory:** Use the ["Report a Vulnerability"](https://github.com/keepassxreboot/keepassxc/security/advisories/new) tab on our GitHub repository.
|
||||
- **Private Matrix Message:** Contact any of the following KeePassXC team members privately (also encrypted):
|
||||
- [@droidmonkey_kpxc](https://matrix.to/#/@droidmonkey_kpxc:matrix.org)
|
||||
- [@varjolintu](https://matrix.to/#/@varjolintu:matrix.org)
|
||||
- [@phoerious](https://matrix.to/#/@phoerious:matrix.org)
|
||||
- **Send an Email:** Send your report to team@keepassxc.org. We recommend encrypting the email if possible.
|
||||
|
||||
Please **DO NOT** use public channels (e.g., GitHub issues, Matrix chat channels) for initial reporting of bona fide security vulnerabilities.
|
||||
|
||||
Once you report a security issue, our team will respond with the next steps. After our initial reply, we will keep you informed of the progress towards a fix and full announcement. We may ask for additional information or guidance during this process. If we disagree that your report constitutes a genuine security vulnerability, we will inform you and close the report. Your report may be turned into an issue for further tracking.
|
||||
|
||||
If you discover vulnerabilities in third-party modules used by KeePassXC, please report them to the maintainers of the respective modules. If the vulnerability impacts KeePassXC directly, we encourage you to notify us using the above methods. We will validate if the vulnerability is exploitable from KeePassXC code; please note that not all vulnerabilities are actually exploitable and do not constitute an immediate concern for the KeePassXC application.
|
||||
|
||||
### Example Security Vulnerabilities
|
||||
|
||||
When reporting, please ensure the issue falls under what can be considered a genuine security vulnerability for KeePassXC. Some examples include:
|
||||
|
||||
- Unauthorized access to sensitive user data (e.g., passwords).
|
||||
- Remote code execution or escalation of privileges.
|
||||
- Bypassing authentication or encryption mechanisms.
|
||||
- Broken or improperly implemented encryption methods.
|
||||
|
||||
### Counter Examples
|
||||
|
||||
The following issues are **not** considered security vulnerabilities:
|
||||
|
||||
- Bugs caused by locally modifying the application (e.g., injecting DLLs, altering code).
|
||||
- Crashes or misbehavior resulting from normal use (report this as a normal issue).
|
||||
- Vulnerabilities found in third-party modules (should be reported to the module’s maintainers).
|
||||
|
||||
### CVE Reporting Policy
|
||||
|
||||
Please **DO NOT** submit a report to a Common Vulnerabilities and Exposures (CVE) Numbering Authority (CNA) before confirming the security vulnerability with the KeePassXC team. If we do not respond to your report within 30 days, this restriction no longer applies.
|
||||
|
||||
|
||||
### Other Communication
|
||||
|
||||
For other inquiries (e.g., developer questions, user questions), please use the public channels on Matrix:
|
||||
- **User's Channel:** [#keepassxc:mozilla.org](https://matrix.to/#/#keepassxc:mozilla.org)
|
||||
- **Developer's Channel:** [#keepassxc-dev:mozilla.org](https://matrix.to/#/#keepassxc-dev:mozilla.org)
|
||||
@@ -17,7 +17,7 @@ set(EXCLUDED_DIRS
|
||||
# third-party directories
|
||||
src/thirdparty
|
||||
# objective-c directories
|
||||
src/quickunlock/touchid
|
||||
src/touchid
|
||||
src/autotype/mac
|
||||
src/gui/osutils/macutils)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Running macdeployqt on a POST_BUILD copied binaries is pointless when using CPack because
|
||||
# the copied binaries will be overridden by the corresponding install(TARGETS) commands.
|
||||
# the copied binaries will be overriden by the corresponding install(TARGETS) commands.
|
||||
# That's why we run macdeployqt using install(CODE) on the already installed binaries.
|
||||
# The precondition is that all install(TARGETS) calls have to be called before this function is
|
||||
# called.
|
||||
|
||||
|
Before Width: | Height: | Size: 43 KiB |
@@ -52,12 +52,11 @@ It provides the ability to query and modify the entries of a KeePass database, d
|
||||
Removes the named attachment from an entry.
|
||||
|
||||
*clip* [_options_] <__database__> <__entry__> [_timeout_]::
|
||||
Copies an attribute, current TOTP value, UUID, or tags list of a database entry to the clipboard.
|
||||
Copies an attribute or the current TOTP (if the *-t* option is specified) of a database entry to the clipboard.
|
||||
If no attribute name is specified using the *-a* option, the password is copied.
|
||||
If multiple entries with the same name exist in different groups, only the attribute for the first one is copied.
|
||||
For copying the attribute of an entry in a specific group, the group path to the entry should be specified as well, instead of just the name.
|
||||
Optionally, a timeout in seconds can be specified to automatically clear the clipboard, the default timeout is 10 seconds, set to 0 to disable.
|
||||
Note: an error will be thrown if you specify multiple options at once (eg, *--uuid* and *-a*).
|
||||
|
||||
*close*::
|
||||
In interactive mode, closes the currently opened database (see *open*).
|
||||
@@ -144,8 +143,8 @@ It provides the ability to query and modify the entries of a KeePass database, d
|
||||
Searches all entries that match a specific search term in a database.
|
||||
|
||||
*show* [_options_] <__database__> <__entry__>::
|
||||
Shows the title, username, password, URL and notes of a database entry by default.
|
||||
Can also show the current TOTP, entry UUID, and tags list.
|
||||
Shows the title, username, password, URL and notes of a database entry.
|
||||
Can also show the current TOTP.
|
||||
Regarding the occurrence of multiple entries with the same name in different groups, everything stated in the *clip* command section also applies here.
|
||||
|
||||
== OPTIONS
|
||||
@@ -236,12 +235,6 @@ The same password generation options as documented for the generate command can
|
||||
Copies the current TOTP instead of the specified attribute to the clipboard.
|
||||
Will report an error if no TOTP is configured for the entry.
|
||||
|
||||
*--uuid*::
|
||||
Copies the UUID of the entry to the clipboard.
|
||||
|
||||
*--tags*::
|
||||
Copies the tags of the entry to the clipboard.
|
||||
|
||||
*-b*, *--best*::
|
||||
Try to find and copy to clipboard a unique entry matching the input
|
||||
If a unique matching entry is found it will be copied to the clipboard.
|
||||
@@ -269,6 +262,7 @@ The same password generation options as documented for the generate command can
|
||||
*-a*, *--attributes* <__attribute__>...::
|
||||
Shows the named attributes.
|
||||
This option can be specified more than once, with each attribute shown one-per-line in the given order.
|
||||
If no attributes are specified and *-t* is not specified, a summary of the default attributes is given.
|
||||
Protected attributes will be displayed in clear text if specified explicitly by this option.
|
||||
|
||||
*--all*::
|
||||
@@ -281,13 +275,7 @@ The same password generation options as documented for the generate command can
|
||||
Shows the attachment names along with the size of the attachments.
|
||||
|
||||
*-t*, *--totp*::
|
||||
Shows the current TOTP and then exits. An error is thrown if no TOTP is configured for the entry.
|
||||
|
||||
*--uuid*::
|
||||
Shows the UUID of the entry.
|
||||
|
||||
*--tags*::
|
||||
Shows the tag list of the entry.
|
||||
Also shows the current TOTP, reporting an error if no TOTP is configured for the entry.
|
||||
|
||||
=== Diceware options
|
||||
*-W*, *--words* <__count__>::
|
||||
|
||||
@@ -28,35 +28,26 @@ keepassxc - a modern open-source password manager
|
||||
*keepassxc* [_options_] [_filename(s)_]
|
||||
|
||||
== DESCRIPTION
|
||||
*KeePassXC* is a free/open-source password manager or safe which helps you to manage your passwords securely.
|
||||
The complete database is always encrypted with the industry-standard AES (also known as Rijndael) encryption algorithm using a 256-bit key.
|
||||
*KeePassXC* 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 database works offline and requires no internet connection.
|
||||
Your wallet works offline and requires no Internet connection.
|
||||
|
||||
== OPTIONS
|
||||
*-h*, *--help*::
|
||||
Displays this help.
|
||||
|
||||
*--help-all*::
|
||||
Displays help including Qt specific options.
|
||||
|
||||
*-v*, *--version*::
|
||||
Displays version information.
|
||||
|
||||
*--config* <__config__>::
|
||||
Path to a custom config file.
|
||||
|
||||
*--localconfig* <__localconfig__>::
|
||||
Path to a custom local config file.
|
||||
|
||||
*--lock*::
|
||||
Locks all open databases.
|
||||
|
||||
*--keyfile* <__keyfile__>::
|
||||
Key file of the database.
|
||||
|
||||
*--pw-stdin*::
|
||||
Reads password of the database from stdin.
|
||||
Read password of the database from stdin.
|
||||
|
||||
*--minimized*::
|
||||
Starts KeePassXC minimized to the system tray.
|
||||
|
||||
@@ -1,201 +1,201 @@
|
||||
= KeePassXC – Browser Plugin
|
||||
include::.sharedheader[]
|
||||
:imagesdir: ../images
|
||||
|
||||
// tag::content[]
|
||||
== Browser Integration
|
||||
The KeePassXC-Browser extension is installed within your web browser so that you can automatically pull usernames and passwords from KeePassXC and populate them directly into website fields. It is a very useful and secure extension that enhances your productivity while using KeePassXC. With this extension, you do not need to manually copy the data from your KeePassXC database and paste it into the website fields.
|
||||
|
||||
The KeePassXC-Browser extension is available on the following web browsers:
|
||||
|
||||
* Google Chrome, Vivaldi, and Brave
|
||||
* Mozilla Firefox and Tor-Browser
|
||||
* Microsoft Edge
|
||||
* Chromium
|
||||
|
||||
NOTE: On Linux, Flatpak and Snap based browsers are generally not supported. Ubuntu's Firefox Snap is currently the only known exception.
|
||||
|
||||
=== Install the Browser Extension
|
||||
You can download the KeePassXC-Browser extension from your web browser. To download the KeePassXC-Browser extension, perform the following steps:
|
||||
|
||||
1. Click the link corresponding to your browser:
|
||||
* https://chromewebstore.google.com/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk[Chrome, Chromium, Vivaldi, and Brave]
|
||||
* https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser[Mozilla Firefox and Tor-Browser]
|
||||
* https://microsoftedge.microsoft.com/addons/detail/keepassxcbrowser/pdffhmdngciaglkoonimfcmckehcpafo[Microsoft Edge]
|
||||
|
||||
2. Click the button to install/add the extension to the browser. Accept any confirmation dialogs.
|
||||
|
||||
TIP: For the most up-to-date troubleshooting advice on all platforms, please read our https://github.com/keepassxreboot/keepassxc-browser/wiki/Troubleshooting-guide[Troubleshooting Guide].
|
||||
|
||||
// tag::advanced[]
|
||||
NOTE: When Microsoft Edge is installed as a managed application, system administrators are required to deploy a custom native messaging configuration. Instructions for this are found in the advanced section below.
|
||||
// end::advanced[]
|
||||
|
||||
=== Configure KeePassXC-Browser
|
||||
To start using KeePassXC-Browser, you must configure it so that it can communicate with the KeePassXC application on your desktop.
|
||||
|
||||
To configure KeePassXC-Browser, perform the following steps:
|
||||
|
||||
1. Open the KeePassXC application on your desktop and navigate to Tools > Settings.
|
||||
|
||||
2. Click the Browser Integration option on the left-hand side *(1)*. The following screen appears:
|
||||
+
|
||||
.Browser Settings
|
||||
image::browser_settings.png[]
|
||||
|
||||
3. Click the _Enable browser integration_ checkbox *(2)*. Then select the browsers for which you have downloaded the KeePassXC-Browser extension *(3)* and click *OK*.
|
||||
|
||||
4. Ensure your database is unlocked, then open (or restart) your browser.
|
||||
|
||||
5. Click the KeePassXC-Browser extension icon *(A)* in your browser (see figure below). A pop-up window appears.
|
||||
+
|
||||
.Connect Extension to KeePassXC
|
||||
image::browser_extension_connect.png[,80%]
|
||||
|
||||
6. Click the _Connect_ button *(B)* in the pop-up window to complete integrating the KeePassXC-Browser extension with your KeePassXC desktop application.
|
||||
|
||||
7. You are now prompted to enter a unique name to identify the connection between this browser and your database. Enter a unique name in the field (e.g., firefox-laptop) and click the _Save and allow access_ button.
|
||||
+
|
||||
.Extension Association Dialog
|
||||
image::browser_extension_association.png[,80%]
|
||||
|
||||
WARNING: If you reuse a connection name in a database, the previous browser connection will be overwritten and prevent access.
|
||||
|
||||
=== Using the Browser Extension
|
||||
The KeePassXC-Browser extension lets you automatically populate the entries from your KeePassXC database into the fields on websites you visit. To do so, perform the following steps:
|
||||
|
||||
1. Open your KeePassXC desktop application and unlock your database.
|
||||
|
||||
2. Open your web browser. The KeePassXC-Browser extension icon in your browser window will change based on its connection state. The figure below shows the different states.
|
||||
+
|
||||
*(A)* KeePassXC is not running or is disconnected. +
|
||||
*(B)* KeePassXC is running, but KeePassXC Browser Extension is not connected to the current database. +
|
||||
*\(C)* Connected to KeePassXC, but database is locked. +
|
||||
*(D)* Connected to KeePassXC and ready to use. If the icon is shown with a number, it indicates the number of credentials found for the current site.
|
||||
+
|
||||
.Extension Icon States
|
||||
image::browser_extension_icons.png[,70%]
|
||||
|
||||
3. If the KeePassXC desktop application is not connected with the KeePassXC-Browser extension, click the extension icon in your web browser and click _Reload_ from the pop-up window as shown in the following screen.
|
||||
+
|
||||
.Reload Extension Connection
|
||||
image::browser_extension_reload.png[,80%]
|
||||
|
||||
4. Open the URL for which you want to use with your database. If you have previously created an entry in your database then the KeePassXC-Browser Confirm Access dialog may appear:
|
||||
+
|
||||
.Confirm Access Dialog
|
||||
image::browser_confirm_access_dialog.png[,80%]
|
||||
|
||||
5. Ensure the credentials you want to use are checked, then click *(A)* Remember _(optional)_, then click _Allow Selected_ *(B)*.
|
||||
|
||||
6. In your website, the KeePassXC icon will appear in the username field of the login form *(A)*. Click the icon to populate the field with your stored credentials. If you have more than one credential for this website, a dropdown will appear to choose the one to use.
|
||||
+
|
||||
.Fill Credentials
|
||||
image::browser_fill_credentials.png[,80%]
|
||||
|
||||
=== Generate Passwords
|
||||
The KeePassXC-Browser Extension also lets you generate passwords directly in your browser.
|
||||
This feature can be used for websites with existing credentials as well as for new websites.
|
||||
You can then choose to update/add the credentials to your KeePassXC database directly from the Browser.
|
||||
|
||||
1. Ensure your database is unlocked and configured to use the Browser extension as shown above.
|
||||
|
||||
2. Right click on a password field and from the KeePassXC sub-menu choose _Show Password Generator_. The standard KeePassXC password generator will appear.
|
||||
|
||||
3. Configure the password generation options and click _Apply Password_ when done. The generated password will be filled into the previously selected field.
|
||||
|
||||
4. When you have successfully submitted the password on the website, a popup will appear asking you to either update an existing entry or add a new one.
|
||||
|
||||
// tag::advanced[]
|
||||
=== Browser statistics
|
||||
You can see a cross-section of all browser-related settings applied to entries within a database through the Browser Statistics report. To access these, use the _Database_ -> _Database reports..._ menu option then click on _Browser Statistics_ on the left-hand menu. From here you can see all entries with URLs applied to them, explicitly allowed and denied URLs, and any entries with custom browser settings.
|
||||
|
||||
.Browser statistics
|
||||
image::browser_statistics.png[]
|
||||
|
||||
=== Advanced Usage
|
||||
You can configure unique browser integration behavior for each entry. This allows you to add multiple URLs to an entry, hide an entry from the browser integration, and more. To access these settings, open an entry for editing then click on _Browser Integration_ option in the left-hand menu *(1)*.
|
||||
|
||||
After opening the settings you can add any number of additional URLs by clicking the _Add_ button *(2)* and typing the URL in the list to the left *(3)*.
|
||||
|
||||
Additional URLs also supports wildcards (with KeePassXC 2.7.10 and later). You can use URLs like:
|
||||
----
|
||||
https://*.example.com
|
||||
https://example.com/*/path
|
||||
https://sub.*.example.com/path/*
|
||||
----
|
||||
|
||||
.Entry browser settings
|
||||
image::browser_entry_settings.png[]
|
||||
|
||||
To set options for all entries within a group, edit the group and go to the browser integration section *(1)*. Here you can explicitly disable access to all entries under a group hierarchy to the browser extension. You can set other useful options for groups of entries as well.
|
||||
|
||||
.Group browser settings
|
||||
image::browser_group_settings.png[]
|
||||
|
||||
Database-wide operations are available in the database settings. To access these use the _Database_ -> _Database settings..._ menu option. Click on _Browser Integration_ on the left-hand menu. From here you can disconnect all browsers, convert legacy KeePass-HTTP settings, reset all entry-level settings, and refresh the database root group ID (useful when making copies of your database file).
|
||||
|
||||
.Database browser settings
|
||||
image::browser_database_settings.png[]
|
||||
|
||||
Finally, advanced application-wide settings are available in the Browser Integration tab of the application settings.
|
||||
|
||||
WARNING: We do not recommend changing any of these settings as they may break the browser integration plugin.
|
||||
|
||||
.Advanced browser settings
|
||||
image::browser_advanced_settings.png[]
|
||||
|
||||
=== Advanced Setup
|
||||
==== Custom Browser option
|
||||
It is possible to enable support for a custom browser (e.g. LibreWolf, WaterFox, Arc, beta and nightly browsers, etc.) using this feature.
|
||||
This feature is only available for Linux and macOS.
|
||||
|
||||
.Custom browser configuration
|
||||
image::browser_custom_browser_configuration.png[]
|
||||
|
||||
The native messaging script file needed for the custom browser depends on the browser type. For Firefox based browsers like Librefox the _Browser type_ must be _Firefox_. For Arc, Opera, etc. the type must be set to _Chromium_.
|
||||
|
||||
_Config location_ must have the exact path for the browser's _native-messaging-hosts_ folder. If you are unsure, refer to our https://github.com/keepassxreboot/keepassxc-browser/wiki/Troubleshooting-guide#1-after-enabling-browser-integration-and-support-for-your-browser[Troubleshooting Guide] for listing of the most common paths, and a few ways for finding a path when it's not known.
|
||||
|
||||
When a Custom Browser has been successfully set, KeePassXC will automatically write the needed native messaging script file to the folder.
|
||||
|
||||
If you wish to support multiple custom browsers, you can copy the native messaging script files manually to the _native-messaging-hosts_ folder from other browsers.
|
||||
|
||||
==== Managed Microsoft Edge on Windows
|
||||
1. Deploy *org.keepassxc.keepassxc_browser_edge.json* to, for example, `C:\ProgramData\KeePassXC\` on all managed platforms.
|
||||
+
|
||||
----
|
||||
{
|
||||
"allowed_origins": [
|
||||
"chrome-extension://pdffhmdngciaglkoonimfcmckehcpafo/"
|
||||
],
|
||||
"description": "KeePassXC integration with native messaging support",
|
||||
"name": "org.keepassxc.keepassxc_browser",
|
||||
"path": "C:\\Program Files\\KeePassXC\\keepassxc-proxy.exe",
|
||||
"type": "stdio"
|
||||
}
|
||||
----
|
||||
|
||||
2. Configure GPO options (see https://learn.microsoft.com/en-us/deployedge/microsoft-edge-policies#native-messaging[Microsoft Edge Native Messaging Policies] for more information.):
|
||||
+
|
||||
----
|
||||
Windows Registry Editor Version 5.00
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Edge\NativeMessagingHosts\org.keepassxc.keepassxc_browser]
|
||||
@="C:\ProgramData\KeepassXC\org.keepassxc.keepassxc_browser_edge.json"
|
||||
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge]
|
||||
"NativeMessagingUserLevelHosts"=dword:00000000
|
||||
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\ExtensionInstallAllowlist]
|
||||
"1"="pdffhmdngciaglkoonimfcmckehcpafo"
|
||||
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\NativeMessagingAllowlist]
|
||||
"1"="org.keepassxc.keepassxc_browser"
|
||||
----
|
||||
|
||||
==== Managed Microsoft Edge on macOS
|
||||
1. Deploy *org.keepassxc.keepassxc_browser_edge.json* to `/Library/Microsoft/Edge/NativeMessagingHosts`.
|
||||
|
||||
2. You may need to configure Edge to allowlist the extension and native messaging host. See https://learn.microsoft.com/en-us/deployedge/microsoft-edge-policies#native-messaging[Microsoft Edge Native Messaging Policies] for more information.
|
||||
// end::advanced[]
|
||||
// end::content[]
|
||||
= KeePassXC – Browser Plugin
|
||||
include::.sharedheader[]
|
||||
:imagesdir: ../images
|
||||
|
||||
// tag::content[]
|
||||
== Browser Integration
|
||||
The KeePassXC-Browser extension is installed within your web browser so that you can automatically pull usernames and passwords from KeePassXC and populate them directly into website fields. It is a very useful and secure extension that enhances your productivity while using KeePassXC. With this extension, you do not need to manually copy the data from your KeePassXC database and paste it into the website fields.
|
||||
|
||||
The KeePassXC-Browser extension is available on the following web browsers:
|
||||
|
||||
* Google Chrome, Vivaldi, and Brave
|
||||
* Mozilla Firefox and Tor-Browser
|
||||
* Microsoft Edge
|
||||
* Chromium
|
||||
|
||||
NOTE: On Linux, Flatpak and Snap based browsers are generally not supported. Ubuntu's Firefox Snap is currently the only known exception.
|
||||
|
||||
=== Install the Browser Extension
|
||||
You can download the KeePassXC-Browser extension from your web browser. To download the KeePassXC-Browser extension, perform the following steps:
|
||||
|
||||
1. Click the link corresponding to your browser:
|
||||
* https://chromewebstore.google.com/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk[Chrome, Chromium, Vivaldi, and Brave]
|
||||
* https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser[Mozilla Firefox and Tor-Browser]
|
||||
* https://microsoftedge.microsoft.com/addons/detail/keepassxcbrowser/pdffhmdngciaglkoonimfcmckehcpafo[Microsoft Edge]
|
||||
|
||||
2. Click the button to install/add the extension to the browser. Accept any confirmation dialogs.
|
||||
|
||||
TIP: For the most up-to-date troubleshooting advice on all platforms, please read our https://github.com/keepassxreboot/keepassxc-browser/wiki/Troubleshooting-guide[Troubleshooting Guide].
|
||||
|
||||
// tag::advanced[]
|
||||
NOTE: When Microsoft Edge is installed as a managed application, system administrators are required to deploy a custom native messaging configuration. Instructions for this are found in the advanced section below.
|
||||
// end::advanced[]
|
||||
|
||||
=== Configure KeePassXC-Browser
|
||||
To start using KeePassXC-Browser, you must configure it so that it can communicate with the KeePassXC application on your desktop.
|
||||
|
||||
To configure KeePassXC-Browser, perform the following steps:
|
||||
|
||||
1. Open the KeePassXC application on your desktop and navigate to Tools > Settings.
|
||||
|
||||
2. Click the Browser Integration option on the left-hand side *(1)*. The following screen appears:
|
||||
+
|
||||
.Browser Settings
|
||||
image::browser_settings.png[]
|
||||
|
||||
3. Click the _Enable browser integration_ checkbox *(2)*. Then select the browsers for which you have downloaded the KeePassXC-Browser extension *(3)* and click *OK*.
|
||||
|
||||
4. Ensure your database is unlocked, then open (or restart) your browser.
|
||||
|
||||
5. Click the KeePassXC-Browser extension icon *(A)* in your browser (see figure below). A pop-up window appears.
|
||||
+
|
||||
.Connect Extension to KeePassXC
|
||||
image::browser_extension_connect.png[,80%]
|
||||
|
||||
6. Click the _Connect_ button *(B)* in the pop-up window to complete integrating the KeePassXC-Browser extension with your KeePassXC desktop application.
|
||||
|
||||
7. You are now prompted to enter a unique name to identify the connection between this browser and your database. Enter a unique name in the field (e.g., firefox-laptop) and click the _Save and allow access_ button.
|
||||
+
|
||||
.Extension Association Dialog
|
||||
image::browser_extension_association.png[,80%]
|
||||
|
||||
WARNING: If you reuse a connection name in a database, the previous browser connection will be overwritten and prevent access.
|
||||
|
||||
=== Using the Browser Extension
|
||||
The KeePassXC-Browser extension lets you automatically populate the entries from your KeePassXC database into the fields on websites you visit. To do so, perform the following steps:
|
||||
|
||||
1. Open your KeePassXC desktop application and unlock your database.
|
||||
|
||||
2. Open your web browser. The KeePassXC-Browser extension icon in your browser window will change based on its connection state. The figure below shows the different states.
|
||||
+
|
||||
*(A)* KeePassXC is not running or is disconnected. +
|
||||
*(B)* KeePassXC is running, but KeePassXC Browser Extension is not connected to the current database. +
|
||||
*\(C)* Connected to KeePassXC, but database is locked. +
|
||||
*(D)* Connected to KeePassXC and ready to use. If the icon is shown with a number, it indicates the number of credentials found for the current site.
|
||||
+
|
||||
.Extension Icon States
|
||||
image::browser_extension_icons.png[,70%]
|
||||
|
||||
3. If the KeePassXC desktop application is not connected with the KeePassXC-Browser extension, click the extension icon in your web browser and click _Reload_ from the pop-up window as shown in the following screen.
|
||||
+
|
||||
.Reload Extension Connection
|
||||
image::browser_extension_reload.png[,80%]
|
||||
|
||||
4. Open the URL for which you want to use with your database. If you have previously created an entry in your database then the KeePassXC-Browser Confirm Access dialog may appear:
|
||||
+
|
||||
.Confirm Access Dialog
|
||||
image::browser_confirm_access_dialog.png[,80%]
|
||||
|
||||
5. Ensure the credentials you want to use are checked, then click *(A)* Remember _(optional)_, then click _Allow Selected_ *(B)*.
|
||||
|
||||
6. In your website, the KeePassXC icon will appear in the username field of the login form *(A)*. Click the icon to populate the field with your stored credentials. If you have more than one credential for this website, a dropdown will appear to choose the one to use.
|
||||
+
|
||||
.Fill Credentials
|
||||
image::browser_fill_credentials.png[,80%]
|
||||
|
||||
=== Generate Passwords
|
||||
The KeePassXC-Browser Extension also lets you generate passwords directly in your browser.
|
||||
This feature can be used for websites with existing credentials as well as for new websites.
|
||||
You can then choose to update/add the credentials to your KeePassXC database directly from the Browser.
|
||||
|
||||
1. Ensure your database is unlocked and configured to use the Browser extension as shown above.
|
||||
|
||||
2. Right click on a password field and from the KeePassXC sub-menu choose _Show Password Generater_. The standard KeePassXC password generator will appear.
|
||||
|
||||
3. Configure the password generation options and click _Apply Password_ when done. The generated password will be filled into the previously selected field.
|
||||
|
||||
4. When you have succussfully submitted the password on the website, a popup will appear asking you to either udpate an existing entry or add a new one.
|
||||
|
||||
// tag::advanced[]
|
||||
=== Browser statistics
|
||||
You can see a cross-section of all browser-related settings applied to entries within a database through the Browser Statistics report. To access these, use the _Database_ -> _Database reports..._ menu option then click on _Browser Statistics_ on the left-hand menu. From here you can see all entries with URLs applied to them, explicitly allowed and denied URLs, and any entries with custom browser settings.
|
||||
|
||||
.Browser statistics
|
||||
image::browser_statistics.png[]
|
||||
|
||||
=== Advanced Usage
|
||||
You can configure unique browser integration behavior for each entry. This allows you to add multiple URLs to an entry, hide an entry from the browser integration, and more. To access these settings, open an entry for editing then click on _Browser Integration_ option in the left-hand menu *(1)*.
|
||||
|
||||
After opening the settings you can add any number of additional URLs by clicking the _Add_ button *(2)* and typing the URL in the list to the left *(3)*.
|
||||
|
||||
Additional URLs also supports wildcards (with KeePassXC 2.7.10 and later). You can use URLs like:
|
||||
----
|
||||
https://*.example.com
|
||||
https://example.com/*/path
|
||||
https://sub.*.example.com/path/*
|
||||
----
|
||||
|
||||
.Entry browser settings
|
||||
image::browser_entry_settings.png[]
|
||||
|
||||
To set options for all entries within a group, edit the group and go to the browser integration section *(1)*. Here you can explicitly disable access to all entries under a group hierarchy to the browser extension. You can set other useful options for groups of entries as well.
|
||||
|
||||
.Group browser settings
|
||||
image::browser_group_settings.png[]
|
||||
|
||||
Database-wide operations are available in the database settings. To access these use the _Database_ -> _Database settings..._ menu option. Click on _Browser Integration_ on the left-hand menu. From here you can disconnect all browsers, convert legacy KeePass-HTTP settings, reset all entry-level settings, and refresh the database root group ID (useful when making copies of your database file).
|
||||
|
||||
.Database browser settings
|
||||
image::browser_database_settings.png[]
|
||||
|
||||
Finally, advanced application-wide settings are available in the Browser Integration tab of the application settings.
|
||||
|
||||
WARNING: We do not recommend changing any of these settings as they may break the browser integration plugin.
|
||||
|
||||
.Advanced browser settings
|
||||
image::browser_advanced_settings.png[]
|
||||
|
||||
=== Advanced Setup
|
||||
==== Custom Browser option
|
||||
It is possible to enable support for a custom browser (e.g. LibreWolf, WaterFox, Arc, beta and nightly browsers, etc.) using this feature.
|
||||
This feature is only available for Linux and macOS.
|
||||
|
||||
.Custom browser configuration
|
||||
image::browser_custom_browser_configuration.png[]
|
||||
|
||||
The native messaging script file needed for the custom browser depends on the browser type. For Firefox based browsers like Librefox the _Browser type_ must be _Firefox_. For Arc, Opera, etc. the type must be set to _Chromium_.
|
||||
|
||||
_Config location_ must have the exact path for the browser's _native-messaging-hosts_ folder. If you are unsure, refer to our https://github.com/keepassxreboot/keepassxc-browser/wiki/Troubleshooting-guide#1-after-enabling-browser-integration-and-support-for-your-browser[Troubleshooting Guide] for listing of the most common paths, and a few ways for finding a path when it's not known.
|
||||
|
||||
When a Custom Browser has been successfully set, KeePassXC will automatically write the needed native messaging script file to the folder.
|
||||
|
||||
If you wish to support multiple custom browsers, you can copy the native messaging script files manually to the _native-messaging-hosts_ folder from other browsers.
|
||||
|
||||
==== Managed Microsoft Edge on Windows
|
||||
1. Deploy *org.keepassxc.keepassxc_browser_edge.json* to, for example, `C:\ProgramData\KeePassXC\` on all managed platforms.
|
||||
+
|
||||
----
|
||||
{
|
||||
"allowed_origins": [
|
||||
"chrome-extension://pdffhmdngciaglkoonimfcmckehcpafo/"
|
||||
],
|
||||
"description": "KeePassXC integration with native messaging support",
|
||||
"name": "org.keepassxc.keepassxc_browser",
|
||||
"path": "C:\\Program Files\\KeePassXC\\keepassxc-proxy.exe",
|
||||
"type": "stdio"
|
||||
}
|
||||
----
|
||||
|
||||
2. Configure GPO options (see https://learn.microsoft.com/en-us/deployedge/microsoft-edge-policies#native-messaging[Microsoft Edge Native Messaging Policies] for more information.):
|
||||
+
|
||||
----
|
||||
Windows Registry Editor Version 5.00
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Edge\NativeMessagingHosts\org.keepassxc.keepassxc_browser]
|
||||
@="C:\ProgramData\KeepassXC\org.keepassxc.keepassxc_browser_edge.json"
|
||||
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge]
|
||||
"NativeMessagingUserLevelHosts"=dword:00000000
|
||||
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\ExtensionInstallAllowlist]
|
||||
"1"="pdffhmdngciaglkoonimfcmckehcpafo"
|
||||
|
||||
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge\NativeMessagingAllowlist]
|
||||
"1"="org.keepassxc.keepassxc_browser"
|
||||
----
|
||||
|
||||
==== Managed Microsoft Edge on macOS
|
||||
1. Deploy *org.keepassxc.keepassxc_browser_edge.json* to `/Library/Microsoft/Edge/NativeMessagingHosts`.
|
||||
|
||||
2. You may need to configure Edge to allowlist the extension and native messaging host. See https://learn.microsoft.com/en-us/deployedge/microsoft-edge-policies#native-messaging[Microsoft Edge Native Messaging Policies] for more information.
|
||||
// end::advanced[]
|
||||
// end::content[]
|
||||
|
||||
@@ -416,23 +416,5 @@ The following key derivation functions are supported:
|
||||
KeePassXC offers some maintenance features that can be applied to clean up your database. Navigate to _Database_ -> _Database settings_ then click on _Maintenance_ on the left hand panel. The following screen appears. On this screen you can delete multiple icons at once and purge any unused icons in your database.
|
||||
|
||||
image::database_maintenance.png[]
|
||||
|
||||
== Remote database support
|
||||
KeePassXC provides support for syncing database files that reside in a remote location. If you can download/upload the database file via a commandline tool (e.g. rsync, ssh, scp etc.) KeePassXC offers easy to use functionality to sync the remote database.
|
||||
|
||||
=== Sync with remote database
|
||||
Open the remote sync settings via _Database > Database Settings… > Remote_ to create commands to sync a local database or a temporary local copy of a remote database.
|
||||
|
||||
Define a name for your sync command and specify a download *(A)* as well as an upload command *(B)*. The command and/or input need a `{TEMP_DATABASE}` placeholder specified where the remote database is temporarily stored. Do not forget to save the command settings with the save button *\(C)*. Remote settings are added as menu entries below the _Remote Sync…_ menu for quick access.
|
||||
|
||||
WARNING: If your download or upload command require a password prompt, the command will most likely not succeed. In case of an SSH connection (e.g. sftp), it is recommended to use <<KeePassXC – SSH Agent integration,SSH agent>> so that no password prompt is needed.
|
||||
|
||||
.Remote sync settings
|
||||
image::sync_remote_settings.png[]
|
||||
|
||||
Select the remote sync command from the _Database > Remote Sync…_ menu to start the syncing process and a progress bar will show up in the lower right corner.
|
||||
|
||||
WARNING: In case the remote database is changed by another user/process after the downloading command finishes and before uploading again, those changes will be overwritten. Syncing is not an atomic operation.
|
||||
|
||||
// end::advanced[]
|
||||
// end::content[]
|
||||
|
||||
@@ -38,7 +38,7 @@ To install KeePassXC on Microsoft Windows, perform the following steps:
|
||||
.Install wizard
|
||||
image::install_wizard_1.png[,80%]
|
||||
|
||||
2. Click Next and follow the simple instructions on the KeePassXC Setup Wizard to complete the installation. You will have the option to choose your install location, add a desktop shortcut, and launch on startup.
|
||||
2. Click Next and follow the simple instructions on the KeepPassXC Setup Wizard to complete the installation. You will have the option to choose your install location, add a desktop shortcut, and launch on startup.
|
||||
+
|
||||
.Install wizard (cont)
|
||||
image::install_wizard_2.png[,80%]
|
||||
@@ -59,7 +59,7 @@ image::linux_store.png[]
|
||||
|
||||
The Snap and Flatpak options are sandboxed applications (more secure). The Native option is installed with the operating system files. Read more about the limitations of these options here: https://keepassxc.org/docs/#faq-appsnap-yubikey[KeePassXC Snap FAQ]
|
||||
|
||||
NOTE: KeePassXC stores a configuration file in `~/.local/state` to remember window position, recent files, and other local settings. If you mount this folder to a tmpdisk you will lose settings after reboot.
|
||||
NOTE: KeePassXC stores a configuration file in `~/.cache` to remember window position, recent files, and other local settings. If you mount this folder to a tmpdisk you will lose settings after reboot.
|
||||
|
||||
=== macOS
|
||||
To install the KeePassXC app on macOS, double click on the downloaded DMG file and use the click and drag option as shown:
|
||||
|
||||
@@ -12,7 +12,6 @@ KeePassXC allows you to import external databases from the following options:
|
||||
* Bitwarden (.json)
|
||||
* Proton Pass (.json)
|
||||
* KeePass 1 Database (.kdb)
|
||||
* Remote database (.kdbx)
|
||||
|
||||
To import any of these files, start KeePassXC and either click the `Import File` button on the welcome screen or use the menu Database > Import... to launch the Import Wizard.
|
||||
|
||||
@@ -79,21 +78,6 @@ To import a KeePass 1 database file in KeePassXC, perform the following steps:
|
||||
|
||||
3. Click `Continue` to unlock and preview the import. Click `Done` to complete the import.
|
||||
|
||||
=== Importing Remote Database
|
||||
Database files that are stored in a remote location can be imported or opened with KeePassXC if you provide a command to download the file from the remote location.
|
||||
|
||||
To import (or temporarily open) a remote database file in KeePassXC, perform the following steps:
|
||||
|
||||
1. Open the Import Wizard as shown above. Select the Remote Database option.
|
||||
|
||||
2. Enter a command to download the remote database. If necessary, enter input that needs to be passed to the command. The command and/or input need a `{TEMP_DATABASE}` placeholder specified where the remote database is temporarily stored.
|
||||
|
||||
3. Enter the password for your database and optionally provide a key file.
|
||||
|
||||
4. Click `Continue` to unlock and preview the import. Click `Done` to complete the import.
|
||||
|
||||
Opening without importing a remote database is possible by selecting Temporary Database in the Import Into section of the wizard.
|
||||
|
||||
== Exporting Databases
|
||||
KeePassXC supports multiple ways to export your database for transfer to another program or to print out and archive.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ NOTE: On macOS please substitute `Ctrl` with `Cmd` (aka `⌘`).
|
||||
|New Entry | Ctrl + N
|
||||
|Edit Entry | Enter ; Ctrl + E
|
||||
|Delete Entry | Delete
|
||||
|Clone Entry | Ctrl + D
|
||||
|Clone Entry | Ctrl + K
|
||||
|Copy Username | Ctrl + B
|
||||
|Copy Password | Ctrl + C
|
||||
|Copy URL | Ctrl + U
|
||||
|
||||
@@ -58,12 +58,7 @@ if(UNIX AND NOT APPLE AND NOT HAIKU)
|
||||
EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE)
|
||||
endif(KEEPASSXC_DIST_FLATPAK)
|
||||
configure_file(linux/${APP_ID}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/linux/${APP_ID}.desktop @ONLY)
|
||||
configure_file(linux/${APP_ID}.policy.in ${CMAKE_CURRENT_BINARY_DIR}/linux/${APP_ID}.policy @ONLY)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/linux/${APP_ID}.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||
if("${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/linux/${APP_ID}.policy DESTINATION ${CMAKE_INSTALL_DATADIR}/polkit-1/actions)
|
||||
endif()
|
||||
install(FILES linux/${APP_ID}.appdata.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo)
|
||||
endif(UNIX AND NOT APPLE AND NOT HAIKU)
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.03 18C13.08 18.7 13.24 19.38 13.5 20H6.5C5 20 3.69 19.5 2.61 18.43C1.54 17.38 1 16.09 1 14.58C1 13.28 1.39 12.12 2.17 11.1S4 9.43 5.25 9.15C5.67 7.62 6.5 6.38 7.75 5.43S10.42 4 12 4C13.95 4 15.6 4.68 16.96 6.04C18.32 7.4 19 9.05 19 11C19.04 11 19.07 11 19.1 11C18.36 11.07 17.65 11.23 17 11.5V11C17 9.62 16.5 8.44 15.54 7.46C14.56 6.5 13.38 6 12 6S9.44 6.5 8.46 7.46C7.5 8.44 7 9.62 7 11H6.5C5.53 11 4.71 11.34 4.03 12.03C3.34 12.71 3 13.53 3 14.5S3.34 16.29 4.03 17C4.71 17.66 5.53 18 6.5 18H13.03M19 13.5V12L16.75 14.25L19 16.5V15C20.38 15 21.5 16.12 21.5 17.5C21.5 17.9 21.41 18.28 21.24 18.62L22.33 19.71C22.75 19.08 23 18.32 23 17.5C23 15.29 21.21 13.5 19 13.5M19 20C17.62 20 16.5 18.88 16.5 17.5C16.5 17.1 16.59 16.72 16.76 16.38L15.67 15.29C15.25 15.92 15 16.68 15 17.5C15 19.71 16.79 21.5 19 21.5V23L21.25 20.75L19 18.5V20Z" /></svg>
|
||||
|
Before Width: | Height: | Size: 914 B |
@@ -76,7 +76,6 @@
|
||||
<file>application/scalable/actions/proton.svg</file>
|
||||
<file>application/scalable/actions/qrcode.svg</file>
|
||||
<file>application/scalable/actions/refresh.svg</file>
|
||||
<file>application/scalable/actions/remote-sync.svg</file>
|
||||
<file>application/scalable/actions/reports.svg</file>
|
||||
<file>application/scalable/actions/reports-exclude.svg</file>
|
||||
<file>application/scalable/actions/sort-alphabetical-ascending.svg</file>
|
||||
|
||||
@@ -52,13 +52,6 @@
|
||||
</screenshots>
|
||||
|
||||
<releases>
|
||||
<release version="2.8.0" date="2025-01-01">
|
||||
<description>
|
||||
<ul>
|
||||
<li>Placeholder for future release notes</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="2.7.10" date="2025-03-02">
|
||||
<description>
|
||||
<ul>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
<vendor>KeePassXC Developers</vendor>
|
||||
<vendor_url></vendor_url>
|
||||
<icon_name>@APP_ICON_NAME@</icon_name>
|
||||
|
||||
<action id="org.keepassxc.KeePassXC.unlockDatabase">
|
||||
<description>Quick Unlock for a KeePassXC Database</description>
|
||||
<message>Authentication is required to unlock a KeePassXC Database</message>
|
||||
<defaults>
|
||||
<allow_inactive>no</allow_inactive>
|
||||
<allow_active>auth_self</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
</policyconfig>
|
||||
0
share/macosx/keepassxc.iconset/icon_128x128.png
Normal file → Executable file
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
0
share/macosx/keepassxc.iconset/icon_128x128@2x.png
Normal file → Executable file
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
0
share/macosx/keepassxc.iconset/icon_16x16.png
Normal file → Executable file
|
Before Width: | Height: | Size: 708 B After Width: | Height: | Size: 708 B |
0
share/macosx/keepassxc.iconset/icon_16x16@2x.png
Normal file → Executable file
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
0
share/macosx/keepassxc.iconset/icon_256x256.png
Normal file → Executable file
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
0
share/macosx/keepassxc.iconset/icon_256x256@2x.png
Normal file → Executable file
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
0
share/macosx/keepassxc.iconset/icon_32x32.png
Normal file → Executable file
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
0
share/macosx/keepassxc.iconset/icon_32x32@2x.png
Normal file → Executable file
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
0
share/macosx/keepassxc.iconset/icon_512x512.png
Normal file → Executable file
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
0
share/macosx/keepassxc.iconset/icon_512x512@2x.png
Normal file → Executable file
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
@@ -11,7 +11,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Report bugs at: <a href="https://github.com/keepassxreboot/keepassxc/issues" style="text-decoration: underline;">https://github.com</a></source>
|
||||
<translation>Reporteu errors a: <a href="https://github.com/keepassxreboot/keepassxc/issues" style="text-decoration: underline;">https://github.com</a></translation>
|
||||
<translation>Informeu d'errors a: <a href="https://github.com/keepassxreboot/keepassxc/issues" style="text-decoration: underline;">https://github.com</a></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
|
||||
@@ -50,7 +50,7 @@
|
||||
<name>AccessControlDialog</name>
|
||||
<message>
|
||||
<source>KeePassXC - Access Request</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>KeePassXC - Sol·licitud d'accés</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Non-existing/inaccessible executable path. Please double-check the client is legit.</source>
|
||||
@@ -78,7 +78,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Details</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Detalls</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remember</source>
|
||||
@@ -94,18 +94,18 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Deny All && Future</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Denegar-ho tot & Futur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Allow All && &Future</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Permet-ho tot & Futur</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>AccessControlDialog::DenyButton</name>
|
||||
<message>
|
||||
<source>Deny for this program</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Denega per a aquest programa</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -116,7 +116,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Pageant</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Usa Pageant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use OpenSSH</source>
|
||||
@@ -124,7 +124,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>SSH_AUTH_SOCK override</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>SSH_AUTH_SOCK override</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SSH_AUTH_SOCK value</source>
|
||||
@@ -140,7 +140,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>SSH_SK_PROVIDER override</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>SSH_SK_PROVIDER override</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No SSH Agent socket available. Either make sure SSH_AUTH_SOCK environment variable exists or set an override.</source>
|
||||
@@ -150,12 +150,16 @@
|
||||
<source>SSH Agent connection is working!</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use both agents</source>
|
||||
<translation>Usa ambdós agents</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationSettingsWidget</name>
|
||||
<message>
|
||||
<source>Application Settings</source>
|
||||
<translation>Configuració de l'aplicació</translation>
|
||||
<translation>Paràmetres de l'aplicació</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>General</source>
|
||||
@@ -221,6 +225,10 @@
|
||||
<source>Select backup storage directory</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>This setting cannot be enabled when minimize on unlock is enabled.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationSettingsWidgetGeneral</name>
|
||||
@@ -270,12 +278,12 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>On database unlock, show entries that </source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Al desbloquejar la base de dades, mostra les entrades que </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>have expired</source>
|
||||
<comment>On database unlock, show entries that...</comment>
|
||||
<translation type="unfinished"/>
|
||||
<translation>ha caducat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source> days</source>
|
||||
@@ -406,7 +414,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Use monospaced font for notes</source>
|
||||
<translation>Usa lletra monoespaiada per a les notes</translation>
|
||||
<translation>Fer servir fonts monoespaiada per les notes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Minimize instead of app exit</source>
|
||||
@@ -489,6 +497,14 @@
|
||||
<source>Remember last typed entry for:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source> recent files</source>
|
||||
<translation> fitxers recents</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show passwords in color</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationSettingsWidgetSecurity</name>
|
||||
@@ -587,7 +603,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Auto-Type Error</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Error de tecleig automàtic</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Permission Required</source>
|
||||
@@ -603,7 +619,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid entry provided</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Entrada proporcionada no vàlida</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bracket imbalance detected, found extra { or }</source>
|
||||
@@ -638,6 +654,10 @@
|
||||
<source>Invalid placeholder: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Entry does not have attribute for PICKCHARS: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>AutoTypeAssociationsModel</name>
|
||||
@@ -685,7 +705,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Sequence aborted: Caps Lock is on</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Seqüència avortada: el bloqueig de majúscules està activat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sequence aborted: Modifier keys held by user</source>
|
||||
@@ -717,11 +737,11 @@ Ctrl+4 - Use Virtual Keyboard (Windows Only)</p></source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search all open databases</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Cerca totes les bases de dades obertes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search…</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Cerca...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Type Sequence</source>
|
||||
@@ -745,19 +765,19 @@ Ctrl+4 - Use Virtual Keyboard (Windows Only)</p></source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy Username</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Copia el nom d'usuari</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy Password</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Copia la contrasenya</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy TOTP</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Copia TOTP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Virtual Keyboard</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Utilitza el teclat virtual</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -784,11 +804,11 @@ Ctrl+4 - Use Virtual Keyboard (Windows Only)</p></source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Allow Selected</source>
|
||||
<translation>Permet els seleccionats</translation>
|
||||
<translation>Permet la selecció</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Deny All</source>
|
||||
<translation>Denega-ho tot</translation>
|
||||
<translation>Denegar tot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disable for this site</source>
|
||||
@@ -1075,7 +1095,7 @@ Would you like to migrate your existing settings now?</source>
|
||||
<message>
|
||||
<source>Browse…</source>
|
||||
<extracomment>Button for opening file dialog</extracomment>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Explora...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use a custom browser configuration location:</source>
|
||||
@@ -1409,10 +1429,6 @@ Còpia de seguretat de la base de dades situada a %2</translation>
|
||||
<source>Key File:</source>
|
||||
<translation>Fitxer clau:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>In addition to a password, you can use a secret file to enhance the security of your database. This file can be generated in your database's security settings.</p><p>This is <strong>not</strong> your *.kdbx database file!<br>If you do not have a key file, leave this field empty.</p><p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Key file help</source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -1425,18 +1441,13 @@ Còpia de seguretat de la base de dades situada a %2</translation>
|
||||
<source>Hardware Key:</source>
|
||||
<translation>Motxilla:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>You can use a hardware security key such as a <strong>YubiKey</strong> or <strong>OnlyKey</strong> with slots configured for HMAC-SHA1.</p>
|
||||
<p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hardware key help</source>
|
||||
<translation>Ajuda de la motxilla</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Key file to unlock the database</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Fitxer clau per desbloquejar la base de dades</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Browse for key file</source>
|
||||
@@ -1444,7 +1455,7 @@ Còpia de seguretat de la base de dades situada a %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Browse…</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Explora...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Refresh hardware tokens</source>
|
||||
@@ -1456,7 +1467,7 @@ Còpia de seguretat de la base de dades situada a %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unlock Database</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Desbloqueja la base de dades</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
@@ -1464,7 +1475,7 @@ Còpia de seguretat de la base de dades situada a %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unlock</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Desbloqueja</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please present or touch your YubiKey to continue…</source>
|
||||
@@ -1490,7 +1501,7 @@ We recommend you update your KeePassXC installation.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database unlock canceled.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Desbloqueig de la base de dades cancel·lat.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unlock failed and no password given</source>
|
||||
@@ -1564,6 +1575,15 @@ If you do not have a key file, please leave the field empty.</source>
|
||||
<source>Select hardware key…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>In addition to a password, you can use a secret file to enhance the security of your database. This file can be generated in your database's security settings.</p><p>This is <strong>not</strong> your *.kdbx database file!<br>If you do not have a key file, leave this field empty.</p><p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>You can use a hardware security key such as a <strong>YubiKey</strong> or <strong>OnlyKey</strong> with slots configured for HMAC-SHA1.</p>
|
||||
<p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DatabaseSettingWidgetMetaData</name>
|
||||
@@ -1588,7 +1608,7 @@ If you do not have a key file, please leave the field empty.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database Credentials</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Credencials de la base de dades</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Encryption Settings</source>
|
||||
@@ -1643,7 +1663,7 @@ If you do not have a key file, please leave the field empty.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove</source>
|
||||
<translation>Suprimeix</translation>
|
||||
<translation>Suprimiu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete the selected key?</source>
|
||||
@@ -2203,13 +2223,21 @@ This is definitely a bug, please report it to the developers.</source>
|
||||
<comment>Database tab name modifier</comment>
|
||||
<translation>%1 [bloquejat]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Export database to XML file</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>XML file</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Writing the XML file failed</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DatabaseWidget</name>
|
||||
<message>
|
||||
<source>Database Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Searching…</source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -2256,7 +2284,7 @@ This is definitely a bug, please report it to the developers.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Expired entries</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Entrades caducades</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No current database.</source>
|
||||
@@ -2376,6 +2404,22 @@ Voleu deshabilitar el desat segur i provar-ho un altre cop?</translation>
|
||||
<source>Entries expiring within %1 day(s)</source>
|
||||
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Searches and Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a unique name or overwrite an existing search from the list:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save</source>
|
||||
<translation>Desa</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditEntryWidget</name>
|
||||
@@ -2512,10 +2556,6 @@ Would you like to correct it?</source>
|
||||
<source>Hide</source>
|
||||
<translation>Oculta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tomorrow</source>
|
||||
<translation>Demà</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n week(s)</source>
|
||||
<translation><numerusform>% n setmana/es</numerusform><numerusform>%n setmana/es</numerusform></translation>
|
||||
@@ -2528,6 +2568,10 @@ Would you like to correct it?</source>
|
||||
<source>%n year(s)</source>
|
||||
<translation><numerusform>% n any/s</numerusform><numerusform>%n any/s</numerusform></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n hour(s)</source>
|
||||
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditEntryWidgetAdvanced</name>
|
||||
@@ -2915,7 +2959,7 @@ Would you like to correct it?</source>
|
||||
<message>
|
||||
<source>Browse…</source>
|
||||
<extracomment>Button for opening file dialog</extracomment>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Explora...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Attachment</source>
|
||||
@@ -3043,6 +3087,14 @@ Would you like to correct it?</source>
|
||||
<source>Do not use HTTP Auth toggle for this and sub groups</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Omit WWW subdomain from matching:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Omit WWW subdomain from matching toggle for this and sub groups</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditGroupWidgetKeeShare</name>
|
||||
@@ -3076,7 +3128,7 @@ Would you like to correct it?</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Browse…</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Explora...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear fields</source>
|
||||
@@ -3624,6 +3676,10 @@ Error: %1</source>
|
||||
<source>Auto-Type</source>
|
||||
<translation>Compleció automàtica</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EntryModel</name>
|
||||
@@ -3730,14 +3786,14 @@ Error: %1</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Has TOTP</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Disposa de TOTP</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EntryPreviewWidget</name>
|
||||
<message>
|
||||
<source>Display current TOTP value</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Mostra el valor actual de TOTP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Close</source>
|
||||
@@ -3831,6 +3887,10 @@ Error: %1</source>
|
||||
<source>Disabled</source>
|
||||
<translation>Inhabilitat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Double click to copy value</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EntryURLModel</name>
|
||||
@@ -4748,7 +4808,7 @@ If this reoccurs, then your database file may be corrupt.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Note: Do NOT use a file that may change as that will prevent you from unlocking your database.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Nota: NO utilitzeu un fitxer que pugui canviar, ja que us impedirà desbloquejar la base de dades.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Browse for key file</source>
|
||||
@@ -4756,7 +4816,7 @@ If this reoccurs, then your database file may be corrupt.</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Browse…</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Explora...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Old key file format</source>
|
||||
@@ -5000,7 +5060,7 @@ Are you sure you want to continue with this file?</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database &Reports…</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Informes de la base de dades</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Statistics, health check, etc.</source>
|
||||
@@ -5072,11 +5132,11 @@ Are you sure you want to continue with this file?</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Lock Database</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>B&loqueja la base de dades</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Lock &All Databases</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Bloqueja totes les bases de dades</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Title</source>
|
||||
@@ -5140,11 +5200,11 @@ Are you sure you want to continue with this file?</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show QR Code</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Mostra el codi QR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set up TOTP…</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Configura el TOTP...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy &TOTP</source>
|
||||
@@ -5192,7 +5252,7 @@ Are you sure you want to continue with this file?</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Database Backup…</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Desa una còpia de seguretat...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Add key to SSH Agent</source>
|
||||
@@ -5216,11 +5276,11 @@ Are you sure you want to continue with this file?</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Dark</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Fosc</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Classic (Platform-native)</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Clàssic (natiu de la plataforma)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show Toolbar</source>
|
||||
@@ -5314,6 +5374,30 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<source>You must restart the application to apply this setting. Would you like to restart now?</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>No Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%1 Entry(s)</source>
|
||||
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy Password and TOTP</source>
|
||||
<translation>Copia la contrasenya i el TOTP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&XML File…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>XML File…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ManageDatabase</name>
|
||||
@@ -5463,7 +5547,7 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<name>NewDatabaseWizardPageDatabaseKey</name>
|
||||
<message>
|
||||
<source>Database Credentials</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Credencials de la base de dades</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>A set of credentials known only to you that protects your database.</source>
|
||||
@@ -5684,29 +5768,6 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PasswordEdit</name>
|
||||
<message>
|
||||
<source>Passwords do not match</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Passwords match so far</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Toggle Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generate Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Caps Lock enabled!</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PasswordEditWidget</name>
|
||||
<message>
|
||||
@@ -5885,10 +5946,6 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<source>Also choose from:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Excluded characters: "0", "1", "l", "I", "O", "|", "﹒"</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exclude look-alike characters</source>
|
||||
<translation>Excloure caràcters d'aspecte semblant</translation>
|
||||
@@ -6038,6 +6095,57 @@ Do you want to overwrite it?</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Excel·lent</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Excluded characters: "0", "1", "l", "I", "O", "|", "﹒"</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PasswordWidget</name>
|
||||
<message>
|
||||
<source>Passwords do not match</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Passwords match so far</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Toggle Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generate Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Caps Lock enabled!</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quality: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Poor</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Pobre</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Weak</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Feble</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Good</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Bona</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Excellent</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Excel·lent</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PickcharsDialog</name>
|
||||
@@ -6382,7 +6490,7 @@ Do you want to overwrite it?</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy the current TOTP to the clipboard (equivalent to "-a totp").</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Copia el TOTP actual al porta-retalls (equivalent a "-a totp").</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Must match only one entry, otherwise a list of possible matches is shown.</source>
|
||||
@@ -6419,11 +6527,11 @@ Do you want to overwrite it?</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>ERROR: Please specify one of --attribute or --totp, not both.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>ERROR: Especifiqueu un, --atribut o --totp, no tots dos.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Entry with path %1 has no TOTP set up.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>L'entrada amb la ruta %1 no té configurat TOTP.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ERROR: attribute %1 is ambiguous, it matches %2.</source>
|
||||
@@ -7095,7 +7203,7 @@ Available commands:
|
||||
</message>
|
||||
<message>
|
||||
<source>Show the entry's current TOTP.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Mostra el TOTP actual de l'entrada.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show the protected attributes in clear text.</source>
|
||||
@@ -7168,10 +7276,6 @@ Please consider generating a new key file.</source>
|
||||
<source>Invalid YubiKey serial %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please present or touch your YubiKey to continue…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter password to encrypt database (optional): </source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -7319,7 +7423,7 @@ Nucli: %3 %4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quick Unlock</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Desbloqueig ràpid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Secret Service Integration</source>
|
||||
@@ -7545,11 +7649,11 @@ Nucli: %3 %4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Browser Statistics</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Estadístiques del navegador</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Health Check</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Informe de salut</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HIBP</source>
|
||||
@@ -7557,7 +7661,7 @@ Nucli: %3 %4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Statistics</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Estadístiques</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unsupported key file version: %1</source>
|
||||
@@ -7589,7 +7693,7 @@ Nucli: %3 %4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>lock all open databases</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>bloqueja totes les bases de dades obertes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>key file of the database</source>
|
||||
@@ -7605,11 +7709,11 @@ Nucli: %3 %4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Locked databases.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Bases de dades bloquejades.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database failed to lock.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>La base de dades no s'ha pogut bloquejar.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Another instance of KeePassXC is already running.</source>
|
||||
@@ -7649,6 +7753,67 @@ Nucli: %3 %4</translation>
|
||||
<source>Failed to sign challenge using Windows Hello.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please present or touch your YubiKey to continue.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show all the attributes of the entry.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Edit a database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not change the database key.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database was not modified.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Successfully edited the database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Loading the new key file failed: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unset the password for the database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unset the key file for the database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot use %1 and %2 at the same time.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot remove all the keys from a database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot remove password: The database does not have a password.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot remove file key: The database does not have a file key.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Found unexpected Key type %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the key file for the database.
|
||||
This options is deprecated, use --set-key-file instead.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtIOCompressor</name>
|
||||
@@ -8196,6 +8361,10 @@ Nucli: %3 %4</translation>
|
||||
<source>Limit search to selected group</source>
|
||||
<translation>Limitar la cerca al grup seleccionat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SettingsClientModel</name>
|
||||
@@ -8408,16 +8577,39 @@ Nucli: %3 %4</translation>
|
||||
</context>
|
||||
<context>
|
||||
<name>TagModel</name>
|
||||
<message>
|
||||
<source>All</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Expired</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Caducades</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Weak Passwords</source>
|
||||
<translation>Contrasenyes febles</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>All Entries</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TagView</name>
|
||||
<message>
|
||||
<source>Remove Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove Tag</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Confirm Remove Tag</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove tag "%1" from all entries in this database?</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
@@ -8449,7 +8641,7 @@ Nucli: %3 %4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error creating the QR code.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Hi hagut un error creant el codi QR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Closing in %1 seconds.</source>
|
||||
@@ -8517,7 +8709,7 @@ Nucli: %3 %4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Invalid TOTP Secret</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Secret de TOTP no vàlid</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You have entered an invalid secret key. The key must be in Base32 format.
|
||||
@@ -8526,7 +8718,7 @@ Example: JBSWY3DPEHPK3PXP</source>
|
||||
</message>
|
||||
<message>
|
||||
<source>Confirm Remove TOTP Settings</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Confirma l'eliminació de la configuració de TOTP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Are you sure you want to delete TOTP settings for this entry?</source>
|
||||
|
||||
@@ -150,6 +150,10 @@
|
||||
<source>SSH Agent connection is working!</source>
|
||||
<translation>SSH Agent veza radi!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use both agents</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationSettingsWidget</name>
|
||||
@@ -221,6 +225,10 @@
|
||||
<source>Select backup storage directory</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>This setting cannot be enabled when minimize on unlock is enabled.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationSettingsWidgetGeneral</name>
|
||||
@@ -489,6 +497,14 @@
|
||||
<source>Remember last typed entry for:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source> recent files</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show passwords in color</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationSettingsWidgetSecurity</name>
|
||||
@@ -638,6 +654,10 @@
|
||||
<source>Invalid placeholder: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Entry does not have attribute for PICKCHARS: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>AutoTypeAssociationsModel</name>
|
||||
@@ -1417,10 +1437,6 @@ Sigurnosna kopija baza podataka nalazi se na %2</translation>
|
||||
<source>Key File:</source>
|
||||
<translation>Datoteka ključa:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>In addition to a password, you can use a secret file to enhance the security of your database. This file can be generated in your database's security settings.</p><p>This is <strong>not</strong> your *.kdbx database file!<br>If you do not have a key file, leave this field empty.</p><p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Key file help</source>
|
||||
<translation>Datoteka ključa pomoć</translation>
|
||||
@@ -1433,11 +1449,6 @@ Sigurnosna kopija baza podataka nalazi se na %2</translation>
|
||||
<source>Hardware Key:</source>
|
||||
<translation>Hardverski ključ:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>You can use a hardware security key such as a <strong>YubiKey</strong> or <strong>OnlyKey</strong> with slots configured for HMAC-SHA1.</p>
|
||||
<p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hardware key help</source>
|
||||
<translation>Hardverski ključ pomoć</translation>
|
||||
@@ -1573,6 +1584,15 @@ Ako nemate datoteku ključa, ostavite polje prazno.</translation>
|
||||
<source>Select hardware key…</source>
|
||||
<translation>Odaberite hardverski ključ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>In addition to a password, you can use a secret file to enhance the security of your database. This file can be generated in your database's security settings.</p><p>This is <strong>not</strong> your *.kdbx database file!<br>If you do not have a key file, leave this field empty.</p><p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>You can use a hardware security key such as a <strong>YubiKey</strong> or <strong>OnlyKey</strong> with slots configured for HMAC-SHA1.</p>
|
||||
<p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DatabaseSettingWidgetMetaData</name>
|
||||
@@ -2219,13 +2239,21 @@ Ovo je definitivno pogreška, molimo prijavite to programerima.</translation>
|
||||
<comment>Database tab name modifier</comment>
|
||||
<translation>%1 [Zaključano]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Export database to XML file</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>XML file</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Writing the XML file failed</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DatabaseWidget</name>
|
||||
<message>
|
||||
<source>Database Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Searching…</source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -2390,6 +2418,22 @@ Disable safe saves and try again?</source>
|
||||
<source>Entries expiring within %1 day(s)</source>
|
||||
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Searches and Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a unique name or overwrite an existing search from the list:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save</source>
|
||||
<translation>Spremi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditEntryWidget</name>
|
||||
@@ -2526,10 +2570,6 @@ Would you like to correct it?</source>
|
||||
<source>Hide</source>
|
||||
<translation>Sakrij</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tomorrow</source>
|
||||
<translation>Sutra</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n week(s)</source>
|
||||
<translation><numerusform>%n tjedan</numerusform><numerusform>%n tjedana</numerusform><numerusform>%n tjedana</numerusform></translation>
|
||||
@@ -2542,6 +2582,10 @@ Would you like to correct it?</source>
|
||||
<source>%n year(s)</source>
|
||||
<translation><numerusform>%n godina</numerusform><numerusform>%n godine</numerusform><numerusform>%n godina</numerusform></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n hour(s)</source>
|
||||
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditEntryWidgetAdvanced</name>
|
||||
@@ -3057,6 +3101,14 @@ Would you like to correct it?</source>
|
||||
<source>Do not use HTTP Auth toggle for this and sub groups</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Omit WWW subdomain from matching:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Omit WWW subdomain from matching toggle for this and sub groups</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditGroupWidgetKeeShare</name>
|
||||
@@ -3638,6 +3690,10 @@ Error: %1</source>
|
||||
<source>Auto-Type</source>
|
||||
<translation>Auto-tipkanje</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EntryModel</name>
|
||||
@@ -3845,6 +3901,10 @@ Error: %1</source>
|
||||
<source>Disabled</source>
|
||||
<translation>Onemogući</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Double click to copy value</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EntryURLModel</name>
|
||||
@@ -5329,6 +5389,30 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<source>You must restart the application to apply this setting. Would you like to restart now?</source>
|
||||
<translation>Morate ponovno pokrenuti aplikaciju da biste primijenili tu postavku. Želite li ju ponovno pokrenuti sada?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>No Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%1 Entry(s)</source>
|
||||
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy Password and TOTP</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>&XML File…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>XML File…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ManageDatabase</name>
|
||||
@@ -5699,29 +5783,6 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PasswordEdit</name>
|
||||
<message>
|
||||
<source>Passwords do not match</source>
|
||||
<translation>Lozinke se ne podudaraju</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Passwords match so far</source>
|
||||
<translation>Lozinke se zasad podudaraju</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Toggle Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generate Password (%1)</source>
|
||||
<translation>Proizvedi Lozinku (%1)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Caps Lock enabled!</source>
|
||||
<translation>Upozorenje: Caps Lock uključen!</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PasswordEditWidget</name>
|
||||
<message>
|
||||
@@ -5900,10 +5961,6 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<source>Also choose from:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Excluded characters: "0", "1", "l", "I", "O", "|", "﹒"</source>
|
||||
<translation>Izostavi znakove: "0", "1", "l", "I", "O", "|", "".</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exclude look-alike characters</source>
|
||||
<translation>Izostavi slične znakove</translation>
|
||||
@@ -6053,6 +6110,57 @@ Do you want to overwrite it?</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Izvrsna</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Excluded characters: "0", "1", "l", "I", "O", "|", "﹒"</source>
|
||||
<translation>Izostavi znakove: "0", "1", "l", "I", "O", "|", "".</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PasswordWidget</name>
|
||||
<message>
|
||||
<source>Passwords do not match</source>
|
||||
<translation>Lozinke se ne podudaraju</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Passwords match so far</source>
|
||||
<translation>Lozinke se zasad podudaraju</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Toggle Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generate Password (%1)</source>
|
||||
<translation>Proizvedi Lozinku (%1)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Caps Lock enabled!</source>
|
||||
<translation>Upozorenje: Caps Lock uključen!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quality: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Poor</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>bijedna</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Weak</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Slaba</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Good</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Dobra</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Excellent</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Izvrsna</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PickcharsDialog</name>
|
||||
@@ -7185,10 +7293,6 @@ Please consider generating a new key file.</source>
|
||||
<source>Invalid YubiKey serial %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please present or touch your YubiKey to continue…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter password to encrypt database (optional): </source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -7664,6 +7768,67 @@ Kernel: %3 %4</source>
|
||||
<source>Failed to sign challenge using Windows Hello.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please present or touch your YubiKey to continue.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show all the attributes of the entry.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Edit a database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not change the database key.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database was not modified.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Successfully edited the database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Loading the new key file failed: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unset the password for the database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unset the key file for the database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot use %1 and %2 at the same time.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot remove all the keys from a database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot remove password: The database does not have a password.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot remove file key: The database does not have a file key.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Found unexpected Key type %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the key file for the database.
|
||||
This options is deprecated, use --set-key-file instead.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtIOCompressor</name>
|
||||
@@ -8211,6 +8376,10 @@ Kernel: %3 %4</source>
|
||||
<source>Limit search to selected group</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SettingsClientModel</name>
|
||||
@@ -8423,10 +8592,6 @@ Kernel: %3 %4</source>
|
||||
</context>
|
||||
<context>
|
||||
<name>TagModel</name>
|
||||
<message>
|
||||
<source>All</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Expired</source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -8435,6 +8600,33 @@ Kernel: %3 %4</source>
|
||||
<source>Weak Passwords</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>All Entries</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TagView</name>
|
||||
<message>
|
||||
<source>Remove Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove Tag</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Confirm Remove Tag</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove tag "%1" from all entries in this database?</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TotpDialog</name>
|
||||
|
||||
@@ -1297,7 +1297,7 @@ Vuoi sovrascrivere la passkey in %1 - %2?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Browsers installed using Snap or Flatpak are not supported with exception to Firefox installed using Snap.</source>
|
||||
<translation>I browser installati tramite Snap o Flatpak non sono supportati, ad eccezione di Firefox installato tramite Snap.</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -1520,11 +1520,11 @@ Database di backup che si trova in %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database file read error.</source>
|
||||
<translation>Errore di lettura del file del database.</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>No file path was provided.</source>
|
||||
<translation>Non è stato fornito alcun percorso del file.</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -2492,13 +2492,7 @@ exit
|
||||
{TEMP_DATABASE} is used as placeholder to store the database in a temporary location
|
||||
The command has to exit. In case of `sftp` as last command `exit` has to be sent
|
||||
</source>
|
||||
<translation>ad es.:
|
||||
get DatabaseOnRemote.kdbx {TEMP_DATABASE}
|
||||
exit
|
||||
---
|
||||
{TEMP_DATABASE} è utilizzato come segnaposto per memorizzare il database in una posizione temporanea
|
||||
Il comando deve uscire. In caso di `sftp` come ultimo comando `exit` deve essere inviato
|
||||
</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>e.g.:
|
||||
@@ -2508,13 +2502,7 @@ exit
|
||||
{TEMP_DATABASE} is used as placeholder to store the database in a temporary location
|
||||
The command has to exit. In case of `sftp` as last command `exit` has to be sent
|
||||
</source>
|
||||
<translation>ad es.:
|
||||
put {TEMP_DATABASE} DatabaseOnRemote.kdbx
|
||||
exit
|
||||
---
|
||||
{TEMP_DATABASE} è utilizzato come segnaposto per memorizzare il database in una posizione temporanea
|
||||
Il comando deve uscire. In caso di `sftp` come ultimo comando `exit` deve essere inviato
|
||||
</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Timeout:</source>
|
||||
@@ -2815,47 +2803,47 @@ Vuoi disabilitare i salvataggi sicuri e riprovare?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The database file "%1" was modified externally</source>
|
||||
<translation>Il file di database "%1" è stato modificato esternamente</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Do you want to load the changes?</source>
|
||||
<translation>Vuoi caricare le modifiche?</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reload database</source>
|
||||
<translation>Ricarica il database</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reloading database…</source>
|
||||
<translation>Ricaricamento del database…</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reload canceled</source>
|
||||
<translation>Ricaricamento annullato</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reload successful</source>
|
||||
<translation>Ricaricamento completato correttamente</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reload pending user action…</source>
|
||||
<translation>Ricaricamento in attesa di azione dell'utente...</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>The database file "%1" was modified externally.<br>How would you like to proceed?<br><br>Merge all changes<br>Ignore the changes on disk until save<br>Discard unsaved changes</source>
|
||||
<translation>Il file di database "%1" è stato modificato esternamente.<br> Come desideri procedere?<br><br>Unisci tutte le modifiche<br>Ignora le modifiche sul disco fino al salvataggio<br>Ignora le modifiche non salvate</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>The database file "%1" was modified externally.<br>How would you like to proceed?<br><br>Merge all changes then save<br>Overwrite the changes on disk<br>Discard unsaved changes</source>
|
||||
<translation>Il file di database "%1" è stato modificato esternamente.<br>Come desideri procedere?<br><br>Unisci tutte le modifiche, quindi salva<br>Sovrascrivi le modifiche sul disco<br>Ignora le modifiche non salvate</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database file overwritten.</source>
|
||||
<translation>File di database sovrascritto.</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database file on disk cannot be unlocked with current credentials.<br>Enter new credentials and/or present hardware key to continue.</source>
|
||||
<translation>Il file del database sul disco non può essere sbloccato con le credenziali attuali.<br> Digita le nuove credenziali e/o presenta la chiave hardware per continuare.</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -3445,7 +3433,7 @@ Vuoi correggerla?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear agent</source>
|
||||
<translation>Cancella agent</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -4835,13 +4823,7 @@ exit
|
||||
{TEMP_DATABASE} is used as placeholder to store the database in a temporary location
|
||||
The command has to exit. In case of `sftp` as last commend `exit` has to be sent
|
||||
</source>
|
||||
<translation>ad es.:
|
||||
get DatabaseOnRemote.kdbx {TEMP_DATABASE}
|
||||
exit
|
||||
---
|
||||
{TEMP_DATABASE} è utilizzato come segnaposto per memorizzare il database in una posizione temporanea
|
||||
Il comando deve uscire. In caso di `sftp` come ultimo comando `exit` deve essere inviato
|
||||
</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remote Database (.kdbx)</source>
|
||||
@@ -6338,11 +6320,11 @@ Aspettatevi alcuni bug e problemi minori, questa versione è pensata per scopi d
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear SSH Agent</source>
|
||||
<translation>Cancella SSH Agent</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear all identities in ssh-agent</source>
|
||||
<translation>Cancella tutte le identità in ssh-agent</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -9214,23 +9196,23 @@ Questa opzione è deprecata, utilizza invece --set-key-file.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Format to use when exporting. Available choices are 'xml', 'csv' or 'html'. Defaults to 'xml'.</source>
|
||||
<translation>Formato da utilizzare per l'esportazione. Scelte disponibili sono 'xml', 'csv' o 'html'. Predefinito è 'xml'.</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>start minimized to the system tray</source>
|
||||
<translation>avvia minimizzato nell'area di notifica di sistema</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>malformed string, possible unescaped delimiter</source>
|
||||
<translation>stringa non valida, possibile delimitatore senza escape</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>missing closing delimiter</source>
|
||||
<translation>delimitatore di chiusura mancante</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1, row: %2, column: %3</source>
|
||||
<translation>%1, riga: %2, colonna: %3</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tags</source>
|
||||
@@ -9814,11 +9796,11 @@ La funzionalità di rete è richiesta per verificare la password con i database
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to remove all SSH identities from agent.</source>
|
||||
<translation>Rimozione delle identità SSH dall'agent non riuscite.</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>All SSH identities removed from agent.</source>
|
||||
<translation>Tutte le identità SSH rimosse dall'agent.</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
||||
@@ -150,6 +150,10 @@
|
||||
<source>SSH Agent connection is working!</source>
|
||||
<translation>Povezava s SSH agentom deluje!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use both agents</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationSettingsWidget</name>
|
||||
@@ -221,6 +225,10 @@
|
||||
<source>Select backup storage directory</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>This setting cannot be enabled when minimize on unlock is enabled.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationSettingsWidgetGeneral</name>
|
||||
@@ -489,6 +497,14 @@
|
||||
<source>Remember last typed entry for:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source> recent files</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show passwords in color</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationSettingsWidgetSecurity</name>
|
||||
@@ -638,6 +654,10 @@
|
||||
<source>Invalid placeholder: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Entry does not have attribute for PICKCHARS: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>AutoTypeAssociationsModel</name>
|
||||
@@ -1407,10 +1427,6 @@ Varnostna kopija baze se nahaja na %2</translation>
|
||||
<source>Key File:</source>
|
||||
<translation>Datoteka s ključi:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>In addition to a password, you can use a secret file to enhance the security of your database. This file can be generated in your database's security settings.</p><p>This is <strong>not</strong> your *.kdbx database file!<br>If you do not have a key file, leave this field empty.</p><p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Key file help</source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -1423,11 +1439,6 @@ Varnostna kopija baze se nahaja na %2</translation>
|
||||
<source>Hardware Key:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>You can use a hardware security key such as a <strong>YubiKey</strong> or <strong>OnlyKey</strong> with slots configured for HMAC-SHA1.</p>
|
||||
<p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hardware key help</source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -1562,6 +1573,15 @@ If you do not have a key file, please leave the field empty.</source>
|
||||
<source>Select hardware key…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>In addition to a password, you can use a secret file to enhance the security of your database. This file can be generated in your database's security settings.</p><p>This is <strong>not</strong> your *.kdbx database file!<br>If you do not have a key file, leave this field empty.</p><p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source><p>You can use a hardware security key such as a <strong>YubiKey</strong> or <strong>OnlyKey</strong> with slots configured for HMAC-SHA1.</p>
|
||||
<p>Click for more information…</p></source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DatabaseSettingWidgetMetaData</name>
|
||||
@@ -2202,13 +2222,21 @@ This is definitely a bug, please report it to the developers.</source>
|
||||
<comment>Database tab name modifier</comment>
|
||||
<translation>%1 [Zaklenjeno]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Export database to XML file</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>XML file</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Writing the XML file failed</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DatabaseWidget</name>
|
||||
<message>
|
||||
<source>Database Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Searching…</source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -2373,6 +2401,22 @@ Disable safe saves and try again?</source>
|
||||
<source>Entries expiring within %1 day(s)</source>
|
||||
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Searches and Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a unique name or overwrite an existing search from the list:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save</source>
|
||||
<translation>Shrani</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditEntryWidget</name>
|
||||
@@ -2510,10 +2554,6 @@ Would you like to correct it?</source>
|
||||
<source>Hide</source>
|
||||
<translation>Skrij</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tomorrow</source>
|
||||
<translation>Jutri</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n week(s)</source>
|
||||
<translation><numerusform>%n ted(ov)</numerusform><numerusform>%n ted(ov)</numerusform><numerusform>%n ted(ov)</numerusform><numerusform>%n teden(ov)</numerusform></translation>
|
||||
@@ -2526,6 +2566,10 @@ Would you like to correct it?</source>
|
||||
<source>%n year(s)</source>
|
||||
<translation><numerusform>%n let</numerusform><numerusform>%n let</numerusform><numerusform>%n let</numerusform><numerusform>%n let</numerusform></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n hour(s)</source>
|
||||
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditEntryWidgetAdvanced</name>
|
||||
@@ -3041,6 +3085,14 @@ Would you like to correct it?</source>
|
||||
<source>Do not use HTTP Auth toggle for this and sub groups</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Omit WWW subdomain from matching:</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Omit WWW subdomain from matching toggle for this and sub groups</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EditGroupWidgetKeeShare</name>
|
||||
@@ -3623,6 +3675,10 @@ Error: %1</source>
|
||||
<source>Auto-Type</source>
|
||||
<translation>Samodejno tipkanje</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EntryModel</name>
|
||||
@@ -3830,6 +3886,10 @@ Error: %1</source>
|
||||
<source>Disabled</source>
|
||||
<translation>Onemogočen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Double click to copy value</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EntryURLModel</name>
|
||||
@@ -5319,6 +5379,30 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<source>You must restart the application to apply this setting. Would you like to restart now?</source>
|
||||
<translation>Če želite uporabiti to nastavitev, morate znova zagnati aplikacijo. Ali želite znova zagnati zdaj?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>No Tags</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%1 Entry(s)</source>
|
||||
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Copy Password and TOTP</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>&XML File…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>XML File…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ManageDatabase</name>
|
||||
@@ -5689,29 +5773,6 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PasswordEdit</name>
|
||||
<message>
|
||||
<source>Passwords do not match</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Passwords match so far</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Toggle Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generate Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Caps Lock enabled!</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PasswordEditWidget</name>
|
||||
<message>
|
||||
@@ -5890,10 +5951,6 @@ We recommend you use the AppImage available on our downloads page.</source>
|
||||
<source>Also choose from:</source>
|
||||
<translation>Izberi tudi med:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Excluded characters: "0", "1", "l", "I", "O", "|", "﹒"</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Exclude look-alike characters</source>
|
||||
<translation>Izključi podobne znake</translation>
|
||||
@@ -6043,6 +6100,57 @@ Do you want to overwrite it?</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Odlična</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Excluded characters: "0", "1", "l", "I", "O", "|", "﹒"</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PasswordWidget</name>
|
||||
<message>
|
||||
<source>Passwords do not match</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Passwords match so far</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Toggle Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Generate Password (%1)</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: Caps Lock enabled!</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quality: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Poor</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Slabo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Weak</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Šibko</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Good</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Dobra</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Excellent</source>
|
||||
<comment>Password quality</comment>
|
||||
<translation>Odlična</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PickcharsDialog</name>
|
||||
@@ -7171,10 +7279,6 @@ Please consider generating a new key file.</source>
|
||||
<source>Invalid YubiKey serial %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please present or touch your YubiKey to continue…</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter password to encrypt database (optional): </source>
|
||||
<translation>Vnesite geslo za šifriranje baze (neobvezno): </translation>
|
||||
@@ -7652,6 +7756,67 @@ Jedro: %3 %4</translation>
|
||||
<source>Failed to sign challenge using Windows Hello.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please present or touch your YubiKey to continue.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show all the attributes of the entry.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Edit a database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not change the database key.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Database was not modified.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Successfully edited the database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Loading the new key file failed: %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unset the password for the database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unset the key file for the database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot use %1 and %2 at the same time.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot remove all the keys from a database.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot remove password: The database does not have a password.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot remove file key: The database does not have a file key.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Found unexpected Key type %1</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the key file for the database.
|
||||
This options is deprecated, use --set-key-file instead.</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtIOCompressor</name>
|
||||
@@ -8199,6 +8364,10 @@ Jedro: %3 %4</translation>
|
||||
<source>Limit search to selected group</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SettingsClientModel</name>
|
||||
@@ -8411,10 +8580,6 @@ Jedro: %3 %4</translation>
|
||||
</context>
|
||||
<context>
|
||||
<name>TagModel</name>
|
||||
<message>
|
||||
<source>All</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Expired</source>
|
||||
<translation type="unfinished"/>
|
||||
@@ -8423,6 +8588,33 @@ Jedro: %3 %4</translation>
|
||||
<source>Weak Passwords</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>All Entries</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Clear Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TagView</name>
|
||||
<message>
|
||||
<source>Remove Search</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove Tag</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Confirm Remove Tag</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remove tag "%1" from all entries in this database?</source>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TotpDialog</name>
|
||||
|
||||
@@ -9224,15 +9224,15 @@ Bu seçenekler kullanımdan kaldırıldı. yerine --set-key-file kullanın.</tra
|
||||
</message>
|
||||
<message>
|
||||
<source>malformed string, possible unescaped delimiter</source>
|
||||
<translation>dizge bozuk, büyük olasılıkla kaçış karakteri olmayan tırnak var</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>missing closing delimiter</source>
|
||||
<translation>kapanış tırnağı eksik</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1, row: %2, column: %3</source>
|
||||
<translation>%1, %2. satır, %3. sütun</translation>
|
||||
<translation type="unfinished"/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tags</source>
|
||||
|
||||
@@ -115,6 +115,14 @@
|
||||
<ComponentRef Id="DesktopShortcut" />
|
||||
</FeatureRef>
|
||||
|
||||
<!-- Detect VCRedist Version -->
|
||||
<Property Id="VCREDISTINSTALLED">
|
||||
<RegistrySearch Id="SearchVCRedist" Root="HKLM" Key="SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" Name="Version" Type="raw" Win64="yes"/>
|
||||
</Property>
|
||||
<Condition Message="The installed version of Visual Studio Redistributable is too old. Please install the latest version from: https://aka.ms/vs/17/release/vc_redist.x64.exe">
|
||||
<![CDATA[VCREDISTINSTALLED AND VCREDISTINSTALLED > "14.32.31332.0"]]>
|
||||
</Condition>
|
||||
|
||||
<!-- Action to launch application after installer exits -->
|
||||
<Property Id="WixShellExecTarget" Value="[#CM_FP_KeePassXC.exe]" />
|
||||
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
|
||||
|
||||
@@ -65,7 +65,6 @@ parts:
|
||||
- libxtst-dev
|
||||
- asciidoctor
|
||||
- libfreetype-dev
|
||||
- libkeyutils-dev
|
||||
stage-packages:
|
||||
- dbus
|
||||
- libbotan-2-19
|
||||
@@ -77,7 +76,6 @@ parts:
|
||||
- libxtst6
|
||||
- libfreetype6
|
||||
- xclip
|
||||
- libkeyutils1
|
||||
lint:
|
||||
ignore:
|
||||
- library:
|
||||
|
||||
@@ -16,19 +16,7 @@
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_feature_info(Auto-Type WITH_XC_AUTOTYPE "Automatic password typing")
|
||||
add_feature_info(Networking WITH_XC_NETWORKING "Compile KeePassXC with network access code (e.g. for downloading website icons)")
|
||||
add_feature_info(KeePassXC-Browser WITH_XC_BROWSER "Browser integration with KeePassXC-Browser")
|
||||
add_feature_info(Passkeys WITH_XC_BROWSER_PASSKEYS "Passkeys support for browser integration")
|
||||
add_feature_info(SSHAgent WITH_XC_SSHAGENT "SSH agent integration compatible with KeeAgent")
|
||||
add_feature_info(KeeShare WITH_XC_KEESHARE "Sharing integration with KeeShare")
|
||||
add_feature_info(YubiKey WITH_XC_YUBIKEY "YubiKey HMAC-SHA1 challenge-response")
|
||||
add_feature_info(UpdateCheck WITH_XC_UPDATECHECK "Automatic update checking")
|
||||
if(UNIX AND NOT APPLE)
|
||||
add_feature_info(FdoSecrets WITH_XC_FDOSECRETS "Implement freedesktop.org Secret Storage Spec server side API.")
|
||||
endif()
|
||||
|
||||
set(core_SOURCES
|
||||
set(keepassx_SOURCES
|
||||
core/Alloc.cpp
|
||||
core/AutoTypeAssociations.cpp
|
||||
core/Base32.cpp
|
||||
@@ -59,6 +47,7 @@ set(core_SOURCES
|
||||
core/Tools.cpp
|
||||
core/Totp.cpp
|
||||
core/Translator.cpp
|
||||
core/UrlTools.cpp
|
||||
cli/Utils.cpp
|
||||
cli/TextStream.cpp
|
||||
crypto/Crypto.cpp
|
||||
@@ -92,19 +81,6 @@ set(core_SOURCES
|
||||
format/OpVaultReaderBandEntry.cpp
|
||||
format/OpVaultReaderSections.cpp
|
||||
format/ProtonPassReader.cpp
|
||||
keys/CompositeKey.cpp
|
||||
keys/FileKey.cpp
|
||||
keys/PasswordKey.cpp
|
||||
keys/ChallengeResponseKey.cpp
|
||||
streams/HashedBlockStream.cpp
|
||||
streams/HashingStream.cpp
|
||||
streams/HmacBlockStream.cpp
|
||||
streams/LayeredStream.cpp
|
||||
streams/qtiocompressor.cpp
|
||||
streams/StoreDataStream.cpp
|
||||
streams/SymmetricCipherStream.cpp)
|
||||
|
||||
set(gui_SOURCES
|
||||
gui/styles/styles.qrc
|
||||
gui/styles/StateColorPalette.cpp
|
||||
gui/styles/base/phantomcolor.cpp
|
||||
@@ -112,7 +88,6 @@ set(gui_SOURCES
|
||||
gui/styles/dark/DarkStyle.cpp
|
||||
gui/styles/light/LightStyle.cpp
|
||||
gui/AboutDialog.cpp
|
||||
gui/ActionCollection.cpp
|
||||
gui/Application.cpp
|
||||
gui/CategoryListWidget.cpp
|
||||
gui/Clipboard.cpp
|
||||
@@ -144,13 +119,11 @@ set(gui_SOURCES
|
||||
gui/SettingsWidget.cpp
|
||||
gui/SortFilterHideProxyModel.cpp
|
||||
gui/SquareSvgWidget.cpp
|
||||
gui/ShortcutSettingsPage.cpp
|
||||
gui/TotpSetupDialog.cpp
|
||||
gui/TotpDialog.cpp
|
||||
gui/TotpExportSettingsDialog.cpp
|
||||
gui/DatabaseOpenDialog.cpp
|
||||
gui/URLEdit.cpp
|
||||
gui/UrlTools.cpp
|
||||
gui/WelcomeWidget.cpp
|
||||
gui/csvImport/CsvImportWidget.cpp
|
||||
gui/csvImport/CsvParserModel.cpp
|
||||
@@ -182,10 +155,6 @@ set(gui_SOURCES
|
||||
gui/dbsettings/DatabaseSettingsWidgetMetaDataSimple.cpp
|
||||
gui/dbsettings/DatabaseSettingsWidgetEncryption.cpp
|
||||
gui/dbsettings/DatabaseSettingsWidgetDatabaseKey.cpp
|
||||
gui/remote/DatabaseSettingsWidgetRemote.cpp
|
||||
gui/remote/RemoteHandler.cpp
|
||||
gui/remote/RemoteProcess.cpp
|
||||
gui/remote/RemoteSettings.cpp
|
||||
gui/reports/ReportsWidget.cpp
|
||||
gui/reports/ReportsDialog.cpp
|
||||
gui/reports/ReportsWidgetHealthcheck.cpp
|
||||
@@ -200,7 +169,6 @@ set(gui_SOURCES
|
||||
gui/widgets/ElidedLabel.cpp
|
||||
gui/widgets/KPToolBar.cpp
|
||||
gui/widgets/PopupHelpWidget.cpp
|
||||
gui/widgets/ShortcutWidget.cpp
|
||||
gui/wizard/ImportWizard.cpp
|
||||
gui/wizard/ImportWizardPageReview.cpp
|
||||
gui/wizard/ImportWizardPageSelect.cpp
|
||||
@@ -209,82 +177,84 @@ set(gui_SOURCES
|
||||
gui/wizard/NewDatabaseWizardPageMetaData.cpp
|
||||
gui/wizard/NewDatabaseWizardPageEncryption.cpp
|
||||
gui/wizard/NewDatabaseWizardPageDatabaseKey.cpp
|
||||
quickunlock/QuickUnlockInterface.cpp
|
||||
../share/icons/icons.qrc
|
||||
../share/wizard/wizard.qrc)
|
||||
|
||||
keys/CompositeKey.cpp
|
||||
keys/FileKey.cpp
|
||||
keys/PasswordKey.cpp
|
||||
keys/ChallengeResponseKey.cpp
|
||||
streams/HashedBlockStream.cpp
|
||||
streams/HashingStream.cpp
|
||||
streams/HmacBlockStream.cpp
|
||||
streams/LayeredStream.cpp
|
||||
streams/qtiocompressor.cpp
|
||||
streams/StoreDataStream.cpp
|
||||
streams/SymmetricCipherStream.cpp)
|
||||
if(APPLE)
|
||||
list(APPEND gui_SOURCES
|
||||
gui/osutils/macutils/MacPasteboard.cpp
|
||||
set(keepassx_SOURCES
|
||||
${keepassx_SOURCES}
|
||||
core/MacPasteboard.cpp
|
||||
gui/osutils/macutils/MacUtils.cpp
|
||||
gui/osutils/macutils/ScreenLockListenerMac.cpp
|
||||
gui/osutils/macutils/AppKitImpl.mm
|
||||
gui/osutils/macutils/AppKit.h
|
||||
quickunlock/TouchID.mm)
|
||||
|
||||
# TODO: Remove -Wno-error once deprecation warnings have been resolved.
|
||||
set_source_files_properties(quickunlock/TouchID.mm PROPERTY COMPILE_FLAGS "-Wno-old-style-cast")
|
||||
gui/osutils/macutils/AppKit.h)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
list(APPEND gui_SOURCES
|
||||
set(keepassx_SOURCES
|
||||
${keepassx_SOURCES}
|
||||
gui/osutils/nixutils/ScreenLockListenerDBus.cpp
|
||||
gui/osutils/nixutils/NixUtils.cpp)
|
||||
if("${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
list(APPEND core_SOURCES
|
||||
quickunlock/Polkit.cpp
|
||||
quickunlock/PolkitDbusTypes.cpp)
|
||||
endif()
|
||||
if(WITH_XC_X11)
|
||||
list(APPEND gui_SOURCES
|
||||
list(APPEND keepassx_SOURCES
|
||||
gui/osutils/nixutils/X11Funcs.cpp)
|
||||
endif()
|
||||
qt5_add_dbus_adaptor(gui_SOURCES
|
||||
qt5_add_dbus_adaptor(keepassx_SOURCES
|
||||
gui/org.keepassxc.KeePassXC.MainWindow.xml
|
||||
gui/MainWindow.h
|
||||
MainWindow)
|
||||
|
||||
set_source_files_properties(
|
||||
quickunlock/dbus/org.freedesktop.PolicyKit1.Authority.xml
|
||||
PROPERTIES
|
||||
INCLUDE "quickunlock/PolkitDbusTypes.h"
|
||||
)
|
||||
qt5_add_dbus_interface(core_SOURCES
|
||||
quickunlock/dbus/org.freedesktop.PolicyKit1.Authority.xml
|
||||
polkit_dbus
|
||||
)
|
||||
|
||||
find_library(KEYUTILS_LIBRARIES NAMES keyutils)
|
||||
if(NOT KEYUTILS_LIBRARIES)
|
||||
message(FATAL_ERROR "Could not find libkeyutils")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND gui_SOURCES
|
||||
set(keepassx_SOURCES
|
||||
${keepassx_SOURCES}
|
||||
gui/osutils/winutils/ScreenLockListenerWin.cpp
|
||||
gui/osutils/winutils/WinUtils.cpp)
|
||||
if (MSVC)
|
||||
list(APPEND gui_SOURCES quickunlock/WindowsHello.cpp)
|
||||
list(APPEND keepassx_SOURCES winhello/WindowsHello.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_XC_YUBIKEY)
|
||||
list(APPEND gui_SOURCES gui/osutils/DeviceListener.cpp)
|
||||
set(keepassx_SOURCES ${keepassx_SOURCES} gui/osutils/DeviceListener.cpp)
|
||||
if(APPLE)
|
||||
list(APPEND gui_SOURCES gui/osutils/macutils/DeviceListenerMac.cpp)
|
||||
set(keepassx_SOURCES ${keepassx_SOURCES} gui/osutils/macutils/DeviceListenerMac.cpp)
|
||||
elseif(UNIX)
|
||||
list(APPEND gui_SOURCES gui/osutils/nixutils/DeviceListenerLibUsb.cpp)
|
||||
set(keepassx_SOURCES ${keepassx_SOURCES} gui/osutils/nixutils/DeviceListenerLibUsb.cpp)
|
||||
elseif(WIN32)
|
||||
list(APPEND gui_SOURCES gui/osutils/winutils/DeviceListenerWin.cpp)
|
||||
set(keepassx_SOURCES ${keepassx_SOURCES} gui/osutils/winutils/DeviceListenerWin.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(keepassx_SOURCES ${keepassx_SOURCES}
|
||||
../share/icons/icons.qrc
|
||||
../share/wizard/wizard.qrc)
|
||||
|
||||
set(keepassx_SOURCES_MAINEXE main.cpp)
|
||||
|
||||
add_feature_info(Auto-Type WITH_XC_AUTOTYPE "Automatic password typing")
|
||||
add_feature_info(Networking WITH_XC_NETWORKING "Compile KeePassXC with network access code (e.g. for downloading website icons)")
|
||||
add_feature_info(KeePassXC-Browser WITH_XC_BROWSER "Browser integration with KeePassXC-Browser")
|
||||
add_feature_info(Passkeys WITH_XC_BROWSER_PASSKEYS "Passkeys support for browser integration")
|
||||
add_feature_info(SSHAgent WITH_XC_SSHAGENT "SSH agent integration compatible with KeeAgent")
|
||||
add_feature_info(KeeShare WITH_XC_KEESHARE "Sharing integration with KeeShare")
|
||||
add_feature_info(YubiKey WITH_XC_YUBIKEY "YubiKey HMAC-SHA1 challenge-response")
|
||||
add_feature_info(UpdateCheck WITH_XC_UPDATECHECK "Automatic update checking")
|
||||
if(UNIX AND NOT APPLE)
|
||||
add_feature_info(FdoSecrets WITH_XC_FDOSECRETS "Implement freedesktop.org Secret Storage Spec server side API.")
|
||||
endif()
|
||||
|
||||
add_subdirectory(browser)
|
||||
add_subdirectory(proxy)
|
||||
if(WITH_XC_BROWSER)
|
||||
set(browser_LIB browser)
|
||||
list(APPEND gui_SOURCES
|
||||
set(keepassxcbrowser_LIB keepassxcbrowser)
|
||||
set(keepassx_SOURCES ${keepassx_SOURCES}
|
||||
gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp
|
||||
gui/entry/EntryURLModel.cpp
|
||||
gui/reports/ReportsWidgetBrowserStatistics.cpp
|
||||
@@ -292,7 +262,7 @@ if(WITH_XC_BROWSER)
|
||||
endif()
|
||||
|
||||
if(WITH_XC_BROWSER_PASSKEYS)
|
||||
list(APPEND gui_SOURCES
|
||||
set(keepassx_SOURCES ${keepassx_SOURCES}
|
||||
gui/reports/ReportsWidgetPasskeys.cpp
|
||||
gui/reports/ReportsPagePasskeys.cpp
|
||||
gui/passkeys/PasskeyExporter.cpp
|
||||
@@ -324,114 +294,123 @@ endif()
|
||||
add_subdirectory(thirdparty)
|
||||
|
||||
set(autotype_SOURCES
|
||||
core/Tools.cpp
|
||||
autotype/AutoType.cpp
|
||||
autotype/AutoTypeAction.cpp
|
||||
autotype/AutoTypeMatchModel.cpp
|
||||
autotype/AutoTypeMatchView.cpp
|
||||
autotype/AutoTypeSelectDialog.cpp
|
||||
autotype/PickcharsDialog.cpp
|
||||
autotype/ShortcutWidget.cpp
|
||||
autotype/WindowSelectComboBox.cpp)
|
||||
|
||||
add_library(autotype STATIC ${autotype_SOURCES})
|
||||
target_link_libraries(autotype Qt5::Core Qt5::Widgets)
|
||||
if(WIN32)
|
||||
set(keepassx_SOURCES_MAINEXE ${keepassx_SOURCES_MAINEXE} ${CMAKE_SOURCE_DIR}/share/windows/icon.rc)
|
||||
endif()
|
||||
|
||||
if(WITH_XC_YUBIKEY)
|
||||
list(APPEND core_SOURCES
|
||||
list(APPEND keepassx_SOURCES
|
||||
keys/drivers/YubiKey.h
|
||||
keys/drivers/YubiKey.cpp
|
||||
keys/drivers/YubiKeyInterface.cpp
|
||||
keys/drivers/YubiKeyInterfaceUSB.cpp
|
||||
keys/drivers/YubiKeyInterfacePCSC.cpp)
|
||||
else()
|
||||
list(APPEND core_SOURCES
|
||||
list(APPEND keepassx_SOURCES
|
||||
keys/drivers/YubiKey.h
|
||||
keys/drivers/YubiKeyStub.cpp)
|
||||
endif()
|
||||
|
||||
if(WITH_XC_NETWORKING)
|
||||
list(APPEND gui_SOURCES
|
||||
networking/HibpDownloader.cpp
|
||||
networking/NetworkManager.cpp
|
||||
networking/UpdateChecker.cpp
|
||||
list(APPEND keepassx_SOURCES
|
||||
core/HibpDownloader.cpp
|
||||
core/NetworkManager.cpp
|
||||
gui/UpdateCheckDialog.cpp
|
||||
gui/IconDownloader.cpp
|
||||
gui/IconDownloaderDialog.cpp)
|
||||
gui/IconDownloaderDialog.cpp
|
||||
updatecheck/UpdateChecker.cpp)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND keepassx_SOURCES touchid/TouchID.mm)
|
||||
# TODO: Remove -Wno-error once deprecation warnings have been resolved.
|
||||
set_source_files_properties(touchid/TouchID.mm PROPERTY COMPILE_FLAGS "-Wno-old-style-cast")
|
||||
endif()
|
||||
|
||||
configure_file(config-keepassx.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-keepassx.h)
|
||||
configure_file(git-info.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/git-info.h)
|
||||
|
||||
# Core Library Definition
|
||||
add_library(keepassxc_core STATIC ${core_SOURCES})
|
||||
set_target_properties(keepassxc_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUILDING_CORE)
|
||||
target_link_libraries(keepassxc_core
|
||||
add_library(autotype STATIC ${autotype_SOURCES})
|
||||
target_link_libraries(autotype Qt5::Core Qt5::Widgets)
|
||||
|
||||
add_library(keepassx_core STATIC ${keepassx_SOURCES})
|
||||
|
||||
set_target_properties(keepassx_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUILDING_CORE)
|
||||
target_link_libraries(keepassx_core
|
||||
autotype
|
||||
${keepassxcbrowser_LIB}
|
||||
${qrcode_LIB}
|
||||
${fdosecrets_LIB}
|
||||
Qt5::Core
|
||||
Qt5::Concurrent
|
||||
Qt5::Network
|
||||
Qt5::Widgets
|
||||
${BOTAN_LIBRARIES}
|
||||
${PCSC_LIBRARIES}
|
||||
${ZXCVBN_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${MINIZIP_LIBRARIES}
|
||||
${ARGON2_LIBRARIES}
|
||||
${KEYUTILS_LIBRARIES}
|
||||
${thirdparty_LIBRARIES})
|
||||
${thirdparty_LIBRARIES}
|
||||
)
|
||||
|
||||
# GUI Library Definition
|
||||
add_library(keepassxc_gui STATIC ${gui_SOURCES})
|
||||
set_target_properties(keepassxc_gui PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUILDING_CORE)
|
||||
target_link_libraries(keepassxc_gui
|
||||
keepassxc_core
|
||||
Qt5::Network
|
||||
Qt5::Widgets
|
||||
autotype
|
||||
${browser_LIB}
|
||||
${fdosecrets_LIB}
|
||||
${keeshare_LIB}
|
||||
${sshagent_LIB})
|
||||
if(WITH_XC_SSHAGENT)
|
||||
target_link_libraries(keepassx_core sshagent)
|
||||
endif()
|
||||
if(WITH_XC_KEESHARE)
|
||||
target_link_libraries(keepassx_core keeshare)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
target_link_libraries(keepassxc_gui "-framework Foundation -framework AppKit -framework Carbon -framework Security -framework LocalAuthentication -framework ScreenCaptureKit")
|
||||
target_link_libraries(keepassx_core "-framework Foundation -framework AppKit -framework Carbon -framework Security -framework LocalAuthentication -framework ScreenCaptureKit")
|
||||
if(Qt5MacExtras_FOUND)
|
||||
target_link_libraries(keepassxc_gui Qt5::MacExtras)
|
||||
target_link_libraries(keepassx_core Qt5::MacExtras)
|
||||
endif()
|
||||
endif()
|
||||
if(HAIKU)
|
||||
target_link_libraries(keepassxc_gui network)
|
||||
target_link_libraries(keepassx_core network)
|
||||
endif()
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(keepassxc_core Qt5::DBus ${LIBUSB_LIBRARIES})
|
||||
target_link_libraries(keepassx_core Qt5::DBus ${LIBUSB_LIBRARIES})
|
||||
if(WITH_XC_X11)
|
||||
target_link_libraries(keepassxc_gui Qt5::X11Extras X11)
|
||||
target_link_libraries(keepassx_core Qt5::X11Extras X11)
|
||||
endif()
|
||||
include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS})
|
||||
endif()
|
||||
if(WIN32)
|
||||
target_link_libraries(keepassxc_gui Wtsapi32.lib Ws2_32.lib)
|
||||
target_link_libraries(keepassx_core Wtsapi32.lib Ws2_32.lib)
|
||||
if (MSVC)
|
||||
target_link_libraries(keepassxc_gui WindowsApp.lib)
|
||||
target_link_libraries(keepassx_core WindowsApp.lib)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Main Executable Definition
|
||||
if(WIN32)
|
||||
include(GenerateProductVersion)
|
||||
generate_product_version(
|
||||
WIN32_ResourceFiles
|
||||
WIN32_ProductVersionFiles
|
||||
NAME "KeePassXC"
|
||||
COMPANY_NAME "KeePassXC Team"
|
||||
VERSION_MAJOR ${KEEPASSXC_VERSION_MAJOR}
|
||||
VERSION_MINOR ${KEEPASSXC_VERSION_MINOR}
|
||||
VERSION_PATCH ${KEEPASSXC_VERSION_PATCH}
|
||||
)
|
||||
list(APPEND WIN32_ResourceFiles "${CMAKE_SOURCE_DIR}/share/windows/icon.rc")
|
||||
endif()
|
||||
|
||||
add_executable(${PROGNAME} WIN32 main.cpp ${WIN32_ResourceFiles})
|
||||
target_link_libraries(${PROGNAME} keepassxc_gui)
|
||||
add_executable(${PROGNAME} WIN32 ${keepassx_SOURCES_MAINEXE} ${WIN32_ProductVersionFiles})
|
||||
target_link_libraries(${PROGNAME} keepassx_core)
|
||||
|
||||
set_target_properties(${PROGNAME} PROPERTIES ENABLE_EXPORTS ON)
|
||||
|
||||
# macOS App Bundle
|
||||
if(APPLE AND WITH_APP_BUNDLE)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/share/macosx/embedded.provisionprofile DESTINATION ${BUNDLE_INSTALL_DIR})
|
||||
configure_file(${CMAKE_SOURCE_DIR}/share/macosx/Info.plist.cmake ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
|
||||
@@ -460,7 +439,6 @@ install(TARGETS ${PROGNAME}
|
||||
BUNDLE DESTINATION . COMPONENT Runtime
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR} COMPONENT Runtime)
|
||||
|
||||
# Windows Installer Definition
|
||||
if(WIN32)
|
||||
if(${CMAKE_SIZEOF_VOID_P} EQUAL "8")
|
||||
set(OUTPUT_FILE_POSTFIX "Win64")
|
||||
@@ -572,5 +550,5 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
# The install commands in this subdirectory will be executed after all the install commands in the
|
||||
# current scope are ran. It is required for correct functioning of macdeployqt.
|
||||
# current scope are ran. It is required for correct functtioning of macdeployqt.
|
||||
add_subdirectory(post_install)
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "autotype/AutoTypePlatformPlugin.h"
|
||||
#include "autotype/AutoTypeSelectDialog.h"
|
||||
#include "autotype/PickcharsDialog.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Resources.h"
|
||||
#include "core/Tools.h"
|
||||
#include "gui/MainWindow.h"
|
||||
@@ -228,7 +227,7 @@ void AutoType::createTestInstance()
|
||||
QStringList AutoType::windowTitles()
|
||||
{
|
||||
if (!m_plugin) {
|
||||
return {};
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
return m_plugin->windowTitles();
|
||||
@@ -360,7 +359,7 @@ void AutoType::executeAutoTypeActions(const Entry* entry,
|
||||
|
||||
/**
|
||||
* Single Autotype entry-point function
|
||||
* Look up the Auto-Type sequence for the given entry then perform Auto-Type in the active window
|
||||
* Look up the Auto-Type sequence for the given entry then perfom Auto-Type in the active window
|
||||
*/
|
||||
void AutoType::performAutoType(const Entry* entry)
|
||||
{
|
||||
@@ -376,7 +375,7 @@ void AutoType::performAutoType(const Entry* entry)
|
||||
|
||||
/**
|
||||
* Extra Autotype entry-point function
|
||||
* Perform Auto-Type of the directly specified sequence in the active window
|
||||
* Perfom Auto-Type of the directly specified sequence in the active window
|
||||
*/
|
||||
void AutoType::performAutoTypeWithSequence(const Entry* entry, const QString& sequence)
|
||||
{
|
||||
|
||||
@@ -38,17 +38,17 @@ public:
|
||||
|
||||
static Result Ok()
|
||||
{
|
||||
return {true, false, QString()};
|
||||
return Result(true, false, QString());
|
||||
}
|
||||
|
||||
static Result Retry(const QString& error)
|
||||
{
|
||||
return {false, true, error};
|
||||
return Result(false, true, error);
|
||||
}
|
||||
|
||||
static Result Failed(const QString& error)
|
||||
{
|
||||
return {false, false, error};
|
||||
return Result(false, false, error);
|
||||
}
|
||||
|
||||
bool isOk() const
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
class AutoTypePlatformInterface
|
||||
{
|
||||
public:
|
||||
virtual ~AutoTypePlatformInterface() = default;
|
||||
virtual ~AutoTypePlatformInterface()
|
||||
{
|
||||
}
|
||||
virtual bool isAvailable() = 0;
|
||||
virtual QStringList windowTitles() = 0;
|
||||
virtual WId activeWindow() = 0;
|
||||
|
||||
@@ -21,8 +21,12 @@
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QMenu>
|
||||
#include <QScreen>
|
||||
#include <QShortcut>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
#include <QScreen>
|
||||
#else
|
||||
#include <QDesktopWidget>
|
||||
#endif
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Database.h"
|
||||
@@ -92,7 +96,9 @@ AutoTypeSelectDialog::AutoTypeSelectDialog(QWidget* parent)
|
||||
}
|
||||
|
||||
// Required for QScopedPointer
|
||||
AutoTypeSelectDialog::~AutoTypeSelectDialog() = default;
|
||||
AutoTypeSelectDialog::~AutoTypeSelectDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void AutoTypeSelectDialog::setMatches(const QList<AutoTypeMatch>& matches,
|
||||
const QList<QSharedPointer<Database>>& dbs,
|
||||
@@ -324,7 +330,7 @@ void AutoTypeSelectDialog::buildActionMenu()
|
||||
submitAutoTypeMatch(match);
|
||||
});
|
||||
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
||||
#ifdef Q_OS_WIN
|
||||
auto typeVirtualAction = new QAction(icons()->icon("auto-type"), tr("Use Virtual Keyboard"), nullptr);
|
||||
m_actionMenu->insertAction(copyUsernameAction, typeVirtualAction);
|
||||
typeVirtualAction->setShortcut(Qt::CTRL + Qt::Key_4);
|
||||
@@ -364,29 +370,35 @@ void AutoTypeSelectDialog::buildActionMenu()
|
||||
}
|
||||
});
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
// Qt 5.10 introduced a new "feature" to hide shortcuts in context menus
|
||||
// Unfortunately, Qt::AA_DontShowShortcutsInContextMenus is broken, have to manually enable them
|
||||
typeUsernameAction->setShortcutVisibleInContextMenu(true);
|
||||
typePasswordAction->setShortcutVisibleInContextMenu(true);
|
||||
typeTotpAction->setShortcutVisibleInContextMenu(true);
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
||||
#if defined(Q_OS_WIN)
|
||||
typeVirtualAction->setShortcutVisibleInContextMenu(true);
|
||||
#endif
|
||||
copyUsernameAction->setShortcutVisibleInContextMenu(true);
|
||||
copyPasswordAction->setShortcutVisibleInContextMenu(true);
|
||||
copyTotpAction->setShortcutVisibleInContextMenu(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AutoTypeSelectDialog::showEvent(QShowEvent* event)
|
||||
{
|
||||
QDialog::showEvent(event);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
auto screen = QApplication::screenAt(QCursor::pos());
|
||||
if (!screen) {
|
||||
// screenAt can return a nullptr, default to the primary screen
|
||||
screen = QApplication::primaryScreen();
|
||||
}
|
||||
QRect screenGeometry = screen->availableGeometry();
|
||||
#else
|
||||
QRect screenGeometry = QApplication::desktop()->availableGeometry(QCursor::pos());
|
||||
#endif
|
||||
|
||||
// Resize to last used size
|
||||
QSize size = config()->get(Config::GUI_AutoTypeSelectDialogSize).toSize();
|
||||
|
||||
@@ -21,8 +21,12 @@
|
||||
#include "gui/Icons.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QScreen>
|
||||
#include <QShortcut>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
#include <QScreen>
|
||||
#else
|
||||
#include <QDesktopWidget>
|
||||
#endif
|
||||
|
||||
PickcharsDialog::PickcharsDialog(const QString& string, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
@@ -153,11 +157,15 @@ void PickcharsDialog::showEvent(QShowEvent* event)
|
||||
QDialog::showEvent(event);
|
||||
|
||||
// Center on active screen
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
auto screen = QApplication::screenAt(QCursor::pos());
|
||||
if (!screen) {
|
||||
// screenAt can return a nullptr, default to the primary screen
|
||||
screen = QApplication::primaryScreen();
|
||||
}
|
||||
QRect screenGeometry = screen->availableGeometry();
|
||||
#else
|
||||
QRect screenGeometry = QApplication::desktop()->availableGeometry(QCursor::pos());
|
||||
#endif
|
||||
move(screenGeometry.center().x() - (size().width() / 2), screenGeometry.center().y() - (size().height() / 2));
|
||||
}
|
||||
|
||||
@@ -20,8 +20,13 @@
|
||||
#include <QKeyEvent>
|
||||
#include <QToolTip>
|
||||
|
||||
#include "autotype/AutoType.h"
|
||||
|
||||
ShortcutWidget::ShortcutWidget(QWidget* parent)
|
||||
: QLineEdit(parent)
|
||||
, m_key(static_cast<Qt::Key>(0))
|
||||
, m_modifiers(nullptr)
|
||||
, m_locked(false)
|
||||
{
|
||||
setReadOnly(true);
|
||||
}
|
||||
@@ -36,11 +41,6 @@ Qt::KeyboardModifiers ShortcutWidget::modifiers() const
|
||||
return m_modifiers;
|
||||
}
|
||||
|
||||
QKeySequence ShortcutWidget::sequence() const
|
||||
{
|
||||
return (m_key == Qt::Key_unknown) ? QKeySequence() : QKeySequence(m_key | m_modifiers);
|
||||
}
|
||||
|
||||
void ShortcutWidget::setShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
m_key = key;
|
||||
@@ -48,15 +48,22 @@ void ShortcutWidget::setShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers)
|
||||
m_locked = true;
|
||||
|
||||
displayShortcut(m_key, m_modifiers);
|
||||
emit shortcutChanged(m_key, m_modifiers);
|
||||
|
||||
QString error;
|
||||
if (autoType()->registerGlobalShortcut(m_key, m_modifiers, &error)) {
|
||||
setStyleSheet("");
|
||||
} else {
|
||||
QToolTip::showText(mapToGlobal(rect().bottomLeft()), error);
|
||||
setStyleSheet("background-color: #FF9696;");
|
||||
}
|
||||
}
|
||||
|
||||
void ShortcutWidget::resetShortcut()
|
||||
{
|
||||
m_key = Qt::Key_unknown;
|
||||
m_modifiers = Qt::NoModifier;
|
||||
m_key = static_cast<Qt::Key>(0);
|
||||
m_modifiers = nullptr;
|
||||
m_locked = false;
|
||||
emit shortcutReset();
|
||||
autoType()->unregisterGlobalShortcut();
|
||||
}
|
||||
|
||||
void ShortcutWidget::keyPressEvent(QKeyEvent* event)
|
||||
@@ -83,7 +90,7 @@ void ShortcutWidget::keyEvent(QKeyEvent* event)
|
||||
return;
|
||||
}
|
||||
|
||||
auto key = static_cast<Qt::Key>(event->key());
|
||||
Qt::Key key = static_cast<Qt::Key>(event->key());
|
||||
|
||||
if (key <= 0 || key == Qt::Key_unknown) {
|
||||
return;
|
||||
@@ -109,11 +116,13 @@ void ShortcutWidget::keyEvent(QKeyEvent* event)
|
||||
setShortcut(key, modifiers);
|
||||
} else {
|
||||
resetShortcut();
|
||||
setStyleSheet("");
|
||||
displayShortcut(key, modifiers);
|
||||
}
|
||||
} else {
|
||||
if (m_locked) {
|
||||
resetShortcut();
|
||||
setStyleSheet("");
|
||||
}
|
||||
|
||||
displayShortcut(static_cast<Qt::Key>(0), modifiers);
|
||||
@@ -18,7 +18,6 @@
|
||||
#ifndef KEEPASSX_SHORTCUTWIDGET_H
|
||||
#define KEEPASSX_SHORTCUTWIDGET_H
|
||||
|
||||
#include <QKeySequence>
|
||||
#include <QLineEdit>
|
||||
|
||||
class ShortcutWidget : public QLineEdit
|
||||
@@ -27,17 +26,10 @@ class ShortcutWidget : public QLineEdit
|
||||
|
||||
public:
|
||||
explicit ShortcutWidget(QWidget* parent = nullptr);
|
||||
|
||||
Qt::Key key() const;
|
||||
Qt::KeyboardModifiers modifiers() const;
|
||||
QKeySequence sequence() const;
|
||||
|
||||
void setShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
|
||||
|
||||
signals:
|
||||
void shortcutChanged(Qt::Key key, Qt::KeyboardModifiers modifiers);
|
||||
void shortcutReset();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void keyReleaseEvent(QKeyEvent* event) override;
|
||||
@@ -47,9 +39,9 @@ private:
|
||||
void displayShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
|
||||
void resetShortcut();
|
||||
|
||||
Qt::Key m_key = Qt::Key_unknown;
|
||||
Qt::KeyboardModifiers m_modifiers = Qt::NoModifier;
|
||||
bool m_locked = false;
|
||||
Qt::Key m_key;
|
||||
Qt::KeyboardModifiers m_modifiers;
|
||||
bool m_locked;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_SHORTCUTWIDGET_H
|
||||
@@ -250,10 +250,6 @@ AutoTypeAction::Result AutoTypeExecutorMac::execType(const AutoTypeKey* action)
|
||||
int ch = action->character.toUpper().toLatin1();
|
||||
m_platform->sendKey(static_cast<Qt::Key>(ch), true, action->modifiers);
|
||||
m_platform->sendKey(static_cast<Qt::Key>(ch), false, action->modifiers);
|
||||
} else if (mode == Mode::VIRTUAL) {
|
||||
int ch = action->character.toLatin1();
|
||||
m_platform->sendKey(static_cast<Qt::Key>(ch), true, action->modifiers);
|
||||
m_platform->sendKey(static_cast<Qt::Key>(ch), false, action->modifiers);
|
||||
} else {
|
||||
m_platform->sendChar(action->character, true);
|
||||
m_platform->sendChar(action->character, false);
|
||||
|
||||
@@ -29,7 +29,7 @@ QString AutoTypePlatformTest::keyToString(Qt::Key key)
|
||||
|
||||
QStringList AutoTypePlatformTest::windowTitles()
|
||||
{
|
||||
return {};
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
WId AutoTypePlatformTest::activeWindow()
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
class AutoTypeTestInterface
|
||||
{
|
||||
public:
|
||||
virtual ~AutoTypeTestInterface() = default;
|
||||
virtual ~AutoTypeTestInterface()
|
||||
{
|
||||
}
|
||||
virtual void setActiveWindowTitle(const QString& title) = 0;
|
||||
|
||||
virtual QString actionChars() = 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
set(autotype_test_SOURCES AutoTypeTest.cpp)
|
||||
|
||||
add_library(keepassxc-autotype-test MODULE ${autotype_test_SOURCES})
|
||||
target_link_libraries(keepassxc-autotype-test keepassxc_gui ${autotype_LIB} Qt5::Core Qt5::Widgets)
|
||||
target_link_libraries(keepassxc-autotype-test keepassx_core ${autotype_LIB} Qt5::Core Qt5::Widgets)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
set(autotype_win_SOURCES AutoTypeWindows.cpp)
|
||||
|
||||
add_library(keepassxc-autotype-windows MODULE ${autotype_win_SOURCES})
|
||||
target_link_libraries(keepassxc-autotype-windows keepassxc_gui ${autotype_LIB} Qt5::Core Qt5::Widgets)
|
||||
target_link_libraries(keepassxc-autotype-windows keepassx_core ${autotype_LIB} Qt5::Core Qt5::Widgets)
|
||||
install(TARGETS keepassxc-autotype-windows
|
||||
BUNDLE DESTINATION . COMPONENT Runtime
|
||||
LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} COMPONENT Runtime)
|
||||
|
||||
@@ -181,17 +181,17 @@ QString AutoTypePlatformX11::windowTitle(Window window, bool useBlacklist)
|
||||
|
||||
if (useBlacklist && !title.isEmpty()) {
|
||||
if (window == m_rootWindow) {
|
||||
return {};
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString className = windowClassName(window);
|
||||
if (m_classBlacklist.contains(className)) {
|
||||
return {};
|
||||
return QString();
|
||||
}
|
||||
|
||||
QList<Window> keepassxWindows = widgetsToX11Windows(QApplication::topLevelWidgets());
|
||||
if (keepassxWindows.contains(window)) {
|
||||
return {};
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ include_directories(SYSTEM ${X11_X11_INCLUDE_PATH})
|
||||
set(autotype_XCB_SOURCES AutoTypeXCB.cpp)
|
||||
|
||||
add_library(keepassxc-autotype-xcb MODULE ${autotype_XCB_SOURCES})
|
||||
target_link_libraries(keepassxc-autotype-xcb keepassxc_gui Qt5::Core Qt5::Widgets Qt5::X11Extras ${X11_X11_LIB} ${X11_Xi_LIB} ${X11_XTest_LIB})
|
||||
target_link_libraries(keepassxc-autotype-xcb keepassx_core Qt5::Core Qt5::Widgets Qt5::X11Extras ${X11_X11_LIB} ${X11_Xi_LIB} ${X11_XTest_LIB})
|
||||
install(TARGETS keepassxc-autotype-xcb
|
||||
BUNDLE DESTINATION . COMPONENT Runtime
|
||||
LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} COMPONENT Runtime)
|
||||
|
||||
0
src/browser/BrowserAccessControlDialog.ui
Normal file → Executable file
@@ -108,8 +108,6 @@ QJsonObject BrowserAction::handleAction(QLocalSocket* socket, const QJsonObject&
|
||||
return handleDeleteEntry(json, action);
|
||||
} else if (action.compare(BROWSER_REQUEST_REQUEST_AUTOTYPE) == 0) {
|
||||
return handleGlobalAutoType(json, action);
|
||||
} else if (action.compare("get-database-entries", Qt::CaseSensitive) == 0) {
|
||||
return handleGetDatabaseEntries(json, action);
|
||||
#ifdef WITH_XC_BROWSER_PASSKEYS
|
||||
} else if (action.compare(BROWSER_REQUEST_PASSKEYS_GET) == 0) {
|
||||
return handlePasskeysGet(json, action);
|
||||
@@ -389,36 +387,6 @@ QJsonObject BrowserAction::handleGetDatabaseGroups(const QJsonObject& json, cons
|
||||
return buildResponse(action, browserRequest.incrementedNonce, params);
|
||||
}
|
||||
|
||||
QJsonObject BrowserAction::handleGetDatabaseEntries(const QJsonObject& json, const QString& action)
|
||||
{
|
||||
if (!m_associated) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_ASSOCIATION_FAILED);
|
||||
}
|
||||
|
||||
const auto browserRequest = decodeRequest(json);
|
||||
if (browserRequest.isEmpty()) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_CANNOT_DECRYPT_MESSAGE);
|
||||
}
|
||||
|
||||
const auto command = browserRequest.getString("action");
|
||||
if (command.isEmpty() || command.compare("get-database-entries") != 0) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_INCORRECT_ACTION);
|
||||
}
|
||||
|
||||
if (!browserSettings()->allowGetDatabaseEntriesRequest()) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_ACCESS_TO_ALL_ENTRIES_DENIED);
|
||||
}
|
||||
|
||||
const QJsonArray entries = browserService()->getDatabaseEntries();
|
||||
if (entries.isEmpty()) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_NO_GROUPS_FOUND);
|
||||
}
|
||||
|
||||
const Parameters params{{"entries", entries}};
|
||||
|
||||
return buildResponse(action, browserRequest.incrementedNonce, params);
|
||||
}
|
||||
|
||||
QJsonObject BrowserAction::handleCreateNewGroup(const QJsonObject& json, const QString& action)
|
||||
{
|
||||
if (!m_associated) {
|
||||
|
||||
@@ -79,7 +79,6 @@ private:
|
||||
QJsonObject handleSetLogin(const QJsonObject& json, const QString& action);
|
||||
QJsonObject handleLockDatabase(const QJsonObject& json, const QString& action);
|
||||
QJsonObject handleGetDatabaseGroups(const QJsonObject& json, const QString& action);
|
||||
QJsonObject handleGetDatabaseEntries(const QJsonObject& json, const QString& action);
|
||||
QJsonObject handleCreateNewGroup(const QJsonObject& json, const QString& action);
|
||||
QJsonObject handleGetTotp(const QJsonObject& json, const QString& action);
|
||||
QJsonObject handleDeleteEntry(const QJsonObject& json, const QString& action);
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "BrowserEntryConfig.h"
|
||||
|
||||
#include "core/Entry.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Tools.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
@@ -35,22 +34,22 @@ BrowserEntryConfig::BrowserEntryConfig(QObject* parent)
|
||||
|
||||
QStringList BrowserEntryConfig::allowedHosts() const
|
||||
{
|
||||
return m_allowedHosts.values();
|
||||
return m_allowedHosts.toList();
|
||||
}
|
||||
|
||||
void BrowserEntryConfig::setAllowedHosts(const QStringList& allowedHosts)
|
||||
{
|
||||
m_allowedHosts = Tools::asSet(allowedHosts);
|
||||
m_allowedHosts = allowedHosts.toSet();
|
||||
}
|
||||
|
||||
QStringList BrowserEntryConfig::deniedHosts() const
|
||||
{
|
||||
return m_deniedHosts.values();
|
||||
return m_deniedHosts.toList();
|
||||
}
|
||||
|
||||
void BrowserEntryConfig::setDeniedHosts(const QStringList& deniedHosts)
|
||||
{
|
||||
m_deniedHosts = Tools::asSet(deniedHosts);
|
||||
m_deniedHosts = deniedHosts.toSet();
|
||||
}
|
||||
|
||||
bool BrowserEntryConfig::isAllowed(const QString& host) const
|
||||
|
||||
0
src/browser/BrowserEntrySaveDialog.ui
Normal file → Executable file
0
src/browser/BrowserPasskeysConfirmationDialog.ui
Normal file → Executable file
@@ -26,9 +26,9 @@
|
||||
#include "BrowserSettings.h"
|
||||
#include "core/EntryAttributes.h"
|
||||
#include "core/Tools.h"
|
||||
#include "core/UrlTools.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "gui/UrlTools.h"
|
||||
#include "gui/osutils/OSUtils.h"
|
||||
#ifdef WITH_XC_BROWSER_PASSKEYS
|
||||
#include "BrowserPasskeys.h"
|
||||
@@ -49,7 +49,6 @@
|
||||
#include <QJsonObject>
|
||||
#include <QListWidget>
|
||||
#include <QLocalSocket>
|
||||
#include <QLocale>
|
||||
#include <QProgressDialog>
|
||||
#include <QStringView>
|
||||
#include <QUrl>
|
||||
@@ -71,7 +70,6 @@ const QString BrowserService::OPTION_HIDE_ENTRY = QStringLiteral("BrowserHideEnt
|
||||
const QString BrowserService::OPTION_ONLY_HTTP_AUTH = QStringLiteral("BrowserOnlyHttpAuth");
|
||||
const QString BrowserService::OPTION_NOT_HTTP_AUTH = QStringLiteral("BrowserNotHttpAuth");
|
||||
const QString BrowserService::OPTION_OMIT_WWW = QStringLiteral("BrowserOmitWww");
|
||||
const QString BrowserService::OPTION_RESTRICT_KEY = QStringLiteral("BrowserRestrictKey");
|
||||
|
||||
Q_GLOBAL_STATIC(BrowserService, s_browserService);
|
||||
|
||||
@@ -603,8 +601,7 @@ QString BrowserService::storeKey(const QString& key)
|
||||
return {};
|
||||
}
|
||||
|
||||
contains =
|
||||
db->metadata()->customData()->contains(CustomData::getKeyWithPrefix(CustomData::BrowserKeyPrefix, id));
|
||||
contains = db->metadata()->customData()->contains(CustomData::BrowserKeyPrefix + id);
|
||||
if (contains) {
|
||||
dialogResult = MessageBox::warning(m_currentDatabaseWidget,
|
||||
tr("KeePassXC - Overwrite existing key?"),
|
||||
@@ -617,8 +614,8 @@ QString BrowserService::storeKey(const QString& key)
|
||||
} while (contains && dialogResult == MessageBox::Cancel);
|
||||
|
||||
hideWindow();
|
||||
db->metadata()->customData()->set(CustomData::getKeyWithPrefix(CustomData::BrowserKeyPrefix, id), key);
|
||||
db->metadata()->customData()->set(CustomData::getKeyWithPrefix(CustomData::Created, id),
|
||||
db->metadata()->customData()->set(CustomData::BrowserKeyPrefix + id, key);
|
||||
db->metadata()->customData()->set(QString("%1%2").arg(CustomData::Created, id),
|
||||
QLocale::system().toString(Clock::currentDateTime(), QLocale::ShortFormat));
|
||||
return id;
|
||||
}
|
||||
@@ -630,7 +627,7 @@ QString BrowserService::getKey(const QString& id)
|
||||
return {};
|
||||
}
|
||||
|
||||
return db->metadata()->customData()->value(CustomData::getKeyWithPrefix(CustomData::BrowserKeyPrefix, id));
|
||||
return db->metadata()->customData()->value(CustomData::BrowserKeyPrefix + id);
|
||||
}
|
||||
|
||||
#ifdef WITH_XC_BROWSER_PASSKEYS
|
||||
@@ -1012,7 +1009,6 @@ void BrowserService::removePluginData(Entry* entry) const
|
||||
QList<Entry*> BrowserService::searchEntries(const QSharedPointer<Database>& db,
|
||||
const QString& siteUrl,
|
||||
const QString& formUrl,
|
||||
const QStringList& keys,
|
||||
bool passkey)
|
||||
{
|
||||
QList<Entry*> entries;
|
||||
@@ -1027,12 +1023,6 @@ QList<Entry*> BrowserService::searchEntries(const QSharedPointer<Database>& db,
|
||||
continue;
|
||||
}
|
||||
|
||||
// If a key restriction is specified and not contained in the keys list then skip this group.
|
||||
auto restrictKey = group->resolveCustomDataString(BrowserService::OPTION_RESTRICT_KEY);
|
||||
if (!restrictKey.isEmpty() && !keys.contains(restrictKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto omitWwwSubdomain =
|
||||
group->resolveCustomDataTriState(BrowserService::OPTION_OMIT_WWW) == Group::Enable;
|
||||
|
||||
@@ -1069,36 +1059,30 @@ QList<Entry*> BrowserService::searchEntries(const QString& siteUrl,
|
||||
const StringPairList& keyList,
|
||||
bool passkey)
|
||||
{
|
||||
// Check if database is connected with KeePassXC-Browser. If so, return browser key (otherwise empty)
|
||||
// Check if database is connected with KeePassXC-Browser
|
||||
auto databaseConnected = [&](const QSharedPointer<Database>& db) {
|
||||
for (const StringPair& keyPair : keyList) {
|
||||
const auto key = db->metadata()->customData()->value(
|
||||
CustomData::getKeyWithPrefix(CustomData::BrowserKeyPrefix, keyPair.first));
|
||||
QString key = db->metadata()->customData()->value(CustomData::BrowserKeyPrefix + keyPair.first);
|
||||
if (!key.isEmpty() && keyPair.second == key) {
|
||||
return keyPair.first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Get the list of databases to search
|
||||
QList<QSharedPointer<Database>> databases;
|
||||
QStringList keys;
|
||||
if (browserSettings()->searchInAllDatabases()) {
|
||||
for (auto dbWidget : getMainWindow()->getOpenDatabases()) {
|
||||
auto db = dbWidget->database();
|
||||
auto key = databaseConnected(dbWidget->database());
|
||||
if (db && !key.isEmpty()) {
|
||||
if (db && databaseConnected(dbWidget->database())) {
|
||||
databases << db;
|
||||
keys << key;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto& db = getDatabase();
|
||||
auto key = databaseConnected(db);
|
||||
if (!key.isEmpty()) {
|
||||
if (databaseConnected(db)) {
|
||||
databases << db;
|
||||
keys << key;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1107,16 +1091,84 @@ QList<Entry*> BrowserService::searchEntries(const QString& siteUrl,
|
||||
QList<Entry*> entries;
|
||||
do {
|
||||
for (const auto& db : databases) {
|
||||
entries << searchEntries(db, siteUrl, formUrl, keys, passkey);
|
||||
entries << searchEntries(db, siteUrl, formUrl, passkey);
|
||||
}
|
||||
} while (entries.isEmpty() && removeFirstDomain(hostname));
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
QString BrowserService::decodeCustomDataRestrictKey(const QString& key)
|
||||
void BrowserService::convertAttributesToCustomData(QSharedPointer<Database> db)
|
||||
{
|
||||
return key.isEmpty() ? tr("Disable") : key;
|
||||
if (!db) {
|
||||
return;
|
||||
}
|
||||
|
||||
QList<Entry*> entries = db->rootGroup()->entriesRecursive();
|
||||
QProgressDialog progress(tr("Converting attributes to custom data…"), tr("Abort"), 0, entries.count());
|
||||
progress.setWindowModality(Qt::WindowModal);
|
||||
|
||||
int counter = 0;
|
||||
int keyCounter = 0;
|
||||
for (auto* entry : entries) {
|
||||
if (progress.wasCanceled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (moveSettingsToCustomData(entry, KEEPASSHTTP_NAME)) {
|
||||
++counter;
|
||||
}
|
||||
|
||||
if (moveSettingsToCustomData(entry, KEEPASSXCBROWSER_OLD_NAME)) {
|
||||
++counter;
|
||||
}
|
||||
|
||||
if (moveSettingsToCustomData(entry, KEEPASSXCBROWSER_NAME)) {
|
||||
++counter;
|
||||
}
|
||||
|
||||
if (entry->title() == KEEPASSHTTP_NAME || entry->title().contains(KEEPASSXCBROWSER_NAME, Qt::CaseInsensitive)) {
|
||||
keyCounter += moveKeysToCustomData(entry, db);
|
||||
db->recycleEntry(entry);
|
||||
}
|
||||
|
||||
progress.setValue(progress.value() + 1);
|
||||
}
|
||||
progress.reset();
|
||||
|
||||
if (counter > 0) {
|
||||
MessageBox::information(nullptr,
|
||||
tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
tr("Successfully converted attributes from %1 entry(s).\n"
|
||||
"Moved %2 keys to custom data.",
|
||||
"")
|
||||
.arg(counter)
|
||||
.arg(keyCounter),
|
||||
MessageBox::Ok);
|
||||
} else if (counter == 0 && keyCounter > 0) {
|
||||
MessageBox::information(nullptr,
|
||||
tr("KeePassXC: Converted KeePassHTTP attributes"),
|
||||
tr("Successfully moved %n keys to custom data.", "", keyCounter),
|
||||
MessageBox::Ok);
|
||||
} else {
|
||||
MessageBox::information(nullptr,
|
||||
tr("KeePassXC: No entry with KeePassHTTP attributes found!"),
|
||||
tr("The active database does not contain an entry with KeePassHTTP attributes."),
|
||||
MessageBox::Ok);
|
||||
}
|
||||
|
||||
// Rename password groupName
|
||||
Group* rootGroup = db->rootGroup();
|
||||
if (!rootGroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto* g : rootGroup->groupsRecursive(true)) {
|
||||
if (g->name() == KEEPASSHTTP_GROUP_NAME) {
|
||||
g->setName(KEEPASSXCBROWSER_GROUP_NAME);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserService::requestGlobalAutoType(const QString& search)
|
||||
@@ -1655,6 +1707,84 @@ QSharedPointer<Database> BrowserService::selectedDatabase()
|
||||
return getDatabase();
|
||||
}
|
||||
|
||||
bool BrowserService::moveSettingsToCustomData(Entry* entry, const QString& name)
|
||||
{
|
||||
if (entry->attributes()->contains(name)) {
|
||||
QString attr = entry->attributes()->value(name);
|
||||
entry->beginUpdate();
|
||||
if (!attr.isEmpty()) {
|
||||
entry->customData()->set(KEEPASSXCBROWSER_NAME, attr);
|
||||
}
|
||||
entry->attributes()->remove(name);
|
||||
entry->endUpdate();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int BrowserService::moveKeysToCustomData(Entry* entry, QSharedPointer<Database> db)
|
||||
{
|
||||
int keyCounter = 0;
|
||||
for (const auto& key : entry->attributes()->keys()) {
|
||||
if (key.contains(CustomData::BrowserLegacyKeyPrefix)) {
|
||||
QString publicKey = key;
|
||||
publicKey.remove(CustomData::BrowserLegacyKeyPrefix);
|
||||
|
||||
// Add key to database custom data
|
||||
if (db && !db->metadata()->customData()->contains(CustomData::BrowserKeyPrefix + publicKey)) {
|
||||
db->metadata()->customData()->set(CustomData::BrowserKeyPrefix + publicKey,
|
||||
entry->attributes()->value(key));
|
||||
++keyCounter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return keyCounter;
|
||||
}
|
||||
|
||||
bool BrowserService::checkLegacySettings(QSharedPointer<Database> db)
|
||||
{
|
||||
if (!db || !browserSettings()->isEnabled() || browserSettings()->noMigrationPrompt()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool legacySettingsFound = false;
|
||||
QList<Entry*> entries = db->rootGroup()->entriesRecursive();
|
||||
for (const auto& e : entries) {
|
||||
if (e->isRecycled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((e->attributes()->contains(KEEPASSHTTP_NAME) || e->attributes()->contains(KEEPASSXCBROWSER_NAME))
|
||||
|| (e->title() == KEEPASSHTTP_NAME || e->title().contains(KEEPASSXCBROWSER_NAME, Qt::CaseInsensitive))) {
|
||||
legacySettingsFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!legacySettingsFound) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* checkbox = new QCheckBox(tr("Don't show this warning again"));
|
||||
QObject::connect(checkbox, &QCheckBox::stateChanged, [&](int state) {
|
||||
browserSettings()->setNoMigrationPrompt(static_cast<Qt::CheckState>(state) == Qt::CheckState::Checked);
|
||||
});
|
||||
|
||||
auto dialogResult =
|
||||
MessageBox::warning(nullptr,
|
||||
tr("KeePassXC: Legacy browser integration settings detected"),
|
||||
tr("Your KeePassXC-Browser settings need to be moved into the database settings.\n"
|
||||
"This is necessary to maintain your current browser connections.\n"
|
||||
"Would you like to migrate your existing settings now?"),
|
||||
MessageBox::Yes | MessageBox::No,
|
||||
MessageBox::NoButton,
|
||||
MessageBox::Raise,
|
||||
checkbox);
|
||||
|
||||
return dialogResult == MessageBox::Yes;
|
||||
}
|
||||
|
||||
void BrowserService::hideWindow() const
|
||||
{
|
||||
if (m_prevWindowState == WindowState::Minimized) {
|
||||
@@ -1738,6 +1868,11 @@ void BrowserService::databaseUnlocked(DatabaseWidget* dbWidget)
|
||||
QJsonObject msg;
|
||||
msg["action"] = QString("database-unlocked");
|
||||
m_browserHost->broadcastClientMessage(msg);
|
||||
|
||||
auto db = dbWidget->database();
|
||||
if (checkLegacySettings(db)) {
|
||||
convertAttributesToCustomData(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,8 +122,7 @@ public:
|
||||
void removePluginData(Entry* entry) const;
|
||||
QJsonArray findEntries(const EntryParameters& entryParameters, const StringPairList& keyList, bool* entriesFound);
|
||||
void requestGlobalAutoType(const QString& search);
|
||||
|
||||
static QString decodeCustomDataRestrictKey(const QString& key);
|
||||
static void convertAttributesToCustomData(QSharedPointer<Database> db);
|
||||
|
||||
static const QString KEEPASSXCBROWSER_NAME;
|
||||
static const QString KEEPASSXCBROWSER_OLD_NAME;
|
||||
@@ -132,8 +131,6 @@ public:
|
||||
static const QString OPTION_ONLY_HTTP_AUTH;
|
||||
static const QString OPTION_NOT_HTTP_AUTH;
|
||||
static const QString OPTION_OMIT_WWW;
|
||||
static const QString ADDITIONAL_URL;
|
||||
static const QString OPTION_RESTRICT_KEY;
|
||||
|
||||
signals:
|
||||
void requestUnlock();
|
||||
@@ -166,7 +163,6 @@ private:
|
||||
QList<Entry*> searchEntries(const QSharedPointer<Database>& db,
|
||||
const QString& siteUrl,
|
||||
const QString& formUrl,
|
||||
const QStringList& keys = {},
|
||||
bool passkey = false);
|
||||
QList<Entry*>
|
||||
searchEntries(const QString& siteUrl, const QString& formUrl, const StringPairList& keyList, bool passkey = false);
|
||||
@@ -205,10 +201,15 @@ private:
|
||||
bool handleURLWithWildcards(const QUrl& entryQUrl, const QString& siteUrl);
|
||||
QString getDatabaseRootUuid();
|
||||
QString getDatabaseRecycleBinUuid();
|
||||
bool checkLegacySettings(QSharedPointer<Database> db);
|
||||
void hideWindow() const;
|
||||
void raiseWindow(const bool force = false);
|
||||
|
||||
void updateWindowState();
|
||||
|
||||
static bool moveSettingsToCustomData(Entry* entry, const QString& name);
|
||||
static int moveKeysToCustomData(Entry* entry, QSharedPointer<Database> db);
|
||||
|
||||
QPointer<BrowserHost> m_browserHost;
|
||||
QHash<QString, QSharedPointer<BrowserAction>> m_browserClients;
|
||||
|
||||
|
||||
@@ -237,16 +237,6 @@ void BrowserSettings::setUpdateBinaryPath(bool enabled)
|
||||
config()->set(Config::Browser_UpdateBinaryPath, enabled);
|
||||
}
|
||||
|
||||
bool BrowserSettings::allowGetDatabaseEntriesRequest()
|
||||
{
|
||||
return config()->get(Config::Browser_AllowGetDatabaseEntriesRequest).toBool();
|
||||
}
|
||||
|
||||
void BrowserSettings::setAllowGetDatabaseEntriesRequest(bool enabled)
|
||||
{
|
||||
config()->set(Config::Browser_AllowGetDatabaseEntriesRequest, enabled);
|
||||
}
|
||||
|
||||
bool BrowserSettings::allowExpiredCredentials()
|
||||
{
|
||||
return config()->get(Config::Browser_AllowExpiredCredentials).toBool();
|
||||
|
||||
@@ -66,8 +66,6 @@ public:
|
||||
#endif
|
||||
bool updateBinaryPath();
|
||||
void setUpdateBinaryPath(bool enabled);
|
||||
bool allowGetDatabaseEntriesRequest();
|
||||
void setAllowGetDatabaseEntriesRequest(bool enabled);
|
||||
bool allowExpiredCredentials();
|
||||
void setAllowExpiredCredentials(bool enabled);
|
||||
|
||||
|
||||
@@ -118,7 +118,6 @@ void BrowserSettingsWidget::loadSettings()
|
||||
m_ui->useCustomProxy->setChecked(settings->useCustomProxy());
|
||||
m_ui->customProxyLocation->setText(settings->replaceHomePath(settings->customProxyLocation()));
|
||||
m_ui->updateBinaryPath->setChecked(settings->updateBinaryPath());
|
||||
m_ui->allowGetDatabaseEntriesRequest->setChecked(settings->allowGetDatabaseEntriesRequest());
|
||||
m_ui->allowExpiredCredentials->setChecked(settings->allowExpiredCredentials());
|
||||
m_ui->chromeSupport->setChecked(settings->browserSupport(BrowserShared::CHROME));
|
||||
m_ui->chromiumSupport->setChecked(settings->browserSupport(BrowserShared::CHROMIUM));
|
||||
@@ -232,7 +231,6 @@ void BrowserSettingsWidget::saveSettings()
|
||||
settings->setCustomProxyLocation(resolveCustomProxyLocation());
|
||||
|
||||
settings->setUpdateBinaryPath(m_ui->updateBinaryPath->isChecked());
|
||||
settings->setAllowGetDatabaseEntriesRequest(m_ui->allowGetDatabaseEntriesRequest->isChecked());
|
||||
settings->setAllowExpiredCredentials(m_ui->allowExpiredCredentials->isChecked());
|
||||
settings->setAlwaysAllowAccess(m_ui->alwaysAllowAccess->isChecked());
|
||||
settings->setAlwaysAllowUpdate(m_ui->alwaysAllowUpdate->isChecked());
|
||||
|
||||
@@ -340,16 +340,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="allowGetDatabaseEntriesRequest">
|
||||
<property name="toolTip">
|
||||
<string>Allow keepassxc-proxy to list all entries with their title, URL and UUID in connected databases.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Allow limited access to all entries in connected databases (ignores site access restrictions)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="useCustomProxy">
|
||||
<property name="toolTip">
|
||||
|
||||
11
src/browser/CMakeLists.txt
Normal file → Executable file
@@ -16,7 +16,7 @@
|
||||
if(WITH_XC_BROWSER)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
set(browser_SOURCES
|
||||
set(keepassxcbrowser_SOURCES
|
||||
BrowserAccessControlDialog.cpp
|
||||
BrowserAction.cpp
|
||||
BrowserEntryConfig.cpp
|
||||
@@ -29,10 +29,11 @@ if(WITH_XC_BROWSER)
|
||||
BrowserSettings.cpp
|
||||
BrowserShared.cpp
|
||||
CustomTableWidget.cpp
|
||||
NativeMessageInstaller.cpp)
|
||||
NativeMessageInstaller.cpp
|
||||
)
|
||||
|
||||
if(WITH_XC_BROWSER_PASSKEYS)
|
||||
list(APPEND browser_SOURCES
|
||||
list(APPEND keepassxcbrowser_SOURCES
|
||||
BrowserCbor.cpp
|
||||
BrowserPasskeys.cpp
|
||||
BrowserPasskeysClient.cpp
|
||||
@@ -40,6 +41,6 @@ if(WITH_XC_BROWSER)
|
||||
PasskeyUtils.cpp)
|
||||
endif()
|
||||
|
||||
add_library(browser STATIC ${browser_SOURCES})
|
||||
target_link_libraries(browser Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network ${BOTAN_LIBRARIES})
|
||||
add_library(keepassxcbrowser STATIC ${keepassxcbrowser_SOURCES})
|
||||
target_link_libraries(keepassxcbrowser Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network ${BOTAN_LIBRARIES})
|
||||
endif()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2025 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2021 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
|
||||
@@ -69,7 +70,7 @@ namespace
|
||||
const QString TARGET_DIR_FIREFOX = QStringLiteral("/.mozilla/native-messaging-hosts");
|
||||
const QString TARGET_DIR_VIVALDI = QStringLiteral("/vivaldi/NativeMessagingHosts");
|
||||
const QString TARGET_DIR_TOR_BROWSER = QStringLiteral(
|
||||
"/torbrowser/tbb/x86_64/tor-browser/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts");
|
||||
"/torbrowser/tbb/x86_64/tor-browser_en-US/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts");
|
||||
const QString TARGET_DIR_BRAVE = QStringLiteral("/BraveSoftware/Brave-Browser/NativeMessagingHosts");
|
||||
const QString TARGET_DIR_EDGE = QStringLiteral("/microsoft-edge/NativeMessagingHosts");
|
||||
#endif
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "BrowserPasskeys.h"
|
||||
#include "core/EntryAttributes.h"
|
||||
#include "core/Tools.h"
|
||||
#include "gui/UrlTools.h"
|
||||
#include "core/UrlTools.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QUrl>
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "Generate.h"
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Group.h"
|
||||
#include "core/PasswordGenerator.h"
|
||||
|
||||
@@ -75,7 +74,7 @@ int Add::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<Q
|
||||
|
||||
// Cannot use those 2 options at the same time!
|
||||
if (parser->isSet(Add::GenerateOption) && parser->isSet(Add::PasswordPromptOption)) {
|
||||
err << QObject::tr("Cannot generate a password and prompt at the same time.") << Qt::endl;
|
||||
err << QObject::tr("Cannot generate a password and prompt at the same time.") << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -91,7 +90,7 @@ int Add::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<Q
|
||||
|
||||
Entry* entry = database->rootGroup()->addEntryWithPath(entryPath);
|
||||
if (!entry) {
|
||||
err << QObject::tr("Could not create entry with path %1.").arg(entryPath) << Qt::endl;
|
||||
err << QObject::tr("Could not create entry with path %1.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -109,7 +108,7 @@ int Add::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<Q
|
||||
|
||||
if (parser->isSet(Add::PasswordPromptOption)) {
|
||||
if (!parser->isSet(Command::QuietOption)) {
|
||||
out << QObject::tr("Enter password for new entry: ") << Qt::flush;
|
||||
out << QObject::tr("Enter password for new entry: ") << flush;
|
||||
}
|
||||
QString password = Utils::getPassword(parser->isSet(Command::QuietOption));
|
||||
entry->setPassword(password);
|
||||
@@ -120,12 +119,12 @@ int Add::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<Q
|
||||
|
||||
QString errorMessage;
|
||||
if (!database->save(Database::Atomic, {}, &errorMessage)) {
|
||||
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << Qt::endl;
|
||||
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!parser->isSet(Command::QuietOption)) {
|
||||
out << QObject::tr("Successfully added entry %1.").arg(entry->title()) << Qt::endl;
|
||||
out << QObject::tr("Successfully added entry %1.").arg(entry->title()) << endl;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "AddGroup.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Group.h"
|
||||
|
||||
#include <QCommandLineParser>
|
||||
@@ -30,7 +29,9 @@ AddGroup::AddGroup()
|
||||
positionalArguments.append({QString("group"), QObject::tr("Path of the group to add."), QString("")});
|
||||
}
|
||||
|
||||
AddGroup::~AddGroup() = default;
|
||||
AddGroup::~AddGroup()
|
||||
{
|
||||
}
|
||||
|
||||
int AddGroup::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<QCommandLineParser> parser)
|
||||
{
|
||||
@@ -46,29 +47,29 @@ int AddGroup::executeWithDatabase(QSharedPointer<Database> database, QSharedPoin
|
||||
|
||||
Group* group = database->rootGroup()->findGroupByPath(groupPath);
|
||||
if (group) {
|
||||
err << QObject::tr("Group %1 already exists!").arg(groupPath) << Qt::endl;
|
||||
err << QObject::tr("Group %1 already exists!").arg(groupPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
Group* parentGroup = database->rootGroup()->findGroupByPath(parentGroupPath);
|
||||
if (!parentGroup) {
|
||||
err << QObject::tr("Group %1 not found.").arg(parentGroupPath) << Qt::endl;
|
||||
err << QObject::tr("Group %1 not found.").arg(parentGroupPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
auto newGroup = new Group();
|
||||
Group* newGroup = new Group();
|
||||
newGroup->setUuid(QUuid::createUuid());
|
||||
newGroup->setName(groupName);
|
||||
newGroup->setParent(parentGroup);
|
||||
|
||||
QString errorMessage;
|
||||
if (!database->save(Database::Atomic, {}, &errorMessage)) {
|
||||
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << Qt::endl;
|
||||
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!parser->isSet(Command::QuietOption)) {
|
||||
out << QObject::tr("Successfully added group %1.").arg(groupName) << Qt::endl;
|
||||
out << QObject::tr("Successfully added group %1.").arg(groupName) << endl;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ class AddGroup : public DatabaseCommand
|
||||
{
|
||||
public:
|
||||
AddGroup();
|
||||
~AddGroup() override;
|
||||
~AddGroup();
|
||||
|
||||
int executeWithDatabase(QSharedPointer<Database> db, QSharedPointer<QCommandLineParser> parser) override;
|
||||
int executeWithDatabase(QSharedPointer<Database> db, QSharedPointer<QCommandLineParser> parser);
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_ADDGROUP_H
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "Analyze.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Group.h"
|
||||
#include "core/HibpOffline.h"
|
||||
|
||||
@@ -61,24 +60,23 @@ int Analyze::executeWithDatabase(QSharedPointer<Database> database, QSharedPoint
|
||||
|
||||
auto okon = parser->value(Analyze::OkonOption);
|
||||
if (!okon.isEmpty()) {
|
||||
out << QObject::tr("Evaluating database entries using okon…") << Qt::endl;
|
||||
out << QObject::tr("Evaluating database entries using okon…") << endl;
|
||||
|
||||
if (!HibpOffline::okonReport(database, okon, hibpDatabase, findings, &error)) {
|
||||
err << error << Qt::endl;
|
||||
err << error << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else {
|
||||
QFile hibpFile(hibpDatabase);
|
||||
if (!hibpFile.open(QFile::ReadOnly)) {
|
||||
err << QObject::tr("Failed to open HIBP file %1: %2").arg(hibpDatabase).arg(hibpFile.errorString())
|
||||
<< Qt::endl;
|
||||
err << QObject::tr("Failed to open HIBP file %1: %2").arg(hibpDatabase).arg(hibpFile.errorString()) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
out << QObject::tr("Evaluating database entries against HIBP file, this will take a while…") << Qt::endl;
|
||||
out << QObject::tr("Evaluating database entries against HIBP file, this will take a while…") << endl;
|
||||
|
||||
if (!HibpOffline::report(database, hibpFile, findings, &error)) {
|
||||
err << error << Qt::endl;
|
||||
err << error << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
@@ -93,10 +91,9 @@ int Analyze::executeWithDatabase(QSharedPointer<Database> database, QSharedPoint
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
out << QObject::tr("Password for '%1' has been leaked %2 time(s)!", "", count).arg(path).arg(count)
|
||||
<< Qt::endl;
|
||||
out << QObject::tr("Password for '%1' has been leaked %2 time(s)!", "", count).arg(path).arg(count) << endl;
|
||||
} else {
|
||||
out << QObject::tr("Password for '%1' has been leaked!").arg(path) << Qt::endl;
|
||||
out << QObject::tr("Password for '%1' has been leaked!").arg(path) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "AttachmentExport.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Group.h"
|
||||
|
||||
#include <QCommandLineParser>
|
||||
@@ -50,7 +49,7 @@ int AttachmentExport::executeWithDatabase(QSharedPointer<Database> database, QSh
|
||||
|
||||
auto entry = database->rootGroup()->findEntryByPath(entryPath);
|
||||
if (!entry) {
|
||||
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
|
||||
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -58,32 +57,32 @@ int AttachmentExport::executeWithDatabase(QSharedPointer<Database> database, QSh
|
||||
|
||||
auto attachments = entry->attachments();
|
||||
if (!attachments->hasKey(attachmentName)) {
|
||||
err << QObject::tr("Could not find attachment with name %1.").arg(attachmentName) << Qt::endl;
|
||||
err << QObject::tr("Could not find attachment with name %1.").arg(attachmentName) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (parser->isSet(AttachmentExport::StdoutOption)) {
|
||||
// Output to STDOUT even in quiet mode
|
||||
Utils::STDOUT << attachments->value(attachmentName) << Qt::flush;
|
||||
Utils::STDOUT << attachments->value(attachmentName) << flush;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (args.size() < 4) {
|
||||
err << QObject::tr("No export target given. Please use '--stdout' or specify an 'export-file'.") << Qt::endl;
|
||||
err << QObject::tr("No export target given. Please use '--stdout' or specify an 'export-file'.") << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
auto exportFileName = args.at(3);
|
||||
QFile exportFile(exportFileName);
|
||||
if (!exportFile.open(QIODevice::WriteOnly)) {
|
||||
err << QObject::tr("Could not open output file %1.").arg(exportFileName) << Qt::endl;
|
||||
err << QObject::tr("Could not open output file %1.").arg(exportFileName) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
exportFile.write(attachments->value(attachmentName));
|
||||
|
||||
out << QObject::tr("Successfully exported attachment %1 of entry %2 to %3.")
|
||||
.arg(attachmentName, entryPath, exportFileName)
|
||||
<< Qt::endl;
|
||||
<< endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "AttachmentImport.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Group.h"
|
||||
|
||||
#include <QCommandLineParser>
|
||||
@@ -49,7 +48,7 @@ int AttachmentImport::executeWithDatabase(QSharedPointer<Database> database, QSh
|
||||
|
||||
auto entry = database->rootGroup()->findEntryByPath(entryPath);
|
||||
if (!entry) {
|
||||
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
|
||||
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -57,7 +56,7 @@ int AttachmentImport::executeWithDatabase(QSharedPointer<Database> database, QSh
|
||||
|
||||
auto attachments = entry->attachments();
|
||||
if (attachments->hasKey(attachmentName) && !parser->isSet(AttachmentImport::ForceOption)) {
|
||||
err << QObject::tr("Attachment %1 already exists for entry %2.").arg(attachmentName, entryPath) << Qt::endl;
|
||||
err << QObject::tr("Attachment %1 already exists for entry %2.").arg(attachmentName, entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -65,7 +64,7 @@ int AttachmentImport::executeWithDatabase(QSharedPointer<Database> database, QSh
|
||||
|
||||
QFile importFile(importFileName);
|
||||
if (!importFile.open(QIODevice::ReadOnly)) {
|
||||
err << QObject::tr("Could not open attachment file %1.").arg(importFileName) << Qt::endl;
|
||||
err << QObject::tr("Could not open attachment file %1.").arg(importFileName) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -75,12 +74,12 @@ int AttachmentImport::executeWithDatabase(QSharedPointer<Database> database, QSh
|
||||
|
||||
QString errorMessage;
|
||||
if (!database->save(Database::Atomic, {}, &errorMessage)) {
|
||||
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << Qt::endl;
|
||||
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
out << QObject::tr("Successfully imported attachment %1 as %2 to entry %3.")
|
||||
.arg(importFileName, attachmentName, entryPath)
|
||||
<< Qt::endl;
|
||||
<< endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "AttachmentRemove.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Group.h"
|
||||
|
||||
#include <QCommandLineParser>
|
||||
@@ -42,7 +41,7 @@ int AttachmentRemove::executeWithDatabase(QSharedPointer<Database> database, QSh
|
||||
|
||||
auto entry = database->rootGroup()->findEntryByPath(entryPath);
|
||||
if (!entry) {
|
||||
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
|
||||
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -50,7 +49,7 @@ int AttachmentRemove::executeWithDatabase(QSharedPointer<Database> database, QSh
|
||||
|
||||
auto attachments = entry->attachments();
|
||||
if (!attachments->hasKey(attachmentName)) {
|
||||
err << QObject::tr("Could not find attachment with name %1.").arg(attachmentName) << Qt::endl;
|
||||
err << QObject::tr("Could not find attachment with name %1.").arg(attachmentName) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -60,10 +59,10 @@ int AttachmentRemove::executeWithDatabase(QSharedPointer<Database> database, QSh
|
||||
|
||||
QString errorMessage;
|
||||
if (!database->save(Database::Atomic, {}, &errorMessage)) {
|
||||
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << Qt::endl;
|
||||
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
out << QObject::tr("Successfully removed attachment %1 from entry %2.").arg(attachmentName, entryPath) << Qt::endl;
|
||||
out << QObject::tr("Successfully removed attachment %1 from entry %2.").arg(attachmentName, entryPath) << endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ add_executable(keepassxc-cli keepassxc-cli.cpp)
|
||||
target_link_libraries(keepassxc-cli
|
||||
${GPGERROR_LIBRARIES}
|
||||
cli
|
||||
keepassxc_core)
|
||||
keepassx_core)
|
||||
|
||||
install(TARGETS keepassxc-cli
|
||||
BUNDLE DESTINATION . COMPONENT Runtime
|
||||
|
||||
@@ -37,12 +37,6 @@ const QCommandLineOption Clip::TotpOption =
|
||||
QCommandLineOption(QStringList() << "t" << "totp",
|
||||
QObject::tr("Copy the current TOTP to the clipboard (equivalent to \"-a totp\")."));
|
||||
|
||||
const QCommandLineOption Clip::UuidOption =
|
||||
QCommandLineOption(QStringList() << "uuid", QObject::tr("Copy the entry's UUID to the clipboard."));
|
||||
|
||||
const QCommandLineOption Clip::TagsOption =
|
||||
QCommandLineOption(QStringList() << "tags", QObject::tr("Copy the entry's tag list to the clipboard."));
|
||||
|
||||
const QCommandLineOption Clip::BestMatchOption =
|
||||
QCommandLineOption(QStringList() << "b" << "best-match",
|
||||
QObject::tr("Must match only one entry, otherwise a list of possible matches is shown."));
|
||||
@@ -53,8 +47,6 @@ Clip::Clip()
|
||||
description = QObject::tr("Copy an entry's attribute to the clipboard.");
|
||||
options.append(Clip::AttributeOption);
|
||||
options.append(Clip::TotpOption);
|
||||
options.append(Clip::UuidOption);
|
||||
options.append(Clip::TagsOption);
|
||||
options.append(Clip::BestMatchOption);
|
||||
positionalArguments.append(
|
||||
{QString("entry"), QObject::tr("Path of the entry to clip.", "clip = copy to clipboard"), QString("")});
|
||||
@@ -77,7 +69,7 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
bool ok;
|
||||
timeout = args.at(2).toInt(&ok);
|
||||
if (!ok) {
|
||||
err << QObject::tr("Invalid timeout value %1.").arg(args.at(2)) << Qt::endl;
|
||||
err << QObject::tr("Invalid timeout value %1.").arg(args.at(2)) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
@@ -88,14 +80,14 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
const auto& searchTerm = args.at(1);
|
||||
const auto results = searcher.search(QString("title:%1").arg(searchTerm), database->rootGroup(), true);
|
||||
if (results.count() > 1) {
|
||||
err << QObject::tr("Multiple entries matching:") << Qt::endl;
|
||||
err << QObject::tr("Multiple entries matching:") << endl;
|
||||
for (const Entry* result : results) {
|
||||
err << result->path().prepend('/') << Qt::endl;
|
||||
err << result->path().prepend('/') << endl;
|
||||
}
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
entryPath = (results.isEmpty()) ? searchTerm : results[0]->path().prepend('/');
|
||||
out << QObject::tr("Using matching entry: %1").arg(entryPath) << Qt::endl;
|
||||
out << QObject::tr("Using matching entry: %1").arg(entryPath) << endl;
|
||||
}
|
||||
} else {
|
||||
entryPath = args.at(1);
|
||||
@@ -103,17 +95,12 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
|
||||
auto* entry = database->rootGroup()->findEntryByPath(entryPath);
|
||||
if (!entry) {
|
||||
err << QObject::tr("Entry %1 not found.").arg(entryPath) << Qt::endl;
|
||||
err << QObject::tr("Entry %1 not found.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
auto optionCount = parser->isSet(AttributeOption) ? 1 : 0;
|
||||
optionCount += parser->isSet(TotpOption) ? 1 : 0;
|
||||
optionCount += parser->isSet(UuidOption) ? 1 : 0;
|
||||
optionCount += parser->isSet(TagsOption) ? 1 : 0;
|
||||
if (optionCount > 1) {
|
||||
err << QObject::tr("ERROR: Cannot specify multiple options at once (--attribute, --totp, --uuid, --tags).")
|
||||
<< Qt::endl;
|
||||
if (parser->isSet(AttributeOption) && parser->isSet(TotpOption)) {
|
||||
err << QObject::tr("ERROR: Please specify one of --attribute or --totp, not both.") << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -122,27 +109,22 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
bool found = false;
|
||||
if (parser->isSet(TotpOption) || selectedAttribute == "totp") {
|
||||
if (!entry->hasTotp()) {
|
||||
err << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << Qt::endl;
|
||||
err << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
selectedAttribute = "totp";
|
||||
found = true;
|
||||
value = entry->totp();
|
||||
selectedAttribute = "TOTP";
|
||||
found = true;
|
||||
} else if (parser->isSet(UuidOption)) {
|
||||
value = entry->uuid().toString();
|
||||
selectedAttribute = "UUID";
|
||||
found = true;
|
||||
} else if (parser->isSet(TagsOption)) {
|
||||
value = entry->tags();
|
||||
selectedAttribute = "Tags";
|
||||
} else if (Utils::EntryFieldNames.contains(selectedAttribute)) {
|
||||
value = Utils::getTopLevelField(entry, selectedAttribute);
|
||||
found = true;
|
||||
} else {
|
||||
QStringList attrs = Utils::findAttributes(*entry->attributes(), selectedAttribute);
|
||||
if (attrs.size() > 1) {
|
||||
err << QObject::tr("ERROR: attribute %1 is ambiguous, it matches %2.")
|
||||
.arg(selectedAttribute, QLocale().createSeparatedList(attrs))
|
||||
<< Qt::endl;
|
||||
<< endl;
|
||||
return EXIT_FAILURE;
|
||||
} else if (attrs.size() == 1) {
|
||||
found = true;
|
||||
@@ -152,7 +134,7 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
out << QObject::tr("Attribute \"%1\" not found.").arg(selectedAttribute) << Qt::endl;
|
||||
out << QObject::tr("Attribute \"%1\" not found.").arg(selectedAttribute) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -161,7 +143,7 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
out << QObject::tr("Entry's \"%1\" attribute copied to the clipboard!").arg(selectedAttribute) << Qt::endl;
|
||||
out << QObject::tr("Entry's \"%1\" attribute copied to the clipboard!").arg(selectedAttribute) << endl;
|
||||
|
||||
if (timeout <= 0) {
|
||||
return exitCode;
|
||||
@@ -171,13 +153,13 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
while (timeout > 0) {
|
||||
out << '\r' << QString(lastLine.size(), ' ') << '\r';
|
||||
lastLine = QObject::tr("Clearing the clipboard in %1 second(s)...", "", timeout).arg(timeout);
|
||||
out << lastLine << Qt::flush;
|
||||
out << lastLine << flush;
|
||||
Tools::sleep(1000);
|
||||
--timeout;
|
||||
}
|
||||
Utils::clipText("");
|
||||
out << '\r' << QString(lastLine.size(), ' ') << '\r';
|
||||
out << QObject::tr("Clipboard cleared!") << Qt::endl;
|
||||
out << QObject::tr("Clipboard cleared!") << endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,6 @@ public:
|
||||
|
||||
static const QCommandLineOption AttributeOption;
|
||||
static const QCommandLineOption TotpOption;
|
||||
static const QCommandLineOption UuidOption;
|
||||
static const QCommandLineOption TagsOption;
|
||||
static const QCommandLineOption BestMatchOption;
|
||||
};
|
||||
|
||||
|
||||
@@ -100,7 +100,9 @@ Command::Command()
|
||||
options.append(Command::QuietOption);
|
||||
}
|
||||
|
||||
Command::~Command() = default;
|
||||
Command::~Command()
|
||||
{
|
||||
}
|
||||
|
||||
QString Command::getDescriptionLine()
|
||||
{
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "DatabaseCreate.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "keys/FileKey.h"
|
||||
|
||||
#include <QCommandLineParser>
|
||||
@@ -68,13 +67,13 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
|
||||
if (decryptionTimeValue.length() != 0) {
|
||||
decryptionTime = decryptionTimeValue.toInt();
|
||||
if (decryptionTime <= 0) {
|
||||
err << QObject::tr("Invalid decryption time %1.").arg(decryptionTimeValue) << Qt::endl;
|
||||
err << QObject::tr("Invalid decryption time %1.").arg(decryptionTimeValue) << endl;
|
||||
return {};
|
||||
}
|
||||
if (decryptionTime < Kdf::MIN_ENCRYPTION_TIME || decryptionTime > Kdf::MAX_ENCRYPTION_TIME) {
|
||||
err << QObject::tr("Target decryption time must be between %1 and %2.")
|
||||
.arg(QString::number(Kdf::MIN_ENCRYPTION_TIME), QString::number(Kdf::MAX_ENCRYPTION_TIME))
|
||||
<< Qt::endl;
|
||||
<< endl;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -84,7 +83,7 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
|
||||
if (parser->isSet(DatabaseCreate::SetPasswordOption)) {
|
||||
auto passwordKey = Utils::getConfirmedPassword();
|
||||
if (passwordKey.isNull()) {
|
||||
err << QObject::tr("Failed to set database password.") << Qt::endl;
|
||||
err << QObject::tr("Failed to set database password.") << endl;
|
||||
return {};
|
||||
}
|
||||
key->addKey(passwordKey);
|
||||
@@ -102,7 +101,7 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
|
||||
}
|
||||
|
||||
if (!Utils::loadFileKey(keyFilePath, fileKey)) {
|
||||
err << QObject::tr("Loading the key file failed") << Qt::endl;
|
||||
err << QObject::tr("Loading the key file failed") << endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -112,7 +111,7 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
|
||||
}
|
||||
|
||||
if (key->isEmpty()) {
|
||||
err << QObject::tr("No key is set. Aborting database creation.") << Qt::endl;
|
||||
err << QObject::tr("No key is set. Aborting database creation.") << endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -123,15 +122,15 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
|
||||
auto kdf = db->kdf();
|
||||
Q_ASSERT(kdf);
|
||||
|
||||
out << QObject::tr("Benchmarking key derivation function for %1ms delay.").arg(decryptionTimeValue) << Qt::endl;
|
||||
out << QObject::tr("Benchmarking key derivation function for %1ms delay.").arg(decryptionTimeValue) << endl;
|
||||
int rounds = kdf->benchmark(decryptionTime);
|
||||
out << QObject::tr("Setting %1 rounds for key derivation function.").arg(QString::number(rounds)) << Qt::endl;
|
||||
out << QObject::tr("Setting %1 rounds for key derivation function.").arg(QString::number(rounds)) << endl;
|
||||
kdf->setRounds(rounds);
|
||||
|
||||
bool ok = db->changeKdf(kdf);
|
||||
|
||||
if (!ok) {
|
||||
err << QObject::tr("error while setting database key derivation settings.") << Qt::endl;
|
||||
err << QObject::tr("error while setting database key derivation settings.") << endl;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -147,7 +146,7 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
|
||||
* If a key file is specified but it can't be loaded, the function will
|
||||
* fail.
|
||||
*
|
||||
* If the database is being saved in a non existent directory, the
|
||||
* If the database is being saved in a non existant directory, the
|
||||
* function will fail.
|
||||
*
|
||||
* @return EXIT_SUCCESS on success, or EXIT_FAILURE on failure
|
||||
@@ -166,7 +165,7 @@ int DatabaseCreate::execute(const QStringList& arguments)
|
||||
|
||||
const QString& databaseFilename = args.at(0);
|
||||
if (QFileInfo::exists(databaseFilename)) {
|
||||
err << QObject::tr("File %1 already exists.").arg(databaseFilename) << Qt::endl;
|
||||
err << QObject::tr("File %1 already exists.").arg(databaseFilename) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -177,10 +176,10 @@ int DatabaseCreate::execute(const QStringList& arguments)
|
||||
|
||||
QString errorMessage;
|
||||
if (!db->saveAs(databaseFilename, Database::Atomic, {}, &errorMessage)) {
|
||||
err << QObject::tr("Failed to save the database: %1.").arg(errorMessage) << Qt::endl;
|
||||
err << QObject::tr("Failed to save the database: %1.").arg(errorMessage) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
out << QObject::tr("Successfully created new database.") << Qt::endl;
|
||||
out << QObject::tr("Successfully created new database.") << endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "Utils.h"
|
||||
#include "cli/DatabaseCreate.h"
|
||||
#include "core/Global.h"
|
||||
#include "keys/ChallengeResponseKey.h"
|
||||
#include "keys/FileKey.h"
|
||||
#include "keys/PasswordKey.h"
|
||||
@@ -54,7 +53,7 @@ int DatabaseEdit::executeWithDatabase(QSharedPointer<Database> database, QShared
|
||||
err << QObject::tr("Cannot use %1 and %2 at the same time.")
|
||||
.arg(DatabaseCreate::SetPasswordOption.names().at(0))
|
||||
.arg(DatabaseEdit::UnsetPasswordOption.names().at(0))
|
||||
<< Qt::endl;
|
||||
<< endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -62,7 +61,7 @@ int DatabaseEdit::executeWithDatabase(QSharedPointer<Database> database, QShared
|
||||
err << QObject::tr("Cannot use %1 and %2 at the same time.")
|
||||
.arg(DatabaseCreate::SetKeyFileOption.names().at(0))
|
||||
.arg(DatabaseEdit::UnsetKeyFileOption.names().at(0))
|
||||
<< Qt::endl;
|
||||
<< endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -77,7 +76,7 @@ int DatabaseEdit::executeWithDatabase(QSharedPointer<Database> database, QShared
|
||||
parser->value(DatabaseCreate::SetKeyFileOption),
|
||||
parser->isSet(DatabaseEdit::UnsetKeyFileOption));
|
||||
if (newDatabaseKey.isNull()) {
|
||||
err << QObject::tr("Could not change the database key.") << Qt::endl;
|
||||
err << QObject::tr("Could not change the database key.") << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
database->setKey(newDatabaseKey);
|
||||
@@ -85,17 +84,17 @@ int DatabaseEdit::executeWithDatabase(QSharedPointer<Database> database, QShared
|
||||
}
|
||||
|
||||
if (!databaseWasChanged) {
|
||||
out << QObject::tr("Database was not modified.") << Qt::endl;
|
||||
out << QObject::tr("Database was not modified.") << endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
QString errorMessage;
|
||||
if (!database->save(Database::Atomic, {}, &errorMessage)) {
|
||||
err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << Qt::endl;
|
||||
err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
out << QObject::tr("Successfully edited the database.") << Qt::endl;
|
||||
out << QObject::tr("Successfully edited the database.") << endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -114,19 +113,19 @@ QSharedPointer<CompositeKey> DatabaseEdit::getNewDatabaseKey(QSharedPointer<Data
|
||||
auto currentChallengeResponseKey = database->key()->getChallengeResponseKey(ChallengeResponseKey::UUID);
|
||||
|
||||
if (removePassword && currentPasswordKey.isNull()) {
|
||||
err << QObject::tr("Cannot remove password: The database does not have a password.") << Qt::endl;
|
||||
err << QObject::tr("Cannot remove password: The database does not have a password.") << endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (removeKeyFile && currentFileKey.isNull()) {
|
||||
err << QObject::tr("Cannot remove file key: The database does not have a file key.") << Qt::endl;
|
||||
err << QObject::tr("Cannot remove file key: The database does not have a file key.") << endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (updatePassword) {
|
||||
QSharedPointer<PasswordKey> newPasswordKey = Utils::getConfirmedPassword();
|
||||
if (newPasswordKey.isNull()) {
|
||||
err << QObject::tr("Failed to set database password.") << Qt::endl;
|
||||
err << QObject::tr("Failed to set database password.") << endl;
|
||||
return {};
|
||||
}
|
||||
newDatabaseKey->addKey(newPasswordKey);
|
||||
@@ -138,7 +137,7 @@ QSharedPointer<CompositeKey> DatabaseEdit::getNewDatabaseKey(QSharedPointer<Data
|
||||
QSharedPointer<FileKey> newFileKey = QSharedPointer<FileKey>::create();
|
||||
QString errorMessage;
|
||||
if (!Utils::loadFileKey(newFileKeyPath, newFileKey)) {
|
||||
err << QObject::tr("Loading the new key file failed: %1").arg(errorMessage) << Qt::endl;
|
||||
err << QObject::tr("Loading the new key file failed: %1").arg(errorMessage) << endl;
|
||||
return {};
|
||||
}
|
||||
newDatabaseKey->addKey(newFileKey);
|
||||
@@ -151,13 +150,13 @@ QSharedPointer<CompositeKey> DatabaseEdit::getNewDatabaseKey(QSharedPointer<Data
|
||||
// silently removed from the database.
|
||||
for (const QSharedPointer<Key>& key : database->key()->keys()) {
|
||||
if (key->uuid() != PasswordKey::UUID && key->uuid() != FileKey::UUID) {
|
||||
err << QObject::tr("Found unexpected Key type %1").arg(key->uuid().toString()) << Qt::endl;
|
||||
err << QObject::tr("Found unexpected Key type %1").arg(key->uuid().toString()) << endl;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
for (const QSharedPointer<ChallengeResponseKey>& key : database->key()->challengeResponseKeys()) {
|
||||
if (key->uuid() != ChallengeResponseKey::UUID) {
|
||||
err << QObject::tr("Found unexpected Key type %1").arg(key->uuid().toString()) << Qt::endl;
|
||||
err << QObject::tr("Found unexpected Key type %1").arg(key->uuid().toString()) << endl;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -167,7 +166,7 @@ QSharedPointer<CompositeKey> DatabaseEdit::getNewDatabaseKey(QSharedPointer<Data
|
||||
}
|
||||
|
||||
if (newDatabaseKey->keys().isEmpty() && newDatabaseKey->challengeResponseKeys().isEmpty()) {
|
||||
err << QObject::tr("Cannot remove all the keys from a database.") << Qt::endl;
|
||||
err << QObject::tr("Cannot remove all the keys from a database.") << endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "DatabaseInfo.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Clock.h"
|
||||
#include "core/DatabaseStats.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Group.h"
|
||||
@@ -36,39 +35,39 @@ int DatabaseInfo::executeWithDatabase(QSharedPointer<Database> database, QShared
|
||||
{
|
||||
auto& out = Utils::STDOUT;
|
||||
|
||||
out << QObject::tr("UUID: ") << database->uuid().toString() << Qt::endl;
|
||||
out << QObject::tr("Name: ") << database->metadata()->name() << Qt::endl;
|
||||
out << QObject::tr("Description: ") << database->metadata()->description() << Qt::endl;
|
||||
out << QObject::tr("UUID: ") << database->uuid().toString() << endl;
|
||||
out << QObject::tr("Name: ") << database->metadata()->name() << endl;
|
||||
out << QObject::tr("Description: ") << database->metadata()->description() << endl;
|
||||
for (auto& cipher : asConst(KeePass2::CIPHERS)) {
|
||||
if (cipher == database->cipher()) {
|
||||
out << QObject::tr("Cipher: ") << KeePass2::cipherToString(cipher) << Qt::endl;
|
||||
out << QObject::tr("Cipher: ") << KeePass2::cipherToString(cipher) << endl;
|
||||
}
|
||||
}
|
||||
out << QObject::tr("KDF: ") << database->kdf()->toString() << Qt::endl;
|
||||
out << QObject::tr("KDF: ") << database->kdf()->toString() << endl;
|
||||
if (database->metadata()->recycleBinEnabled()) {
|
||||
out << QObject::tr("Recycle bin is enabled.") << Qt::endl;
|
||||
out << QObject::tr("Recycle bin is enabled.") << endl;
|
||||
} else {
|
||||
out << QObject::tr("Recycle bin is not enabled.") << Qt::endl;
|
||||
out << QObject::tr("Recycle bin is not enabled.") << endl;
|
||||
}
|
||||
|
||||
DatabaseStats stats(database);
|
||||
out << QObject::tr("Location") << ": " << database->filePath() << Qt::endl;
|
||||
out << QObject::tr("Database created") << ": " << Clock::toString(database->rootGroup()->timeInfo().creationTime())
|
||||
<< Qt::endl;
|
||||
out << QObject::tr("Last saved") << ": " << Clock::toString(stats.modified) << Qt::endl;
|
||||
out << QObject::tr("Location") << ": " << database->filePath() << endl;
|
||||
out << QObject::tr("Database created") << ": "
|
||||
<< database->rootGroup()->timeInfo().creationTime().toString(Qt::DefaultLocaleShortDate) << endl;
|
||||
out << QObject::tr("Last saved") << ": " << stats.modified.toString(Qt::DefaultLocaleShortDate) << endl;
|
||||
out << QObject::tr("Unsaved changes") << ": " << (database->isModified() ? QObject::tr("yes") : QObject::tr("no"))
|
||||
<< Qt::endl;
|
||||
out << QObject::tr("Number of groups") << ": " << QString::number(stats.groupCount) << Qt::endl;
|
||||
out << QObject::tr("Number of entries") << ": " << QString::number(stats.entryCount) << Qt::endl;
|
||||
out << QObject::tr("Number of expired entries") << ": " << QString::number(stats.expiredEntries) << Qt::endl;
|
||||
out << QObject::tr("Unique passwords") << ": " << QString::number(stats.uniquePasswords) << Qt::endl;
|
||||
out << QObject::tr("Non-unique passwords") << ": " << QString::number(stats.reusedPasswords) << Qt::endl;
|
||||
out << QObject::tr("Maximum password reuse") << ": " << QString::number(stats.maxPwdReuse()) << Qt::endl;
|
||||
out << QObject::tr("Number of short passwords") << ": " << QString::number(stats.shortPasswords) << Qt::endl;
|
||||
out << QObject::tr("Number of weak passwords") << ": " << QString::number(stats.weakPasswords) << Qt::endl;
|
||||
out << QObject::tr("Entries excluded from reports") << ": " << QString::number(stats.excludedEntries) << Qt::endl;
|
||||
<< endl;
|
||||
out << QObject::tr("Number of groups") << ": " << QString::number(stats.groupCount) << endl;
|
||||
out << QObject::tr("Number of entries") << ": " << QString::number(stats.entryCount) << endl;
|
||||
out << QObject::tr("Number of expired entries") << ": " << QString::number(stats.expiredEntries) << endl;
|
||||
out << QObject::tr("Unique passwords") << ": " << QString::number(stats.uniquePasswords) << endl;
|
||||
out << QObject::tr("Non-unique passwords") << ": " << QString::number(stats.reusedPasswords) << endl;
|
||||
out << QObject::tr("Maximum password reuse") << ": " << QString::number(stats.maxPwdReuse()) << endl;
|
||||
out << QObject::tr("Number of short passwords") << ": " << QString::number(stats.shortPasswords) << endl;
|
||||
out << QObject::tr("Number of weak passwords") << ": " << QString::number(stats.weakPasswords) << endl;
|
||||
out << QObject::tr("Entries excluded from reports") << ": " << QString::number(stats.excludedEntries) << endl;
|
||||
out << QObject::tr("Average password length") << ": " << QObject::tr("%1 characters").arg(stats.averagePwdLength())
|
||||
<< Qt::endl;
|
||||
<< endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class DatabaseInfo : public DatabaseCommand
|
||||
public:
|
||||
DatabaseInfo();
|
||||
|
||||
int executeWithDatabase(QSharedPointer<Database> db, QSharedPointer<QCommandLineParser> parser) override;
|
||||
int executeWithDatabase(QSharedPointer<Database> db, QSharedPointer<QCommandLineParser> parser);
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_DATABASEINFO_H
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "Diceware.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/PassphraseGenerator.h"
|
||||
|
||||
#include <QCommandLineParser>
|
||||
@@ -57,7 +56,7 @@ int Diceware::execute(const QStringList& arguments)
|
||||
if (wordCount.isEmpty()) {
|
||||
dicewareGenerator.setWordCount(PassphraseGenerator::DefaultWordCount);
|
||||
} else if (wordCount.toInt() <= 0) {
|
||||
err << QObject::tr("Invalid word count %1").arg(wordCount) << Qt::endl;
|
||||
err << QObject::tr("Invalid word count %1").arg(wordCount) << endl;
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
dicewareGenerator.setWordCount(wordCount.toInt());
|
||||
@@ -71,12 +70,12 @@ int Diceware::execute(const QStringList& arguments)
|
||||
if (!dicewareGenerator.isValid()) {
|
||||
// We already validated the word count input so if the generator is invalid, it
|
||||
// must be because the word list is too small.
|
||||
err << QObject::tr("Cannot generate valid passphrases because the wordlist is too short") << Qt::endl;
|
||||
err << QObject::tr("Cannot generate valid passphrases because the wordlist is too short") << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
QString password = dicewareGenerator.generatePassphrase();
|
||||
out << password << Qt::endl;
|
||||
out << password << endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "Add.h"
|
||||
#include "Generate.h"
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Group.h"
|
||||
#include "core/PasswordGenerator.h"
|
||||
|
||||
@@ -65,7 +64,7 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
|
||||
// Cannot use those 2 options at the same time!
|
||||
if (parser->isSet(Add::GenerateOption) && parser->isSet(Add::PasswordPromptOption)) {
|
||||
err << QObject::tr("Cannot generate a password and prompt at the same time.") << Qt::endl;
|
||||
err << QObject::tr("Cannot generate a password and prompt at the same time.") << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -82,7 +81,7 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
|
||||
Entry* entry = database->rootGroup()->findEntryByPath(entryPath);
|
||||
if (!entry) {
|
||||
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
|
||||
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -92,7 +91,7 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
QString title = parser->value(Edit::TitleOption);
|
||||
bool prompt = parser->isSet(Add::PasswordPromptOption);
|
||||
if (username.isEmpty() && url.isEmpty() && notes.isEmpty() && title.isEmpty() && !prompt && !generate) {
|
||||
err << QObject::tr("Not changing any field for entry %1.").arg(entryPath) << Qt::endl;
|
||||
err << QObject::tr("Not changing any field for entry %1.").arg(entryPath) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -115,7 +114,7 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
}
|
||||
|
||||
if (prompt) {
|
||||
out << QObject::tr("Enter new password for entry: ") << Qt::flush;
|
||||
out << QObject::tr("Enter new password for entry: ") << flush;
|
||||
QString password = Utils::getPassword(parser->isSet(Command::QuietOption));
|
||||
entry->setPassword(password);
|
||||
} else if (generate) {
|
||||
@@ -127,10 +126,10 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
|
||||
|
||||
QString errorMessage;
|
||||
if (!database->save(Database::Atomic, {}, &errorMessage)) {
|
||||
err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << Qt::endl;
|
||||
err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
out << QObject::tr("Successfully edited entry %1.").arg(entry->title()) << Qt::endl;
|
||||
out << QObject::tr("Successfully edited entry %1.").arg(entry->title()) << endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "Estimate.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/PasswordHealth.h"
|
||||
|
||||
#include <QCommandLineParser>
|
||||
@@ -40,13 +39,13 @@ static void estimate(const char* pwd, bool advanced)
|
||||
{
|
||||
auto& out = Utils::STDOUT;
|
||||
|
||||
auto len = static_cast<int>(strlen(pwd));
|
||||
int len = static_cast<int>(strlen(pwd));
|
||||
if (!advanced) {
|
||||
const auto e = PasswordHealth(pwd).entropy();
|
||||
// clang-format off
|
||||
out << QObject::tr("Length %1").arg(len, 0) << '\t'
|
||||
<< QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t'
|
||||
<< QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << Qt::endl;
|
||||
<< QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << endl;
|
||||
// clang-format on
|
||||
} else {
|
||||
int pwdLen = 0;
|
||||
@@ -61,7 +60,7 @@ static void estimate(const char* pwd, bool advanced)
|
||||
out << QObject::tr("Length %1").arg(len) << '\t'
|
||||
<< QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t'
|
||||
<< QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << "\n "
|
||||
<< QObject::tr("Multi-word extra bits %1").arg(m, 0, 'f', 1) << Qt::endl;
|
||||
<< QObject::tr("Multi-word extra bits %1").arg(m, 0, 'f', 1) << endl;
|
||||
// clang-format on
|
||||
p = info;
|
||||
pwdLen = 0;
|
||||
@@ -134,13 +133,13 @@ static void estimate(const char* pwd, bool advanced)
|
||||
for (n = 0; n < p->Length; ++n, ++pwd) {
|
||||
out << *pwd;
|
||||
}
|
||||
out << Qt::endl;
|
||||
out << endl;
|
||||
p = p->Next;
|
||||
}
|
||||
ZxcvbnFreeInfo(info);
|
||||
if (pwdLen != len) {
|
||||
out << QObject::tr("*** Password length (%1) != sum of length of parts (%2) ***").arg(len).arg(pwdLen)
|
||||
<< Qt::endl;
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "TextStream.h"
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "format/CsvExporter.h"
|
||||
#include "format/HtmlExporter.h"
|
||||
|
||||
@@ -47,7 +46,7 @@ int Export::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
|
||||
QByteArray xmlData;
|
||||
QString errorMessage;
|
||||
if (!database->extract(xmlData, &errorMessage)) {
|
||||
err << QObject::tr("Unable to export database to XML: %1").arg(errorMessage) << Qt::endl;
|
||||
err << QObject::tr("Unable to export database to XML: %1").arg(errorMessage) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
out.write(xmlData.constData());
|
||||
@@ -58,7 +57,7 @@ int Export::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
|
||||
HtmlExporter htmlExporter;
|
||||
out << htmlExporter.exportDatabase(database);
|
||||
} else {
|
||||
err << QObject::tr("Unsupported format %1").arg(format) << Qt::endl;
|
||||
err << QObject::tr("Unsupported format %1").arg(format) << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "Generate.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/PasswordGenerator.h"
|
||||
|
||||
#include <QCommandLineParser>
|
||||
@@ -82,13 +81,13 @@ QSharedPointer<PasswordGenerator> Generate::createGenerator(QSharedPointer<QComm
|
||||
if (passwordLength.isEmpty()) {
|
||||
passwordGenerator->setLength(PasswordGenerator::DefaultLength);
|
||||
} else if (passwordLength.toInt() <= 0) {
|
||||
err << QObject::tr("Invalid password length %1").arg(passwordLength) << Qt::endl;
|
||||
return {};
|
||||
err << QObject::tr("Invalid password length %1").arg(passwordLength) << endl;
|
||||
return QSharedPointer<PasswordGenerator>(nullptr);
|
||||
} else {
|
||||
passwordGenerator->setLength(passwordLength.toInt());
|
||||
}
|
||||
|
||||
PasswordGenerator::CharClasses classes;
|
||||
PasswordGenerator::CharClasses classes = 0x0;
|
||||
|
||||
if (parser->isSet(Generate::LowerCaseOption)) {
|
||||
classes |= PasswordGenerator::LowerLetters;
|
||||
@@ -106,7 +105,7 @@ QSharedPointer<PasswordGenerator> Generate::createGenerator(QSharedPointer<QComm
|
||||
classes |= PasswordGenerator::EASCII;
|
||||
}
|
||||
|
||||
PasswordGenerator::GeneratorFlags flags;
|
||||
PasswordGenerator::GeneratorFlags flags = 0x0;
|
||||
|
||||
if (parser->isSet(Generate::ExcludeSimilarCharsOption)) {
|
||||
flags |= PasswordGenerator::ExcludeLookAlike;
|
||||
@@ -128,8 +127,8 @@ QSharedPointer<PasswordGenerator> Generate::createGenerator(QSharedPointer<QComm
|
||||
passwordGenerator->setExcludedCharacterSet(parser->value(Generate::ExcludeCharsOption));
|
||||
|
||||
if (!passwordGenerator->isValid()) {
|
||||
err << QObject::tr("Invalid password generator after applying all options") << Qt::endl;
|
||||
return {};
|
||||
err << QObject::tr("Invalid password generator after applying all options") << endl;
|
||||
return QSharedPointer<PasswordGenerator>(nullptr);
|
||||
}
|
||||
|
||||
return passwordGenerator;
|
||||
@@ -149,7 +148,7 @@ int Generate::execute(const QStringList& arguments)
|
||||
|
||||
auto& out = Utils::STDOUT;
|
||||
QString password = passwordGenerator->generatePassword();
|
||||
out << password << Qt::endl;
|
||||
out << password << endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||