|
|
|
@ -33,6 +33,7 @@
@@ -33,6 +33,7 @@
|
|
|
|
|
#include <QThread> |
|
|
|
|
#include <QObject> |
|
|
|
|
#include <QDebug> |
|
|
|
|
#include <sodium.h> |
|
|
|
|
|
|
|
|
|
QVector<QString> Profile::profiles; |
|
|
|
|
|
|
|
|
@ -325,9 +326,18 @@ void Profile::saveToxSave(QByteArray data)
@@ -325,9 +326,18 @@ void Profile::saveToxSave(QByteArray data)
|
|
|
|
|
newProfile = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString Profile::avatarPath(const QString &ownerId) |
|
|
|
|
QString Profile::avatarPath(const QString &ownerId, bool forceUnencrypted) |
|
|
|
|
{ |
|
|
|
|
return Settings::getInstance().getSettingsDirPath() + "avatars/" + ownerId + ".png"; |
|
|
|
|
if (password.isEmpty() || forceUnencrypted) |
|
|
|
|
return Settings::getInstance().getSettingsDirPath() + "avatars/" + ownerId + ".png"; |
|
|
|
|
|
|
|
|
|
QByteArray idData = ownerId.toUtf8(); |
|
|
|
|
constexpr int hashSize = TOX_PUBLIC_KEY_SIZE; // As long as an unencrypted hash
|
|
|
|
|
static_assert(hashSize >= crypto_generichash_BYTES_MIN |
|
|
|
|
&& hashSize <= crypto_generichash_BYTES_MAX, "Hash size not supported by libsodium"); |
|
|
|
|
QByteArray hash(hashSize, 0); |
|
|
|
|
crypto_generichash((uint8_t*)hash.data(), hashSize, (uint8_t*)idData.data(), idData.size(), nullptr, 0); |
|
|
|
|
return Settings::getInstance().getSettingsDirPath() + "avatars/" + hash.toHex().toUpper() + ".png"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QPixmap Profile::loadAvatar() |
|
|
|
@ -344,16 +354,38 @@ QPixmap Profile::loadAvatar(const QString &ownerId)
@@ -344,16 +354,38 @@ QPixmap Profile::loadAvatar(const QString &ownerId)
|
|
|
|
|
|
|
|
|
|
QByteArray Profile::loadAvatarData(const QString &ownerId) |
|
|
|
|
{ |
|
|
|
|
QFile file(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 (!password.isEmpty() && !QFile::exists(path)) |
|
|
|
|
{ |
|
|
|
|
encrypted = false; |
|
|
|
|
path = avatarPath(ownerId, true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QFile file(path); |
|
|
|
|
if (!file.open(QIODevice::ReadOnly)) |
|
|
|
|
return {}; |
|
|
|
|
return file.readAll(); |
|
|
|
|
|
|
|
|
|
QByteArray pic = file.readAll(); |
|
|
|
|
if (encrypted) |
|
|
|
|
{ |
|
|
|
|
uint8_t salt[TOX_PASS_SALT_LENGTH]; |
|
|
|
|
tox_get_salt(reinterpret_cast<uint8_t *>(pic.data()), salt); |
|
|
|
|
auto passkey = core->createPasskey(password, salt); |
|
|
|
|
pic = core->decryptData(pic, *passkey); |
|
|
|
|
} |
|
|
|
|
return pic; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Profile::saveAvatar(QByteArray pic, const QString &ownerId) |
|
|
|
|
{ |
|
|
|
|
if (!password.isEmpty()) |
|
|
|
|
pic = core->encryptData(pic, passkey); |
|
|
|
|
|
|
|
|
|
QString path = avatarPath(ownerId); |
|
|
|
|
QSaveFile file(avatarPath(ownerId)); |
|
|
|
|
QSaveFile file(path); |
|
|
|
|
if (!file.open(QIODevice::WriteOnly)) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "Tox avatar " << path << " couldn't be saved"; |
|
|
|
|