2021-03-05 02:35:15 +03:00
|
|
|
// SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr>
|
|
|
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
2022-01-01 06:57:53 +03:00
|
|
|
// SPDX-FileCopyrightText: 2022 Nheko Contributors
|
2021-03-05 02:35:15 +03:00
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
2017-04-06 02:06:42 +03:00
|
|
|
|
2022-06-25 17:16:54 +03:00
|
|
|
#include <set>
|
|
|
|
|
2022-01-28 17:24:56 +03:00
|
|
|
#include <mtx/responses/common.hpp>
|
2020-01-31 18:08:30 +03:00
|
|
|
#include <mtx/responses/register.hpp>
|
2022-06-25 17:16:54 +03:00
|
|
|
#include <mtx/responses/version.hpp>
|
2021-06-03 16:52:41 +03:00
|
|
|
#include <mtx/responses/well-known.hpp>
|
2021-07-21 13:55:41 +03:00
|
|
|
#include <mtxclient/http/client.hpp>
|
2020-01-31 18:08:30 +03:00
|
|
|
|
2017-07-15 17:11:46 +03:00
|
|
|
#include "Config.h"
|
2018-07-17 16:37:25 +03:00
|
|
|
#include "Logging.h"
|
2022-01-28 17:24:56 +03:00
|
|
|
#include "LoginPage.h"
|
2018-03-12 23:23:26 +03:00
|
|
|
#include "MainWindow.h"
|
2017-10-28 15:46:39 +03:00
|
|
|
#include "MatrixClient.h"
|
2017-11-22 22:13:22 +03:00
|
|
|
#include "RegisterPage.h"
|
2021-11-03 20:36:12 +03:00
|
|
|
#include "ui/UIA.h"
|
2017-04-06 02:06:42 +03:00
|
|
|
|
2022-01-28 17:24:56 +03:00
|
|
|
RegisterPage::RegisterPage(QObject *parent)
|
|
|
|
: QObject(parent)
|
2022-01-29 19:27:28 +03:00
|
|
|
{
|
|
|
|
connect(this, &RegisterPage::registerOk, this, [] { MainWindow::instance()->showChatPage(); });
|
|
|
|
}
|
2017-04-06 02:06:42 +03:00
|
|
|
|
2017-08-20 13:47:22 +03:00
|
|
|
void
|
2022-01-28 17:24:56 +03:00
|
|
|
RegisterPage::setError(QString err)
|
2017-04-06 02:06:42 +03:00
|
|
|
{
|
2022-01-28 17:24:56 +03:00
|
|
|
registrationError_ = err;
|
|
|
|
emit errorChanged();
|
|
|
|
registering_ = false;
|
|
|
|
emit registeringChanged();
|
2017-04-06 02:06:42 +03:00
|
|
|
}
|
2017-08-20 13:47:22 +03:00
|
|
|
void
|
2022-01-28 17:24:56 +03:00
|
|
|
RegisterPage::setHsError(QString err)
|
2017-04-07 19:25:06 +03:00
|
|
|
{
|
2022-01-28 17:24:56 +03:00
|
|
|
hsError_ = err;
|
|
|
|
emit hsErrorChanged();
|
|
|
|
lookingUpHs_ = false;
|
|
|
|
emit lookingUpHsChanged();
|
2017-04-07 19:25:06 +03:00
|
|
|
}
|
|
|
|
|
2022-01-28 17:24:56 +03:00
|
|
|
QString
|
|
|
|
RegisterPage::initialDeviceName() const
|
2020-12-01 01:30:33 +03:00
|
|
|
{
|
2022-01-28 17:24:56 +03:00
|
|
|
return QString::fromStdString(LoginPage::initialDeviceName_());
|
2020-12-01 01:30:33 +03:00
|
|
|
}
|
2017-09-10 12:59:21 +03:00
|
|
|
|
2020-12-01 01:30:33 +03:00
|
|
|
void
|
2022-01-28 17:24:56 +03:00
|
|
|
RegisterPage::setServer(QString server)
|
2020-12-01 01:30:33 +03:00
|
|
|
{
|
2022-01-28 17:24:56 +03:00
|
|
|
if (server == lastServer)
|
|
|
|
return;
|
2021-09-18 01:22:33 +03:00
|
|
|
|
2022-01-28 17:24:56 +03:00
|
|
|
lastServer = server;
|
2021-09-18 01:22:33 +03:00
|
|
|
|
2022-01-28 17:24:56 +03:00
|
|
|
http::client()->set_server(server.toStdString());
|
|
|
|
http::client()->verify_certificates(!UserSettings::instance()->disableCertificateValidation());
|
2021-09-18 01:22:33 +03:00
|
|
|
|
2022-01-28 17:24:56 +03:00
|
|
|
hsError_.clear();
|
|
|
|
emit hsErrorChanged();
|
|
|
|
supported_ = false;
|
|
|
|
lookingUpHs_ = true;
|
|
|
|
emit lookingUpHsChanged();
|
2021-09-18 01:22:33 +03: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 13:55:41 +03:00
|
|
|
// Check that the homeserver can be reached
|
2022-01-28 17:24:56 +03:00
|
|
|
versionsCheck();
|
2021-09-18 01:22:33 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!err->parse_error.empty()) {
|
2022-01-28 17:24:56 +03:00
|
|
|
setHsError(tr("Autodiscovery failed. Received malformed response."));
|
2021-09-18 01:22:33 +03:00
|
|
|
nhlog::net()->error("Autodiscovery failed. Received malformed response.");
|
2022-01-28 17:24:56 +03:00
|
|
|
emit hsErrorChanged();
|
2021-09-18 01:22:33 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-28 17:24:56 +03:00
|
|
|
setHsError(tr("Autodiscovery failed. Unknown error when requesting .well-known."));
|
2021-09-18 01:22:33 +03: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 17:24:56 +03:00
|
|
|
emit hsErrorChanged();
|
2021-09-18 01:22:33 +03:00
|
|
|
// Check that the homeserver can be reached
|
2022-01-28 17:24:56 +03:00
|
|
|
versionsCheck();
|
2021-09-18 01:22:33 +03:00
|
|
|
});
|
2017-04-06 02:06:42 +03:00
|
|
|
}
|
|
|
|
|
2021-06-03 16:52:41 +03:00
|
|
|
void
|
2022-01-28 17:24:56 +03:00
|
|
|
RegisterPage::versionsCheck()
|
2021-06-03 16:52:41 +03:00
|
|
|
{
|
2021-09-18 01:22:33 +03:00
|
|
|
// Make a request to /_matrix/client/versions to check the address
|
|
|
|
// given is a Matrix homeserver.
|
2022-06-25 17:16:54 +03: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 17:24:56 +03:00
|
|
|
emit hsErrorChanged();
|
|
|
|
return;
|
|
|
|
}
|
2022-06-25 17:16:54 +03:00
|
|
|
|
|
|
|
if (!err->parse_error.empty()) {
|
|
|
|
setHsError(
|
|
|
|
tr("Received malformed response. Make sure the homeserver domain is valid."));
|
2022-01-28 17:24:56 +03:00
|
|
|
emit hsErrorChanged();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-06-25 17:16:54 +03: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-06-03 16:52:41 +03:00
|
|
|
}
|
|
|
|
|
2021-07-21 13:55:41 +03:00
|
|
|
void
|
2022-01-28 17:24:56 +03: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 13:55:41 +03:00
|
|
|
{
|
2021-09-18 01:22:33 +03:00
|
|
|
// These inputs should still be alright, but check just in case
|
2022-01-28 17:24:56 +03:00
|
|
|
if (!username.isEmpty() && !password.isEmpty() && usernameAvailable_ && supported_) {
|
|
|
|
registrationError_.clear();
|
|
|
|
emit errorChanged();
|
|
|
|
registering_ = true;
|
|
|
|
emit registeringChanged();
|
|
|
|
|
2021-11-03 20:36:12 +03:00
|
|
|
connect(UIA::instance(), &UIA::error, this, [this](QString msg) {
|
2022-01-28 17:24:56 +03:00
|
|
|
setError(msg);
|
2021-11-03 20:36:12 +03:00
|
|
|
disconnect(UIA::instance(), &UIA::error, this, nullptr);
|
|
|
|
});
|
|
|
|
http::client()->registration(
|
2022-01-28 17:24:56 +03:00
|
|
|
username.toStdString(),
|
|
|
|
password.toStdString(),
|
2021-12-29 08:01:38 +03:00
|
|
|
::UIA::instance()->genericHandler(QStringLiteral("Registration")),
|
2022-01-28 17:24:56 +03: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);
|
2022-01-29 19:27:28 +03:00
|
|
|
emit registerOk();
|
2022-01-28 17:24:56 +03:00
|
|
|
disconnect(UIA::instance(), &UIA::error, this, nullptr);
|
|
|
|
return;
|
|
|
|
}
|
2021-09-18 01:22:33 +03:00
|
|
|
|
2022-01-28 17:24:56 +03: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 01:22:33 +03:00
|
|
|
|
2022-01-28 17:24:56 +03:00
|
|
|
nhlog::net()->error("failed to register: status_code ({}), matrix_error({})",
|
|
|
|
static_cast<int>(err->status_code),
|
|
|
|
err->matrix_error.error);
|
2021-07-21 13:55:41 +03:00
|
|
|
|
2022-01-28 17:24:56 +03:00
|
|
|
setError(QString::fromStdString(err->matrix_error.error));
|
|
|
|
disconnect(UIA::instance(), &UIA::error, this, nullptr);
|
|
|
|
},
|
|
|
|
devicename.isEmpty() ? LoginPage::initialDeviceName_() : devicename.toStdString());
|
|
|
|
}
|
2017-11-22 20:52:38 +03:00
|
|
|
}
|