diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp
index 5c5545ec..36fd71a8 100644
--- a/src/RegisterPage.cpp
+++ b/src/RegisterPage.cpp
@@ -11,6 +11,7 @@
#include <QtMath>
#include <mtx/responses/register.hpp>
+#include <mtx/responses/well-known.hpp>
#include "Config.h"
#include "Logging.h"
@@ -108,6 +109,10 @@ RegisterPage::RegisterPage(QWidget *parent)
error_password_confirmation_label_->setWordWrap(true);
error_password_confirmation_label_->hide();
+ error_server_label_ = new QLabel(this);
+ error_server_label_->setWordWrap(true);
+ error_server_label_->hide();
+
form_layout_->addWidget(username_input_, Qt::AlignHCenter);
form_layout_->addWidget(error_username_label_, Qt::AlignHCenter);
form_layout_->addWidget(password_input_, Qt::AlignHCenter);
@@ -115,6 +120,7 @@ RegisterPage::RegisterPage(QWidget *parent)
form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter);
form_layout_->addWidget(error_password_confirmation_label_, Qt::AlignHCenter);
form_layout_->addWidget(server_input_, Qt::AlignHCenter);
+ form_layout_->addWidget(error_server_label_, Qt::AlignHCenter);
button_layout_ = new QHBoxLayout();
button_layout_->setSpacing(0);
@@ -140,6 +146,17 @@ RegisterPage::RegisterPage(QWidget *parent)
top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter);
top_layout_->addStretch(1);
+ connect(
+ this,
+ &RegisterPage::versionErrorCb,
+ this,
+ [this](const QString &msg) {
+ error_server_label_->show();
+ server_input_->setValid(false);
+ showError(error_server_label_, msg);
+ },
+ Qt::QueuedConnection);
+
connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked()));
connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked()));
@@ -351,10 +368,12 @@ RegisterPage::checkFields()
error_username_label_->setText("");
error_password_label_->setText("");
error_password_confirmation_label_->setText("");
+ error_server_label_->setText("");
error_username_label_->hide();
error_password_label_->hide();
error_password_confirmation_label_->hide();
+ error_server_label_->hide();
password_confirmation_->setValid(true);
server_input_->setValid(true);
@@ -379,7 +398,8 @@ RegisterPage::checkFields()
all_fields_good = false;
} else if (server_input_->isModified() &&
(!server_input_->hasAcceptableInput() || server_input_->text().isEmpty())) {
- showError(tr("Invalid server name"));
+ error_server_label_->show();
+ showError(error_server_label_, tr("Invalid server name"));
server_input_->setValid(false);
all_fields_good = false;
}
@@ -406,45 +426,39 @@ RegisterPage::onRegisterButtonClicked()
http::client()->set_server(server);
http::client()->verify_certificates(
!UserSettings::instance()->disableCertificateValidation());
- http::client()->registration(
- username,
- password,
- [this, username, password](const mtx::responses::Register &res,
+
+ http::client()->well_known(
+ [this, username, password](const mtx::responses::WellKnown &res,
mtx::http::RequestErr err) {
- if (!err) {
- http::client()->set_user(res.user_id);
- http::client()->set_access_token(res.access_token);
+ if (err) {
+ using namespace boost::beast::http;
- emit registerOk();
- return;
- }
+ if (err->status_code == status::not_found) {
+ nhlog::net()->info("Autodiscovery: No .well-known.");
+ checkVersionAndRegister(username, password);
+ return;
+ }
- // The server requires registration flows.
- if (err->status_code == boost::beast::http::status::unauthorized) {
- if (err->matrix_error.unauthorized.flows.empty()) {
- nhlog::net()->warn(
- "failed to retrieve registration flows1: ({}) "
- "{}",
- static_cast<int>(err->status_code),
- err->matrix_error.error);
- emit errorOccurred();
- emit registerErrorCb(
- QString::fromStdString(err->matrix_error.error));
+ if (!err->parse_error.empty()) {
+ emit versionErrorCb(tr(
+ "Autodiscovery failed. Received malformed response."));
+ nhlog::net()->error(
+ "Autodiscovery failed. Received malformed response.");
return;
}
- emit registrationFlow(
- username, password, err->matrix_error.unauthorized);
+ emit versionErrorCb(tr("Autodiscovery failed. Unknown error when "
+ "requesting .well-known."));
+ nhlog::net()->error("Autodiscovery failed. Unknown error when "
+ "requesting .well-known. {}",
+ err->error_code.message());
return;
}
- nhlog::net()->error(
- "failed to register: status_code ({}), matrix_error({})",
- static_cast<int>(err->status_code),
- err->matrix_error.error);
-
- emit registerErrorCb(QString::fromStdString(err->matrix_error.error));
- emit errorOccurred();
+ nhlog::net()->info("Autodiscovery: Discovered '" +
+ res.homeserver.base_url + "'");
+ http::client()->set_server(res.homeserver.base_url);
+ checkVersionAndRegister(username, password);
});
emit registering();
@@ -452,6 +466,74 @@ RegisterPage::onRegisterButtonClicked()
}
void
+RegisterPage::checkVersionAndRegister(const std::string &username, const std::string &password)
+{
+ http::client()->versions(
+ [this, username, password](const mtx::responses::Versions &, mtx::http::RequestErr err) {
+ if (err) {
+ using namespace boost::beast::http;
+
+ if (err->status_code == status::not_found) {
+ emit versionErrorCb(tr("The required endpoints were not found. "
+ "Possibly not a Matrix server."));
+ return;
+ }
+
+ if (!err->parse_error.empty()) {
+ emit versionErrorCb(tr("Received malformed response. Make sure "
+ "the homeserver domain is valid."));
+ return;
+ }
+
+ emit versionErrorCb(tr(
+ "An unknown error occured. Make sure the homeserver domain is valid."));
+ return;
+ }
+
+ http::client()->registration(
+ username,
+ password,
+ [this, username, password](const mtx::responses::Register &res,
+ mtx::http::RequestErr err) {
+ if (!err) {
+ http::client()->set_user(res.user_id);
+ http::client()->set_access_token(res.access_token);
+
+ emit registerOk();
+ return;
+ }
+
+ // The server requires registration flows.
+ if (err->status_code == boost::beast::http::status::unauthorized) {
+ if (err->matrix_error.unauthorized.flows.empty()) {
+ nhlog::net()->warn(
+ "failed to retrieve registration flows1: ({}) "
+ "{}",
+ static_cast<int>(err->status_code),
+ err->matrix_error.error);
+ emit errorOccurred();
+ emit registerErrorCb(
+ QString::fromStdString(err->matrix_error.error));
+ return;
+ }
+
+ emit registrationFlow(
+ username, password, err->matrix_error.unauthorized);
+ return;
+ }
+
+ nhlog::net()->error(
+ "failed to register: status_code ({}), matrix_error({})",
+ static_cast<int>(err->status_code),
+ err->matrix_error.error);
+
+ emit registerErrorCb(QString::fromStdString(err->matrix_error.error));
+ emit errorOccurred();
+ });
+ });
+}
+
+void
RegisterPage::paintEvent(QPaintEvent *)
{
QStyleOption opt;
diff --git a/src/RegisterPage.h b/src/RegisterPage.h
index 2f05d04c..0e4a45d0 100644
--- a/src/RegisterPage.h
+++ b/src/RegisterPage.h
@@ -31,6 +31,10 @@ protected:
signals:
void backButtonClicked();
void errorOccurred();
+
+ //! Used to trigger the corresponding slot outside of the main thread.
+ void versionErrorCb(const QString &err);
+
void registering();
void registerOk();
void registerErrorCb(const QString &msg);
@@ -52,6 +56,7 @@ private:
bool checkOneField(QLabel *label, const TextField *t_field, const QString &msg);
bool checkFields();
void showError(QLabel *label, const QString &msg);
+ void checkVersionAndRegister(const std::string &username, const std::string &password);
QVBoxLayout *top_layout_;
QHBoxLayout *back_layout_;
@@ -63,6 +68,7 @@ private:
QLabel *error_username_label_;
QLabel *error_password_label_;
QLabel *error_password_confirmation_label_;
+ QLabel *error_server_label_;
FlatButton *back_button_;
RaisedButton *register_button_;
|