mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
feat: stop using plaintext passwords in the code
This commit is contained in:
parent
0f54e44262
commit
084f3b0626
|
@ -51,7 +51,6 @@ QVector<QString> Profile::profiles;
|
||||||
|
|
||||||
Profile::Profile(QString name, const QString& password, bool isNewProfile, const QByteArray& toxsave)
|
Profile::Profile(QString name, const QString& password, bool isNewProfile, const QByteArray& toxsave)
|
||||||
: name{name}
|
: name{name}
|
||||||
, password{password}
|
|
||||||
, newProfile{isNewProfile}
|
, newProfile{isNewProfile}
|
||||||
, isRemoved{false}
|
, isRemoved{false}
|
||||||
{
|
{
|
||||||
|
@ -62,7 +61,9 @@ Profile::Profile(QString name, const QString& password, bool isNewProfile, const
|
||||||
coreThread = new QThread();
|
coreThread = new QThread();
|
||||||
coreThread->setObjectName("qTox Core");
|
coreThread->setObjectName("qTox Core");
|
||||||
core = new Core(coreThread, *this);
|
core = new Core(coreThread, *this);
|
||||||
QObject::connect(core, &Core::idSet, this, &Profile::loadDatabase, Qt::QueuedConnection);
|
QObject::connect(core, &Core::idSet, this,
|
||||||
|
[this, password](const ToxId& id) { loadDatabase(id, password); },
|
||||||
|
Qt::QueuedConnection);
|
||||||
core->moveToThread(coreThread);
|
core->moveToThread(coreThread);
|
||||||
QObject::connect(coreThread, &QThread::started, core, [=]() { core->start(toxsave); });
|
QObject::connect(coreThread, &QThread::started, core, [=]() { core->start(toxsave); });
|
||||||
}
|
}
|
||||||
|
@ -88,7 +89,7 @@ Profile* Profile::loadProfile(QString name, const QString& password)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ToxEncrypt> tmpKey;
|
std::unique_ptr<ToxEncrypt> tmpKey = nullptr;
|
||||||
QByteArray data = QByteArray();
|
QByteArray data = QByteArray();
|
||||||
Profile* p = nullptr;
|
Profile* p = nullptr;
|
||||||
qint64 fileSize = 0;
|
qint64 fileSize = 0;
|
||||||
|
@ -140,6 +141,9 @@ Profile* Profile::loadProfile(QString name, const QString& password)
|
||||||
saveFile.close();
|
saveFile.close();
|
||||||
p = new Profile(name, password, false, data);
|
p = new Profile(name, password, false, data);
|
||||||
p->passkey = std::move(tmpKey);
|
p->passkey = std::move(tmpKey);
|
||||||
|
if (tmpKey) {
|
||||||
|
p->encrypted = true;
|
||||||
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
|
@ -188,6 +192,9 @@ Profile* Profile::createProfile(QString name, QString password)
|
||||||
Settings::getInstance().createPersonal(name);
|
Settings::getInstance().createPersonal(name);
|
||||||
Profile* p = new Profile(name, password, true, QByteArray());
|
Profile* p = new Profile(name, password, true, QByteArray());
|
||||||
p->passkey = std::move(tmpKey);
|
p->passkey = std::move(tmpKey);
|
||||||
|
if (tmpKey) {
|
||||||
|
p->encrypted = true;
|
||||||
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -308,7 +315,7 @@ void Profile::saveToxSave(QByteArray data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!password.isEmpty()) {
|
if (encrypted) {
|
||||||
data = passkey->encrypt(data);
|
data = passkey->encrypt(data);
|
||||||
if (data.isEmpty()) {
|
if (data.isEmpty()) {
|
||||||
qCritical() << "Failed to encrypt, can't save!";
|
qCritical() << "Failed to encrypt, can't save!";
|
||||||
|
@ -339,7 +346,7 @@ void Profile::saveToxSave(QByteArray data)
|
||||||
*/
|
*/
|
||||||
QString Profile::avatarPath(const QString& ownerId, bool forceUnencrypted)
|
QString Profile::avatarPath(const QString& ownerId, bool forceUnencrypted)
|
||||||
{
|
{
|
||||||
if (password.isEmpty() || forceUnencrypted)
|
if (!encrypted || forceUnencrypted)
|
||||||
return Settings::getInstance().getSettingsDirPath() + "avatars/" + ownerId + ".png";
|
return Settings::getInstance().getSettingsDirPath() + "avatars/" + ownerId + ".png";
|
||||||
|
|
||||||
QByteArray idData = ownerId.toUtf8();
|
QByteArray idData = ownerId.toUtf8();
|
||||||
|
@ -379,28 +386,16 @@ QPixmap Profile::loadAvatar(const QString& ownerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a contact's avatar from cache
|
* @brief Get a contact's avatar from cache.
|
||||||
* @param ownerId Friend ID to load avatar.
|
* @param ownerId Friend ID to load avatar.
|
||||||
* @return Avatar as QByteArray.
|
* @return Avatar as QByteArray.
|
||||||
*/
|
*/
|
||||||
QByteArray Profile::loadAvatarData(const QString& ownerId)
|
QByteArray Profile::loadAvatarData(const QString& ownerId)
|
||||||
{
|
|
||||||
return loadAvatarData(ownerId, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a contact's avatar from cache, with a specified profile password.
|
|
||||||
* @param ownerId Friend ID to load avatar.
|
|
||||||
* @param password Profile password to decrypt data.
|
|
||||||
* @return Avatar as QByteArray.
|
|
||||||
*/
|
|
||||||
QByteArray Profile::loadAvatarData(const QString& ownerId, const QString& password)
|
|
||||||
{
|
{
|
||||||
QString path = avatarPath(ownerId);
|
QString path = avatarPath(ownerId);
|
||||||
bool encrypted = !password.isEmpty();
|
|
||||||
|
|
||||||
// If the encrypted avatar isn't found, try loading the unencrypted one for the same ID
|
// If the encrypted avatar isn't found, try loading the unencrypted one for the same ID
|
||||||
if (!password.isEmpty() && !QFile::exists(path)) {
|
if (encrypted && !QFile::exists(path)) {
|
||||||
encrypted = false;
|
encrypted = false;
|
||||||
path = avatarPath(ownerId, true);
|
path = avatarPath(ownerId, true);
|
||||||
}
|
}
|
||||||
|
@ -412,14 +407,13 @@ QByteArray Profile::loadAvatarData(const QString& ownerId, const QString& passwo
|
||||||
|
|
||||||
QByteArray pic = file.readAll();
|
QByteArray pic = file.readAll();
|
||||||
if (encrypted && !pic.isEmpty()) {
|
if (encrypted && !pic.isEmpty()) {
|
||||||
// TODO: check if we can use passkey-decrypt(pic) here
|
pic = passkey->decrypt(pic);
|
||||||
pic = ToxEncrypt::decryptPass(password, pic);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pic;
|
return pic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Profile::loadDatabase(const ToxId& id)
|
void Profile::loadDatabase(const ToxId& id, QString password)
|
||||||
{
|
{
|
||||||
if (isRemoved) {
|
if (isRemoved) {
|
||||||
qDebug() << "Can't load database of removed profile";
|
qDebug() << "Can't load database of removed profile";
|
||||||
|
@ -452,7 +446,7 @@ void Profile::loadDatabase(const ToxId& id)
|
||||||
*/
|
*/
|
||||||
void Profile::saveAvatar(QByteArray pic, const QString& ownerId)
|
void Profile::saveAvatar(QByteArray pic, const QString& ownerId)
|
||||||
{
|
{
|
||||||
if (!password.isEmpty() && !pic.isEmpty()) {
|
if (encrypted && !pic.isEmpty()) {
|
||||||
pic = passkey->encrypt(pic);
|
pic = passkey->encrypt(pic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,7 +528,7 @@ bool Profile::exists(QString name)
|
||||||
*/
|
*/
|
||||||
bool Profile::isEncrypted() const
|
bool Profile::isEncrypted() const
|
||||||
{
|
{
|
||||||
return !password.isEmpty();
|
return encrypted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -640,14 +634,9 @@ bool Profile::rename(QString newName)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Profile::getPassword() const
|
const ToxEncrypt* Profile::getPasskey() const
|
||||||
{
|
{
|
||||||
return password;
|
return passkey.get();
|
||||||
}
|
|
||||||
|
|
||||||
const ToxEncrypt& Profile::getPasskey() const
|
|
||||||
{
|
|
||||||
return *passkey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -665,37 +654,57 @@ void Profile::restartCore()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Changes the encryption password and re-saves everything with it
|
* @brief Changes the encryption password and re-saves everything with it
|
||||||
* @param newPassword Password for encryption.
|
* @param newPassword Password for encryption, if empty profile will be decrypted.
|
||||||
|
* @param oldPassword Supply previous password if already encrypted or empty QString if not yet
|
||||||
|
* encrypted.
|
||||||
|
* @return Empty QString on success or error message on failure.
|
||||||
*/
|
*/
|
||||||
void Profile::setPassword(const QString& newPassword)
|
QString Profile::setPassword(const QString& newPassword)
|
||||||
{
|
{
|
||||||
QByteArray avatar = loadAvatarData(core->getSelfId().getPublicKey().toString());
|
if (newPassword.isEmpty()) {
|
||||||
QString oldPassword = password;
|
// remove password
|
||||||
std::unique_ptr<ToxEncrypt> oldpasskey = std::move(passkey);
|
encrypted = false;
|
||||||
password = newPassword;
|
} else {
|
||||||
passkey = ToxEncrypt::makeToxEncrypt(password);
|
std::unique_ptr<ToxEncrypt> newpasskey = ToxEncrypt::makeToxEncrypt(newPassword);
|
||||||
if (!passkey) {
|
if (!newpasskey) {
|
||||||
qCritical() << "Failed to derive key from password, the profile won't use the new password";
|
qCritical()
|
||||||
password = oldPassword;
|
<< "Failed to derive key from password, the profile won't use the new password";
|
||||||
passkey = std::move(oldpasskey);
|
return tr(
|
||||||
return;
|
"Failed to derive key from password, the profile won't use the new password.");
|
||||||
|
}
|
||||||
|
// apply change
|
||||||
|
passkey = std::move(newpasskey);
|
||||||
|
encrypted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apply new encryption
|
||||||
saveToxSave();
|
saveToxSave();
|
||||||
|
|
||||||
|
bool dbSuccess = false;
|
||||||
|
|
||||||
// TODO: ensure the database and the tox save file use the same password
|
// TODO: ensure the database and the tox save file use the same password
|
||||||
if (database) {
|
if (database) {
|
||||||
database->setPassword(newPassword);
|
dbSuccess = database->setPassword(newPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString error{};
|
||||||
|
if (!dbSuccess) {
|
||||||
|
error = tr("Couldn't change password on the database, it might be corrupted or use the old "
|
||||||
|
"password.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Nexus::getDesktopGUI()->reloadHistory();
|
Nexus::getDesktopGUI()->reloadHistory();
|
||||||
|
|
||||||
|
QByteArray avatar = loadAvatarData(core->getSelfId().getPublicKey().toString());
|
||||||
saveAvatar(avatar, core->getSelfId().getPublicKey().toString());
|
saveAvatar(avatar, core->getSelfId().getPublicKey().toString());
|
||||||
|
|
||||||
QVector<uint32_t> friendList = core->getFriendList();
|
QVector<uint32_t> friendList = core->getFriendList();
|
||||||
QVectorIterator<uint32_t> i(friendList);
|
QVectorIterator<uint32_t> i(friendList);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
QString friendPublicKey = core->getFriendPublicKey(i.next()).toString();
|
QString friendPublicKey = core->getFriendPublicKey(i.next()).toString();
|
||||||
saveAvatar(loadAvatarData(friendPublicKey, oldPassword), friendPublicKey);
|
saveAvatar(loadAvatarData(friendPublicKey), friendPublicKey);
|
||||||
}
|
}
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -52,9 +52,8 @@ public:
|
||||||
void restartCore();
|
void restartCore();
|
||||||
bool isNewProfile();
|
bool isNewProfile();
|
||||||
bool isEncrypted() const;
|
bool isEncrypted() const;
|
||||||
QString getPassword() const;
|
QString setPassword(const QString& newPassword);
|
||||||
void setPassword(const QString& newPassword);
|
const ToxEncrypt* getPasskey() const;
|
||||||
const ToxEncrypt& getPasskey() const;
|
|
||||||
|
|
||||||
void saveToxSave();
|
void saveToxSave();
|
||||||
void saveToxSave(QByteArray data);
|
void saveToxSave(QByteArray data);
|
||||||
|
@ -62,7 +61,6 @@ public:
|
||||||
QPixmap loadAvatar();
|
QPixmap loadAvatar();
|
||||||
QPixmap loadAvatar(const QString& ownerId);
|
QPixmap loadAvatar(const QString& ownerId);
|
||||||
QByteArray loadAvatarData(const QString& ownerId);
|
QByteArray loadAvatarData(const QString& ownerId);
|
||||||
QByteArray loadAvatarData(const QString& ownerId, const QString& password);
|
|
||||||
void saveAvatar(QByteArray pic, const QString& ownerId);
|
void saveAvatar(QByteArray pic, const QString& ownerId);
|
||||||
QByteArray getAvatarHash(const QString& ownerId);
|
QByteArray getAvatarHash(const QString& ownerId);
|
||||||
void removeAvatar(const QString& ownerId);
|
void removeAvatar(const QString& ownerId);
|
||||||
|
@ -83,7 +81,7 @@ public:
|
||||||
static QString getDbPath(const QString& profileName);
|
static QString getDbPath(const QString& profileName);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void loadDatabase(const ToxId& id);
|
void loadDatabase(const ToxId& id, QString password);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Profile(QString name, const QString& password, bool newProfile, const QByteArray& toxsave);
|
Profile(QString name, const QString& password, bool newProfile, const QByteArray& toxsave);
|
||||||
|
@ -93,12 +91,13 @@ private:
|
||||||
private:
|
private:
|
||||||
Core* core;
|
Core* core;
|
||||||
QThread* coreThread;
|
QThread* coreThread;
|
||||||
QString name, password;
|
QString name;
|
||||||
std::unique_ptr<ToxEncrypt> passkey;
|
std::unique_ptr<ToxEncrypt> passkey = nullptr;
|
||||||
std::shared_ptr<RawDatabase> database;
|
std::shared_ptr<RawDatabase> database;
|
||||||
std::unique_ptr<History> history;
|
std::unique_ptr<History> history;
|
||||||
bool newProfile;
|
bool newProfile;
|
||||||
bool isRemoved;
|
bool isRemoved;
|
||||||
|
bool encrypted = false;
|
||||||
static QVector<QString> profiles;
|
static QVector<QString> profiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -341,7 +341,7 @@ void Settings::loadPersonal(Profile* profile)
|
||||||
|
|
||||||
qDebug() << "Loading personal settings from" << filePath;
|
qDebug() << "Loading personal settings from" << filePath;
|
||||||
|
|
||||||
SettingsSerializer ps(filePath, profile->getPassword());
|
SettingsSerializer ps(filePath, profile->getPasskey());
|
||||||
ps.load();
|
ps.load();
|
||||||
friendLst.clear();
|
friendLst.clear();
|
||||||
|
|
||||||
|
@ -618,15 +618,14 @@ void Settings::savePersonal(Profile* profile)
|
||||||
qDebug() << "Could not save personal settings because there is no active profile";
|
qDebug() << "Could not save personal settings because there is no active profile";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
savePersonal(profile->getName(), profile->getPassword());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::savePersonal(QString profileName, const QString& password)
|
|
||||||
{
|
|
||||||
if (QThread::currentThread() != settingsThread)
|
if (QThread::currentThread() != settingsThread)
|
||||||
return (void)QMetaObject::invokeMethod(&getInstance(), "savePersonal",
|
return (void)QMetaObject::invokeMethod(&getInstance(), "savePersonal",
|
||||||
Q_ARG(QString, profileName), Q_ARG(QString, password));
|
Q_ARG(Profile*, profile));
|
||||||
|
savePersonal(profile->getName(), profile->getPasskey());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::savePersonal(QString profileName, const ToxEncrypt* passkey)
|
||||||
|
{
|
||||||
QMutexLocker locker{&bigLock};
|
QMutexLocker locker{&bigLock};
|
||||||
if (!loaded)
|
if (!loaded)
|
||||||
return;
|
return;
|
||||||
|
@ -635,7 +634,7 @@ void Settings::savePersonal(QString profileName, const QString& password)
|
||||||
|
|
||||||
qDebug() << "Saving personal settings at " << path;
|
qDebug() << "Saving personal settings at " << path;
|
||||||
|
|
||||||
SettingsSerializer ps(path, password);
|
SettingsSerializer ps(path, passkey);
|
||||||
ps.beginGroup("Friends");
|
ps.beginGroup("Friends");
|
||||||
{
|
{
|
||||||
ps.beginWriteArray("Friend", friendLst.size());
|
ps.beginWriteArray("Friend", friendLst.size());
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define SETTINGS_HPP
|
#define SETTINGS_HPP
|
||||||
|
|
||||||
#include "src/core/corestructs.h"
|
#include "src/core/corestructs.h"
|
||||||
|
#include "src/core/toxencrypt.h"
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QFlags>
|
#include <QFlags>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
|
@ -140,7 +141,6 @@ public:
|
||||||
void createPersonal(QString basename);
|
void createPersonal(QString basename);
|
||||||
|
|
||||||
void savePersonal();
|
void savePersonal();
|
||||||
void savePersonal(Profile* profile);
|
|
||||||
|
|
||||||
void loadGlobal();
|
void loadGlobal();
|
||||||
void loadPersonal();
|
void loadPersonal();
|
||||||
|
@ -523,9 +523,10 @@ private:
|
||||||
~Settings();
|
~Settings();
|
||||||
Settings(Settings& settings) = delete;
|
Settings(Settings& settings) = delete;
|
||||||
Settings& operator=(const Settings&) = delete;
|
Settings& operator=(const Settings&) = delete;
|
||||||
|
void savePersonal(QString profileName, const ToxEncrypt* passkey);
|
||||||
|
|
||||||
private slots:
|
public slots:
|
||||||
void savePersonal(QString profileName, const QString& password);
|
void savePersonal(Profile* profile);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool loaded;
|
bool loaded;
|
||||||
|
|
|
@ -99,9 +99,9 @@ QDataStream& readStream(QDataStream& dataStream, QByteArray& data)
|
||||||
return dataStream;
|
return dataStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsSerializer::SettingsSerializer(QString filePath, const QString& password)
|
SettingsSerializer::SettingsSerializer(QString filePath, const ToxEncrypt* passKey)
|
||||||
: path{filePath}
|
: path{filePath}
|
||||||
, password{password}
|
, passKey{passKey}
|
||||||
, group{-1}
|
, group{-1}
|
||||||
, array{-1}
|
, array{-1}
|
||||||
, arrayIndex{-1}
|
, arrayIndex{-1}
|
||||||
|
@ -300,9 +300,8 @@ void SettingsSerializer::save()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt
|
// Encrypt
|
||||||
if (!password.isEmpty()) {
|
if (passKey) {
|
||||||
// TODO: use passkey
|
data = passKey->encrypt(data);
|
||||||
data = ToxEncrypt::encryptPass(password, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f.write(data);
|
f.write(data);
|
||||||
|
@ -327,19 +326,19 @@ void SettingsSerializer::readSerialized()
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
if (tox_is_data_encrypted(reinterpret_cast<uint8_t*>(data.data()))) {
|
if (ToxEncrypt::isEncrypted(data)) {
|
||||||
if (password.isEmpty()) {
|
if (!passKey) {
|
||||||
qCritical() << "The settings file is encrypted, but we don't have a password!";
|
qCritical() << "The settings file is encrypted, but we don't have a passkey!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = ToxEncrypt::decryptPass(password, data);
|
data = passKey->decrypt(data);
|
||||||
if (data.isEmpty()) {
|
if (data.isEmpty()) {
|
||||||
qCritical() << "Failed to decrypt the settings file";
|
qCritical() << "Failed to decrypt the settings file";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!password.isEmpty())
|
if (passKey)
|
||||||
qWarning() << "We have a password, but the settings file is not encrypted";
|
qWarning() << "We have a password, but the settings file is not encrypted";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#ifndef SETTINGSSERIALIZER_H
|
#ifndef SETTINGSSERIALIZER_H
|
||||||
#define SETTINGSSERIALIZER_H
|
#define SETTINGSSERIALIZER_H
|
||||||
|
|
||||||
|
#include "src/core/toxencrypt.h"
|
||||||
|
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -28,7 +30,7 @@
|
||||||
class SettingsSerializer
|
class SettingsSerializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SettingsSerializer(QString filePath, const QString& password = QString());
|
SettingsSerializer(QString filePath, const ToxEncrypt* passKey = nullptr);
|
||||||
|
|
||||||
static bool isSerializedFormat(QString filePath);
|
static bool isSerializedFormat(QString filePath);
|
||||||
|
|
||||||
|
@ -102,7 +104,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString path;
|
QString path;
|
||||||
QString password;
|
const ToxEncrypt* passKey;
|
||||||
int group, array, arrayIndex;
|
int group, array, arrayIndex;
|
||||||
QVector<QString> groups;
|
QVector<QString> groups;
|
||||||
QVector<Array> arrays;
|
QVector<Array> arrays;
|
||||||
|
|
|
@ -433,11 +433,15 @@ void ProfileForm::onDeletePassClicked()
|
||||||
"deletion confirmation text")))
|
"deletion confirmation text")))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Nexus::getProfile()->setPassword(QString());
|
QString errorMsg = pro->setPassword(QString());
|
||||||
|
if (!errorMsg.isEmpty()) {
|
||||||
|
GUI::showInfo(tr("Couldn't change password"), errorMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileForm::onChangePassClicked()
|
void ProfileForm::onChangePassClicked()
|
||||||
{
|
{
|
||||||
|
Profile* p = Nexus::getProfile();
|
||||||
SetPasswordDialog* dialog =
|
SetPasswordDialog* dialog =
|
||||||
new SetPasswordDialog(tr("Please enter a new password."), QString(), 0);
|
new SetPasswordDialog(tr("Please enter a new password."), QString(), 0);
|
||||||
int r = dialog->exec();
|
int r = dialog->exec();
|
||||||
|
@ -445,7 +449,10 @@ void ProfileForm::onChangePassClicked()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString newPass = dialog->getPassword();
|
QString newPass = dialog->getPassword();
|
||||||
Nexus::getProfile()->setPassword(newPass);
|
QString errorMsg = p->setPassword(newPass);
|
||||||
|
if (!errorMsg.isEmpty()) {
|
||||||
|
GUI::showInfo(tr("Couldn't change password"), errorMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileForm::retranslateUi()
|
void ProfileForm::retranslateUi()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user