Merge pull request #766 from Thulinma/deviceDeletion

Add support for listing devices that do not support encryption, add support for logging out devices.
This commit is contained in:
DeepBlueV7.X 2021-10-16 22:09:36 +00:00 committed by GitHub
commit 16e234016a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 3 deletions

View file

@ -385,7 +385,7 @@ if(USE_BUNDLED_MTXCLIENT)
FetchContent_Declare( FetchContent_Declare(
MatrixClient MatrixClient
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
GIT_TAG 8b56b466dbacde501ed9087d53bb4f51b297eca8 GIT_TAG e5284ccc9d902117bbe782b0be76fa272b7f0a90
) )
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "") set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")

View file

@ -163,7 +163,7 @@ modules:
buildsystem: cmake-ninja buildsystem: cmake-ninja
name: mtxclient name: mtxclient
sources: sources:
- commit: 8b56b466dbacde501ed9087d53bb4f51b297eca8 - commit: e5284ccc9d902117bbe782b0be76fa272b7f0a90
type: git type: git
url: https://github.com/Nheko-Reborn/mtxclient.git url: https://github.com/Nheko-Reborn/mtxclient.git
- config-opts: - config-opts:

View file

@ -310,6 +310,7 @@ ApplicationWindow {
Image { Image {
Layout.preferredHeight: 16 Layout.preferredHeight: 16
Layout.preferredWidth: 16 Layout.preferredWidth: 16
visible: verificationStatus != VerificationStatus.NOT_APPLICABLE
source: { source: {
switch (verificationStatus) { switch (verificationStatus) {
case VerificationStatus.VERIFIED: case VerificationStatus.VERIFIED:
@ -337,6 +338,15 @@ ApplicationWindow {
} }
} }
ImageButton {
image: ":/icons/icons/ui/power-button-off.png"
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("Sign out this device.")
onClicked: profile.signOutDevice(deviceId)
visible: profile.isSelf
}
} }
footer: DialogButtonBox { footer: DialogButtonBox {

View file

@ -16,6 +16,7 @@
#include "mtx/responses/crypto.hpp" #include "mtx/responses/crypto.hpp"
#include "timeline/TimelineModel.h" #include "timeline/TimelineModel.h"
#include "timeline/TimelineViewManager.h" #include "timeline/TimelineViewManager.h"
#include "ui/UIA.h"
UserProfile::UserProfile(QString roomid, UserProfile::UserProfile(QString roomid,
QString userid, QString userid,
@ -137,6 +138,27 @@ UserProfile::isSelf() const
return this->userid_ == utils::localUser(); return this->userid_ == utils::localUser();
} }
void
UserProfile::signOutDevice(const QString &deviceID)
{
http::client()->delete_device(
deviceID.toStdString(),
UIA::instance()->genericHandler(tr("Sign out device %1").arg(deviceID)),
[this, deviceID](mtx::http::RequestErr e) {
if (e) {
nhlog::ui()->critical("Failure when attempting to sign out device {}",
deviceID.toStdString());
return;
}
nhlog::ui()->info("Device {} successfully signed out!", deviceID.toStdString());
// This is us. Let's update the interface accordingly
if (isSelf() && deviceID.toStdString() == ::http::client()->device_id()) {
ChatPage::instance()->dropToLoginPageCb(tr("You signed out this device."));
}
refreshDevices();
});
}
void void
UserProfile::refreshDevices() UserProfile::refreshDevices()
{ {
@ -221,6 +243,47 @@ UserProfile::updateVerificationStatus()
verified}); verified});
} }
// For self, also query devices without keys
if (isSelf()) {
http::client()->query_devices(
[this, deviceInfo](const mtx::responses::QueryDevices &allDevs,
mtx::http::RequestErr err) mutable {
if (err) {
nhlog::net()->warn("failed to query devices: {} {}",
err->matrix_error.error,
static_cast<int>(err->status_code));
this->deviceList_.queueReset(std::move(deviceInfo));
emit devicesChanged();
return;
}
for (const auto &d : allDevs.devices) {
// First, check if we already have an entry for this device
bool found = false;
for (auto &e : deviceInfo) {
if (e.device_id.toStdString() == d.device_id) {
found = true;
// Gottem! Let's fill in the blanks
e.lastIp = QString::fromStdString(d.last_seen_ip);
e.lastTs = d.last_seen_ts;
break;
}
}
// No entry? Let's add one.
if (!found) {
deviceInfo.push_back({QString::fromStdString(d.device_id),
QString::fromStdString(d.display_name),
verification::NOT_APPLICABLE,
QString::fromStdString(d.last_seen_ip),
d.last_seen_ts});
}
}
this->deviceList_.queueReset(std::move(deviceInfo));
emit devicesChanged();
});
return;
}
this->deviceList_.queueReset(std::move(deviceInfo)); this->deviceList_.queueReset(std::move(deviceInfo));
emit devicesChanged(); emit devicesChanged();
} }

View file

@ -21,7 +21,8 @@ enum Status
SELF, SELF,
VERIFIED, VERIFIED,
UNVERIFIED, UNVERIFIED,
BLOCKED BLOCKED,
NOT_APPLICABLE
}; };
Q_ENUM_NS(Status) Q_ENUM_NS(Status)
} }
@ -33,12 +34,24 @@ class TimelineViewManager;
class DeviceInfo class DeviceInfo
{ {
public: public:
DeviceInfo(const QString deviceID,
const QString displayName,
verification::Status verification_status_,
const QString lastIp_,
const size_t lastTs_)
: device_id(deviceID)
, display_name(displayName)
, verification_status(verification_status_)
, lastIp(lastIp_)
, lastTs(lastTs_)
{}
DeviceInfo(const QString deviceID, DeviceInfo(const QString deviceID,
const QString displayName, const QString displayName,
verification::Status verification_status_) verification::Status verification_status_)
: device_id(deviceID) : device_id(deviceID)
, display_name(displayName) , display_name(displayName)
, verification_status(verification_status_) , verification_status(verification_status_)
, lastTs(0)
{} {}
DeviceInfo() DeviceInfo()
: verification_status(verification::UNVERIFIED) : verification_status(verification::UNVERIFIED)
@ -48,6 +61,8 @@ public:
QString display_name; QString display_name;
verification::Status verification_status; verification::Status verification_status;
QString lastIp;
size_t lastTs;
}; };
class DeviceInfoModel : public QAbstractListModel class DeviceInfoModel : public QAbstractListModel
@ -121,6 +136,7 @@ public:
Q_INVOKABLE void fetchDeviceList(const QString &userID); Q_INVOKABLE void fetchDeviceList(const QString &userID);
Q_INVOKABLE void refreshDevices(); Q_INVOKABLE void refreshDevices();
Q_INVOKABLE void banUser(); Q_INVOKABLE void banUser();
Q_INVOKABLE void signOutDevice(const QString &deviceID);
// Q_INVOKABLE void ignoreUser(); // Q_INVOKABLE void ignoreUser();
Q_INVOKABLE void kickUser(); Q_INVOKABLE void kickUser();
Q_INVOKABLE void startChat(); Q_INVOKABLE void startChat();