1
0
mirror of https://github.com/QRouland/UTPass.git synced 2025-04-21 21:46:31 +00:00

Compare commits

..

No commits in common. "399173b776fbb4ba364ae4895816e13ff792eb52" and "63d53caad5bbcb09d5a64ec64c1d6f81b1e8b8bd" have entirely different histories.

45 changed files with 477 additions and 808 deletions

View File

@ -5,7 +5,8 @@ suffix=none
--align-reference=name
--convert-tabs
--attach-namespaces
--max-code-length=120
--max-code-length=100
--max-instatement-indent=120
--pad-header
--pad-oper
--lineend=linux

View File

@ -3,10 +3,6 @@ cmake_minimum_required(VERSION 3.5.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
execute_process(
COMMAND dpkg-architecture -qDEB_HOST_ARCH
OUTPUT_VARIABLE CLICK_ARCH
@ -32,11 +28,10 @@ set(PROJECT_NAME "UTPass")
set(FULL_PROJECT_NAME "utpass.qrouland")
set(CMAKE_INSTALL_PREFIX /)
set(DATA_DIR /)
# set(BIN_DIR ${DATA_DIR}lib/bin)
set(DESKTOP_FILE_NAME ${PROJECT_NAME}.desktop)
add_executable(${PROJECT_NAME} main.cpp
qml/pages/settings/ImportGitClone.qml)
add_executable(${PROJECT_NAME} main.cpp)
qt5_use_modules(${PROJECT_NAME} Gui Qml Quick)
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
@ -46,6 +41,7 @@ configure_file(${CMAKE_CURRENT_BINARY_DIR}/manifest.json ${CMAKE_CURRENT_BINARY_
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest.json DESTINATION ${CMAKE_INSTALL_PREFIX})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest_.json DESTINATION ${DATA_DIR})
#install(DIRECTORY desktop DESTINATION ${DATA_DIR})
install(FILES ${PROJECT_NAME}.apparmor DESTINATION ${DATA_DIR})
install(FILES ${PROJECT_NAME}.contenthub DESTINATION ${DATA_DIR})
@ -53,6 +49,14 @@ install(FILES LICENSE DESTINATION ${DATA_DIR})
install(DIRECTORY qml DESTINATION ${DATA_DIR})
install(DIRECTORY assets DESTINATION ${DATA_DIR})
# file(GLOB_RECURSE BIN_FILES
# "/usr/bin/gpg*"
# )
# install(
# FILES ${BIN_FILES}
# PERMISSIONS OWNER_EXECUTE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
# DESTINATION ${BIN_DIR}
# )
# Translations
file(GLOB_RECURSE I18N_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/po qml/*.qml qml/*.js)

View File

@ -4,10 +4,9 @@ kill: UTPass
scripts:
style: >-
echo 'Astyle :' && astyle --options=.astylerc main.cpp && astyle --options=.astylerc --recursive 'plugins/*.cpp,*.h' && echo 'Running QmlFormat' && find . -name "*.qml" -exec qmlformat -i {} \; && echo 'Success'
echo 'Astyle :' && astyle --options=.astylerc main.cpp && astyle
--options=.astylerc --recursive 'plugins/*.cpp,*.h' && echo 'QmlFmt :' &&
qmlfmt -l tests && qmlfmt -w tests && qmlfmt -l qml && qmlfmt -w qml
dependencies_target:
- libgpgmepp-dev
@ -18,17 +17,12 @@ dependencies_target:
install_lib:
- "libgpg-error.so.0.28.0"
- "libassuan.so*"
- "libgpgme.so*"
- "libgpgmepp.so*"
- "libqgpgme.so*"
- "libgit2.so*"
- "libquazip5.so*"
- "libmbedtls.so*"
- "libmbedx509.so*"
- "libmbedcrypto.so*"
- "libhttp_parser.so*"
- "libssh2.so*"
- "libassuan.so"
- "libgpgme.so"
- "libgpgmepp.so"
- "libqgpgme.so.7"
- "libgit2.so"
- "libquazip5.so"
install_bin:
- "gpg"

View File

@ -1,3 +1,2 @@
add_subdirectory(Git)
add_subdirectory(Pass)
add_subdirectory(Utils)

View File

@ -1,37 +0,0 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(PLUGIN "Git")
set(
SRC
plugin.cpp
libgit.cpp
git.cpp
)
set(CMAKE_AUTOMOC ON)
execute_process(
COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
OUTPUT_VARIABLE ARCH_TRIPLET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(ARCH_TRIPLET STREQUAL "")
set(ARCH_TRIPLET x86_64-linux-gnu)
endif()
add_library(${PLUGIN} MODULE ${SRC})
set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN})
qt5_use_modules(${PLUGIN} Qml Quick DBus)
add_library(libgit2 SHARED IMPORTED)
set_property(TARGET libgit2 PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgit2.so")
target_link_libraries(${PLUGIN} libgit2)
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)
install(FILES qmldir DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)

View File

@ -1,34 +0,0 @@
#include <QUrl>
#include <QtCore/QDir>
#include <QDebug>
#include <QStandardPaths>
#include "git.h"
#include "libgit.h"
bool Git::clone(QString url, QString destination_dir_path)
{
qInfo() << "Cloning " << url << " to destination " << destination_dir_path;
QDir tmp_dir(QStandardPaths::writableLocation(
QStandardPaths::CacheLocation).append("/clone"));
tmp_dir.removeRecursively();
tmp_dir.mkpath(".");
qDebug() << "Temp dir path is " << tmp_dir.absolutePath();
qDebug() << "Cloning " << url << " to tmp dir " << tmp_dir.absolutePath();
auto ret = LibGit::instance()->clone(url, tmp_dir.absolutePath()); // TODO Better error handling
if (ret) {
qDebug() << "Removing password_store " << destination_dir_path;
QDir destination_dir(destination_dir_path);
destination_dir.removeRecursively();
qDebug() << "Moving cloned content to destination dir";
QDir dir;
qDebug() << tmp_dir.absolutePath() << " to " << destination_dir.absolutePath();
ret = dir.rename(tmp_dir.absolutePath(), destination_dir.absolutePath()); // TODO Better error handling
}
//tmp_dir.removeRecursively();
return ret ;
}

View File

@ -1,20 +0,0 @@
#ifndef GIT_H
#define GIT_H
#include <QUrl>
#include <QObject>
class Git : public QObject
{
Q_OBJECT
public:
Git() = default;
~Git() override = default;
Q_INVOKABLE bool clone(QString url, QString path);
// Q_INVOKABLE bool update(QUrl url, QString path);
};
#endif

View File

@ -1,52 +0,0 @@
#include <QUrl>
#include <QDebug>
extern "C" {
#include <git2.h>
}
#include "libgit.h"
LibGit::LibGit()
{
git_libgit2_init();
}
LibGit::~LibGit()
{
git_libgit2_shutdown();
}
int LibGit::credentials_cb(git_cred **out, const char *url, const char *username_from_url,
unsigned int allowed_types, void *payload)
{
int error;
const char *user, *pass;
/*
* Ask the user via the UI. On error, store the information and return GIT_EUSER which will be
* bubbled up to the code performing the fetch or push. Using GIT_EUSER allows the application
* to know it was an error from the application instead of libgit2.
*/
// if ((error = ask_user(&user, &pass, url, username_from_url, allowed_types)) < 0) {
// store_error(error);
// return GIT_EUSER;
// }
// user = "user";
// pass = "pass";
// return git_cred_userpass_plaintext_new(out, user, pass);
return GIT_EUSER;
}
bool LibGit::clone(QString url, QString path)
{
git_repository *repo = NULL;
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
opts.fetch_opts.callbacks.credentials = *credentials_cb;
int ret = git_clone(&repo, url.toLocal8Bit().data(), path.toLocal8Bit().data(), &opts);
if (repo) {
git_repository_free(repo);
}
return ret == 0; // TODO Clean error handling to return specifics errors for the ui
}

View File

@ -1,32 +0,0 @@
#ifndef LIBGIT_H
#define LIBGIT_H
#include <QObject>
#include <QUrl>
extern "C" {
#include <git2/transport.h>
}
#include <memory>
class LibGit
{
private:
LibGit();
static int credentials_cb(git_cred **out, const char *url, const char *username_from_url,
unsigned int allowed_types, void *payload);
public:
~LibGit();
static std::shared_ptr<LibGit> instance()
{
static std::shared_ptr<LibGit> s{new LibGit};
return s;
}
LibGit(LibGit const &) = delete;
void operator=(LibGit const &) = delete;
bool clone(QString url, QString path);
};
#endif

View File

@ -1,10 +0,0 @@
#include <QtQml>
#include "plugin.h"
#include "git.h"
void GitPlugin::registerTypes(const char *uri)
{
//@uri Git
qmlRegisterSingletonType<Git>(uri, 1, 0, "Git", [](QQmlEngine *, QJSEngine *) -> QObject * { return new Git; });
}

View File

@ -1,16 +0,0 @@
#ifndef GITPLUGIN_H
#define GITPLUGIN_H
#include <QQmlExtensionPlugin>
class GitPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID
"org.qt-project.Qt.QQmlExtensionInterface")
public:
void registerTypes(const char *uri) override;
};
#endif

