Add key exporting to account settings
This commit is contained in:
parent
11486ab51d
commit
a87f98fae0
1
TODO.md
1
TODO.md
|
@ -121,7 +121,6 @@
|
|||
- Edit/delete own devices
|
||||
- Request room keys from own other devices
|
||||
- Auto-trust accounts within the same client
|
||||
- Export keys
|
||||
- Uploads & proper http thumbnails
|
||||
- Reduce messages ListView cacheBuffer height once http thumbnails
|
||||
downloading is implemented
|
||||
|
|
|
@ -338,6 +338,17 @@ class MatrixClient(nio.AsyncClient):
|
|||
await self.retry_decrypting_events()
|
||||
|
||||
|
||||
async def export_keys(self, outfile: str, passphrase: str) -> None:
|
||||
path = Path(outfile)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Remove any existing file
|
||||
# (the QML dialog asks the user if he wants to overwrite before this)
|
||||
path.unlink()
|
||||
|
||||
await super().export_keys(outfile, passphrase)
|
||||
|
||||
|
||||
async def clear_import_error(self) -> None:
|
||||
self.models[Account][self.user_id].import_error = ("", "", "")
|
||||
|
||||
|
|
|
@ -28,10 +28,10 @@ Popup {
|
|||
|
||||
|
||||
function verifyPassword(pass, callback) {
|
||||
// Implement this function when using this component.
|
||||
// Return true on success, false on invalid password, or
|
||||
// Can be reimplemented when using this component.
|
||||
// Pass to the callback true on success, false on invalid password, or
|
||||
// a [error message, translated] array for any other error.
|
||||
return ["Verification not implemented", false]
|
||||
callback(true)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,19 @@ HLoader {
|
|||
property bool importing: false
|
||||
|
||||
|
||||
function exportKeys(file, passphrase, button=null) {
|
||||
if (button) button.loading = true
|
||||
|
||||
let path = file.toString().replace(/^file:\/\//, "")
|
||||
|
||||
py.callClientCoro(
|
||||
editAccount.userId, "export_keys", [path, passphrase], () => {
|
||||
// null: user is on another page
|
||||
if (encryptionUI !== null && button) button.loading = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function importKeys(file, passphrase, button=null) {
|
||||
if (button) button.loading = true
|
||||
encryptionUI.importing = true
|
||||
|
@ -22,7 +35,7 @@ HLoader {
|
|||
|
||||
py.callClientCoro(
|
||||
editAccount.userId, "import_keys", [path, passphrase], () => {
|
||||
if (encryptionUI !== null) { // null: user is on another page
|
||||
if (encryptionUI !== null) {
|
||||
encryptionUI.importing = false
|
||||
if (button) button.loading = false
|
||||
}
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import Qt.labs.platform 1.1
|
||||
import "../../Base"
|
||||
import "../../utils.js" as Utils
|
||||
|
||||
HBox {
|
||||
property var exportButton: null
|
||||
|
||||
horizontalSpacing: currentSpacing
|
||||
verticalSpacing: currentSpacing
|
||||
|
||||
buttonModel: [
|
||||
{ name: "export", text: qsTr("Export"), iconName: "export-keys",
|
||||
enabled: false },
|
||||
{ name: "export", text: qsTr("Export"), iconName: "export-keys"},
|
||||
{ name: "import", text: qsTr("Import"), iconName: "import-keys"},
|
||||
]
|
||||
|
||||
buttonCallbacks: ({
|
||||
export: button => {},
|
||||
import: button => { fileDialog.dialog.open() },
|
||||
export: button => {
|
||||
exportButton = button
|
||||
exportFileDialog.dialog.open()
|
||||
},
|
||||
import: button => { importFileDialog.dialog.open() },
|
||||
})
|
||||
|
||||
|
||||
|
@ -24,29 +29,49 @@ HBox {
|
|||
wrapMode: Text.Wrap
|
||||
text: qsTr(
|
||||
"The decryption keys for messages you received in encrypted " +
|
||||
"rooms can be exported to a passphrase-protected file.%1" +
|
||||
"You will then be able to import this file in another " +
|
||||
"Matrix client."
|
||||
).arg(pageLoader.isWide ? "\n" :"\n\n")
|
||||
"rooms can be exported to a passphrase-protected file.\n" +
|
||||
"You can then import this file on another Matrix account or " +
|
||||
"client, to be able to decrypt these messages again."
|
||||
)
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
HFileDialogOpener {
|
||||
id: fileDialog
|
||||
id: exportFileDialog
|
||||
fill: false
|
||||
dialog.title: qsTr("Select a decryption key file to import")
|
||||
dialog.title: qsTr("Save decryption keys file as...")
|
||||
dialog.fileMode: FileDialog.SaveFile
|
||||
onFileChanged: {
|
||||
exportPasswordPopup.file = file
|
||||
exportPasswordPopup.open()
|
||||
}
|
||||
}
|
||||
|
||||
HFileDialogOpener {
|
||||
id: importFileDialog
|
||||
fill: false
|
||||
dialog.title: qsTr("Select a decryption keys file to import")
|
||||
onFileChanged: {
|
||||
importPasswordPopup.file = file
|
||||
importPasswordPopup.open()
|
||||
}
|
||||
}
|
||||
|
||||
HPasswordPopup {
|
||||
property url file: ""
|
||||
|
||||
id: exportPasswordPopup
|
||||
label.text: qsTr("Please enter a passphrase to protect this file:")
|
||||
onAcceptedPasswordChanged:
|
||||
encryptionUI.exportKeys(file, acceptedPassword, exportButton)
|
||||
}
|
||||
|
||||
HPasswordPopup {
|
||||
property url file: ""
|
||||
|
||||
function verifyPassword(pass, callback) {
|
||||
return py.callCoro(
|
||||
py.callCoro(
|
||||
"check_exported_keys_passphrase",
|
||||
[file.toString().replace(/^file:\/\//, ""), pass],
|
||||
callback
|
||||
|
|
Loading…
Reference in New Issue
Block a user