Get 3PID binds on startup
Get binds on startup and update the staus properly after bind/unbinding 3PIDs
This commit is contained in:
@@ -3,6 +3,12 @@
|
|||||||
|
|
||||||
#include "threepidmodel.h"
|
#include "threepidmodel.h"
|
||||||
|
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
#include <Quotient/csapi/openid.h>
|
||||||
|
#include <Quotient/networkaccessmanager.h>
|
||||||
|
|
||||||
#include "neochatconnection.h"
|
#include "neochatconnection.h"
|
||||||
|
|
||||||
ThreePIdModel::ThreePIdModel(NeoChatConnection *connection)
|
ThreePIdModel::ThreePIdModel(NeoChatConnection *connection)
|
||||||
@@ -30,6 +36,9 @@ QVariant ThreePIdModel::data(const QModelIndex &index, int role) const
|
|||||||
if (role == MediumRole) {
|
if (role == MediumRole) {
|
||||||
return m_threePIds.at(index.row()).medium;
|
return m_threePIds.at(index.row()).medium;
|
||||||
}
|
}
|
||||||
|
if (role == IsBoundRole) {
|
||||||
|
return m_bindings.contains(m_threePIds.at(index.row()).address);
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -45,6 +54,7 @@ QHash<int, QByteArray> ThreePIdModel::roleNames() const
|
|||||||
return {
|
return {
|
||||||
{AddressRole, QByteArrayLiteral("address")},
|
{AddressRole, QByteArrayLiteral("address")},
|
||||||
{MediumRole, QByteArrayLiteral("medium")},
|
{MediumRole, QByteArrayLiteral("medium")},
|
||||||
|
{IsBoundRole, QByteArrayLiteral("isBound")},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,8 +67,80 @@ void ThreePIdModel::refreshModel()
|
|||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_threePIds = threePIdJob->threepids();
|
m_threePIds = threePIdJob->threepids();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
|
||||||
|
refreshBindStatus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThreePIdModel::refreshBindStatus()
|
||||||
|
{
|
||||||
|
const auto connection = dynamic_cast<NeoChatConnection *>(this->parent());
|
||||||
|
if (connection == nullptr || !connection->hasIdentityServer()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto openIdJob = connection->callApi<Quotient::RequestOpenIdTokenJob>(connection->userId());
|
||||||
|
connect(openIdJob, &Quotient::BaseJob::success, this, [this, connection, openIdJob]() {
|
||||||
|
const auto requestUrl = QUrl(connection->identityServer().toString() + QStringLiteral("/_matrix/identity/v2/account/register"));
|
||||||
|
if (!(requestUrl.scheme() == QStringLiteral("https") || requestUrl.scheme() == QStringLiteral("http"))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkRequest request(requestUrl);
|
||||||
|
auto newRequest = Quotient::NetworkAccessManager::instance()->post(request, QJsonDocument(openIdJob->jsonData()).toJson());
|
||||||
|
connect(newRequest, &QNetworkReply::finished, this, [this, connection, newRequest]() {
|
||||||
|
QJsonObject replyJson = QJsonDocument::fromJson(newRequest->readAll()).object();
|
||||||
|
const auto identityServerToken = replyJson[QLatin1String("token")].toString();
|
||||||
|
|
||||||
|
const auto requestUrl = QUrl(connection->identityServer().toString() + QStringLiteral("/_matrix/identity/v2/hash_details"));
|
||||||
|
if (!(requestUrl.scheme() == QStringLiteral("https") || requestUrl.scheme() == QStringLiteral("http"))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkRequest hashRequest(requestUrl);
|
||||||
|
hashRequest.setRawHeader("Authorization", "Bearer " + identityServerToken.toLatin1());
|
||||||
|
|
||||||
|
auto hashReply = Quotient::NetworkAccessManager::instance()->get(hashRequest);
|
||||||
|
connect(hashReply, &QNetworkReply::finished, this, [this, connection, identityServerToken, hashReply]() {
|
||||||
|
QJsonObject replyJson = QJsonDocument::fromJson(hashReply->readAll()).object();
|
||||||
|
const auto lookupPepper = replyJson[QLatin1String("lookup_pepper")].toString();
|
||||||
|
|
||||||
|
const auto requestUrl = QUrl(connection->identityServer().toString() + QStringLiteral("/_matrix/identity/v2/lookup"));
|
||||||
|
if (!(requestUrl.scheme() == QStringLiteral("https") || requestUrl.scheme() == QStringLiteral("http"))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkRequest lookupRequest(requestUrl);
|
||||||
|
lookupRequest.setRawHeader("Authorization", "Bearer " + identityServerToken.toLatin1());
|
||||||
|
|
||||||
|
QJsonObject requestData = {
|
||||||
|
{QLatin1String("algorithm"), QLatin1String("none")},
|
||||||
|
{QLatin1String("pepper"), lookupPepper},
|
||||||
|
};
|
||||||
|
QJsonArray idLookups;
|
||||||
|
for (const auto &id : m_threePIds) {
|
||||||
|
idLookups += QStringLiteral("%1 %2").arg(id.address, id.medium);
|
||||||
|
}
|
||||||
|
requestData[QLatin1String("addresses")] = idLookups;
|
||||||
|
|
||||||
|
auto lookupReply = Quotient::NetworkAccessManager::instance()->post(lookupRequest, QJsonDocument(requestData).toJson(QJsonDocument::Compact));
|
||||||
|
connect(lookupReply, &QNetworkReply::finished, this, [this, connection, lookupReply]() {
|
||||||
|
beginResetModel();
|
||||||
|
m_bindings.clear();
|
||||||
|
|
||||||
|
QJsonObject mappings = QJsonDocument::fromJson(lookupReply->readAll()).object()[QLatin1String("mappings")].toObject();
|
||||||
|
for (const auto &id : mappings.keys()) {
|
||||||
|
if (mappings[id] == connection->userId()) {
|
||||||
|
m_bindings += id.section(u' ', 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_threepidmodel.cpp"
|
#include "moc_threepidmodel.cpp"
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public:
|
|||||||
enum EventRoles {
|
enum EventRoles {
|
||||||
AddressRole = Qt::DisplayRole, /**< The third-party identifier address. */
|
AddressRole = Qt::DisplayRole, /**< The third-party identifier address. */
|
||||||
MediumRole, /**< The medium of the third-party identifier. One of: [email, msisdn]. */
|
MediumRole, /**< The medium of the third-party identifier. One of: [email, msisdn]. */
|
||||||
|
IsBoundRole, /**< Whether the 3PID is bound to the current identity server. */
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ThreePIdModel(NeoChatConnection *parent);
|
explicit ThreePIdModel(NeoChatConnection *parent);
|
||||||
@@ -57,4 +58,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<Quotient::GetAccount3PIDsJob::ThirdPartyIdentifier> m_threePIds;
|
QVector<Quotient::GetAccount3PIDsJob::ThirdPartyIdentifier> m_threePIds;
|
||||||
|
|
||||||
|
QList<QString> m_bindings;
|
||||||
|
|
||||||
|
void refreshBindStatus();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ ColumnLayout {
|
|||||||
id: threePIdDelegate
|
id: threePIdDelegate
|
||||||
required property string address
|
required property string address
|
||||||
required property string medium
|
required property string medium
|
||||||
|
required property bool isBound
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
@@ -50,7 +51,13 @@ ColumnLayout {
|
|||||||
color: Kirigami.Theme.textColor
|
color: Kirigami.Theme.textColor
|
||||||
}
|
}
|
||||||
QQC2.ToolButton {
|
QQC2.ToolButton {
|
||||||
visible: threePIdBindHelper.bindStatus === ThreePIdBindHelper.Ready && root.connection.hasIdentityServer
|
visible: root.connection.hasIdentityServer && threePIdDelegate.isBound
|
||||||
|
text: i18nc("@action:button", "Hide")
|
||||||
|
icon.name: "hide_table_row"
|
||||||
|
onClicked: threePIdBindHelper.unbind3PId(threePIdDelegate.address, threePIdDelegate.medium)
|
||||||
|
}
|
||||||
|
QQC2.ToolButton {
|
||||||
|
visible: threePIdBindHelper.bindStatus === ThreePIdBindHelper.Ready && root.connection.hasIdentityServer && !threePIdDelegate.isBound
|
||||||
text: i18nc("@action:button", "Share")
|
text: i18nc("@action:button", "Share")
|
||||||
icon.name: "send-to-symbolic"
|
icon.name: "send-to-symbolic"
|
||||||
onClicked: threePIdBindHelper.bindStatus === ThreePIdBindHelper.Verification ? threePIdBindHelper.finalizeNewIdBind() : threePIdBindHelper.initiateNewIdBind()
|
onClicked: threePIdBindHelper.bindStatus === ThreePIdBindHelper.Verification ? threePIdBindHelper.finalizeNewIdBind() : threePIdBindHelper.initiateNewIdBind()
|
||||||
@@ -70,7 +77,7 @@ ColumnLayout {
|
|||||||
type: threePIdBindHelper.statusType
|
type: threePIdBindHelper.statusType
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
visible: threePIdBindHelper.bindStatus !== ThreePIdBindHelper.Ready
|
visible: threePIdBindHelper.bindStatus !== ThreePIdBindHelper.Ready && threePIdBindHelper.bindStatus !== ThreePIdBindHelper.Success
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ void ThreePIdBindHelper::finalizeNewIdBind()
|
|||||||
connect(job, &Quotient::BaseJob::success, this, [this] {
|
connect(job, &Quotient::BaseJob::success, this, [this] {
|
||||||
m_bindStatus = Success;
|
m_bindStatus = Success;
|
||||||
Q_EMIT bindStatusChanged();
|
Q_EMIT bindStatusChanged();
|
||||||
|
m_connection->threePIdModel()->refreshModel();
|
||||||
});
|
});
|
||||||
connect(job, &Quotient::BaseJob::failure, this, [this, job]() {
|
connect(job, &Quotient::BaseJob::failure, this, [this, job]() {
|
||||||
if (job->jsonData()[QLatin1String("errcode")] == QLatin1String("M_SESSION_NOT_VALIDATED")) {
|
if (job->jsonData()[QLatin1String("errcode")] == QLatin1String("M_SESSION_NOT_VALIDATED")) {
|
||||||
@@ -208,6 +209,7 @@ void ThreePIdBindHelper::unbind3PId(const QString &threePId, const QString &type
|
|||||||
{
|
{
|
||||||
const auto job = m_connection->callApi<Quotient::Unbind3pidFromAccountJob>(type, threePId);
|
const auto job = m_connection->callApi<Quotient::Unbind3pidFromAccountJob>(type, threePId);
|
||||||
connect(job, &Quotient::BaseJob::success, this, [this]() {
|
connect(job, &Quotient::BaseJob::success, this, [this]() {
|
||||||
|
cancel();
|
||||||
m_connection->threePIdModel()->refreshModel();
|
m_connection->threePIdModel()->refreshModel();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user