mirror of
https://github.com/QRouland/UTPass.git
synced 2025-04-21 21:46:31 +00:00
Compare commits
No commits in common. "0cf07b1b7ad0acb14e882841ed01595d357a9994" and "ba52ddac5cf202799cd58179b53843a5af6a16db" have entirely different histories.
0cf07b1b7a
...
ba52ddac5c
24
CHANGELOG.md
24
CHANGELOG.md
@ -1,24 +0,0 @@
|
||||
# 0.0.3: Git Initial Support and Move to RNP
|
||||
- Port app to Focal
|
||||
- Improve UI :
|
||||
- Follow human interface guidelines
|
||||
- Fix various components color to work with black theme
|
||||
- Rewrite of Pass Plugin:
|
||||
- Move from GPGMe to RNP for GPG operations due to issues running GPG agent in a confined app
|
||||
- Improve multithreading code for GPG operations
|
||||
- Add Git HTTP and HTTP AUTH clone for password store import feature
|
||||
- Add delete password store feature
|
||||
|
||||
# 0.0.2 : Added translations
|
||||
- Added French by Anne17 and Reda
|
||||
- Added Catalan by Joan CiberSheep
|
||||
- Added Spanish by Advocatux and Reda
|
||||
|
||||
Thanks to all the translators !
|
||||
|
||||
# 0.0.1 : Initial Release
|
||||
- Import of gpg keys via file
|
||||
- Suppression of gpg keys
|
||||
- Import of password via a password store zip
|
||||
- Password decryption
|
||||
- Password copy to clipboard
|
13
README.md
13
README.md
@ -20,13 +20,10 @@ Assuming that there are already passwords in another device using [ZX2C4’s pas
|
||||
|
||||
Export gpg private keys in order to decrypt passwords:
|
||||
```
|
||||
gpg --output keys.gpg --export-secret-keys <key>
|
||||
gpg --output keys.gpg --export-secret-keys
|
||||
```
|
||||
|
||||
If your password store is already hosted in a Git repository that provides HTTP or HTTP with authentication for cloning (we're working to have support for SSH soon), you can clone your password store directly from the app.
|
||||
Otherwise, follow these steps to export it to a ZIP file for importing.
|
||||
|
||||
Export passwords to a ZIP archive, assuming they reside in the *.password-store* folder:
|
||||
Export passwords, assuming they reside in *.password-store* folder:
|
||||
```
|
||||
zip passwords.zip -r .password-store/
|
||||
```
|
||||
@ -47,9 +44,11 @@ See [Contributing wiki page](https://github.com/QRouland/UTPass/wiki/Contributin
|
||||
|
||||
Some useful links related to UTPass development :
|
||||
* [Ubports](https://ubports.com/) : Ubuntu Touch Community
|
||||
* [ZX2C4’s pass command line application](https://www.passwordstore.org/) : The standard unix password manager.
|
||||
* [ZX2C4’s pass command line application](https://www.passwordstore.org/) : the standard unix password manager.
|
||||
* [Clickable](https://github.com/bhdouglass/clickable) : Compile, build, and deploy Ubuntu Touch click packages
|
||||
* [Rnp](https://github.com/rnpgp/rnp) : High performance C++ OpenPGP library used by Mozilla Thunderbird
|
||||
* [GnuPG](https://gnupg.org/): The GNU Privacy Guard
|
||||
* [Gpgme](https://www.gnupg.org/software/gpgme/index.html) : GnuPG Made Easy (GPGME) is a library designed to make access to GnuPG easier for applications
|
||||
|
||||
|
||||
## License
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
"content-hub": "UTPass.contenthub"
|
||||
}
|
||||
},
|
||||
"version": "0.0.3",
|
||||
"version": "0.0.3-dev",
|
||||
"maintainer": "Quentin Rouland <quentin@qrouland.com>",
|
||||
"framework" : "ubuntu-sdk-20.04"
|
||||
}
|
||||
|
@ -22,13 +22,13 @@ CloneJob::CloneJob(QString url, QString path, cred_type cred):
|
||||
void CloneJob::run()
|
||||
{
|
||||
auto tmp_dir = this->cloneSetup();
|
||||
auto ret = this->clone(this->m_url, tmp_dir.absolutePath(), this->m_cred, this->credentialsCB);
|
||||
if (ret) {
|
||||
auto err = this->clone(this->m_url, tmp_dir.absolutePath(), this->m_cred, this->credentialsCB);
|
||||
if (!err) {
|
||||
this->moveToDestination(tmp_dir, this->m_path);
|
||||
}
|
||||
this->cloneCleanUp(tmp_dir);
|
||||
this->cloneTearDown(tmp_dir);
|
||||
|
||||
emit resultReady(!ret); // TODO Clean error handling to return specifics errors for the ui
|
||||
emit resultReady(err); // TODO Clean error handling to return specifics errors for the ui
|
||||
}
|
||||
|
||||
|
||||
@ -37,26 +37,26 @@ QDir CloneJob::cloneSetup()
|
||||
QDir tmp_dir(QStandardPaths::writableLocation( QStandardPaths::CacheLocation).append("/clone"));
|
||||
|
||||
tmp_dir.removeRecursively();
|
||||
qDebug() << "[CloneJob]Temp dir path is " << tmp_dir.absolutePath();
|
||||
qDebug() << "Temp dir path is " << tmp_dir.absolutePath();
|
||||
|
||||
return tmp_dir;
|
||||
}
|
||||
|
||||
|
||||
bool CloneJob::cloneCleanUp(QDir tmp_dir)
|
||||
bool CloneJob::cloneTearDown(QDir tmp_dir)
|
||||
{
|
||||
return tmp_dir.removeRecursively();
|
||||
}
|
||||
|
||||
bool CloneJob::moveToDestination(QDir tmp_dir, QString path)
|
||||
{
|
||||
qDebug() << "[CloneJob] Removing password_store " << path;
|
||||
qDebug() << "Removing password_store " << path;
|
||||
QDir destination_dir(path);
|
||||
destination_dir.removeRecursively();
|
||||
|
||||
qDebug() << "[CloneJob] Moving cloned content to destination dir";
|
||||
qDebug() << "Moving cloned content to destination dir";
|
||||
QDir dir;
|
||||
qDebug() << "[CloneJob]" << tmp_dir.absolutePath() << " to " << destination_dir.absolutePath();
|
||||
qDebug() << tmp_dir.absolutePath() << " to " << destination_dir.absolutePath();
|
||||
return dir.rename(tmp_dir.absolutePath(), destination_dir.absolutePath()); // TODO Better error handling
|
||||
}
|
||||
|
||||
@ -69,17 +69,12 @@ bool CloneJob::clone(QString url, QString path, cred_type cred, git_cred_acquire
|
||||
opts.fetch_opts.callbacks.payload = &cred;
|
||||
|
||||
int ret = git_clone(&repo, url.toLocal8Bit().data(), path.toLocal8Bit().data(), &opts);
|
||||
if (ret == GIT_EUSER ) {
|
||||
qDebug() << "[CloneJob] CallBack Error";
|
||||
} else if (ret != 0) {
|
||||
auto err = git_error_last(); // TODO Better error handling for return ui messages
|
||||
if (err) {
|
||||
qDebug() << "[CloneJob]" << git_error_last()->message;
|
||||
}
|
||||
if (ret != 0) {
|
||||
qDebug() << git_error_last()->message;
|
||||
}
|
||||
if (repo) {
|
||||
git_repository_free(repo);
|
||||
}
|
||||
return ret == 0;
|
||||
}// TODO Better error handling
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ private:
|
||||
* @param tmp_dir The temporary directory to tear down.
|
||||
* @return `true` if the teardown was successful, `false` otherwise.
|
||||
*/
|
||||
static bool cloneCleanUp(QDir tmp_dir);
|
||||
static bool cloneTearDown(QDir tmp_dir);
|
||||
|
||||
/**
|
||||
* @brief Clones a repository from a specified URL.
|
||||
|
@ -25,27 +25,27 @@ int GitJob::credentialsCB(git_cred **out, const char *url, const char *username_
|
||||
auto v = overload {
|
||||
[](const HTTP & x)
|
||||
{
|
||||
qDebug() << "[GitJob] credentialsCB : HTTP ";
|
||||
qWarning() << "[GitJob] credentialsCB : callback should never be call for HTTP ";
|
||||
qDebug() << "credentialsCB : HTTP ";
|
||||
qWarning() << "credentialsCB : callback should never be call for HTTP ";
|
||||
return (int) GIT_EUSER;
|
||||
},
|
||||
[&out, &username_from_url](const HTTPUserPass & x)
|
||||
{
|
||||
qDebug() << "[GitJob] credentialsCB : HTTPUserPass ";
|
||||
qDebug() << "credentialsCB : HTTPUserPass ";
|
||||
if (!username_from_url) {
|
||||
qWarning() << "[GitJob] credentials_cb : no username provided ";
|
||||
qWarning() << "credentials_cb : no username provided ";
|
||||
return (int) GIT_EUSER;
|
||||
}
|
||||
return git_cred_userpass_plaintext_new(out, username_from_url, x.pass.toLocal8Bit().constData());
|
||||
},
|
||||
[](const SSHPass & x)
|
||||
{
|
||||
qWarning() << "[GitJob] credentials_cb : SSHAuth to be implemented ";
|
||||
qWarning() << "credentials_cb : SSHAuth to be implemented ";
|
||||
return (int) GIT_EUSER;
|
||||
}, // TODO
|
||||
[](const SSHKey & x)
|
||||
{
|
||||
qWarning() << "[GitJob] credentials_cb : SSHKey to be implemented ";
|
||||
qWarning() << "credentials_cb : SSHKey to be implemented ";
|
||||
return (int) GIT_EUSER;
|
||||
} // TODO
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ void DecryptJob::run()
|
||||
ret = rnp_output_memory_get_buf(output, &buf, &buf_len, false);
|
||||
}
|
||||
if (ret == RNP_SUCCESS) {
|
||||
data = QString::fromUtf8((char*)buf, buf_len);
|
||||
data = QString::fromUtf8((char*)buf);
|
||||
}
|
||||
|
||||
rnp_input_destroy(input);
|
||||
|
@ -95,12 +95,12 @@ void Pass::slotShowSucceed(QString encrypted_file_path, QString plain_text)
|
||||
|
||||
bool Pass::deletePasswordStore()
|
||||
{
|
||||
qInfo() << "[Pass] Delete Password Store at" << this->m_password_store;
|
||||
qInfo() << "[Pass] Delete Password Store at" << this->password_store();
|
||||
if (!this->m_sem->tryAcquire(1, 500)) {
|
||||
qInfo() << "[Pass] A command is already running";
|
||||
return false;
|
||||
}
|
||||
auto job = new RmJob(this->m_password_store);
|
||||
auto job = new RmJob(this->password_store());
|
||||
connect(job, &RmJob::resultReady, this, &Pass::slotDeletePasswordStoreResult);
|
||||
connect(job, &RmJob::finished, job, &QObject::deleteLater);
|
||||
job->start();
|
||||
@ -109,7 +109,6 @@ bool Pass::deletePasswordStore()
|
||||
|
||||
void Pass::slotDeletePasswordStoreResult(bool err)
|
||||
{
|
||||
this->initPasswordStore(); // reinit an empty password-store
|
||||
if (err) {
|
||||
qInfo() << "[Pass] delete Password Store Failed";
|
||||
emit deletePasswordStoreFailed("failed to delete password store");
|
||||
|
@ -22,8 +22,8 @@ extern "C" {
|
||||
class Pass : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString password_store MEMBER m_password_store WRITE set_password_store )
|
||||
Q_PROPERTY(QString gpg_home MEMBER m_gpg_home WRITE set_gpg_home )
|
||||
Q_PROPERTY(QString password_store MEMBER m_password_store READ password_store WRITE set_password_store )
|
||||
Q_PROPERTY(QString gpg_home MEMBER m_gpg_home READ gpg_home WRITE set_gpg_home )
|
||||
|
||||
private slots:
|
||||
/**
|
||||
@ -166,6 +166,15 @@ public:
|
||||
*/
|
||||
Pass();
|
||||
|
||||
/**
|
||||
* @brief Gets the path to the password store.
|
||||
* @return The path to the password store.
|
||||
*/
|
||||
QString password_store() const
|
||||
{
|
||||
return this->m_password_store;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set the path to the password store.
|
||||
* @param The path to the password store.
|
||||
@ -176,6 +185,15 @@ public:
|
||||
this->m_password_store = password_store;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Gets the path to the gpg home.
|
||||
* @return The path to the gpg home.
|
||||
*/
|
||||
QString gpg_home() const
|
||||
{
|
||||
return this->m_gpg_home;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set the path to the gpg hom.
|
||||
* @param The path to the gpg hom
|
||||
|
@ -52,5 +52,6 @@ void UnzipJob::run()
|
||||
qDebug() << dir_import_path << " to " << this->m_dir_out;
|
||||
auto ret = dir.rename(dir_import_path, this->m_dir_out.absolutePath());
|
||||
tmp_dir.removeRecursively();;
|
||||
emit resultReady(!ret);
|
||||
emit resultReady(ret);
|
||||
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ void Utils::unzipResult(bool err)
|
||||
qDebug() << "Unzip Result";
|
||||
if (err) {
|
||||
qInfo() << "Unzip Failed";
|
||||
emit unzipFailed();
|
||||
emit unzipFailed("failed to unzip archive");
|
||||
|
||||
} else {
|
||||
qInfo() << "Unzip Succeed";
|
||||
@ -45,14 +45,3 @@ QString Utils::manifestPath()
|
||||
qInfo() << "Manifest path : " << path;
|
||||
return path;
|
||||
}
|
||||
|
||||
bool Utils::rmFile(QUrl file_url)
|
||||
{
|
||||
return QFile::remove(file_url.toLocalFile());
|
||||
}
|
||||
|
||||
bool Utils::rmDir(QUrl dir_url)
|
||||
{
|
||||
QDir dir(dir_url.toLocalFile());
|
||||
return dir.removeRecursively();
|
||||
}
|
||||
|
@ -34,8 +34,9 @@ signals:
|
||||
|
||||
/**
|
||||
* @brief Emitted when the unzipping operation fails.
|
||||
* @param message The error message describing the failure.
|
||||
*/
|
||||
void unzipFailed();
|
||||
void unzipFailed(QString message);
|
||||
|
||||
private:
|
||||
std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing concurrent operations. */
|
||||
@ -47,14 +48,19 @@ public:
|
||||
Utils();
|
||||
|
||||
/**
|
||||
* @brief Start a job to unzips a ZIP file to the specified output directory.
|
||||
* @brief Unzips a ZIP file to the specified output directory.
|
||||
*
|
||||
* This method extracts the contents of a ZIP file from the specified URL and saves them to the provided
|
||||
* output directory path.
|
||||
*
|
||||
* @param zip_url The URL of the ZIP file to unzip.
|
||||
* @param dir_out The output directory where the contents of the ZIP file should be extracted.
|
||||
* @return `true` if the unzipping job is started successfullly, `false` otherwise.
|
||||
* @return `true` if the unzipping operation was successful, `false` otherwise.
|
||||
*/
|
||||
Q_INVOKABLE bool unzip(QUrl zip_url, QString dir_out);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Retrieves the path to the manifest data.
|
||||
*
|
||||
@ -64,22 +70,6 @@ public:
|
||||
*/
|
||||
Q_INVOKABLE QString manifestPath();
|
||||
|
||||
/**
|
||||
* @brief Removes a file located at the specified URL.
|
||||
*
|
||||
* @param file_url The URL of the file to remove.
|
||||
* @return `true` if the file was successfully removed; `false` otherwise.
|
||||
*/
|
||||
Q_INVOKABLE bool rmFile(QUrl file_url);
|
||||
|
||||
/**
|
||||
* @brief Removes a directory located at the specified URL.
|
||||
*
|
||||
* @param dir_url The URL of the directory to remove.
|
||||
* @return `true` if the directory was successfully removed; `false` otherwise.
|
||||
*/
|
||||
Q_INVOKABLE bool rmDir(QUrl dir_url);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: utpass.qrouland\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-02-04 17:49+0100\n"
|
||||
"POT-Creation-Date: 2025-02-03 21:35+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -122,8 +122,8 @@ msgid "You're are about to delete<br>the current Password Store.<br>Continue ?"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/DeleteRepo.qml:56
|
||||
#: ../qml/pages/settings/ImportZip.qml:66
|
||||
#: ../qml/pages/settings/InfoKeys.qml:174
|
||||
#: ../qml/pages/settings/ImportZip.qml:64
|
||||
#: ../qml/pages/settings/InfoKeys.qml:170
|
||||
#: ../qml/pages/settings/git/ImportGitClone.qml:56
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
@ -137,37 +137,37 @@ msgid "Password Store deleted !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/DeleteRepo.qml:90
|
||||
#: ../qml/pages/settings/InfoKeys.qml:216
|
||||
#: ../qml/pages/settings/InfoKeys.qml:212
|
||||
msgid "Info Keys"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/ImportKeyFile.qml:61
|
||||
#: ../qml/pages/settings/ImportKeyFile.qml:59
|
||||
msgid "Key import failed !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/ImportKeyFile.qml:70
|
||||
#: ../qml/pages/settings/ImportKeyFile.qml:68
|
||||
msgid "Key successfully imported !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/ImportKeyFile.qml:81
|
||||
#: ../qml/pages/settings/ImportKeyFile.qml:79
|
||||
msgid "GPG Key Import"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/ImportZip.qml:65
|
||||
#: ../qml/pages/settings/ImportZip.qml:63
|
||||
msgid ""
|
||||
"Importing a new zip will delete<br>any existing password store!<br>Continue ?"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/ImportZip.qml:79
|
||||
#: ../qml/pages/settings/ImportZip.qml:77
|
||||
msgid "Password store import failed !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/ImportZip.qml:88
|
||||
#: ../qml/pages/settings/ImportZip.qml:86
|
||||
#: ../qml/pages/settings/git/ImportGitClone.qml:78
|
||||
msgid "Password store sucessfully imported !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/ImportZip.qml:100
|
||||
#: ../qml/pages/settings/ImportZip.qml:98
|
||||
msgid "Zip Password Store Import"
|
||||
msgstr ""
|
||||
|
||||
@ -179,27 +179,27 @@ msgstr ""
|
||||
msgid "Key ID :"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:124
|
||||
msgid "User IDs : "
|
||||
#: ../qml/pages/settings/InfoKeys.qml:120
|
||||
msgid "Users IDs : "
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:151
|
||||
#: ../qml/pages/settings/InfoKeys.qml:147
|
||||
msgid "Delete this key"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:173
|
||||
#: ../qml/pages/settings/InfoKeys.qml:169
|
||||
msgid "You're are about to delete<br>%1.<br>Continue ?"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:187
|
||||
#: ../qml/pages/settings/InfoKeys.qml:183
|
||||
msgid "Key removal failed !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:196
|
||||
#: ../qml/pages/settings/InfoKeys.qml:192
|
||||
msgid "Key successfully deleted !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:208
|
||||
#: ../qml/pages/settings/InfoKeys.qml:204
|
||||
msgid "An Error occured getting GPG keys !"
|
||||
msgstr ""
|
||||
|
||||
|
@ -19,14 +19,12 @@ Item {
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: theme.palette.normal.background
|
||||
|
||||
Text {
|
||||
text: copyText.text
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: units.gu(2)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: theme.palette.normal.backgroundText
|
||||
}
|
||||
|
||||
Icon {
|
||||
|
@ -14,7 +14,7 @@ Component {
|
||||
color: theme.palette.normal.background
|
||||
|
||||
Text {
|
||||
text: fileIsDir ? fileName : fileName.slice(0, -4) // remove .gpg if it's a file
|
||||
text: fileBaseName
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: units.gu(2)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
@ -26,7 +26,6 @@ Page {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
color: theme.palette.normal.background
|
||||
|
||||
Flow {
|
||||
id: container
|
||||
|
@ -77,8 +77,8 @@ Page {
|
||||
SuccessDialog {
|
||||
textSuccess: i18n.tr("Password Store deleted !")
|
||||
onDialogClosed: {
|
||||
pageStack.clear();
|
||||
pageStack.push(Qt.resolvedUrl("../PasswordList.qml"));
|
||||
pageStack.pop();
|
||||
pageStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,12 +30,10 @@ Page {
|
||||
console.log(importKeyFilePage.activeTransfer.items[0].url);
|
||||
var status = Pass.importGPGKey(importKeyFilePage.activeTransfer.items[0].url);
|
||||
Pass.importGPGKeySucceed.connect(function() {
|
||||
Utils.rmFile(importKeyFilePage.activeTransfer.items[0].url);
|
||||
importKeyFilePage.activeTransfer = null;
|
||||
PopupUtils.open(dialogImportKeyPageSucess);
|
||||
});
|
||||
Pass.importGPGKeyFailed.connect(function(message) {
|
||||
Utils.rmFile(importKeyFilePage.activeTransfer.items[0].url);
|
||||
importKeyFilePage.activeTransfer = null;
|
||||
PopupUtils.open(dialogImportKeyPageError);
|
||||
});
|
||||
|
@ -32,14 +32,12 @@ Page {
|
||||
if (importZipPage.activeTransfer.state === ContentTransfer.Charged) {
|
||||
console.log("Charged");
|
||||
console.log(importZipPage.activeTransfer.items[0].url);
|
||||
var status = Utils.unzip(importZipPage.activeTransfer.items[0].url, Pass.password_store);
|
||||
var status = Utils.unzip(importZipPage.activeTransfer.items[0].url, Pass.getPasswordStore());
|
||||
Utils.unzipSucceed.connect(function() {
|
||||
Utils.rmFile(importZipPage.activeTransfer.items[0].url);
|
||||
importZipPage.activeTransfer = null;
|
||||
PopupUtils.open(dialogImportZipPageSuccess);
|
||||
});
|
||||
Utils.unzipFailed.connect(function() {
|
||||
Utils.rmFile(importZipPage.activeTransfer.items[0].url);
|
||||
Utils.unzipFailed.connect(function(message) {
|
||||
importZipPage.activeTransfer = null;
|
||||
PopupUtils.open(dialogImportZipPageError);
|
||||
});
|
||||
@ -87,8 +85,8 @@ Page {
|
||||
SuccessDialog {
|
||||
textSuccess: i18n.tr("Password store sucessfully imported !")
|
||||
onDialogClosed: {
|
||||
pageStack.clear();
|
||||
pageStack.push(Qt.resolvedUrl("../PasswordList.qml"));
|
||||
pageStack.pop();
|
||||
pageStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,10 +89,11 @@ Page {
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: {
|
||||
if (!model.modelData)
|
||||
if (!model.modelData) {
|
||||
"";
|
||||
else
|
||||
} else {
|
||||
model.modelData.keyid;
|
||||
}
|
||||
}
|
||||
color: theme.palette.normal.backgroundText
|
||||
}
|
||||
@ -121,7 +122,7 @@ Page {
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: i18n.tr('User IDs : ')
|
||||
text: i18n.tr('Users IDs : ')
|
||||
color: theme.palette.normal.backgroundText
|
||||
}
|
||||
|
||||
|
@ -77,8 +77,8 @@ Page {
|
||||
SuccessDialog {
|
||||
textSuccess: i18n.tr("Password store sucessfully imported !")
|
||||
onDialogClosed: {
|
||||
pageStack.clear();
|
||||
pageStack.push(Qt.resolvedUrl("../../PasswordList.qml"));
|
||||
pageStack.pop();
|
||||
pageStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user