Add 1Password 1PUX and Bitwarden JSON Importers

* Closes #7545 - Support 1Password 1PUX import format based on https://support.1password.com/1pux-format/

* Closes #8367 - Support Bitwarden JSON import format (both unencrypted and encrypted) based on https://bitwarden.com/help/encrypted-export/

* Fixes #9577 - OPVault import when fields have the same name or type

* Introduce the import wizard to handle all import tasks (CSV, KDBX1, OPVault, 1PUX, JSON)

* Clean up CSV parser code to make it much more efficient and easier to read

* Combine all importer tests (except CSV) into one test file
This commit is contained in:
Jonathan White 2023-08-27 21:54:53 -04:00
parent a02bceabd2
commit e700195f0a
70 changed files with 3562 additions and 1876 deletions

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21,11C21,16.55 17.16,21.74 12,23C6.84,21.74 3,16.55 3,11V5L12,1L21,5V11M12,21C15.75,20 19,15.54 19,11.22V6.3L12,3.18V21Z" /></svg>

After

Width:  |  Height:  |  Size: 200 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V8L14 2M18 20H6V4H13V9H18V20M10 19L12 15H9V10H15V15L13 19H10" /></svg>

After

Width:  |  Height:  |  Size: 209 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,1C5.92,1 1,5.92 1,12C1,18.08 5.92,23 12,23C18.08,23 23,18.08 23,12C23,5.92 18.08,1 12,1M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20M13,13.5C13,14.13 13.4,14.7 14,14.91V18H10V11.91C10.78,11.64 11.19,10.8 10.93,10C10.78,9.58 10.44,9.24 10,9.09V6H14V12.09C13.4,12.3 13,12.87 13,13.5Z" /></svg>

After

Width:  |  Height:  |  Size: 387 B

View file

@ -8,11 +8,13 @@
<file>application/scalable/actions/application-exit.svg</file>
<file>application/scalable/actions/attributes-copy.svg</file>
<file>application/scalable/actions/auto-type.svg</file>
<file>application/scalable/actions/bitwarden.svg</file>
<file>application/scalable/actions/bugreport.svg</file>
<file>application/scalable/actions/chevron-double-down.svg</file>
<file>application/scalable/actions/chevron-double-right.svg</file>
<file>application/scalable/actions/clipboard-text.svg</file>
<file>application/scalable/actions/configure.svg</file>
<file>application/scalable/actions/csv.svg</file>
<file>application/scalable/actions/database-change-key.svg</file>
<file>application/scalable/actions/database-lock.svg</file>
<file>application/scalable/actions/database-lock-all.svg</file>
@ -58,6 +60,7 @@
<file>application/scalable/actions/move-up.svg</file>
<file>application/scalable/actions/object-locked.svg</file>
<file>application/scalable/actions/object-unlocked.svg</file>
<file>application/scalable/actions/onepassword.svg</file>
<file>application/scalable/actions/paperclip.svg</file>
<file>application/scalable/actions/passkey.svg</file>
<file>application/scalable/actions/password-copy.svg</file>

View file

