QML the fallback auth dialog

This commit is contained in:
Loren Burkholder 2023-07-13 12:53:51 -04:00
parent 03fe9f8a25
commit 0634d3f09c
9 changed files with 149 additions and 124 deletions

View file

@ -350,10 +350,6 @@ configure_file(cmake/nheko.h config/nheko.h)
# Declare source and header files.
#
set(SRC_FILES
# Dialogs
src/dialogs/FallbackAuth.cpp
src/dialogs/FallbackAuth.h
# Emoji
src/emoji/Provider.cpp
src/emoji/Provider.h
@ -463,6 +459,8 @@ set(SRC_FILES
src/Config.h
src/EventAccessors.cpp
src/EventAccessors.h
src/FallbackAuth.cpp
src/FallbackAuth.h
src/ImagePackListModel.cpp
src/ImagePackListModel.h
src/InviteesModel.cpp
@ -764,8 +762,9 @@ set(QML_SOURCES
resources/qml/dialogs/ConfirmJoinRoomDialog.qml
resources/qml/dialogs/CreateDirect.qml
resources/qml/dialogs/CreateRoom.qml
resources/qml/dialogs/FallbackAuthDialog.qml
resources/qml/dialogs/HiddenEventsDialog.qml
resources/qml/dialogs/EventExpirationDialog.qml
resources/qml/dialogs/EventExpirationDialog.qml
resources/qml/dialogs/ImageOverlay.qml
resources/qml/dialogs/ImagePackEditorDialog.qml
resources/qml/dialogs/ImagePackSettingsDialog.qml

View file

@ -385,6 +385,18 @@ Pane {
console.error("Failed to create component: " + component.errorString());
}
}
function onFallbackAuth(fallback) {
var component = Qt.createComponent("qrc:/resources/qml/dialogs/FallbackAuthDialog.qml");
if (component.status == Component.Ready) {
var dialog = component.createObject(timelineRoot, {
"fallback": fallback
});
dialog.show();
destroyOnClose(dialog);
} else {
console.error("Failed to create component: " + component.errorString());
}
}
target: UIA
}

View file

@ -0,0 +1,63 @@
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick
import QtQuick.Controls
import im.nheko
ApplicationWindow {
id: fallbackRoot
required property FallbackAuth fallback
function accept() {
fallback.confirm();
fallbackRoot.close();
}
function reject() {
fallback.cancel();
fallbackRoot.close();
}
color: palette.window
title: qsTr("Fallback authentication")
flags: Qt.Tool | Qt.WindowStaysOnTopHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
height: msg.implicitHeight + footer.implicitHeight
width: Math.max(msg.implicitWidth, footer.implicitWidth)
Shortcut {
sequence: StandardKey.Cancel
onActivated: fallbackRoot.reject()
}
Label {
id: msg
anchors.fill: parent
padding: 8
text: qsTr("Open the fallback, follow the steps, and confirm after completing them.")
}
footer: DialogButtonBox {
onAccepted: fallbackRoot.accept()
onRejected: fallbackRoot.reject()
Button {
text: qsTr("Open Fallback in Browser")
onClicked: fallback.openFallbackAuth()
}
Button {
text: qsTr("Cancel")
DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
}
Button {
text: qsTr("Confirm")
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
}
}
}

29
src/FallbackAuth.cpp Normal file
View file

@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "FallbackAuth.h"
#include <QDesktopServices>
#include <QUrl>
#include "MatrixClient.h"
FallbackAuth::FallbackAuth(const QString &session, const QString &authType, QObject *parent)
: QObject{parent}
, m_session{session}
, m_authType{authType}
{
}
void
FallbackAuth::openFallbackAuth()
{
const auto url = QString("https://%1:%2/_matrix/client/r0/auth/%4/"
"fallback/web?session=%3")
.arg(QString::fromStdString(http::client()->server()))
.arg(http::client()->port())
.arg(m_session, m_authType);
QDesktopServices::openUrl(url);
}

32
src/FallbackAuth.h Normal file
View file

@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QQmlEngine>
class FallbackAuth : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
Q_PROPERTY(QString authType MEMBER m_authType CONSTANT)
Q_PROPERTY(QString session MEMBER m_session CONSTANT)
public:
FallbackAuth(const QString &session, const QString &authType, QObject *parent = nullptr);
Q_INVOKABLE void openFallbackAuth();
Q_INVOKABLE void confirm() { emit confirmation(); }
Q_INVOKABLE void cancel() { emit cancelled(); }
signals:
void confirmation();
void cancelled();
private:
const QString m_session;
const QString m_authType;
};

View file

@ -1,75 +0,0 @@
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include <QDesktopServices>
#include <QLabel>
#include <QPushButton>
#include <QUrl>
#include <QVBoxLayout>
#include "dialogs/FallbackAuth.h"
#include "Config.h"
#include "MatrixClient.h"
using namespace dialogs;
FallbackAuth::FallbackAuth(const QString &authType, const QString &session, QWidget *parent)
: QWidget(parent)
{
setAutoFillBackground(true);
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
setWindowModality(Qt::WindowModal);
setAttribute(Qt::WA_DeleteOnClose, true);
auto layout = new QVBoxLayout(this);
layout->setSpacing(conf::modals::WIDGET_SPACING);
layout->setContentsMargins(conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN,
conf::modals::WIDGET_MARGIN);
auto buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(8);
buttonLayout->setContentsMargins(0, 0, 0, 0);
openBtn_ = new QPushButton(tr("Open Fallback in Browser"), this);
cancelBtn_ = new QPushButton(tr("Cancel"), this);
confirmBtn_ = new QPushButton(tr("Confirm"), this);
confirmBtn_->setDefault(true);
buttonLayout->addStretch(1);
buttonLayout->addWidget(openBtn_);
buttonLayout->addWidget(cancelBtn_);
buttonLayout->addWidget(confirmBtn_);
QFont font;
font.setPointSizeF(font.pointSizeF() * conf::modals::LABEL_MEDIUM_SIZE_RATIO);
auto label = new QLabel(
tr("Open the fallback, follow the steps, and confirm after completing them."), this);
label->setFont(font);
layout->addWidget(label);
layout->addLayout(buttonLayout);
connect(openBtn_, &QPushButton::clicked, [session, authType]() {
const auto url = QString("https://%1:%2/_matrix/client/r0/auth/%4/"
"fallback/web?session=%3")
.arg(QString::fromStdString(http::client()->server()))
.arg(http::client()->port())
.arg(session, authType);
QDesktopServices::openUrl(url);
});
connect(confirmBtn_, &QPushButton::clicked, this, [this]() {
emit confirmation();
emit close();
});
connect(cancelBtn_, &QPushButton::clicked, this, [this]() {
emit cancel();
emit close();
});
}

View file

@ -1,30 +0,0 @@
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QWidget>
class QPushButton;
class QLabel;
namespace dialogs {
class FallbackAuth final : public QWidget
{
Q_OBJECT
public:
FallbackAuth(const QString &authType, const QString &session, QWidget *parent = nullptr);
signals:
void confirmation();
void cancel();
private:
QPushButton *openBtn_;
QPushButton *confirmBtn_;
QPushButton *cancelBtn_;
};
} // dialogs

View file

@ -13,8 +13,6 @@
#include "Logging.h"
#include "MatrixClient.h"
#include "ReCaptcha.h"
#include "dialogs/FallbackAuth.h"
UIA *
UIA::instance()
@ -132,23 +130,18 @@ UIA::genericHandler(QString context)
}
} else {
// use fallback
auto dialog = new dialogs::FallbackAuth(QString::fromStdString(current_stage),
QString::fromStdString(u.session),
nullptr);
dialog->setWindowTitle(context);
connect(dialog, &dialogs::FallbackAuth::confirmation, this, [h, u, dialog]() {
dialog->close();
dialog->deleteLater();
auto fallback = new FallbackAuth(QString::fromStdString(u.session),
QString::fromStdString(current_stage),
nullptr);
QQmlEngine::setObjectOwnership(fallback, QQmlEngine::JavaScriptOwnership);
connect(fallback, &FallbackAuth::confirmation, this, [h, u]() {
h.next(mtx::user_interactive::Auth{u.session,
mtx::user_interactive::auth::Fallback{}});
});
connect(dialog, &dialogs::FallbackAuth::cancel, this, [this]() {
connect(fallback, &FallbackAuth::cancelled, this, [this]() {
emit error(tr("Registration aborted"));
});
dialog->show();
emit fallbackAuth(fallback);
}
});
});

View file

@ -9,6 +9,7 @@
#include <mtxclient/http/client.hpp>
#include "FallbackAuth.h"
#include "ReCaptcha.h"
class UIA final : public QObject
@ -62,6 +63,7 @@ signals:
void email();
void phoneNumber();
void reCaptcha(ReCaptcha *recaptcha);
void fallbackAuth(FallbackAuth *fallback);
void confirm3pidToken();
void prompt3pidToken();