summary refs log tree commit diff
path: root/src/RegisterPage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/RegisterPage.cpp')
-rw-r--r--src/RegisterPage.cpp267
1 files changed, 267 insertions, 0 deletions
diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp
new file mode 100644

index 00000000..5a02713a --- /dev/null +++ b/src/RegisterPage.cpp
@@ -0,0 +1,267 @@ +/* + * nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <QStyleOption> +#include <QTimer> + +#include "Config.h" +#include "Logging.h" +#include "MainWindow.h" +#include "MatrixClient.h" +#include "RegisterPage.h" +#include "ui/FlatButton.h" +#include "ui/RaisedButton.h" +#include "ui/TextField.h" + +#include "dialogs/ReCaptcha.h" + +RegisterPage::RegisterPage(QWidget *parent) + : QWidget(parent) +{ + top_layout_ = new QVBoxLayout(); + + back_layout_ = new QHBoxLayout(); + back_layout_->setSpacing(0); + back_layout_->setContentsMargins(5, 5, -1, -1); + + back_button_ = new FlatButton(this); + back_button_->setMinimumSize(QSize(30, 30)); + + QIcon icon; + icon.addFile(":/icons/icons/ui/angle-pointing-to-left.png"); + + back_button_->setIcon(icon); + back_button_->setIconSize(QSize(32, 32)); + + back_layout_->addWidget(back_button_, 0, Qt::AlignLeft | Qt::AlignVCenter); + back_layout_->addStretch(1); + + QIcon logo; + logo.addFile(":/logos/register.png"); + + logo_ = new QLabel(this); + logo_->setPixmap(logo.pixmap(128)); + + logo_layout_ = new QHBoxLayout(); + logo_layout_->setMargin(0); + logo_layout_->addWidget(logo_, 0, Qt::AlignHCenter); + + form_wrapper_ = new QHBoxLayout(); + form_widget_ = new QWidget(); + form_widget_->setMinimumSize(QSize(350, 300)); + + form_layout_ = new QVBoxLayout(); + form_layout_->setSpacing(20); + form_layout_->setContentsMargins(0, 0, 0, 40); + form_widget_->setLayout(form_layout_); + + form_wrapper_->addStretch(1); + form_wrapper_->addWidget(form_widget_); + form_wrapper_->addStretch(1); + + username_input_ = new TextField(); + username_input_->setLabel(tr("Username")); + + password_input_ = new TextField(); + password_input_->setLabel(tr("Password")); + password_input_->setEchoMode(QLineEdit::Password); + + password_confirmation_ = new TextField(); + password_confirmation_->setLabel(tr("Password confirmation")); + password_confirmation_->setEchoMode(QLineEdit::Password); + + server_input_ = new TextField(); + server_input_->setLabel(tr("Home Server")); + + form_layout_->addWidget(username_input_, Qt::AlignHCenter, 0); + form_layout_->addWidget(password_input_, Qt::AlignHCenter, 0); + form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter, 0); + form_layout_->addWidget(server_input_, Qt::AlignHCenter, 0); + + button_layout_ = new QHBoxLayout(); + button_layout_->setSpacing(0); + button_layout_->setMargin(0); + + QFont font; + font.setPixelSize(conf::fontSize); + + error_label_ = new QLabel(this); + error_label_->setFont(font); + + register_button_ = new RaisedButton(tr("REGISTER"), this); + register_button_->setMinimumSize(350, 65); + register_button_->setFontSize(conf::btn::fontSize); + register_button_->setCornerRadius(conf::btn::cornerRadius); + + button_layout_->addStretch(1); + button_layout_->addWidget(register_button_); + button_layout_->addStretch(1); + + top_layout_->addLayout(back_layout_); + top_layout_->addLayout(logo_layout_); + top_layout_->addLayout(form_wrapper_); + top_layout_->addStretch(1); + top_layout_->addLayout(button_layout_); + top_layout_->addStretch(1); + top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter); + + connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked())); + connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked())); + + connect(username_input_, SIGNAL(returnPressed()), register_button_, SLOT(click())); + connect(password_input_, SIGNAL(returnPressed()), register_button_, SLOT(click())); + connect(password_confirmation_, SIGNAL(returnPressed()), register_button_, SLOT(click())); + connect(server_input_, SIGNAL(returnPressed()), register_button_, SLOT(click())); + connect(this, &RegisterPage::registerErrorCb, this, &RegisterPage::registerError); + connect( + this, + &RegisterPage::registrationFlow, + this, + [this](const std::string &user, const std::string &pass, const std::string &session) { + emit errorOccurred(); + + if (!captchaDialog_) { + captchaDialog_ = std::make_shared<dialogs::ReCaptcha>( + QString::fromStdString(session), this); + connect( + captchaDialog_.get(), + &dialogs::ReCaptcha::closing, + this, + [this, user, pass, session]() { + captchaDialog_->close(); + emit registering(); + + http::client()->flow_response( + user, + pass, + session, + "m.login.recaptcha", + [this](const mtx::responses::Register &res, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn( + "failed to retrieve registration flows: {}", + err->matrix_error.error); + emit errorOccurred(); + emit registerErrorCb(QString::fromStdString( + err->matrix_error.error)); + return; + } + + http::client()->set_user(res.user_id); + http::client()->set_access_token(res.access_token); + + emit registerOk(); + }); + }); + } + + QTimer::singleShot(1000, this, [this]() { captchaDialog_->show(); }); + }); + + setLayout(top_layout_); +} + +void +RegisterPage::onBackButtonClicked() +{ + emit backButtonClicked(); +} + +void +RegisterPage::registerError(const QString &msg) +{ + emit errorOccurred(); + error_label_->setText(msg); +} + +void +RegisterPage::onRegisterButtonClicked() +{ + error_label_->setText(""); + + if (!username_input_->hasAcceptableInput()) { + registerError(tr("Invalid username")); + } else if (!password_input_->hasAcceptableInput()) { + registerError(tr("Password is not long enough (min 8 chars)")); + } else if (password_input_->text() != password_confirmation_->text()) { + registerError(tr("Passwords don't match")); + } else if (!server_input_->hasAcceptableInput()) { + registerError(tr("Invalid server name")); + } else { + auto username = username_input_->text().toStdString(); + auto password = password_input_->text().toStdString(); + auto server = server_input_->text().toStdString(); + + http::client()->set_server(server); + 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) { + http::client()->flow_register( + username, + password, + [this, username, password]( + const mtx::responses::RegistrationFlows &res, + mtx::http::RequestErr err) { + if (res.session.empty() && err) { + nhlog::net()->warn( + "failed to retrieve registration flows: ({}) " + "{}", + 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, res.session); + }); + return; + } + + nhlog::net()->warn("failed to register: status_code ({})", + static_cast<int>(err->status_code)); + + emit registerErrorCb(QString::fromStdString(err->matrix_error.error)); + emit errorOccurred(); + }); + + emit registering(); + } +} + +void +RegisterPage::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +}