[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix.spec
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -2,6 +2,6 @@
<service name="tar_git">
<param name="url">https://gitlab.com/HengYeDev/harbour-sailtrix</param>
<param name="branch">master</param>
- <param name="revision">1.3.10</param>
+ <param name="revision">1.4</param>
</service>
</services>
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/harbour-sailtrix.pro
^
|
@@ -120,6 +120,7 @@
qml/logged-in.qml \
qml/pages/CreateRoom.qml \
qml/pages/Credits.qml \
+ qml/pages/ErrorPage.qml \
qml/pages/Invite.qml \
qml/pages/JoinPublicRoom.qml \
qml/pages/LoginDialog.qml \
@@ -196,6 +197,7 @@
src/dbus/notifications.h \
src/dbus/sailtrixadapter.h \
src/dbus/sailtrixsignals.h \
+ src/emoji.h \
src/enc-util.h \
src/invitebackend.h \
src/loginbridge.h \
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/qml/custom/RoomsDisplay.qml
^
|
@@ -54,12 +54,30 @@
visible: type === "Rooms"
onClicked: pageStack.push("../pages/CreateRoom.qml");
}
+
+ MenuItem {
+ text: headerItem.visible ? qsTr("Hide Search") : qsTr("Search")
+ onClicked: {
+ headerItem.visible = !headerItem.visible
+ headerItem.height = headerItem.height == 0 ? Theme.itemSizeMedium : 0
+ searchBar.text = "";
+ }
+ }
}
section.property: "section_name"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
+ header: SearchField {
+ width: parent.width
+ placeholderText: qsTr("Search")
+ id: searchBar
+ visible: false
+ height: 0
+ onTextChanged: rooms.search(text)
+ }
+
onCountChanged: console.log("COUNT CHANGED: " + count)
delegate: ListItem {
@@ -98,7 +116,7 @@
if (is_invite) {
pageStack.push("../pages/Invite.qml", { name: name, room_id: rid, is_direct: is_direct});
} else {
- pageStack.push("../pages/Messages.qml", { room_name: name, room_id: rid});
+ pageStack.push("../pages/Messages.qml", { room_name: name, room_id: rid, roomIconPath: img.source});
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/qml/pages/Credits.qml
^
|
@@ -18,7 +18,7 @@
spacing: Theme.paddingLarge
Label {
- text: "Sailtrix 1.3.10"
+ text: "Sailtrix 1.4"
color: Theme.highlightColor
font.family: Theme.fontFamilyHeading
font.pixelSize: Theme.fontSizeLarge
|
[-]
[+]
|
Added |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/qml/pages/ErrorPage.qml
^
|
@@ -0,0 +1,42 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+Page {
+ id: page
+
+ allowedOrientations: Orientation.All
+
+ property string errorMsg;
+
+ PageHeader {
+ title: qsTr("Error")
+ }
+
+ Column {
+ id: column
+
+ width: page.width
+ anchors.verticalCenter: parent.verticalCenter
+ spacing: Theme.paddingLarge
+
+
+
+ Label {
+ text: "Error"
+ color: Theme.errorColor
+ font.family: Theme.fontFamilyHeading
+ font.pixelSize: Theme.fontSizeLarge
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+
+ Label {
+ text: errorMsg
+ color: Theme.errorColor
+ width: parent.width
+ leftPadding: Theme.horizontalPageMargin
+ rightPadding: Theme.horizontalPageMargin
+ wrapMode: "WrapAtWordBoundaryOrAnywhere"
+ }
+ }
+}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/qml/pages/LoginDialog.qml
^
|
@@ -10,6 +10,7 @@
bridge.homeserverUrl = homeserverUrl.text
bridge.username = username.text
bridge.password = password.text
+ bridge.deviceName = displayName.text
bridge.login()
pageStack.push("LoginWaiting.qml", { lBridge: bridge });
}
@@ -18,47 +19,62 @@
id: bridge
}
- Column {
- id: column
+ SilicaFlickable {
+ anchors.fill: parent
+ contentHeight: column.height
+ contentWidth: column.width
+ Column {
+ id: column
+
+ width: page.width
+ height: page.height
+ spacing: Theme.paddingLarge
- width: parent.width
- spacing: Theme.paddingLarge
+ DialogHeader {
+ title: qsTr("Login")
+ }
- DialogHeader {
- title: qsTr("Login")
- }
+ TextField {
+ label: qsTr("Homeserver")
+ placeholderText: qsTr("Homeserver URL (matrix.org)")
+ width: parent.width
+ id: homeserverUrl
+ EnterKey.iconSource: "image://theme/icon-m-enter-next"
+ EnterKey.onClicked: username.focus = true
+ validator: RegExpValidator { regExp: /^((?!-))(xn--)?[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.(xn--)?([a-zA-Z0-9\-]{1,61}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,})$/ }
+ }
- TextField {
- label: qsTr("Homeserver")
- placeholderText: qsTr("Homeserver URL (matrix.org)")
- width: parent.width
- id: homeserverUrl
- EnterKey.iconSource: "image://theme/icon-m-enter-next"
- EnterKey.onClicked: username.focus = true
- validator: RegExpValidator { regExp: /^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/ }
- }
+ TextField {
+ label: qsTr("Username")
+ placeholderText: qsTr("Username (user1)")
+ width: parent.width
+ id: username
+ EnterKey.iconSource: "image://theme/icon-m-enter-next"
+ EnterKey.onClicked: password.focus = true
+ validator: RegExpValidator { regExp: /^[^@:]*$/ }
+ }
- TextField {
- label: qsTr("Username")
- placeholderText: qsTr("Username (user1)")
- width: parent.width
- id: username
- EnterKey.iconSource: "image://theme/icon-m-enter-next"
- EnterKey.onClicked: password.focus = true
- validator: RegExpValidator { regExp: /^[^@:]*$/ }
- }
+ PasswordField {
+ label: qsTr("Password")
+ width: parent.width
+ id: password
+ EnterKey.iconSource: "image://theme/icon-m-enter-accept"
+ EnterKey.onClicked: {
+ bridge.homeserverUrl = homeserverUrl.text
+ bridge.username = username.text
+ bridge.password = password.text
+ bridge.deviceName = displayName.text
+ bridge.login()
+ pageStack.push("LoginWaiting.qml", { lBridge: bridge });
+ }
+ }
- PasswordField {
- label: qsTr("Password")
- width: parent.width
- id: password
- EnterKey.iconSource: "image://theme/icon-m-enter-accept"
- EnterKey.onClicked: {
- bridge.homeserverUrl = homeserverUrl.text
- bridge.username = username.text
- bridge.password = password.text
- bridge.login()
- pageStack.push("LoginWaiting.qml", { lBridge: bridge });
+ TextField {
+ label: qsTr("Device display name");
+ placeholderText: "Sailtrix on SailfishOS"
+ width: parent.width
+ id: displayName
+ text: "Sailtrix on SailfishOS"
}
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/qml/pages/Messages.qml
^
|
@@ -17,6 +17,7 @@
property string room_name
property string file_name;
property bool downloading;
+ property string roomIconPath;
function formatTimestamp(timestamp) {
var date = new Date(timestamp);
@@ -81,17 +82,28 @@
id: settings
}
- PageHeader {
- title: room_name
- anchors.top: page.top
- id: page_header
- }
-
SilicaFlickable {
- width: parent.width
- height: parent.height - page_header.height
- anchors.bottom: parent.bottom
+ PageHeader {
+ title: room_name
+ anchors.top: parent.top
+ id: page_header
+ rightMargin: roomIcon.width + Theme.horizontalPageMargin*2
+ }
+ Image {
+ source: roomIconPath
+ width: page_header.height - Theme.horizontalPageMargin*2
+ height: width
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.topMargin: Theme.horizontalPageMargin
+ anchors.rightMargin: Theme.horizontalPageMargin
+ id: roomIcon
+ }
+
+ contentWidth: parent.width
+ contentHeight: parent.height
+ anchors.fill: parent
SilicaListView {
VerticalScrollDecorator {}
@@ -100,16 +112,11 @@
width: page.width
spacing: Theme.paddingLarge
- anchors.top: parent.top
+ anchors.top: page_header.bottom
anchors.bottom: messageArea.top
anchors.bottomMargin: Theme.paddingLarge
clip: true
- /* header: PageHeader {
- title: room_name
- anchors.top:
- } */
-
model: backend.messages
delegate: ListItem {
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/qml/pages/Rooms.qml
^
|
@@ -11,6 +11,9 @@
property string active_room;
property int notifs;
+ property string emojis;
+ property string emojiLabels;
+ property bool errored: false;
objectName: "Rooms"
@@ -18,8 +21,60 @@
id: rooms
onNotifCountChanged: notifs = notifCount
+ onGotVerification: {
+ emojis = emoji;
+ emojiLabels = text;
+ pageStack.push(verifDialog)
+ }
+
+ onError: {
+ errored = true;
+ pageStack.push("ErrorPage.qml", {errorMsg: errorMsg});
+ }
}
+ Component {
+ id: verifDialog;
+
+ Dialog {
+ Column {
+ DialogHeader {
+ id: v_dh
+ title: "Verify emoji"
+ acceptText: "Match"
+ cancelText: "No match"
+ }
+ width: parent.width
+
+ Label {
+ text: emojis;
+ wrapMode: "WrapAtWordBoundaryOrAnywhere"
+ leftPadding: Theme.horizontalPageMargin
+ rightPadding: Theme.horizontalPageMargin
+ font.pixelSize: Theme.fontSizeHuge;
+ width: parent.width
+ }
+
+ Label {
+ text: emojiLabels;
+ wrapMode: "WrapAtWordBoundaryOrAnywhere"
+ leftPadding: Theme.horizontalPageMargin
+ rightPadding: Theme.horizontalPageMargin
+ width: parent.width
+ }
+
+ Label {
+ text: "Note: emoji verification is still experimental"
+ wrapMode: "WrapAtWordBoundaryOrAnywhere"
+ leftPadding: Theme.horizontalPageMargin
+ rightPadding: Theme.horizontalPageMargin
+ width: parent.width
+ color: Theme.errorColor
+ }
+ }
+ onAccepted: rooms.verifMatched()
+ }
+ }
Connections {
@@ -152,14 +207,16 @@
if (status == PageStatus.Inactive) {
rooms.pause();
} else if (status == PageStatus.Active) {
- rooms.reloadSettings();
- if (rooms.loaded()) {
- rooms.mark_read(active_room);
- active_room = "";
- rooms.resume();
+ if (!errored) {
+ rooms.reloadSettings();
+ if (rooms.loaded()) {
+ rooms.mark_read(active_room);
+ active_room = "";
+ rooms.resume();
+ }
+ else
+ rooms.load();
}
- else
- rooms.load();
}
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/src/dbus/notifications.cpp
^
|
@@ -298,8 +298,10 @@
iter.value()->close();
delete iter.value();
}
+
notifications_map.clear();
new_notifications.clear();
+
}
void Notifications::resume() {
@@ -317,3 +319,5 @@
}
return activity->isStopped();
}
+
+
|
[-]
[+]
|
Added |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/src/emoji.h
^
|
@@ -0,0 +1,8 @@
+#ifndef EMOJI_H
+#define EMOJI_H
+#include <QStringList>
+
+const QStringList SAS_EMOJIS = {"🐶", "🐱", "🦁", "🐎", "🦄", "🐷", "🐘", "🐰", "🐼", "🐓", "🐧", "🐢", "🐟", "🐙", "🦋", "🌷", "🌳", "🌵", "🍄", "🌏", "🌙", "☁️", "🔥", "🍌", "🍎", "🍓", "🌽", "🍕", "🎂", "❤️", "😀", "🤖", "🎩", "👓", "🔧", "🎅", "👍", "☂️", "⌛", "⏰", "🎁", "💡", "📕", "✏️", "📎", "✂️", "🔒", "🔑", "🔨", "☎️", "🏁", "🚂", "🚲", "✈️", "🚀", "🏆", "⚽", "🎸", "🎺", "🔔", "⚓", "🎧", "📁", "📌"};
+const QStringList SAS_EMOJI_TEXT = {"Dog", "Cat", "Lion", "Horse", "Unicorn", "Pig", "Elephant", "Rabbit", "Panda", "Rooster", "Penguin", "Turtle", "Fish", "Octopus", "Butterfly", "Flower", "Tree", "Cactus", "Mushroom", "Globe", "Moon", "Cloud", "Fire", "Banana", "Apple", "Strawberry", "Corn", "Pizza", "Cake", "Heart", "Smiley", "Robot", "Hat", "Glasses", "Spanner", "Santa", "Thumbs Up", "Umbrella", "Hourglass", "Clock", "Gift", "Light Bulb", "Book", "Pencil", "Paperclip", "Scissors", "Lock", "Key", "Hammer", "Telephone", "Flag", "Train", "Bicycle", "Aeroplane", "Rocket", "Trophy", "Ball", "Guitar", "Trumpet", "Bell", "Anchor", "Headphones", "Folder", "Pin"};
+
+#endif // EMOJI_H
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/src/enc-util.cpp
^
|
@@ -6,6 +6,7 @@
#include <QJsonDocument>
#include <QJsonArray>
#include <QDebug>
+#include <QCryptographicHash>
#include <olm/olm.hh>
#include <QUuid>
#include <Sailfish/Secrets/secret.h>
@@ -869,3 +870,7 @@
memcpy(buf, randomBytes.data(), num);
return 1;
}
+
+QString commitment(QString canonical_json, QString ephemerasPK) {
+ return QCryptographicHash::hash(QString(ephemerasPK + canonical_json).toUtf8(), QCryptographicHash::Sha256).toBase64(QByteArray::OmitTrailingEquals);
+}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/src/enc-util.h
^
|
@@ -6,6 +6,7 @@
#include <QJsonDocument>
#include <QByteArray>
#include <olm/olm.h>
+#include <olm/sas.h>
#include <Sailfish/Secrets/secretmanager.h>
#include <Sailfish/Secrets/secret.h>
#include <Sailfish/Crypto/key.h>
@@ -39,5 +40,6 @@
QByteArray file_dec2(Crypto::CryptoManager* manager, QByteArray ciphertext, QByteArray key, QByteArray iv);
QByteArray encrypt_bytes(Crypto::CryptoManager* manager, QByteArray data, QString& key_str, QString& iv_str);
int SailfishCryptoRAND_bytes(unsigned char* buf, int num, Crypto::CryptoManager* manager);
+QString commitment(QString canonical_json, QString ephemerasPK);
#endif // ENCUTIL_H
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/src/loginbridge.cpp
^
|
@@ -64,6 +64,13 @@
m_password = password;
}
+QString LoginBridge::deviceName() {
+ return m_device_name;
+}
+
+void LoginBridge::setDeviceName(const QString &dn) {
+ m_device_name = dn;
+}
QString LoginBridge::error() {
return m_error;
}
@@ -155,7 +162,7 @@
obj.insert("identifier", identifier);
obj.insert("password", password());
- obj.insert("initial_device_display_name", "Sailtrix on SailfishOS");
+ obj.insert("initial_device_display_name", m_device_name);
QNetworkRequest loginRequest(QString(homeserver_url.toString() + "/_matrix/client/r0/login"));
loginRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/src/loginbridge.h
^
|
@@ -18,6 +18,7 @@
Q_PROPERTY(QString username READ username WRITE setUsername)
Q_PROPERTY(QString password READ password WRITE setPassword)
Q_PROPERTY(QString error READ error WRITE setError NOTIFY errorChanged)
+ Q_PROPERTY(QString deviceName READ deviceName WRITE setDeviceName)
public:
Q_INVOKABLE void login(bool serverDiscoveryOnly = false);
Q_INVOKABLE void ssoLogin(QString token);
@@ -25,10 +26,12 @@
QString username();
QString password();
QString error();
+ QString deviceName();
void setHomeserverUrl(const QString &hsUrl);
void setUsername(const QString &username);
void setPassword(const QString &password);
void setError(const QString &error);
+ void setDeviceName(const QString &dn);
signals:
void errorChanged();
void discovered();
@@ -44,6 +47,7 @@
QString m_username;
QString m_password;
QString m_error;
+ QString m_device_name;
bool m_serverDiscoveryOnly = false;
QNetworkAccessManager* manager;
QNetworkAccessManager* keys_upload;
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/src/messages.cpp
^
|
@@ -1160,7 +1160,7 @@
item->setData(url, MessagesModel::img_url);
item->setData(key, MessagesModel::key);
item->setData(iv, MessagesModel::iv);
- item->setData(content.value("info").toObject().value("mimetype").toString(), MessagesModel::mime_type);
+ item->setData(content.value("info").toObject().value("mimetype").toString() != "" ? content.value("info").toObject().value("mimetype").toString() : content.value("file").toObject().value("mimetype").toString() , MessagesModel::mime_type);
qDebug() << "Mimetype: " << content.value("file").toObject().value("mimetype").toString();
item->setData(content.value("file").toObject().value("hashes").toObject().value("sha256").toString(), MessagesModel::sha256hash);
@@ -2267,7 +2267,7 @@
QDir output_dir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/org.yeheng/sailtrix/files/" + hostname);
output_dir.mkpath(output_dir.path());
- qDebug() << "Saving encrypted image";
+ qDebug() << "Saving encrypted image" << m_messages->data(m_messages->index(i, 0), MessagesModel::mime_type).toString();
save_image(decrypted, out_path, hostname, media_id, m_messages->data(m_messages->index(i, 0), MessagesModel::mime_type).toString());
}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/src/rooms.cpp
^
|
@@ -12,7 +12,12 @@
#include <QMimeDatabase>
#include <QUrl>
#include <QSortFilterProxyModel>
+#include <QBitArray>
+#include <bitset>
#include "enc-util.h"
+#include "emoji.h"
+
+using namespace std;
RoomsModel* Rooms::rooms() { return m_rooms; }
@@ -62,7 +67,7 @@
}
}
-Rooms::Rooms() : m_rooms{ new RoomsModel }, m_direct_rooms { new QSortFilterProxyModel }, m_regular_rooms { new QSortFilterProxyModel }, m_invites { new QSortFilterProxyModel }, m_favorites { new QSortFilterProxyModel }, m_master_obj {new QJsonObject }, olm_sessions { new QJsonObject}, megolm_sessions {new QJsonObject} , m_reply { nullptr }, message_index { 0 }, get_all { false } , load_finished { false }, m_invite_total {0}, m_direct_total {0} {
+Rooms::Rooms() : m_rooms{ new RoomsModel }, m_search_rooms { new QSortFilterProxyModel }, m_direct_rooms { new QSortFilterProxyModel }, m_regular_rooms { new QSortFilterProxyModel }, m_invites { new QSortFilterProxyModel }, m_favorites { new QSortFilterProxyModel }, m_master_obj {new QJsonObject }, olm_sessions { new QJsonObject}, megolm_sessions {new QJsonObject} , m_reply { nullptr }, message_index { 0 }, get_all { false } , load_finished { false }, m_invite_total {0}, m_direct_total {0} {
bool sort_by_alphabet = false;
QFile settings(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/org.yeheng/sailtrix/settings.json");
@@ -74,7 +79,12 @@
settings.close();
}
- m_direct_rooms->setSourceModel(m_rooms);
+ m_search_rooms->setSourceModel(m_rooms);
+ m_search_rooms->setFilterRole(RoomsModel::name);
+ m_search_rooms->setFilterKeyColumn(0);
+ m_search_rooms->setFilterCaseSensitivity(Qt::CaseInsensitive);
+
+ m_direct_rooms->setSourceModel(m_search_rooms);
m_direct_rooms->setFilterRole(RoomsModel::section_name);
m_direct_rooms->setFilterKeyColumn(0);
m_direct_rooms->setFilterFixedString(QStringLiteral("Direct Messages"));
@@ -91,7 +101,7 @@
m_direct_rooms->sort(0, Qt::DescendingOrder);
}
- m_regular_rooms->setSourceModel(m_rooms);
+ m_regular_rooms->setSourceModel(m_search_rooms);
m_regular_rooms->setFilterRole(RoomsModel::section_name);
m_regular_rooms->setFilterKeyColumn(0);
m_regular_rooms->setFilterFixedString(QStringLiteral("Rooms"));
@@ -109,7 +119,7 @@
}
- m_invites->setSourceModel(m_rooms);
+ m_invites->setSourceModel(m_search_rooms);
m_invites->setFilterRole(RoomsModel::section_name);
m_invites->setFilterKeyColumn(0);
m_invites->setFilterFixedString(QStringLiteral("Invites"));
@@ -117,7 +127,7 @@
m_invites->sort(0);
m_invites->setSortCaseSensitivity(Qt::CaseInsensitive);
- m_favorites->setSourceModel(m_rooms);
+ m_favorites->setSourceModel(m_search_rooms);
m_favorites->setFilterRole(RoomsModel::section_name);
m_favorites->setFilterKeyColumn(0);
m_favorites->setFilterFixedString(QStringLiteral("Favorites"));
@@ -317,12 +327,14 @@
account_data_getter = new QNetworkAccessManager(this);
user_info_getter = new QNetworkAccessManager(this);
tagger = new QNetworkAccessManager(this);
+ toDeviceSender = new QNetworkAccessManager(this);
connect(manager, &QNetworkAccessManager::finished, this, &Rooms::handleRooms);
connect(key_uploader, &QNetworkAccessManager::finished, this, &Rooms::uploadKeysDone);
connect(account_data_getter, &QNetworkAccessManager::finished, this, &Rooms::processAccountData);
connect(user_info_getter, &QNetworkAccessManager::finished, this, &Rooms::processUserInfo);
connect(tagger, &QNetworkAccessManager::finished, this, &Rooms::setTagDone);
+ connect(toDeviceSender, &QNetworkAccessManager::finished, this, &Rooms::onToDeviceSent);
m_local_key = get_key(&m_cryptoManager, file_key());
@@ -453,6 +465,7 @@
if (reply->error() != QNetworkReply::NoError) {
qWarning() << "sync error: " << reply->errorString();
+ emit error(reply->errorString());
return;
}
@@ -577,7 +590,145 @@
}
}
+ } else if (type == QStringLiteral("m.key.verification.request")) {
+ if (!verifs.keys().contains(event_obj.value("content").toObject().value("transaction_id").toString())) {
+ QNetworkRequest req(hs_url + QStringLiteral("/_matrix/client/r0/sendToDevice/m.key.verification.ready/") + get_uuid());
+
+ QJsonObject parentObj;
+ QJsonObject messages;
+ QJsonObject sender;
+ QJsonObject device;
+ QJsonArray methods;
+
+ methods.append(QStringLiteral("m.sas.v1"));
+ device.insert(QStringLiteral("methods"), methods);
+ device.insert(QStringLiteral("from_device"), device_id);
+ device.insert(QStringLiteral("transaction_id"), event_obj.value("content").toObject().value("transaction_id").toString());
+
+ sender.insert(event_obj.value("content").toObject().value("from_device").toString(), device);
+
+ messages.insert(event_obj.value("sender").toString(), sender);
+ parentObj.insert("messages", messages);
+ req.setRawHeader(QByteArray("Authorization"), (QString("Bearer " + access_token).toUtf8()));
+ verifs.insert(event_obj.value("content").toObject().value("transaction_id").toString(), event_obj.value("content").toObject().value("from_device").toString());
+ qDebug() << QJsonDocument(parentObj).toJson();
+ toDeviceSender->put(req, QJsonDocument(parentObj).toJson());
+ }
+ } else if (type == QStringLiteral("m.key.verification.start")) {
+ if (!startedVerifs.keys().contains(event_obj.value("content").toObject().value("transaction_id").toString())) {
+ qDebug() << "Starting verif";
+
+ sas = (OlmSAS*) malloc(olm_sas_size());
+ sas = olm_sas(sas);
+
+ unsigned char* random = (unsigned char*) malloc(olm_create_sas_random_length(sas));
+ SailfishCryptoRAND_bytes(random, olm_create_sas_random_length(sas), &m_cryptoManager);
+ olm_create_sas(sas, random, olm_create_sas_random_length(sas));
+ free(random);
+
+ char* ephemeralPK = (char*) malloc(olm_sas_pubkey_length(sas));
+ int res = olm_sas_get_pubkey(sas, ephemeralPK, olm_sas_pubkey_length(sas));
+
+
+ ephemeralPubkey = QString::fromUtf8(ephemeralPK, olm_sas_pubkey_length(sas));
+ free(ephemeralPK);
+
+ qDebug() << "KEY" << ephemeralPubkey << "ERR" << res;
+
+ QString cm = commitment(canonical_json(QJsonDocument(event_obj.value("content").toObject())), ephemeralPubkey);
+ qDebug() << "Commitment:" << QString(ephemeralPubkey + canonical_json(QJsonDocument(event_obj.value("content").toObject())));
+
+ QJsonObject parentObj;
+ QJsonObject messages;
+ QJsonObject sender;
+ QJsonObject device;
+
+ device.insert(QStringLiteral("method"), QStringLiteral("m.sas.v1"));
+ device.insert(QStringLiteral("key_agreement_protocol"), QStringLiteral("curve25519-hkdf-sha256"));
+ device.insert(QStringLiteral("hash"), QStringLiteral("sha256"));
+ device.insert(QStringLiteral("message_authentication_code"), QStringLiteral("hkdf-hmac-sha256"));
+ QJsonArray sasMethods;
+ sasMethods.append(QStringLiteral("emoji"));
+ sasMethods.append(QStringLiteral("decimal"));
+
+ device.insert(QStringLiteral("short_authentication_string"), sasMethods);
+ device.insert(QStringLiteral("commitment"), cm);
+ device.insert(QStringLiteral("transaction_id"), event_obj.value("content").toObject().value("transaction_id").toString());
+ sender.insert(event_obj.value("content").toObject().value("from_device").toString(), device);
+
+ messages.insert(event_obj.value("sender").toString(), sender);
+ parentObj.insert("messages", messages);
+ QNetworkRequest req(hs_url + QStringLiteral("/_matrix/client/r0/sendToDevice/m.key.verification.accept/") + get_uuid());
+ req.setRawHeader(QByteArray("Authorization"), (QString("Bearer " + access_token).toUtf8()));
+ qDebug() << QJsonDocument(parentObj).toJson();
+
+ toDeviceSender->put(req, QJsonDocument(parentObj).toJson());
+ current_txn = event_obj.value("content").toObject().value("transaction_id").toString();
+ startedVerifs.insert(event_obj.value("content").toObject().value("transaction_id").toString(), event_obj.value("content").toObject().value("from_device").toString());
+ }
+ } else if (type == QStringLiteral("m.key.verification.key")) {
+ if (event_obj.value("content").toObject().value("transaction_id").toString() == current_txn && !gotEmojiVerifs.contains(current_txn)) {
+ size_t err = olm_sas_set_their_key(sas, event_obj.value("content").toObject().value("key").toString().toLocal8Bit().data(), event_obj.value("content").toObject().value("key").toString().toLocal8Bit().length());
+ qDebug() << "Key error:" << err;
+
+ QJsonObject parentObj;
+ QJsonObject messages;
+ QJsonObject sender;
+ QJsonObject device;
+
+ device.insert(QStringLiteral("key"), ephemeralPubkey);
+ device.insert(QStringLiteral("transaction_id"), event_obj.value("content").toObject().value("transaction_id").toString());
+ sender.insert(verifs.value(current_txn), device);
+
+ messages.insert(event_obj.value("sender").toString(), sender);
+ verif_uid = event_obj.value("sender").toString();
+ parentObj.insert("messages", messages);
+ QNetworkRequest req(hs_url + QStringLiteral("/_matrix/client/r0/sendToDevice/m.key.verification.key/") + get_uuid());
+ req.setRawHeader(QByteArray("Authorization"), (QString("Bearer " + access_token).toUtf8()));
+ qDebug() << QJsonDocument(parentObj).toJson();
+
+ toDeviceSender->put(req, QJsonDocument(parentObj).toJson());
+
+ QString sasInfo = QStringLiteral("MATRIX_KEY_VERIFICATION_SAS|") + event_obj.value("sender").toString() + '|' + startedVerifs.value(current_txn) + '|' +
+ event_obj.value("content").toObject().value("key").toString() + '|' + user_id + '|' + device_id + '|' + ephemeralPubkey + '|' + current_txn;
+
+ qDebug() << "SAS Info:" << sasInfo;
+
+ char* outputArr = (char*) malloc(6);
+ olm_sas_generate_bytes(sas, sasInfo.toLocal8Bit().constData(), sasInfo.toLocal8Bit().length(), outputArr, 6);
+
+
+ QByteArray bytes = QByteArray(outputArr, 6);
+ qDebug() << bytes.toBase64();
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/src/rooms.h
^
|
@@ -8,6 +8,7 @@
#include <QUrl>
#include <QJsonObject>
#include <olm/olm.h>
+#include <olm/sas.h>
#include <QSortFilterProxyModel>
#include <Sailfish/Secrets/secretmanager.h>
#include <Sailfish/Crypto/cryptomanager.h>
@@ -35,6 +36,7 @@
Q_INVOKABLE bool load();
Q_INVOKABLE void leave(QString room_id);
RoomsModel* rooms();
+
QSortFilterProxyModel* directRooms();
QSortFilterProxyModel* regularRooms();
QSortFilterProxyModel* invites();
@@ -50,6 +52,8 @@
Q_INVOKABLE void reloadSettings();
Q_INVOKABLE void setFavorite(QString room_id);
Q_INVOKABLE void unFavorite(QString room_id);
+ Q_INVOKABLE void search(QString searchPattern);
+ Q_INVOKABLE void verifMatched();
bool done();
int notifCount();
@@ -63,6 +67,8 @@
void invitesChanged();
void notifCountChanged();
void favoritesChanged();
+ void gotVerification(QString emoji, QString text);
+ void error(QString errorMsg);
private:
QNetworkAccessManager* manager = nullptr;
QNetworkAccessManager* imageDownloader = nullptr;
@@ -72,7 +78,9 @@
QNetworkAccessManager* account_data_getter = nullptr;
QNetworkAccessManager* user_info_getter = nullptr;
QNetworkAccessManager* tagger = nullptr;
+ QNetworkAccessManager* toDeviceSender = nullptr;
RoomsModel* m_rooms = nullptr;
+ QSortFilterProxyModel* m_search_rooms = nullptr;
QSortFilterProxyModel* m_direct_rooms = nullptr;
QSortFilterProxyModel* m_regular_rooms = nullptr;
QSortFilterProxyModel* m_invites = nullptr;
@@ -91,7 +99,14 @@
QString m_curve25519_id;
QString m_ed25519_id;
+ QMap<QString,QString> verifs;
+ QMap<QString,QString> startedVerifs;
+ QMap<QString,QString> gotEmojiVerifs;
+ QString verif_uid;
+
+ QString current_txn;
OlmAccount* account;
+ QString ephemeralPubkey;
int num_keys_on_server;
void loadCache(QJsonDocument doc);
QString get_filter_json();
@@ -107,8 +122,13 @@
Crypto::CryptoManager m_cryptoManager;
Crypto::Key m_local_key;
QJsonObject dm_obj;
+
int m_invite_total;
int m_direct_total;
+
+ OlmSAS* sas;
+
+ QString calculateMac(QString input, QString info);
private slots:
void handleRooms(QNetworkReply* reply);
void downloadRoomAvatar(QNetworkReply* reply);
@@ -118,6 +138,7 @@
void processUserInfo(QNetworkReply* reply);
void onRoomsChanged();
void setTagDone(QNetworkReply* reply);
+ void onToDeviceSent(QNetworkReply* reply);
QUrl getUrl();
};
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix-1.4.tar.bz2/translations/harbour-sailtrix.ts
^
|
@@ -70,6 +70,14 @@
</message>
</context>
<context>
+ <name>ErrorPage</name>
+ <message>
+ <location filename="../qml/pages/ErrorPage.qml" line="12"/>
+ <source>Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>Invite</name>
<message>
<location filename="../qml/pages/Invite.qml" line="15"/>
@@ -126,35 +134,40 @@
<context>
<name>LoginDialog</name>
<message>
- <location filename="../qml/pages/LoginDialog.qml" line="28"/>
+ <location filename="../qml/pages/LoginDialog.qml" line="34"/>
<source>Login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/LoginDialog.qml" line="32"/>
+ <location filename="../qml/pages/LoginDialog.qml" line="38"/>
<source>Homeserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/LoginDialog.qml" line="33"/>
+ <location filename="../qml/pages/LoginDialog.qml" line="39"/>
<source>Homeserver URL (matrix.org)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/LoginDialog.qml" line="42"/>
+ <location filename="../qml/pages/LoginDialog.qml" line="48"/>
<source>Username</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/LoginDialog.qml" line="43"/>
+ <location filename="../qml/pages/LoginDialog.qml" line="49"/>
<source>Username (user1)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/LoginDialog.qml" line="52"/>
+ <location filename="../qml/pages/LoginDialog.qml" line="58"/>
<source>Password</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../qml/pages/LoginDialog.qml" line="73"/>
+ <source>Device display name</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>MessageSource</name>
@@ -167,84 +180,84 @@
<context>
<name>Messages</name>
<message>
- <location filename="../qml/pages/Messages.qml" line="37"/>
- <location filename="../qml/pages/Messages.qml" line="40"/>
+ <location filename="../qml/pages/Messages.qml" line="38"/>
+ <location filename="../qml/pages/Messages.qml" line="41"/>
<source>File saved</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="38"/>
+ <location filename="../qml/pages/Messages.qml" line="39"/>
<source>File saved to Downloads directory</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="130"/>
+ <location filename="../qml/pages/Messages.qml" line="137"/>
<source>Copy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="136"/>
+ <location filename="../qml/pages/Messages.qml" line="143"/>
<source>Reply</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="139"/>
+ <location filename="../qml/pages/Messages.qml" line="146"/>
<source>Replying to </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="152"/>
+ <location filename="../qml/pages/Messages.qml" line="159"/>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="170"/>
+ <location filename="../qml/pages/Messages.qml" line="177"/>
<source>View Source</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="175"/>
+ <location filename="../qml/pages/Messages.qml" line="182"/>
<source>Delete</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="269"/>
+ <location filename="../qml/pages/Messages.qml" line="276"/>
<source>Download audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="301"/>
- <location filename="../qml/pages/Messages.qml" line="321"/>
+ <location filename="../qml/pages/Messages.qml" line="308"/>
+ <location filename="../qml/pages/Messages.qml" line="328"/>
<source>View video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="301"/>
+ <location filename="../qml/pages/Messages.qml" line="308"/>
<source>Download</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="330"/>
+ <location filename="../qml/pages/Messages.qml" line="337"/>
<source>Download file</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="423"/>
+ <location filename="../qml/pages/Messages.qml" line="430"/>
<source>Message</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="424"/>
+ <location filename="../qml/pages/Messages.qml" line="431"/>
<source>Send message to room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="454"/>
+ <location filename="../qml/pages/Messages.qml" line="461"/>
<source>New Messages</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Messages.qml" line="475"/>
+ <location filename="../qml/pages/Messages.qml" line="482"/>
<source>Send file</source>
<translation type="unfinished"></translation>
</message>
@@ -350,22 +363,22 @@
<context>
<name>Rooms</name>
<message>
- <location filename="../qml/pages/Rooms.qml" line="74"/>
+ <location filename="../qml/pages/Rooms.qml" line="129"/>
<source>No Favorites</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Rooms.qml" line="90"/>
+ <location filename="../qml/pages/Rooms.qml" line="145"/>
<source>No Rooms</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Rooms.qml" line="106"/>
+ <location filename="../qml/pages/Rooms.qml" line="161"/>
<source>No Direct Messages</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/pages/Rooms.qml" line="121"/>
+ <location filename="../qml/pages/Rooms.qml" line="176"/>
<source>No Invites</source>
<translation type="unfinished"></translation>
</message>
@@ -388,17 +401,28 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qml/custom/RoomsDisplay.qml" line="77"/>
+ <location filename="../qml/custom/RoomsDisplay.qml" line="59"/>
+ <location filename="../qml/custom/RoomsDisplay.qml" line="74"/>
+ <source>Search</source>
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-sailtrix.yaml
^
|
@@ -1,6 +1,6 @@
Name: harbour-sailtrix
Summary: Matrix client for SailfishOS
-Version: 1.3.10
+Version: 1.4
Release: 1
# The contents of the Group field should be one of the groups listed here:
# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
@@ -20,7 +20,7 @@
- Network
Custom:
Repo: https://gitlab.com/HengYeDev/harbour-sailtrix
- Icon: https://gitlab.com/HengYeDev/harbour-sailtrix/-/raw/master/icons/172x172/harbour-sailtrix.png
+ Icon: https://gitlab.com/sailtrix/harbour-sailtrix/-/raw/master/icons/172x172/harbour-sailtrix.png
Screenshots:
- https://openrepos.net/sites/default/files/packages/16540/screenshot-newrooms.png
- https://openrepos.net/sites/default/files/packages/16540/screenshot-8.png
|