@ -1256,14 +1256,6 @@ Do you want to overwrite the Passkey in %1 - %2?</source>
</context>
<context>
<name>CsvImportWidget</name>
<message>
<source>Import CSV fields</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>filename</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>size, rows, columns</source>
<translation type="unfinished"></translation>
@ -1372,18 +1364,6 @@ Do you want to overwrite the Passkey in %1 - %2?</source>
<source>Column %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Imported from CSV file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Original data: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error(s) detected in CSV file!</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
<source>[%n more message(s) skipped]</source>
<translation type="unfinished">
@ -1392,31 +1372,19 @@ Do you want to overwrite the Passkey in %1 - %2?</source>
</translation>
</message>
<message>
<source>Error</source>
<source>Failed to parse CSV file: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>CSV import: writer has errors:
%1</source>
<source>Imported from CSV file: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CsvParserModel</name>
<message>
<source>%1, %2, %3</source>
<comment>file info: bytes, rows, columns</comment>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
<source>%n byte(s)</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%n row(s)</source>
<comment>CSV row count</comment>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
@ -1424,6 +1392,7 @@ Do you want to overwrite the Passkey in %1 - %2?</source>
</message>
<message numerus="yes">
<source>%n column(s)</source>
<comment>CSV column count</comment>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
@ -1800,6 +1769,10 @@ Permissions to access entries will be revoked.</source>
This is only necessary if your database is a copy of another and the browser extension cannot connect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Convert legacy KeePassHTTP attributes to KeePassXC-Browser compatible custom data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No keys found</source>
<translation type="unfinished"></translation>
@ -2287,26 +2260,10 @@ This is definitely a bug, please report it to the developers.</source>
<source>CSV file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select CSV file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Merge database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>KeePass 1 database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open KeePass 1 database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open OPVault</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Export database to CSV file</source>
<translation type="unfinished"></translation>
@ -2339,15 +2296,6 @@ This is definitely a bug, please report it to the developers.</source>
<source>You are about to export your database to an unencrypted file. This will leave your passwords and sensitive information vulnerable! Are you sure you want to continue?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New Database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>%1 [New Database]</source>
<comment>Database tab name modifier</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>%1 [Locked]</source>
<comment>Database tab name modifier</comment>
@ -2536,6 +2484,15 @@ Disable safe saves and try again?</source>
<source>Could not find database file: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New Database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>%1 [New Database]</source>
<comment>Database tab name modifier</comment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditEntryWidget</name>
@ -4299,6 +4256,147 @@ You can enable the DuckDuckGo website icon service in the security section of th
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportWizard</name>
<message>
<source>Import Wizard</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportWizardPageReview</name>
<message>
<source>WizardPage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Entry count: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Group</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Title</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Username</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Password</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Url</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportWizardPageSelect</name>
<message>
<source>Form</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import File Selection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Password:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Key File:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Browse</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import Into:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New Database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No unlocked databases available</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Existing Database:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import File:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Comma Separated Values (.csv)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>1Password Export (.1pux)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>1Password Vault (.opvault)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Bitwarden (.json)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>KeePass 1 Database (.kdb)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open OPVault</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select import file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>All files</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Key files</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select key file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Comma Separated Values</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>1Password Export</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Bitwarden JSON Export</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>1Password Vault</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>KeePass1 Database</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>KMessageWidget</name>
<message>
@ -4726,17 +4824,6 @@ Line %2, column %3</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>KeePass1OpenWidget</name>
<message>
<source>Import KeePass1 Database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to open the database.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>KeePass1Reader</name>
<message>
@ -5090,10 +5177,6 @@ Are you sure you want to continue with this file?</source>
<source>&amp;Recent Databases</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Import</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;Export</source>
<translation type="unfinished"></translation>
@ -5500,6 +5583,18 @@ We recommend you use the AppImage available on our downloads page.</source>
<source>Allow Screen Capture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>1Password 1PUX...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import a 1Password 1PUX file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Passkeys</source>
<translation type="unfinished"></translation>
@ -5948,14 +6043,6 @@ We recommend you use the AppImage available on our downloads page.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>OpVaultOpenWidget</name>
<message>
<source>Read Database did not produce an instance
%1</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>OpVaultReader</name>
<message>
@ -8485,6 +8572,76 @@ Kernel: %3 %4</source>
<source>Failed to decrypt key data.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Favorite</source>
<comment>Tag for favorite entries</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>File does not exist.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cannot open file: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cannot parse file: %1 at position %2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to decrypt json file: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Invalid encKeyValidation field</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Invalid cipher list within encKeyValidation field</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Wrong password</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Invalid encrypted data field</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Invalid cipher list within encrypted data field</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cannot initialize cipher</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cannot decrypt data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Bitwarden Import</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Archived</source>
<comment>Tag for archived entries</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Invalid 1PUX file format: Not a valid ZIP file.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Invalid 1PUX file format: Missing export.data</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>1Password Import</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Origin is empty or not allowed</source>
<translation type="unfinished"></translation>
@ -9577,26 +9734,6 @@ Example: JBSWY3DPEHPK3PXP</source>
<source>Start storing your passwords securely in a KeePassXC database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Create new database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open existing database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import from KeePass 1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import from 1Password</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import from CSV</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Recent databases</source>
<translation type="unfinished"></translation>
@ -9609,6 +9746,18 @@ Example: JBSWY3DPEHPK3PXP</source>
<source>Welcome to KeePassXC %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Create Database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open Database</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import File</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>WinUtils</name>