View File

@ -1,2 +0,0 @@
module Git
plugin Git

View File

@ -4,6 +4,7 @@ set(PLUGIN "Pass")
set(
SRC
plugin.cpp
git.cpp
pass.cpp
gpg.cpp
passkeymodel.h
@ -40,10 +41,13 @@ add_library(libgpgmepp SHARED IMPORTED)
set_property(TARGET libgpgmepp PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpgmepp.so")
add_library(libqgpgme SHARED IMPORTED)
set_property(TARGET libqgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libqgpgme.so")
set_property(TARGET libqgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libqgpgme.so.7")
target_link_libraries(${PLUGIN} gpgerror libassuan libgpgme libgpgmepp libqgpgme)
add_library(libgit2 SHARED IMPORTED)
set_property(TARGET libgit2 PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgit2.so")
target_link_libraries(${PLUGIN} gpgerror libassuan libgpgme libgpgmepp libgit2)
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")

26
plugins/Pass/git.cpp Normal file
View File

@ -0,0 +1,26 @@
#include <QDebug>
#include <QUrl>
extern "C" {
#include <git2.h>
}
#include "git.h"
Git::Git()
{
git_libgit2_init();
}
Git::~Git() {
git_libgit2_shutdown();
}
bool Git::clone(QString url)
{
return false;
}

27
plugins/Pass/git.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef GIT_H
#define GIT_H
#include <QObject>
#include <QUrl>
#include <memory>
class Git
{
private:
Git();
public:
~Git();
static std::shared_ptr<Git> instance()
{
static std::shared_ptr<Git> s{new Git};
return s;
}
Git(Git const &) = delete;
void operator=(Git const &) = delete;
bool clone(QString url);
};
#endif

View File

@ -63,8 +63,7 @@ QString Gpg::initGpgHome()
}
QString Gpg::findCommandPath(const QString &command)
{
QString Gpg::findCommandPath(const QString &command) {
// Retrieve the PATH environment variable
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
QString pathEnv = env.value("PATH");
@ -112,10 +111,10 @@ void Gpg::initGpgConfig()
agentConf.close();
auto err = gpgme_set_engine_info (
GPGME_PROTOCOL_OpenPGP,
exec.toLocal8Bit().data(),
home.toLocal8Bit().data()
);
GPGME_PROTOCOL_OpenPGP,
exec.toLocal8Bit().data(),
home.toLocal8Bit().data()
);
if (err != GPG_ERR_NO_ERROR) {
qDebug() << "Error code : " << err;
qDebug() << "Error str : " << gpg_strerror(err);
@ -199,13 +198,13 @@ Error Gpg::encryptToFile(QString str, QString path, QString uid, bool ascii_armo
QPair<Error, std::vector< GpgME::Key >> Gpg::getAllKeys ( bool remote, const bool include_sigs,
bool validate )
bool validate )
{
return getKeys(QString(""), remote, include_sigs, validate);
}
QPair<Error, std::vector<Key >> Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs,
bool validate)
QPair<Error, std::vector<Key>> Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs,
bool validate)
{
qDebug() << "Getting the keys " << pattern_uid;
auto job = std::unique_ptr<KeyListJob>(openpgp()->keyListJob(remote, include_sigs, validate));
@ -214,7 +213,7 @@ QPair<Error, std::vector<Key >> Gpg::getKeys(QString pattern_uid, bool remote, b
auto result = job->exec(QStringList() << pattern_uid, false, keys);
qDebug() << "Got the keys " << pattern_uid;
return QPair<Error, std::vector< Key >> (result.error(), keys);
return QPair<Error, std::vector< Key >>(result.error(), keys);
}

View File

@ -13,7 +13,6 @@ class Gpg
{
private:
Gpg();
QObject *m_window;
QString findCommandPath(const QString &command);
@ -22,6 +21,8 @@ private:
void initGpgConfig();
public:
~Gpg();
static std::shared_ptr<Gpg> instance()
{
static std::shared_ptr<Gpg> s{new Gpg};
@ -41,11 +42,11 @@ public:
};
QPair<Error, std::vector<Key >> getAllKeys(bool remote = false, bool include_sigs = {}, bool
validate = false);
QPair<Error, std::vector<Key >> getKeys( QString pattern_uid, bool remote = false,
bool include_sigs = false,
bool validate = false);
QPair< Error, std::vector< Key > > getAllKeys(bool remote = false, bool include_sigs = {}, bool
validate = false);
QPair<Error, std::vector<Key>> getKeys( QString pattern_uid, bool remote = false,
bool include_sigs = false,
bool validate = false);
QPair<Error, Key> getKey( QString uid, bool remote = false, bool include_sigs = false,
bool validate = false);
QPair<Error, QString> decrypt( QByteArray cipherText);

View File

@ -3,6 +3,7 @@
#include <QtCore/QDir>
#include "pass.h"
#include "git.h"
#include "gpg.h"
#include "passkeymodel.h"
@ -21,9 +22,8 @@ void Pass::init(QObject *window)
Gpg::instance()->setWindow(window);
QDir dir(m_password_store);
if (!dir.exists()) {
if (!dir.exists())
dir.mkpath(".");
}
qInfo() << "Password Store is :" << m_password_store;
}
@ -62,3 +62,13 @@ QVariant Pass::gpgGetAllKeysModel()
Gpg::instance()->getAllKeys().second));
}
QString Pass::getPasswordStore()
{
return m_password_store;
}
bool Pass::gitClone(QString url)
{
qInfo() << "Cloning . password_store from " << url;
return Git::instance()->clone(url);
}

View File

@ -9,9 +9,6 @@
class Pass : public QObject
{
Q_OBJECT
Q_PROPERTY(QString password_store READ password_store)
private:
QString m_password_store;
signals:
@ -19,20 +16,18 @@ signals:
void decryptCanceled();
void decryptFailed();
public:
Pass();
~Pass() override = default;
QString password_store() const
{
return m_password_store;
}
Q_INVOKABLE void init(QObject *window);
Q_INVOKABLE QString getPasswordStore();
Q_INVOKABLE void decrypt(QUrl url);
Q_INVOKABLE bool gpgDeleteKeyId(QString id);
Q_INVOKABLE bool gpgImportKeyFromFile(QUrl url);
Q_INVOKABLE QVariant gpgGetAllKeysModel();
Q_INVOKABLE bool gitClone(QString url);
};
#endif

View File

@ -7,6 +7,7 @@
#include <QEventLoop>
#include <QSemaphore>
#include <gpgme++/interfaces/passphraseprovider.h>
#include "passphraseprovider.h"
#include "gpg.h"

View File

@ -23,10 +23,6 @@ add_library(${PLUGIN} MODULE ${SRC})
set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN})
qt5_use_modules(${PLUGIN} Qml Quick DBus)
add_library(libquazip5 SHARED IMPORTED)
set_property(TARGET libquazip5 PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libquazip5.so")
target_link_libraries(${PLUGIN} libquazip5)
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")

View File

@ -7,6 +7,8 @@
#include "utils.h"
Utils::Utils() {};
bool Utils::unzip(QUrl zip_url, QString dir_out_path)
{
auto tmp_dir_path = QStandardPaths::writableLocation(
@ -29,7 +31,7 @@ bool Utils::unzip(QUrl zip_url, QString dir_out_path)
qDebug() << "Guessing if it should remove a single root folder";
QStringList files_in_tmp_dir = tmp_dir.entryList(QDir::AllEntries | QDir::Hidden |
QDir::NoDotAndDotDot);
QDir::NoDotAndDotDot);
auto dir_import_path =
files_in_tmp_dir.length() == 1 ?

View File

@ -10,7 +10,7 @@ class Utils : public QObject
Q_OBJECT
public:
Utils() = default;
Utils();
~Utils() override = default;
Q_INVOKABLE bool unzip(QUrl zip_url, QString dir_out);

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: utpass.qrouland\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-10 14:39+0100\n"
"POT-Creation-Date: 2025-01-07 13:36+0000\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"
@ -37,8 +37,8 @@ msgstr ""
msgid "Error !"
msgstr ""
#: ../qml/dialogs/ErrorDialog.qml:15
msgid "Close"
#: ../qml/dialogs/ErrorDialog.qml:15 ../qml/dialogs/SuccessDialog.qml:15
msgid "OK"
msgstr ""
#: ../qml/dialogs/PassphraseDialog.qml:7
@ -57,10 +57,6 @@ msgstr ""
msgid "Success !"
msgstr ""
#: ../qml/dialogs/SuccessDialog.qml:15
msgid "OK"
msgstr ""
#: ../qml/pages/Info.qml:11 ../qml/pages/headers/MainHeader.qml:58
msgid "Info"
msgstr ""
@ -107,37 +103,6 @@ msgstr ""
msgid "Settings"
msgstr ""
#: ../qml/pages/settings/ImportGitClone.qml:15
msgid "Git Clone Import"
msgstr ""
#: ../qml/pages/settings/ImportGitClone.qml:36
msgid "Repo Url"
msgstr ""
#: ../qml/pages/settings/ImportGitClone.qml:44
msgid "Git repo url"
msgstr ""
#: ../qml/pages/settings/ImportGitClone.qml:50
msgid "Clone"
msgstr ""
#: ../qml/pages/settings/ImportGitClone.qml:68
msgid ""
"Importing a git repo will delete<br>any existing password store!"
"<br>Continue ?"
msgstr ""
#: ../qml/pages/settings/ImportGitClone.qml:78
msgid "An error occured during git clone !"
msgstr ""
#: ../qml/pages/settings/ImportGitClone.qml:85
#: ../qml/pages/settings/ImportZip.qml:89
msgid "Password store sucessfully imported !"
msgstr ""
#: ../qml/pages/settings/ImportKeyFile.qml:17
msgid "GPG Key Import"
msgstr ""
@ -163,6 +128,10 @@ msgstr ""
msgid "Password store import failed !"
msgstr ""
#: ../qml/pages/settings/ImportZip.qml:89
msgid "Password store sucessfully imported !"
msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:16
msgid "Info Keys"
msgstr ""
@ -208,13 +177,9 @@ msgid "Password Store"
msgstr ""
#: ../qml/pages/settings/Settings.qml:47
msgid "Import a Password Store using Git"
msgstr ""
#: ../qml/pages/settings/Settings.qml:51
msgid "Import a Password Store Zip"
msgstr ""
#: ../qml/pages/settings/Settings.qml:60
#: ../qml/pages/settings/Settings.qml:56
msgid "Warning: importing delete any exiting Password Store"
msgstr ""

View File

@ -1,46 +1,49 @@
import QtQuick 2.4
import QtQuick.Layouts 1.1
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import Pass 1.0
import QtQuick 2.4
import QtQuick.Layouts 1.1
import "dialogs"
MainView {
id: root
objectName: "mainView"
applicationName: "utpass.qrouland"
automaticOrientation: false
width: units.gu(48)
height: units.gu(80)
signal responsePassphraseDialog(bool canceled, string passphrase)
function initPass(rootView) {
Pass.init(rootView);
Pass.init(rootView)
pageStack.push(Qt.resolvedUrl("pages/PasswordList.qml"));
}
function callPassphraseDialog(useridHint, description, previousWasBad) {
//TODO use parameters to impove passphrase dialog
var passphraseDialog = PopupUtils.open(Qt.resolvedUrl("dialogs/PassphraseDialog.qml"));
passphraseDialog.activateFocus();
var validated = function validated(passphrase) {
responsePassphraseDialog(false, passphrase);
};
var canceled = function canceled() {
responsePassphraseDialog(true, "");
};
passphraseDialog.validated.connect(validated);
passphraseDialog.canceled.connect(canceled);
}
var passphraseDialog = PopupUtils.open(
Qt.resolvedUrl("dialogs/PassphraseDialog.qml"))
passphraseDialog.activateFocus()
objectName: "mainView"
applicationName: "utpass.qrouland"
automaticOrientation: false
width: units.gu(48)
height: units.gu(80)
var validated = function (passphrase) {
responsePassphraseDialog(false, passphrase)
}
var canceled = function () {
responsePassphraseDialog(true, "")
}
passphraseDialog.validated.connect(validated)
passphraseDialog.canceled.connect(canceled)
}
PageStack {
id: pageStack
anchors.fill: parent
Component.onCompleted: {
}
}
Component.onCompleted: {}
}
}

