diff --git a/src/login/Homeserver.qml b/src/login/Homeserver.qml index 122dba69f..49e00d080 100644 --- a/src/login/Homeserver.qml +++ b/src/login/Homeserver.qml @@ -37,10 +37,23 @@ LoginStep { onTriggered: Registration.homeserver = urlField.text } + Connections { + target: Registration + function onConnected(connection): void { + root.processed("Loading"); + } + } + nextAction: Kirigami.Action { - text: Registration.testing ? i18n("Loading") : null + text: Registration.testing ? i18n("Loading") : Registration.status === Registration.Oidc ? i18nc("@action:button", "Continue in Browser") : null enabled: Registration.status > Registration.ServerNoRegistration - onTriggered: root.processed("Username") + onTriggered: { + if (Registration.status === Registration.Oidc) { + Qt.openUrlExternally(Registration.oidcUrl) + } else { + root.processed("Username") + } + } } previousAction: Kirigami.Action { onTriggered: root.processed("LoginRegister") diff --git a/src/login/registration.cpp b/src/login/registration.cpp index 5c0168466..255d7292b 100644 --- a/src/login/registration.cpp +++ b/src/login/registration.cpp @@ -180,6 +180,41 @@ void Registration::testHomeserver() if (m_testServerJob) { delete m_testServerJob; } +#if Quotient_VERSION_MINOR > 9 || Quotient_VERSION_PATCH > 2 + auto ssoFlow = m_connection->getLoginFlow(LoginFlowTypes::SSO); + if (ssoFlow && ssoFlow->delegatedOidcCompatibility) { + auto session = m_connection->prepareForSso(u"NeoChat"_s); + m_oidcUrl = session->ssoUrlForRegistration(); + Q_EMIT oidcUrlChanged(); + setStatus(Oidc); + connect(m_connection, &Connection::connected, this, [this] { + Q_EMIT connected(m_connection.get()); + Q_ASSERT(m_connection); + AccountSettings account(m_connection->userId()); + account.setKeepLoggedIn(true); + account.setHomeserver(m_connection->homeserver()); + account.setDeviceId(m_connection->deviceId()); + account.sync(); + QMetaObject::invokeMethod( + this, + [this]() { + m_accountManager->addConnection(m_connection); + m_accountManager->setActiveConnection(m_connection); + m_connection = nullptr; + }, + Qt::QueuedConnection); + connect( + m_connection.get(), + &Connection::syncDone, + this, + [this]() { + Q_EMIT loaded(); + }, + Qt::SingleShotConnection); + }); + return; + } +#endif m_testServerJob = m_connection->callApi("user"_L1, std::nullopt, "user"_L1, QString(), QString(), QString(), false); connect(m_testServerJob.data(), &BaseJob::finished, this, [this]() { diff --git a/src/login/registration.h b/src/login/registration.h index 1cf3a7163..f469832b5 100644 --- a/src/login/registration.h +++ b/src/login/registration.h @@ -75,6 +75,7 @@ class Registration : public QObject Q_PROPERTY(QList terms READ terms NOTIFY termsChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(QString statusString READ statusString NOTIFY statusChanged) + Q_PROPERTY(QUrl oidcUrl MEMBER m_oidcUrl NOTIFY oidcUrlChanged) public: enum Status { @@ -87,6 +88,7 @@ public: UsernameTaken, Ready, Working, + Oidc, }; Q_ENUM(Status); static Registration &instance() @@ -147,6 +149,8 @@ Q_SIGNALS: void nextStepChanged(); void statusChanged(); void loaded(); + void oidcUrlChanged(); + void connected(NeoChatConnection *connection); private: QPointer m_accountManager; @@ -163,6 +167,7 @@ private: QString m_session; QString m_sid; QString m_emailSecret; + QUrl m_oidcUrl; QPointer m_usernameJob; QPointer m_testServerJob;