Login via access token.

This commit is contained in:
Black Hat
2019-07-26 15:35:45 +08:00
parent 6f5c23b3c3
commit 18c42b6af6
4 changed files with 66 additions and 8 deletions

View File

@@ -44,6 +44,16 @@ Dialog {
placeholderText: "Password"
echoMode: TextInput.Password
onAccepted: accessTokenField.forceActiveFocus()
}
AutoTextField {
Layout.fillWidth: true
id: accessTokenField
placeholderText: "Access Token (Optional)"
onAccepted: deviceNameField.forceActiveFocus()
}
@@ -52,14 +62,19 @@ Dialog {
id: deviceNameField
placeholderText: "Device Name"
placeholderText: "Device Name (Optional)"
onAccepted: root.accept()
}
}
function doLogin() {
spectralController.loginWithCredentials(serverField.text, usernameField.text, passwordField.text, deviceNameField.text)
if (accessTokenField.text !== "") {
console.log("Login using access token.")
spectralController.loginWithAccessToken(serverField.text, usernameField.text, accessTokenField.text, deviceNameField.text)
} else {
spectralController.loginWithCredentials(serverField.text, usernameField.text, passwordField.text, deviceNameField.text)
}
}
onClosed: destroy()

View File

@@ -103,6 +103,39 @@ void Controller::loginWithCredentials(QString serverAddr,
}
}
void Controller::loginWithAccessToken(QString serverAddr,
QString user,
QString token,
QString deviceName) {
if (!user.isEmpty() && !token.isEmpty()) {
QUrl serverUrl(serverAddr);
Connection* conn = new Connection(this);
if (serverUrl.isValid()) {
conn->setHomeserver(serverUrl);
}
connect(conn, &Connection::connected, [=] {
AccountSettings account(conn->userId());
account.setKeepLoggedIn(true);
account.clearAccessToken(); // Drop the legacy - just in case
account.setHomeserver(conn->homeserver());
account.setDeviceId(conn->deviceId());
account.setDeviceName(deviceName);
if (!saveAccessTokenToKeyChain(account, conn->accessToken()))
qWarning() << "Couldn't save access token";
account.sync();
addConnection(conn);
setConnection(conn);
});
connect(conn, &Connection::networkError,
[=](QString error, QString, int, int) {
emit errorOccured("Network Error", error);
});
conn->connectWithToken(user, token, deviceName);
}
}
void Controller::logout(Connection* conn) {
if (!conn) {
qCritical() << "Attempt to logout null connection";
@@ -112,16 +145,24 @@ void Controller::logout(Connection* conn) {
SettingsGroup("Accounts").remove(conn->userId());
QFile(accessTokenFileName(AccountSettings(conn->userId()))).remove();
auto job = conn->callApi<LogoutJob>();
connect(job, &LogoutJob::finished, conn, [=] {
QKeychain::DeletePasswordJob job(qAppName());
job.setAutoDelete(true);
job.setKey(conn->userId());
QEventLoop loop;
QKeychain::DeletePasswordJob::connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
job.start();
loop.exec();
auto logoutJob = conn->callApi<LogoutJob>();
connect(logoutJob, &LogoutJob::finished, conn, [=] {
conn->stopSync();
emit conn->stateChanged();
emit conn->loggedOut();
if (!m_connections.isEmpty())
setConnection(m_connections[0]);
});
connect(job, &LogoutJob::failure, this, [=] {
emit errorOccured("Server-side Logout Failed", job->errorString());
connect(logoutJob, &LogoutJob::failure, this, [=] {
emit errorOccured("Server-side Logout Failed", logoutJob->errorString());
});
}

View File

@@ -32,6 +32,7 @@ class Controller : public QObject {
~Controller();
Q_INVOKABLE void loginWithCredentials(QString, QString, QString, QString);
Q_INVOKABLE void loginWithAccessToken(QString, QString, QString, QString);
QVector<Connection*> connections() { return m_connections; }

View File

@@ -12,6 +12,7 @@
#include "events/accountdataevents.h"
#include "events/roommessageevent.h"
#include "events/typingevent.h"
#include "events/reactionevent.h"
#include "jobs/downloadfilejob.h"
#include <QFileDialog>
@@ -119,13 +120,13 @@ QString SpectralRoom::lastEvent() {
for (auto i = messageEvents().rbegin(); i < messageEvents().rend(); i++) {
const RoomEvent* evt = i->get();
if (is<RedactionEvent>(*evt))
if (is<RedactionEvent>(*evt) || is<ReactionEvent>(*evt))
continue;
if (evt->isRedacted())
continue;
if (evt->isStateEvent() &&
static_cast<const StateEventBase*>(evt)->repeatsState())
static_cast<const StateEventBase&>(*evt).repeatsState())
continue;
if (connection()->isIgnored(user(evt->senderId())))