View File

@ -1,11 +1,11 @@
import "../styles"
import Lomiri.Components 1.3
import QtQuick 2.4
import Lomiri.Components 1.3
import "../styles"
Item {
id: copyText
property string text
property bool commonBorder: true
property int lBorderwidth: 0
property int rBorderwidth: 0
@ -39,21 +39,20 @@ Item {
MouseArea {
anchors.fill: parent
onPressed: {
parent.color = LomiriColors.warmGrey;
parent.color = LomiriColors.warmGrey
}
onClicked: {
var mimeData = Clipboard.newData();
mimeData.text = copyText.text;
Clipboard.push(mimeData);
var mimeData = Clipboard.newData()
mimeData.text = copyText.text
Clipboard.push(mimeData)
}
onReleased: {
parent.color = theme.palette.normal.background;
parent.color = theme.palette.normal.background
}
}
CustomBorder {
id: cb
commonBorder: copyText.commonBorder
lBorderwidth: copyText.lBorderwidth
rBorderwidth: copyText.rBorderwidth
@ -61,7 +60,5 @@ Item {
bBorderwidth: copyText.bBorderwidth
borderColor: copyText.borderColor
}
}
}

View File

@ -1,12 +1,13 @@
import "../styles"
import Lomiri.Components 1.3
import QtQuick 2.4
import Lomiri.Components 1.3
import "../styles"
Item {
id: externalLink
property string url
property string text
property bool commonBorder: true
property int lBorderwidth: 0
property int rBorderwidth: 0
@ -41,13 +42,12 @@ Item {
MouseArea {
anchors.fill: parent
onClicked: {
Qt.openUrlExternally(externalLink.url);
Qt.openUrlExternally(externalLink.url)
}
}
CustomBorder {
id: cb
commonBorder: externalLink.commonBorder
lBorderwidth: externalLink.lBorderwidth
rBorderwidth: externalLink.rBorderwidth
@ -55,7 +55,5 @@ Item {
bBorderwidth: externalLink.bBorderwidth
borderColor: externalLink.borderColor
}
}
}

View File

@ -1,14 +1,13 @@
import "../dialogs"
import "../styles"
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import Pass 1.0
import QtQuick 2.4
import "../styles"
import "../dialogs"
Component {
Rectangle {
id: fileDir
property string activePasswordName
anchors.right: parent.right
@ -35,20 +34,24 @@ Component {
anchors.fill: parent
onClicked: {
if (fileIsDir) {
folderModel.folder = folderModel.folder + "/" + fileName;
backAction.visible = true;
folderModel.folder = folderModel.folder + "/" + fileName
backAction.visible = true
} else {
fileDir.activePasswordName = fileBaseName;
Pass.onDecrypted.connect(function(text) {
pageStack.push(Qt.resolvedUrl("../pages/Password.qml"), {
"plainText": text,
"title": fileDir.activePasswordName
});
});
Pass.onDecryptFailed.connect(function() {
PopupUtils.open(passwordPageDecryptError);
});
Pass.decrypt(folderModel.folder + "/" + fileName);
fileDir.activePasswordName = fileBaseName
Pass.onDecrypted.connect(function (text) {
pageStack.push(Qt.resolvedUrl("../pages/Password.qml"),
{
"plainText": text,
"title": fileDir.activePasswordName
})
})
Pass.onDecryptFailed.connect(function () {
PopupUtils.open(passwordPageDecryptError)
})
Pass.decrypt(folderModel.folder + "/" + fileName)
}
}
}
@ -64,13 +67,12 @@ Component {
Component {
id: passwordPageDecryptError
ErrorDialog {
textError: i18n.tr("Decryption failed !")
onDialogClosed: {
pageStack.pop()
}
}
}
}
}

View File

@ -1,14 +1,16 @@
import "../styles"
import Lomiri.Components 1.3
import QtQuick 2.4
import Lomiri.Components 1.3
import "../styles"
Item {
id: pageStackLink
property string page
property var params: {
}
property string text
property bool commonBorder: true
property int lBorderwidth: 0
property int rBorderwidth: 0
@ -43,13 +45,12 @@ Item {
MouseArea {
anchors.fill: parent
onClicked: {
pageStack.push(page, params);
pageStack.push(page, params)
}
}
CustomBorder {
id: cb
commonBorder: pageStackLink.commonBorder
lBorderwidth: pageStackLink.lBorderwidth
rBorderwidth: pageStackLink.rBorderwidth
@ -57,7 +58,5 @@ Item {
bBorderwidth: pageStackLink.bBorderwidth
borderColor: pageStackLink.borderColor
}
}
}

View File

@ -1,6 +1,6 @@
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import QtQuick 2.4
Dialog {
id: doubleValidationDialog
@ -9,8 +9,8 @@ Dialog {
property string text1
property string text2
signal doubleValidated()
signal canceled()
signal doubleValidated
signal canceled
Text {
visible: nb_validation == 0
@ -27,27 +27,26 @@ Dialog {
Button {
text: i18n.tr("Ok")
color: LomiriColors.green
onClicked: {
if (nb_validation == 1) {
nb_validation = 0;
doubleValidated();
PopupUtils.close(doubleValidationDialog);
nb_validation = 0
doubleValidated()
PopupUtils.close(doubleValidationDialog)
} else {
nb_validation += 1;
nb_validation += 1
}
}
}
Button {
id: cancelButton
text: i18n.tr("Cancel")
color: LomiriColors.red
onClicked: {
nb_validation = 0;
canceled();
PopupUtils.close(doubleValidationDialog);
nb_validation = 0
canceled()
PopupUtils.close(doubleValidationDialog)
}
}
}

View File

@ -1,24 +1,22 @@
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import QtQuick 2.4
Dialog {
id: dialogError
id: dialogSuccess
property string textError
signal dialogClosed()
signal dialogClosed
title: i18n.tr("Error !")
text: textError
Button {
text: i18n.tr("Close")
text: i18n.tr("OK")
color: LomiriColors.red
onClicked: function() {
dialogClosed();
PopupUtils.close(dialogError);
onClicked: function () {
dialogClosed()
PopupUtils.close(dialogSuccess)
}
}
}

View File

@ -1,25 +1,25 @@
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import QtQuick 2.4
Dialog {
id: passphraseProvider
signal validated(string passphrase)
signal canceled()
function activateFocus() {
passphraseField.forceActiveFocus();
}
title: i18n.tr("Authentication required")
text: i18n.tr("Enter passphrase:")
signal validated(string passphrase)
signal canceled
function activateFocus() {
passphraseField.forceActiveFocus()
}
TextField {
id: passphraseField
placeholderText: i18n.tr("passphrase")
echoMode: TextInput.Password
onAccepted: okButton.clicked(text)
}
@ -28,22 +28,23 @@ Dialog {
text: i18n.tr("Ok")
color: LomiriColors.green
onClicked: {
validated(passphraseField.text);
passphraseField.text = "";
PopupUtils.close(passphraseProvider);
validated(passphraseField.text)
passphraseField.text = ""
PopupUtils.close(passphraseProvider)
}
}
Button {
id: cancelButton
text: i18n.tr("Cancel")
color: LomiriColors.red
onClicked: {
canceled();
PopupUtils.close(passphraseProvider);
canceled()
PopupUtils.close(passphraseProvider)
}
}
}

View File

@ -1,14 +1,14 @@
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import QtQuick 2.4
Dialog {
id: doubleValidationDialog
property string text
signal validated()
signal canceled()
signal validated
signal canceled
Text {
horizontalAlignment: Text.AlignHCenter
@ -18,21 +18,20 @@ Dialog {
Button {
text: i18n.tr("Ok")
color: LomiriColors.green
onClicked: {
validated();
PopupUtils.close(doubleValidationDialog);
validated()
PopupUtils.close(doubleValidationDialog)
}
}
Button {
id: cancelButton
text: i18n.tr("Cancel")
color: LomiriColors.red
onClicked: {
canceled();
PopupUtils.close(doubleValidationDialog);
canceled()
PopupUtils.close(doubleValidationDialog)
}
}
}

View File

@ -1,24 +1,22 @@
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import QtQuick 2.4
Dialog {
id: dialogSuccess
property string textSuccess
signal dialogClosed()
signal dialogClosed
title: i18n.tr("Success !")
text: textSuccess
Button {
text: i18n.tr("OK")
color: LomiriColors.green
onClicked: function() {
dialogClosed();
PopupUtils.close(dialogSuccess);
onClicked: function () {
dialogClosed()
PopupUtils.close(dialogSuccess)
}
}
}

View File

@ -1,19 +1,14 @@
import "../components"
import Lomiri.Components 1.3
import QtQuick 2.4
import Lomiri.Components 1.3
import "headers"
import "../components"
Page {
id: infoPage
Component.onCompleted: {
var xhr = new XMLHttpRequest();
xhr.open("GET", "../../manifest_.json", false);
xhr.send();
var mJson = JSON.parse(xhr.responseText);
manifestTitle.text = "<b>" + mJson.title + "</b>";
manifestVersion.text = mJson.version + "<br>" + mJson.framework + "@" + mJson.architecture;
manifestMaintener.text = mJson.maintainer;
header: StackHeader {
id: infoHeader
title: i18n.tr('Info')
}
Flow {
@ -29,7 +24,6 @@ Page {
Text {
id: manifestTitle
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
width: parent.width
@ -41,14 +35,12 @@ Page {
Rectangle {
width: parent.width
height: units.gu(12)
Image {
source: "../../assets/logo.svg"
width: units.gu(12)
height: units.gu(12)
anchors.horizontalCenter: parent.horizontalCenter
}
}
Text {
@ -62,7 +54,6 @@ Page {
Text {
id: manifestVersion
horizontalAlignment: Text.AlignHCenter
width: parent.width
height: units.gu(4)
@ -81,14 +72,12 @@ Page {
Text {
id: manifestMaintener
horizontalAlignment: Text.AlignHCenter
width: parent.width
height: units.gu(2)
fontSizeMode: Text.Fit
font.pixelSize: 72
}
}
Flow {
@ -96,17 +85,14 @@ Page {
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
ExternalLink {
url: "https://github.com/QRouland/UTPass/issues"
url: "https://taiga.rdrive.ovh/project/utpass/issues"
text: i18n.tr("Suggest improvement(s) or report a bug(s)")
}
ExternalLink {
url: "https://github.com/QRouland/UTPass"
url: "https://git.rdrive.ovh/QRouland/UTPass"
text: i18n.tr("Access to the source code")
}
Text {
width: parent.width
height: units.gu(2)
@ -114,13 +100,17 @@ Page {
verticalAlignment: Text.AlignVCenter
text: i18n.tr("Released under the terms of the GNU GPL v3")
}
}
header: StackHeader {
id: infoHeader
Component.onCompleted: {
var xhr = new XMLHttpRequest()
xhr.open("GET", "../../manifest_.json", false)
xhr.send()
title: i18n.tr('Info')
var mJson = JSON.parse(xhr.responseText)
manifestTitle.text = "<b>" + mJson.title + "</b>"
manifestVersion.text = mJson.version + "<br>" + mJson.framework + "@" + mJson.architecture
manifestMaintener.text = mJson.maintainer
}
}

View File

@ -1,6 +1,6 @@
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import QtQuick 2.4
import "headers"
Page {
@ -10,15 +10,38 @@ Page {
property string plainText
property var objects
Component.onCompleted: {
var text_split = passwordPage.plainText.split('\n');
var component = Qt.createComponent("../components/CopyText.qml");
for (var i = 0; i < text_split.length; i++) {
if (text_split[i]) {
var object = component.createObject(container);
object.text = text_split[i];
header: PageHeader {
id: passwordPageHeader
width: parent.width
height: units.gu(6)
title: passwordPage.title
contents: Item {
height: parent.height
width: parent.width
Label {
id: labelTitle
text: passwordPage.title
anchors.verticalCenter: parent.verticalCenter
}
}
leadingActionBar.height: units.gu(4)
leadingActionBar.actions: [
Action {
id: backAction
iconName: "back"
text: "Back"
onTriggered: {
passwordPage.plainText = ""
for (var object in objects) {
object.text = ""
object.destroy()
}
pageStack.pop()
}
}
]
}
Rectangle {
@ -29,49 +52,18 @@ Page {
Flow {
id: container
anchors.fill: parent
}
}
header: PageHeader {
id: passwordPageHeader
width: parent.width
height: units.gu(6)
title: passwordPage.title
leadingActionBar.height: units.gu(4)
leadingActionBar.actions: [
Action {
id: backAction
iconName: "back"
text: "Back"
onTriggered: {
passwordPage.plainText = "";
for (var object in objects) {
object.text = "";
object.destroy();
}
pageStack.pop();
}
Component.onCompleted: {
var text_split = passwordPage.plainText.split('\n')
var component = Qt.createComponent("../components/CopyText.qml")
for (var i = 0; i < text_split.length; i++) {
if (text_split[i]) {
var object = component.createObject(container)
object.text = text_split[i]
}
]
contents: Item {
height: parent.height
width: parent.width
Label {
id: labelTitle
text: passwordPage.title
anchors.verticalCenter: parent.verticalCenter
}
}
}
}

View File

@ -1,8 +1,8 @@
import "../components"
import Lomiri.Components 1.3
import Pass 1.0
import Qt.labs.folderlistmodel 2.1
import QtQuick 2.4
import Lomiri.Components 1.3
import Qt.labs.folderlistmodel 2.1
import Pass 1.0
import "../components"
import "headers"
Page {
@ -11,8 +11,25 @@ Page {
property string passwordStorePath
anchors.fill: parent
Component.onCompleted: {
passwordStorePath = "file:" + Pass.password_store;
header: MainHeader {
id: passwordListHeader
leadingActionBar.height: units.gu(4)
leadingActionBar.actions: [
Action {
id: backAction
iconName: "back"
text: i18n.tr("Back")
visible: false
onTriggered: {
folderModel.folder = folderModel.parentFolder
if (folderModel.rootFolder === folderModel.folder) {
backAction.visible = false
}
}
}
]
}
Rectangle {
@ -21,14 +38,13 @@ Page {
anchors.right: parent.right
anchors.left: parent.left
visible: folderModel.count == 0
Text {
text: i18n.tr("No password found<br>You can import a password store zip in the settings")
text: i18n.tr(
"No password found<br>You can import a password store zip in the settings")
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignHCenter
}
}
ListView {
@ -40,38 +56,17 @@ Page {
model: FolderListModel {
id: folderModel
nameFilters: ["*.gpg"]
rootFolder: passwordStorePath
folder: passwordStorePath
showDirs: true
}
delegate: FileDir {
id: fileDelegate
}
}
header: MainHeader {
id: passwordListHeader
leadingActionBar.height: units.gu(4)
leadingActionBar.actions: [
Action {
id: backAction
iconName: "back"
text: i18n.tr("Back")
visible: false
onTriggered: {
folderModel.folder = folderModel.parentFolder;
if (folderModel.rootFolder === folderModel.folder)
backAction.visible = false;
}
}
]
Component.onCompleted: {
passwordStorePath = "file:" + Pass.getPasswordStore()
}
}

View File

@ -1,15 +1,40 @@
import Lomiri.Components 1.3
import QtQuick 2.4
import Lomiri.Components 1.3
PageHeader {
id: mainHeader
width: parent.width
height: units.gu(6)
title: i18n.tr("UTPass")
contents: Item {
height: parent.height
width: parent.width
Label {
id: labelTitle
text: mainHeader.title
anchors.verticalCenter: parent.verticalCenter
visible: true
}
TextField {
id: searchBar
anchors.right: parent.right
anchors.left: parent.left
placeholderText: i18n.tr("Search")
height: units.gu(4)
visible: false
anchors.verticalCenter: parent.verticalCenter
onFocusChanged: {
}
}
}
trailingActionBar.height: units.gu(4)
trailingActionBar.numberOfSlots: 2
trailingActionBar.actions: [
/*Action { TODO
iconName: "search"
text: i18n.tr("Search")
@ -25,43 +50,15 @@ PageHeader {
iconName: "settings"
text: i18n.tr("Settings")
onTriggered: {
pageStack.push(Qt.resolvedUrl("../settings/Settings.qml"));
pageStack.push(Qt.resolvedUrl("../settings/Settings.qml"))
}
},
Action {
iconName: "info"
text: i18n.tr("Info")
onTriggered: {
pageStack.push(Qt.resolvedUrl("../Info.qml"));
pageStack.push(Qt.resolvedUrl("../Info.qml"))
}
}
]
contents: Item {
height: parent.height
width: parent.width
Label {
id: labelTitle
text: mainHeader.title
anchors.verticalCenter: parent.verticalCenter
visible: true
}
TextField {
id: searchBar
anchors.right: parent.right
anchors.left: parent.left
placeholderText: i18n.tr("Search")
height: units.gu(4)
visible: false
anchors.verticalCenter: parent.verticalCenter
onFocusChanged: {
}
}
}
}

View File

@ -1,36 +1,31 @@
import Lomiri.Components 1.3
import QtQuick 2.4
import Lomiri.Components 1.3
PageHeader {
id: stackHeader
width: parent.width
height: units.gu(6)
title: i18n.tr("UTPass")
leadingActionBar.height: units.gu(4)
leadingActionBar.actions: [
Action {
id: backAction
iconName: "back"
text: "Back"
onTriggered: {
pageStack.pop();
}
}
]
contents: Item {
height: parent.height
width: parent.width
Label {
id: labelTitle
text: stackHeader.title
anchors.verticalCenter: parent.verticalCenter
}
}
leadingActionBar.height: units.gu(4)
leadingActionBar.actions: [
Action {
id: backAction
iconName: "back"
text: "Back"
onTriggered: {
pageStack.pop()
}
}
]
}

View File

@ -1,104 +0,0 @@
import "../../components"
import "../../dialogs"
import "../headers"
import Git 1.0
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import Pass 1.0
import QtQuick 2.4
Page {
id: importGitClonePage
Component.onCompleted: {
PopupUtils.open(importGitCloneValidation, importGitClonePage);
}
Flow {
anchors.top: importGitCloneHeader.bottom
anchors.right: parent.right
anchors.left: parent.left
anchors.leftMargin: units.gu(2)
anchors.rightMargin: units.gu(2)
spacing: units.gu(1)
Rectangle {
width: parent.width
height: units.gu(1)
}
Text {
id: repoUrlLabe
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
width: parent.width
text: i18n.tr('Repo Url')
}
TextField {
id: textFieldInput
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
width: parent.width
placeholderText: i18n.tr('Git repo url')
}
Button {
id: buttonAdd
width: parent.width
text: i18n.tr('Clone')
onClicked: {
var ret = Git.clone(textFieldInput.text, Pass.password_store);
if (ret)
PopupUtils.open(dialogImportGitCloneSuccess);
else
PopupUtils.open(importGitCloneError, importGitClonePage);
}
}
}
Component {
id: importGitCloneValidation
SimpleValidationDialog {
text: i18n.tr("Importing a git repo will delete<br>any existing password store!<br>Continue ?")
onCanceled: {
pageStack.pop();
}
}
}
Component {
id: importGitCloneError
ErrorDialog {
textError: i18n.tr("An error occured during git clone !")
}
}
Component {
id: dialogImportGitCloneSuccess
SuccessDialog {
textSuccess: i18n.tr("Password store sucessfully imported !")
onDialogClosed: {
pageStack.pop();
pageStack.pop();
}
}
}
header: StackHeader {
id: importGitCloneHeader
title: i18n.tr('Git Clone Import')
}
}

View File

@ -1,80 +1,82 @@
import "../../dialogs"
import "../headers"
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import Lomiri.Content 1.3
import Pass 1.0
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Content 1.3
import Lomiri.Components.Popups 1.3
import Pass 1.0
import Utils 1.0
import "../headers"
import "../../dialogs"
Page {
id: importKeyFilePage
property var activeTransfer
header: StackHeader {
id: importKeyHeader
title: i18n.tr("GPG Key Import")
}
ContentPeerPicker {
anchors.top: importKeyHeader.bottom
anchors.bottom: parent.bottom
anchors.topMargin: importKeyFilePage.header.height
width: parent.width
visible: parent.visible
showTitle: false
contentType: ContentType.Text
handler: ContentHandler.Source
onPeerSelected: {
peer.selectionType = ContentTransfer.Single;
importKeyFilePage.activeTransfer = peer.request();
importKeyFilePage.activeTransfer.stateChanged.connect(function() {
peer.selectionType = ContentTransfer.Single
importKeyFilePage.activeTransfer = peer.request()
importKeyFilePage.activeTransfer.stateChanged.connect(function () {
if (importKeyFilePage.activeTransfer.state === ContentTransfer.Charged) {
console.log("Charged");
console.log(importKeyFilePage.activeTransfer.items[0].url);
var status = Pass.gpgImportKeyFromFile(importKeyFilePage.activeTransfer.items[0].url);
Utils.rmFile(importKeyFilePage.activeTransfer.items[0].url);
if (status)
PopupUtils.open(dialogImportKeyPageSucess);
else
PopupUtils.open(dialogImportKeyPageError);
importKeyFilePage.activeTransfer = null;
console.log("Charged")
console.log(importKeyFilePage.activeTransfer.items[0].url)
var status = Pass.gpgImportKeyFromFile(
importKeyFilePage.activeTransfer.items[0].url)
Utils.rmFile(importKeyFilePage.activeTransfer.items[0].url)
if (status) {
PopupUtils.open(dialogImportKeyPageSucess)
} else {
PopupUtils.open(dialogImportKeyPageError)
}
importKeyFilePage.activeTransfer = null
}
});
})
}
onCancelPressed: {
pageStack.pop();
pageStack.pop()
}
}
ContentTransferHint {
id: transferHint
anchors.fill: parent
activeTransfer: importKeyFilePage.activeTransfer
}
Component {
id: dialogImportKeyPageError
ErrorDialog {
textError: i18n.tr("Key import failed !")
}
}
Component {
id: dialogImportKeyPageSucess
SuccessDialog {
textSuccess: i18n.tr("Key successfully imported !")
onDialogClosed: {
pageStack.pop();
pageStack.pop()
}
}
}
header: StackHeader {
id: importKeyHeader
title: i18n.tr("GPG Key Import")
}
}

View File

@ -1,97 +1,99 @@
import "../../dialogs"
import "../headers"
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import Lomiri.Content 1.3
import Pass 1.0
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Content 1.3
import Lomiri.Components.Popups 1.3
import Pass 1.0
import Utils 1.0
import "../headers"
import "../../dialogs"
Page {
id: importZipPage
property var activeTransfer
Component.onCompleted: {
PopupUtils.open(importZipPageImportValidation, importZipPage);
header: StackHeader {
id: importZipHeader
title: i18n.tr("Zip Password Store Import")
}
ContentPeerPicker {
anchors.top: importZipHeader.bottom
anchors.bottom: parent.bottom
anchors.topMargin: importZipPage.header.height
width: parent.width
visible: parent.visible
showTitle: false
contentType: ContentType.Text
handler: ContentHandler.Source
onPeerSelected: {
peer.selectionType = ContentTransfer.Single;
importZipPage.activeTransfer = peer.request();
importZipPage.activeTransfer.stateChanged.connect(function() {
peer.selectionType = ContentTransfer.Single
importZipPage.activeTransfer = peer.request()
importZipPage.activeTransfer.stateChanged.connect(function () {
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.getPasswordStore());
Utils.rmFile(importZipPage.activeTransfer.items[0].url);
if (status)
PopupUtils.open(dialogImportZipPageSuccess);
else
PopupUtils.open(dialogImportZipPageError);
importZipPage.activeTransfer = null;
console.log("Charged")
console.log(importZipPage.activeTransfer.items[0].url)
var status = Utils.unzip(
importZipPage.activeTransfer.items[0].url,
Pass.getPasswordStore())
Utils.rmFile(importZipPage.activeTransfer.items[0].url)
if (status) {
PopupUtils.open(dialogImportZipPageSuccess)
} else {
PopupUtils.open(dialogImportZipPageError)
}
importZipPage.activeTransfer = null
}
});
})
}
onCancelPressed: {
pageStack.pop();
pageStack.pop()
}
}
ContentTransferHint {
id: transferHint
anchors.fill: parent
activeTransfer: importZipPage.activeTransfer
}
Component {
id: importZipPageImportValidation
SimpleValidationDialog {
text: i18n.tr("Importing a new zip will delete<br>any existing password store!<br>Continue ?")
text: i18n.tr(
"Importing a new zip will delete<br>any existing password store!<br>Continue ?")
onCanceled: {
pageStack.pop();
pageStack.pop()
}
}
}
Component {
id: dialogImportZipPageError
ErrorDialog {
textError: i18n.tr("Password store import failed !")
}
}
Component {
id: dialogImportZipPageSuccess
SuccessDialog {
textSuccess: i18n.tr("Password store sucessfully imported !")
onDialogClosed: {
pageStack.pop();
pageStack.pop();
pageStack.pop()
}
}
}
header: StackHeader {
id: importZipHeader
title: i18n.tr("Zip Password Store Import")
Component.onCompleted: {
PopupUtils.open(importZipPageImportValidation, importZipPage)
}
}

View File

@ -1,23 +1,28 @@
import "../../components"
import "../../dialogs"
import "../headers"
import QtQuick 2.4
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import Pass 1.0
import QtQuick 2.4
import "../headers"
import "../../components"
import "../../dialogs"
Page {
id: infoKeysPage
property string currentKey
header: StackHeader {
id: infoKeysHeader
title: i18n.tr('Info Keys')
}
ListView {
id: infoKeysListView
anchors.top: infoKeysHeader.bottom
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
model: Pass.gpgGetAllKeysModel()
delegate: Grid {
@ -33,7 +38,6 @@ Page {
Text {
id: uidKey
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
@ -42,12 +46,11 @@ Page {
Button {
id: buttonDeleteKey
text: i18n.tr("Delete this key")
color: LomiriColors.red
onClicked: {
infoKeysPage.currentKey = model.modelData.uid;
PopupUtils.open(infoKeysPageDeleteValidation, infoKeysPage);
infoKeysPage.currentKey = model.modelData.uid
PopupUtils.open(infoKeysPageDeleteValidation, infoKeysPage)
}
}
@ -55,53 +58,43 @@ Page {
width: parent.width
height: units.gu(1)
}
}
}
Component {
id: infoKeysPageDeleteValidation
DoubleValidationDialog {
text1: i18n.tr("You're are about to delete<br>%1<br>Continue ?").arg(infoKeysPage.currentKey)
text2: i18n.tr("%1<br>will be definitively removed.<br>Continue ?").arg(infoKeysPage.currentKey)
text1: i18n.tr(
"You're are about to delete<br>%1<br>Continue ?").arg(
infoKeysPage.currentKey)
text2: i18n.tr(
"%1<br>will be definitively removed.<br>Continue ?").arg(
infoKeysPage.currentKey)
onDoubleValidated: {
var status = Pass.gpgDeleteKeyId(infoKeysPage.currentKey);
if (status)
PopupUtils.open(infoKeysPageDeleteSuccess);
else
PopupUtils.open(infoKeysPageDeleteError);
var status = Pass.gpgDeleteKeyId(infoKeysPage.currentKey)
if (status) {
PopupUtils.open(infoKeysPageDeleteSuccess)
} else {
PopupUtils.open(infoKeysPageDeleteError)
}
}
}
}
Component {
id: infoKeysPageDeleteError
ErrorDialog {
textError: i18n.tr("Key removal failed !")
}
}
Component {
id: infoKeysPageDeleteSuccess
SuccessDialog {
textSuccess: i18n.tr("Key successfully deleted !")
onDialogClosed: {
infoKeysListView.model = Pass.gpgGetAllKeysModel();
infoKeysListView.model = Pass.gpgGetAllKeysModel()
}
}
}
header: StackHeader {
id: infoKeysHeader
title: i18n.tr('Info Keys')
}
}

View File

@ -1,14 +1,19 @@
import "../../components"
import "../headers"
import QtQuick 2.4
import Lomiri.Components 1.3
import Pass 1.0
import QtQuick 2.4
import "../headers"
import "../../components"
Page {
id: settingsPage
property string gpgKeyId: ""
header: StackHeader {
id: settingsHeader
title: i18n.tr('Settings')
}
Flow {
anchors.top: settingsHeader.bottom
anchors.bottom: parent.bottom
@ -22,17 +27,14 @@ Page {
height: units.gu(4)
text: i18n.tr('GPG')
}
PageStackLink {
page: Qt.resolvedUrl("ImportKeyFile.qml")
text: i18n.tr('Import a GPG key file')
}
PageStackLink {
page: Qt.resolvedUrl("InfoKeys.qml")
text: i18n.tr('Show GPG keys')
}
Text {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
@ -40,32 +42,18 @@ Page {
height: units.gu(4)
text: i18n.tr('Password Store')
}
PageStackLink {
page: Qt.resolvedUrl("ImportGitClone.qml")
text: i18n.tr('Import a Password Store using Git')
}
PageStackLink {
page: Qt.resolvedUrl("ImportZip.qml")
text: i18n.tr('Import a Password Store Zip')
}
Text {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
width: parent.width
height: units.gu(4)
color: LomiriColors.red
text: i18n.tr('Warning: importing delete any exiting Password Store')
text: i18n.tr(
'Warning: importing delete any exiting Password Store')
}
}
header: StackHeader {
id: settingsHeader
title: i18n.tr('Settings')
}
}

View File

@ -4,14 +4,18 @@ import QtQuick 2.4
Rectangle {
property bool commonBorder: true
property int lBorderwidth: 1
property int rBorderwidth: 1
property int tBorderwidth: 1
property int bBorderwidth: 1
property int commonBorderWidth: 1
property string borderColor: "white"
z: -1
property string borderColor: "white"
color: borderColor
anchors {
@ -19,10 +23,10 @@ Rectangle {
right: parent.right
top: parent.top
bottom: parent.bottom
topMargin: commonBorder ? -commonBorderWidth : -tBorderwidth
bottomMargin: commonBorder ? -commonBorderWidth : -bBorderwidth
leftMargin: commonBorder ? -commonBorderWidth : -lBorderwidth
rightMargin: commonBorder ? -commonBorderWidth : -rBorderwidth
}
}