nheko/src/RegisterPage.cpp

250 lines
8.7 KiB
C++
Raw Normal View History

2021-03-05 00:35:15 +01:00
// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr>
// SPDX-FileCopyrightText: 2021 Nheko Contributors
// SPDX-FileCopyrightText: 2022 Nheko Contributors
2021-03-05 00:35:15 +01:00
//
// SPDX-License-Identifier: GPL-3.0-or-later
2017-04-06 01:06:42 +02:00
2022-06-25 16:16:54 +02:00
#include <set>
2022-01-28 15:24:56 +01:00
#include <mtx/responses/common.hpp>
2020-01-31 16:08:30 +01:00
#include <mtx/responses/register.hpp>
2022-06-25 16:16:54 +02:00
#include <mtx/responses/version.hpp>
#include <mtx/responses/well-known.hpp>
2021-07-21 12:55:41 +02:00
#include <mtxclient/http/client.hpp>
2020-01-31 16:08:30 +01:00
#include "Config.h"
2018-07-17 15:37:25 +02:00
#include "Logging.h"
2022-01-28 15:24:56 +01:00
#include "LoginPage.h"
#include "MainWindow.h"
2017-10-28 14:46:39 +02:00
#include "MatrixClient.h"
2017-11-22 20:13:22 +01:00
#include "RegisterPage.h"
#include "ui/UIA.h"
2017-04-06 01:06:42 +02:00
2022-01-28 15:24:56 +01:00
RegisterPage::RegisterPage(QObject *parent)
: QObject(parent)
{
connect(this, &RegisterPage::registerOk, this, [] { MainWindow::instance()->showChatPage(); });
}
2017-04-06 01:06:42 +02:00
2017-08-20 12:47:22 +02:00
void
2022-01-28 15:24:56 +01:00
RegisterPage::setError(QString err)
2017-04-06 01:06:42 +02:00
{
2022-01-28 15:24:56 +01:00
registrationError_ = err;
emit errorChanged();
registering_ = false;
emit registeringChanged();
2017-04-06 01:06:42 +02:00
}
2017-08-20 12:47:22 +02:00
void
2022-01-28 15:24:56 +01:00
RegisterPage::setHsError(QString err)
{
2022-01-28 15:24:56 +01:00
hsError_ = err;
emit hsErrorChanged();
lookingUpHs_ = false;
emit lookingUpHsChanged();
}
2022-01-28 15:24:56 +01:00
QString
RegisterPage::initialDeviceName() const
{
2022-01-28 15:24:56 +01:00
return QString::fromStdString(LoginPage::initialDeviceName_());
}
2017-09-10 11:59:21 +02:00
void
2022-01-28 15:24:56 +01:00
RegisterPage::setServer(QString server)
{
2022-01-28 15:24:56 +01:00
if (server == lastServer)
return;
2021-09-18 00:22:33 +02:00
2022-01-28 15:24:56 +01:00
lastServer = server;
2021-09-18 00:22:33 +02:00
2022-01-28 15:24:56 +01:00
http::client()->set_server(server.toStdString());
http::client()->verify_certificates(!UserSettings::instance()->disableCertificateValidation());
2021-09-18 00:22:33 +02:00
2022-01-28 15:24:56 +01:00
hsError_.clear();
emit hsErrorChanged();
supported_ = false;
lookingUpHs_ = true;
emit lookingUpHsChanged();
2021-09-18 00:22:33 +02:00
http::client()->well_known(
[this](const mtx::responses::WellKnown &res, mtx::http::RequestErr err) {
if (err) {
if (err->status_code == 404) {
nhlog::net()->info("Autodiscovery: No .well-known.");
2021-07-21 12:55:41 +02:00
// Check that the homeserver can be reached
2022-01-28 15:24:56 +01:00
versionsCheck();
2021-09-18 00:22:33 +02:00
return;
}
if (!err->parse_error.empty()) {
2022-01-28 15:24:56 +01:00
setHsError(tr("Autodiscovery failed. Received malformed response."));
2021-09-18 00:22:33 +02:00
nhlog::net()->error("Autodiscovery failed. Received malformed response.");
2022-01-28 15:24:56 +01:00
emit hsErrorChanged();
2021-09-18 00:22:33 +02:00
return;
}
2022-01-28 15:24:56 +01:00
setHsError(tr("Autodiscovery failed. Unknown error when requesting .well-known."));
2021-09-18 00:22:33 +02:00
nhlog::net()->error("Autodiscovery failed. Unknown error when "
"requesting .well-known. {} {}",
err->status_code,
err->error_code);
return;
}
nhlog::net()->info("Autodiscovery: Discovered '" + res.homeserver.base_url + "'");
http::client()->set_server(res.homeserver.base_url);
2022-01-28 15:24:56 +01:00
emit hsErrorChanged();
2021-09-18 00:22:33 +02:00
// Check that the homeserver can be reached
2022-01-28 15:24:56 +01:00
versionsCheck();
2021-09-18 00:22:33 +02:00
});
2017-04-06 01:06:42 +02:00
}
void
2022-01-28 15:24:56 +01:00
RegisterPage::versionsCheck()
{
2021-09-18 00:22:33 +02:00
// Make a request to /_matrix/client/versions to check the address
// given is a Matrix homeserver.
2022-06-25 16:16:54 +02:00
http::client()->versions(
[this](const mtx::responses::Versions &versions, mtx::http::RequestErr err) {
if (err) {
if (err->status_code == 404) {
setHsError(
tr("The required endpoints were not found. Possibly not a Matrix server."));
2022-01-28 15:24:56 +01:00
emit hsErrorChanged();
return;
}
2022-06-25 16:16:54 +02:00
if (!err->parse_error.empty()) {
setHsError(
tr("Received malformed response. Make sure the homeserver domain is valid."));
2022-01-28 15:24:56 +01:00
emit hsErrorChanged();
return;
}
2022-06-25 16:16:54 +02:00
setHsError(tr("An unknown error occured. Make sure the homeserver domain is valid."));
emit hsErrorChanged();
return;
}
if (std::find_if(
versions.versions.cbegin(), versions.versions.cend(), [](const std::string &v) {
static const std::set<std::string_view, std::less<>> supported{
"v1.1",
"v1.2",
"v1.3",
};
return supported.count(v) != 0;
}) == versions.versions.cend()) {
emit setHsError(
tr("The selected server does not support a version of the Matrix protocol, that "
"this client understands (v1.1, v1.2 or v1.3). You can't register."));
emit hsErrorChanged();
return;
}
http::client()->registration(
[this](const mtx::responses::Register &, mtx::http::RequestErr e) {
nhlog::net()->debug("Registration check: {}", e);
if (!e) {
setHsError(tr("Server does not support querying registration flows!"));
emit hsErrorChanged();
return;
}
if (e->status_code != 401) {
setHsError(tr("Server does not support registration."));
emit hsErrorChanged();
return;
}
supported_ = true;
lookingUpHs_ = false;
emit lookingUpHsChanged();
});
});
}
2021-07-21 12:55:41 +02:00
void
2022-01-28 15:24:56 +01:00
RegisterPage::checkUsername(QString name)
{
usernameAvailable_ = usernameUnavailable_ = false;
usernameError_.clear();
lookingUpUsername_ = true;
emit lookingUpUsernameChanged();
http::client()->register_username_available(
name.toStdString(),
[this](const mtx::responses::Available &available, mtx::http::RequestErr e) {
if (e) {
if (e->matrix_error.errcode == mtx::errors::ErrorCode::M_INVALID_USERNAME) {
usernameError_ = tr("Invalid username.");
} else if (e->matrix_error.errcode == mtx::errors::ErrorCode::M_USER_IN_USE) {
usernameError_ = tr("Name already in use.");
} else if (e->matrix_error.errcode == mtx::errors::ErrorCode::M_EXCLUSIVE) {
usernameError_ = tr("Part of the reserved namespace.");
} else {
}
usernameAvailable_ = false;
usernameUnavailable_ = true;
} else {
usernameAvailable_ = available.available;
usernameUnavailable_ = !available.available;
}
lookingUpUsername_ = false;
emit lookingUpUsernameChanged();
});
}
void
RegisterPage::startRegistration(QString username, QString password, QString devicename)
2021-07-21 12:55:41 +02:00
{
2021-09-18 00:22:33 +02:00
// These inputs should still be alright, but check just in case
2022-01-28 15:24:56 +01:00
if (!username.isEmpty() && !password.isEmpty() && usernameAvailable_ && supported_) {
registrationError_.clear();
emit errorChanged();
registering_ = true;
emit registeringChanged();
connect(UIA::instance(), &UIA::error, this, [this](QString msg) {
2022-01-28 15:24:56 +01:00
setError(msg);
disconnect(UIA::instance(), &UIA::error, this, nullptr);
});
http::client()->registration(
2022-01-28 15:24:56 +01:00
username.toStdString(),
password.toStdString(),
::UIA::instance()->genericHandler(QStringLiteral("Registration")),
2022-01-28 15:24:56 +01:00
[this](const mtx::responses::Register &res, mtx::http::RequestErr err) {
registering_ = false;
emit registeringChanged();
if (!err) {
http::client()->set_user(res.user_id);
http::client()->set_access_token(res.access_token);
emit registerOk();
2022-01-28 15:24:56 +01:00
disconnect(UIA::instance(), &UIA::error, this, nullptr);
return;
}
2021-09-18 00:22:33 +02:00
2022-01-28 15:24:56 +01:00
// The server requires registration flows.
if (err->status_code == 401 && err->matrix_error.unauthorized.flows.empty()) {
nhlog::net()->warn("failed to retrieve registration flows: "
"status_code({}), matrix_error({}) ",
static_cast<int>(err->status_code),
err->matrix_error.error);
setError(QString::fromStdString(err->matrix_error.error));
disconnect(UIA::instance(), &UIA::error, this, nullptr);
return;
}
2021-09-18 00:22:33 +02:00
2022-01-28 15:24:56 +01:00
nhlog::net()->error("failed to register: status_code ({}), matrix_error({})",
static_cast<int>(err->status_code),
err->matrix_error.error);
2021-07-21 12:55:41 +02:00
2022-01-28 15:24:56 +01:00
setError(QString::fromStdString(err->matrix_error.error));
disconnect(UIA::instance(), &UIA::error, this, nullptr);
},
devicename.isEmpty() ? LoginPage::initialDeviceName_() : devicename.toStdString());
}
}