Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libQuotient for openSUSE:Factory 
checked in at 2025-04-04 17:30:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libQuotient (Old)
 and      /work/SRC/openSUSE:Factory/.libQuotient.new.1907 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libQuotient"

Fri Apr  4 17:30:10 2025 rev:20 rq:1266962 version:0.9.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/libQuotient/libQuotient.changes  2025-01-13 
17:50:41.700028692 +0100
+++ /work/SRC/openSUSE:Factory/.libQuotient.new.1907/libQuotient.changes        
2025-04-04 17:30:18.090980856 +0200
@@ -1,0 +2,10 @@
+Thu Apr  3 20:22:52 UTC 2025 - Christophe Marin <christo...@krop.fr>
+
+- Update to 0.9.3
+  * Support event relations on all post message functions
+  * OIDC awareness
+  * A couple of internal minor fixes
+  * Emit finished() and delete verification session when it's
+    cancelled on the remote side
+
+-------------------------------------------------------------------

Old:
----
  libQuotient-0.9.2.tar.gz

New:
----
  libQuotient-0.9.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libQuotient.spec ++++++
--- /var/tmp/diff_new_pack.gY923S/_old  2025-04-04 17:30:18.779009516 +0200
+++ /var/tmp/diff_new_pack.gY923S/_new  2025-04-04 17:30:18.779009516 +0200
@@ -29,7 +29,7 @@
 %define sonum 0.9
 %define rname libQuotient
 Name:           libQuotient%{?pkg_suffix}
-Version:        0.9.2
+Version:        0.9.3
 Release:        0
 Summary:        Library for Qt Matrix Clients
 License:        LGPL-2.1-only

++++++ libQuotient-0.9.2.tar.gz -> libQuotient-0.9.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/.github/workflows/ci.yml 
new/libQuotient-0.9.3/.github/workflows/ci.yml
--- old/libQuotient-0.9.2/.github/workflows/ci.yml      2024-12-29 
11:43:12.000000000 +0100
+++ new/libQuotient-0.9.3/.github/workflows/ci.yml      2025-03-18 
15:38:48.000000000 +0100
@@ -60,7 +60,7 @@
         gnome-keyring-daemon -d --unlock <<<'' # Create a login keyring with 
no password
 
     - name: Install dependencies (non-Linux)
-      uses: jurplel/install-qt-action@v3.0.0
+      uses: jurplel/install-qt-action@v4.1.1
       with:
         version: '${{ matrix.qt-version }}.*'
         cache: true
@@ -137,7 +137,7 @@
     - name: Build and install QtKeychain
       run: |
         cd ..
-        git clone -b 0.14.3 https://github.com/frankosterfeld/qtkeychain.git
+        git clone -b 0.15.0 https://github.com/frankosterfeld/qtkeychain.git
         cmake -S qtkeychain -B qtkeychain/build -DBUILD_WITH_QT6=ON $CMAKE_ARGS
         cmake --build qtkeychain/build --target install
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/CMakeLists.txt 
new/libQuotient-0.9.3/CMakeLists.txt
--- old/libQuotient-0.9.2/CMakeLists.txt        2024-12-29 11:43:12.000000000 
+0100
+++ new/libQuotient-0.9.3/CMakeLists.txt        2025-03-18 15:38:48.000000000 
+0100
@@ -4,7 +4,7 @@
 endif()
 
 set(API_VERSION "0.9")
-project(Quotient VERSION "${API_VERSION}.2" LANGUAGES CXX)
+project(Quotient VERSION "${API_VERSION}.3" LANGUAGES CXX)
 set(PRE_STAGE "")
 string(JOIN ~ FULL_VERSION ${PROJECT_VERSION} ${PRE_STAGE})
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/connection.cpp 
new/libQuotient-0.9.3/Quotient/connection.cpp
--- old/libQuotient-0.9.2/Quotient/connection.cpp       2024-12-29 
11:43:12.000000000 +0100
+++ new/libQuotient-0.9.3/Quotient/connection.cpp       2025-03-18 
15:38:48.000000000 +0100
@@ -156,8 +156,8 @@
                                    const QString& initialDeviceName,
                                    const QString& deviceId)
 {
-    d->ensureHomeserver(userId, LoginFlows::Password).then([=, this] {
-        d->loginToServer(LoginFlows::Password.type, makeUserIdentifier(userId),
+    d->ensureHomeserver(userId, LoginFlowTypes::Password).then([=, this] {
+        d->loginToServer(LoginFlowTypes::Password, makeUserIdentifier(userId),
                          password, /*token*/ QString(), deviceId, 
initialDeviceName);
     });
 }
@@ -172,8 +172,8 @@
                                 const QString& initialDeviceName,
                                 const QString& deviceId)
 {
-    Q_ASSERT(d->data->baseUrl().isValid() && 
d->loginFlows.contains(LoginFlows::Token));
-    d->loginToServer(LoginFlows::Token.type, std::nullopt /*user is encoded in 
loginToken*/,
+    Q_ASSERT(d->data->baseUrl().isValid() && 
d->supportsLoginFlow(LoginFlowTypes::Token));
+    d->loginToServer(LoginFlowTypes::Token, std::nullopt /*user is encoded in 
loginToken*/,
                      QString() /*password*/, loginToken, deviceId, 
initialDeviceName);
 }
 
@@ -355,28 +355,28 @@
 }
 
 QFuture<void> Connection::Private::ensureHomeserver(const QString& userId,
-                                                    const 
std::optional<LoginFlow>& flow)
+                                                    const LoginFlowType& 
flowType)
 {
     QPromise<void> promise;
     auto result = promise.future();
     promise.start();
-    if (data->baseUrl().isValid() && (!flow || loginFlows.contains(*flow))) {
+    if (data->baseUrl().isValid() && (flowType.isEmpty() || 
supportsLoginFlow(flowType))) {
         q->setObjectName(userId % u"(?)");
         promise.finish(); // Perfect, we're already good to go
     } else if (userId.startsWith(u'@') && userId.indexOf(u':') != -1) {
         // Try to ascertain the homeserver URL and flows
         q->setObjectName(userId % u"(?)");
         q->resolveServer(userId);
-        if (flow)
+        if (!flowType.isEmpty())
             QtFuture::connect(q, &Connection::loginFlowsChanged)
-                .then([this, flow, p = std::move(promise)]() mutable {
-                    if (loginFlows.contains(*flow))
+                .then([this, flowType, p = std::move(promise)]() mutable {
+                    if (supportsLoginFlow(flowType))
                         p.finish();
                     else // Leave the promise unfinished and emit the error
                         emit q->loginError(tr("Unsupported login flow"),
                                            tr("The homeserver at %1 does not 
support"
-                                              " the login flow '%2'")
-                                               
.arg(data->baseUrl().toDisplayString(), flow->type));
+                                              " login flows of type '%2'")
+                                               
.arg(data->baseUrl().toDisplayString(), flowType));
                 });
         else // Any flow is fine, just wait until the homeserver is resolved
             return QFuture<void>(QtFuture::connect(q, 
&Connection::homeserverChanged));
@@ -404,6 +404,7 @@
     emit stateChanged();
 
     QFutureInterface<void> p;
+    p.reportStarted();
     connect(d->logoutJob.get(), &BaseJob::finished, this, [this, wasSyncing, 
p]() mutable {
         if (d->logoutJob->status().good()
             || d->logoutJob->error() == BaseJob::Unauthorised
@@ -710,6 +711,7 @@
 {
     Q_ASSERT(mxcUrl.scheme() == "mxc"_L1);
     QUrlQuery q(mxcUrl.query());
+    q.removeAllQueryItems(u"user_id"_s);
     q.addQueryItem(u"user_id"_s, userId());
     mxcUrl.setQuery(q);
     return mxcUrl;
@@ -960,14 +962,25 @@
     return d->loginFlows;
 }
 
+std::optional<LoginFlow> Connection::getLoginFlow(const QString& flowType) 
const
+{
+    if (auto it = std::ranges::find(d->loginFlows, flowType, &LoginFlow::type);
+        it != d->loginFlows.cend())
+        return *it;
+    return std::nullopt;
+}
+
 bool Connection::supportsPasswordAuth() const
 {
-    return d->loginFlows.contains(LoginFlows::Password);
+    if (auto ssoFlow = getLoginFlow(LoginFlowTypes::SSO);
+        ssoFlow && ssoFlow->delegatedOidcCompatibility)
+        return false; // See MSC3824
+    return d->supportsLoginFlow(LoginFlowTypes::Password);
 }
 
 bool Connection::supportsSso() const
 {
-    return d->loginFlows.contains(LoginFlows::SSO);
+    return d->supportsLoginFlow(LoginFlowTypes::SSO);
 }
 
 Room* Connection::room(const QString& roomId, JoinStates states) const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/connection.h 
new/libQuotient-0.9.3/Quotient/connection.h
--- old/libQuotient-0.9.2/Quotient/connection.h 2024-12-29 11:43:12.000000000 
+0100
+++ new/libQuotient-0.9.3/Quotient/connection.h 2025-03-18 15:38:48.000000000 
+0100
@@ -57,21 +57,34 @@
 class QOlmInboundGroupSession;
 
 using LoginFlow = GetLoginFlowsJob::LoginFlow;
+using LoginFlowType = QString;
+
+//! Predefined login flow types
+namespace LoginFlowTypes {
+    inline constexpr auto Password = "m.login.password"_L1, SSO = 
"m.login.sso"_L1,
+                          Token = "m.login.token"_L1;
+}
 
 //! Predefined login flows
-namespace LoginFlows {
-    inline const LoginFlow Password { "m.login.password"_L1 };
-    inline const LoginFlow SSO { "m.login.sso"_L1 };
-    inline const LoginFlow Token { "m.login.token"_L1 };
+namespace
+#ifndef Q_MOC_RUN
+    [[deprecated("Use login flow types and Connection::getLoginFlow() 
instead")]]
+#endif
+    LoginFlows {
+    inline const LoginFlow Password { LoginFlowTypes::Password };
+    inline const LoginFlow SSO { LoginFlowTypes::SSO };
+    inline const LoginFlow Token { LoginFlowTypes::Token };
 }
 
 // To simplify comparisons of LoginFlows
 
+[[deprecated("Compare login flow types instead")]]
 inline bool operator==(const LoginFlow& lhs, const LoginFlow& rhs)
 {
     return lhs.type == rhs.type;
 }
 
+[[deprecated("Compare login flow types instead")]]
 inline bool operator!=(const LoginFlow& lhs, const LoginFlow& rhs)
 {
     return !(lhs == rhs);
@@ -297,6 +310,8 @@
     bool isUsable() const;
     //! Get the list of supported login flows
     QVector<GetLoginFlowsJob::LoginFlow> loginFlows() const;
+    //! Get the login flow of a given type
+    Q_INVOKABLE std::optional<LoginFlow> getLoginFlow(const QString& flowType) 
const;
     //! Check whether the current homeserver supports password auth
     bool supportsPasswordAuth() const;
     //! Check whether the current homeserver supports SSO
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/connection_p.h 
new/libQuotient-0.9.3/Quotient/connection_p.h
--- old/libQuotient-0.9.2/Quotient/connection_p.h       2024-12-29 
11:43:12.000000000 +0100
+++ new/libQuotient-0.9.3/Quotient/connection_p.h       2025-03-18 
15:38:48.000000000 +0100
@@ -8,6 +8,7 @@
 #include "connection.h"
 #include "connectiondata.h"
 #include "connectionencryptiondata_p.h"
+#include "ranges_extras.h"
 #include "settings.h"
 #include "syncdata.h"
 
@@ -76,21 +77,27 @@
         != "json"_L1;
     bool lazyLoading = false;
 
+    bool supportsLoginFlow(const LoginFlowType& flowType) const
+    {
+        return rangeContains(loginFlows, flowType, &LoginFlow::type);
+    }
+
     //! \brief Check the homeserver and resolve it if needed, before connecting
     //!
     //! A single entry for functions that need to check whether the homeserver 
is valid before
     //! running. Emits resolveError() if the homeserver URL is not valid and 
cannot be resolved
-    //! from \p userId; loginError() if the homeserver is accessible but 
doesn't support \p flow.
+    //! from \p userId; loginError() if the homeserver is accessible but 
doesn't support \p
+    //! flowType.
     //!
     //! \param userId    fully-qualified MXID to resolve HS from
-    //! \param flow      optionally, a login flow that should be supported;
-    //!                  `std::nullopt`, if there are no login flow 
requirements
+    //! \param flowType      optionally, a login flowType that should be 
supported;
+    //!                  `std::nullopt`, if there are no login flowType 
requirements
     //! \return a future that becomes ready once the homeserver is available; 
if the homeserver
     //!         URL is incorrect or other problems occur, the future is never 
resolved and is
     //!         deleted (along with associated continuations) as soon as the 
problem becomes
     //!         apparent
     //! \sa resolveServer, resolveError, loginError
-    QFuture<void> ensureHomeserver(const QString& userId, const 
std::optional<LoginFlow>& flow = {});
+    QFuture<void> ensureHomeserver(const QString& userId, const LoginFlowType& 
flowType = {});
     template <typename... LoginArgTs>
     void loginToServer(LoginArgTs&&... loginArgs);
     void completeSetup(const QString& mxId, bool newLogin = true,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/csapi/login.h 
new/libQuotient-0.9.3/Quotient/csapi/login.h
--- old/libQuotient-0.9.2/Quotient/csapi/login.h        2024-12-29 
11:43:12.000000000 +0100
+++ new/libQuotient-0.9.3/Quotient/csapi/login.h        2025-03-18 
15:38:48.000000000 +0100
@@ -29,6 +29,8 @@
         //! necessarily indicate that the user attempting to log in will
         //! be able to generate such a token.
         bool getLoginToken{ false };
+
+        bool delegatedOidcCompatibility{ false };
     };
 
     // Construction/destruction
@@ -55,6 +57,8 @@
     {
         fillFromJson(jo.value("type"_L1), result.type);
         fillFromJson(jo.value("get_login_token"_L1), result.getLoginToken);
+        
fillFromJson(jo.value("org.matrix.msc3824.delegated_oidc_compatibility"_L1),
+                     result.delegatedOidcCompatibility);
     }
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libQuotient-0.9.2/Quotient/keyverificationsession.cpp 
new/libQuotient-0.9.3/Quotient/keyverificationsession.cpp
--- old/libQuotient-0.9.2/Quotient/keyverificationsession.cpp   2024-12-29 
11:43:12.000000000 +0100
+++ new/libQuotient-0.9.3/Quotient/keyverificationsession.cpp   2025-03-18 
15:38:48.000000000 +0100
@@ -130,11 +130,9 @@
 
 void KeyVerificationSession::handleEvent(const KeyVerificationEvent& baseEvent)
 {
-    if (!switchOnType(
-            baseEvent,
+    if (!baseEvent.switchOnType( // true if state transition is correct; false 
otherwise
             [this](const KeyVerificationCancelEvent& event) {
-                setError(stringToError(event.code()));
-                setState(CANCELED);
+                handleCancel(stringToError(event.code()));
                 return true;
             },
             [this](const KeyVerificationStartEvent& event) {
@@ -162,13 +160,13 @@
                 }
                 if (m_commonMacCodes.isEmpty()) {
                     cancelVerification(UNKNOWN_METHOD);
-                    return false;
+                    return true;
                 }
                 m_commitment = event.commitment().toLatin1();
                 if (!QByteArray::fromBase64Encoding(m_commitment,
                                                     
QByteArray::AbortOnBase64DecodingErrors)) {
                     cancelVerification(INVALID_MESSAGE);
-                    return false;
+                    return true;
                 }
                 sendKey();
                 setState(WAITINGFORKEY);
@@ -361,15 +359,13 @@
                                m_encrypted);
 }
 
-
 void KeyVerificationSession::cancelVerification(Error error)
 {
-    sendEvent(m_remoteUserId, m_remoteDeviceId, 
KeyVerificationCancelEvent(m_transactionId,
-                                                          
errorToString(error)), m_encrypted);
-    setState(CANCELED);
-    setError(error);
-    emit finished();
-    deleteLater();
+    if (QUO_ALARM(state() == CANCELED))
+        return; // Make sure not to overwrite previous error
+    sendEvent(m_remoteUserId, m_remoteDeviceId,
+              KeyVerificationCancelEvent(m_transactionId, 
errorToString(error)), m_encrypted);
+    handleCancel(error);
 }
 
 void KeyVerificationSession::sendReady()
@@ -499,6 +495,14 @@
     }
 }
 
+void KeyVerificationSession::handleCancel(Error error)
+{
+    setState(CANCELED);
+    setError(error);
+    emit finished();
+    deleteLater();
+}
+
 void KeyVerificationSession::trustKeys()
 {
     m_connection->database()->setSessionVerified(m_pendingEdKeyId);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/keyverificationsession.h 
new/libQuotient-0.9.3/Quotient/keyverificationsession.h
--- old/libQuotient-0.9.2/Quotient/keyverificationsession.h     2024-12-29 
11:43:12.000000000 +0100
+++ new/libQuotient-0.9.3/Quotient/keyverificationsession.h     2025-03-18 
15:38:48.000000000 +0100
@@ -170,6 +170,7 @@
     void handleStart(const KeyVerificationStartEvent& event);
     void handleKey(const KeyVerificationKeyEvent& event);
     void handleMac(const KeyVerificationMacEvent& event);
+    void handleCancel(Error error);
     void setupTimeout(std::chrono::milliseconds timeout);
     void setState(State state);
     void setError(Error error);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/ranges_extras.h 
new/libQuotient-0.9.3/Quotient/ranges_extras.h
--- old/libQuotient-0.9.2/Quotient/ranges_extras.h      2024-12-29 
11:43:12.000000000 +0100
+++ new/libQuotient-0.9.3/Quotient/ranges_extras.h      2025-03-18 
15:38:48.000000000 +0100
@@ -48,4 +48,13 @@
 #endif
 }
 
+#ifdef __cpp_lib_ranges_contains
+constexpr auto rangeContains = std::ranges::contains;
+#else
+[[nodiscard]] constexpr auto rangeContains(const auto& c, const auto& v, auto 
proj)
+{
+    return std::ranges::find(c, v, std::move(proj)) != std::ranges::end(c);
+}
+#endif
+
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/room.cpp 
new/libQuotient-0.9.3/Quotient/room.cpp
--- old/libQuotient-0.9.2/Quotient/room.cpp     2024-12-29 11:43:12.000000000 
+0100
+++ new/libQuotient-0.9.3/Quotient/room.cpp     2025-03-18 15:38:48.000000000 
+0100
@@ -1416,8 +1416,10 @@
     auto url = connection()->makeMediaUrl(mxcUrl);
     QUrlQuery q(url.query());
     Q_ASSERT(q.hasQueryItem("user_id"_L1));
-    q.addQueryItem("room_id"_L1, id());
-    q.addQueryItem("event_id"_L1, eventId);
+    q.removeAllQueryItems(u"room_id"_s);
+    q.addQueryItem(u"room_id"_s, id());
+    q.removeAllQueryItems(u"event_id"_s);
+    q.addQueryItem(u"event_id"_s, eventId);
     url.setQuery(q);
     return url;
 }
@@ -2239,6 +2241,13 @@
 QString Room::postFile(const QString& plainText,
                        std::unique_ptr<EventContent::FileContentBase> 
fileContent)
 {
+    return postFile(plainText, std::move(fileContent), std::nullopt);
+}
+
+QString Room::postFile(const QString& plainText,
+                       std::unique_ptr<EventContent::FileContentBase> 
fileContent,
+                       std::optional<EventRelation> relatesTo)
+{
     Q_ASSERT(fileContent != nullptr);
     const auto url = fileContent->url();
     // toLocalFile() doesn't work on Android and toString() doesn't work on 
the desktop
@@ -2247,7 +2256,7 @@
 
     return d->doPostFile(makeEvent<RoomMessageEvent>(plainText,
                                                      
RoomMessageEvent::rawMsgTypeForFile(localFile),
-                                                     std::move(fileContent)),
+                                                     std::move(fileContent), 
relatesTo),
                          url);
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/room.h 
new/libQuotient-0.9.3/Quotient/room.h
--- old/libQuotient-0.9.2/Quotient/room.h       2024-12-29 11:43:12.000000000 
+0100
+++ new/libQuotient-0.9.3/Quotient/room.h       2025-03-18 15:38:48.000000000 
+0100
@@ -726,8 +726,31 @@
         return post(makeEvent<EvT>(std::forward<ArgTs>(args)...));
     }
 
+    //! \brief Send a text type message
+    //!
+    //! This means MessageEventType Text, Emote or Notice.
+    template<MessageEventType type = MessageEventType::Text>
+    QString postText(const QString& plainText,
+                     const std::optional<QString>& html = std::nullopt,
+                     const std::optional<EventRelation>& relatesTo = 
std::nullopt)
+    {
+        static_assert(type == MessageEventType::Text || type == 
MessageEventType::Emote
+                          || type == MessageEventType::Notice,
+                      "MessageEvent type is not a text message");
+
+        return post<RoomMessageEvent>(
+                   plainText, type,
+                   html ? std::make_unique<EventContent::TextContent>(*html, 
u"text/html"_s)
+                        : nullptr,
+                   relatesTo)
+            ->transactionId();
+    }
+
     QString postFile(const QString& plainText,
                      std::unique_ptr<EventContent::FileContentBase> 
fileContent);
+    QString postFile(const QString& plainText,
+                     std::unique_ptr<EventContent::FileContentBase> 
fileContent,
+                     std::optional<EventRelation> relatesTo);
 
     PendingEventItem::future_type whenMessageMerged(QString txnId) const;
 
@@ -754,11 +777,16 @@
     /** Check whether the room should be upgraded */
     void checkVersion();
 
+    [[deprecated("Use postText() instead")]]
     QString postMessage(const QString& plainText, MessageEventType type);
+    [[deprecated("Use postText() instead")]]
     QString postPlainText(const QString& plainText);
+    [[deprecated("Use postText() instead")]]
     QString postHtmlMessage(const QString& plainText, const QString& html,
                             MessageEventType type = MessageEventType::Text);
+    [[deprecated("Use postText() instead")]]
     QString postHtmlText(const QString& plainText, const QString& html);
+
     /// Send a reaction on a given event with a given key
     QString postReaction(const QString& eventId, const QString& key);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/ssosession.cpp 
new/libQuotient-0.9.3/Quotient/ssosession.cpp
--- old/libQuotient-0.9.2/Quotient/ssosession.cpp       2024-12-29 
11:43:12.000000000 +0100
+++ new/libQuotient-0.9.3/Quotient/ssosession.cpp       2025-03-18 
15:38:48.000000000 +0100
@@ -77,7 +77,19 @@
     , d(makeImpl<Private>(this, initialDeviceName, deviceId, connection))
 {}
 
-QUrl SsoSession::ssoUrl() const { return d->ssoUrl; }
+namespace {
+QUrl withAction(QUrl url, const QString& value)
+{
+    QUrlQuery q{ url.query() };
+    q.addQueryItem(u"action"_s, value);
+    url.setQuery(q);
+    return url;
+}
+}
+
+QUrl SsoSession::ssoUrl() const { return withAction(d->ssoUrl, u"login"_s); }
+
+QUrl SsoSession::ssoUrlForRegistration() const { return withAction(d->ssoUrl, 
u"register"_s); }
 
 QUrl SsoSession::callbackUrl() const { return QUrl(d->callbackUrl); }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/Quotient/ssosession.h 
new/libQuotient-0.9.3/Quotient/ssosession.h
--- old/libQuotient-0.9.2/Quotient/ssosession.h 2024-12-29 11:43:12.000000000 
+0100
+++ new/libQuotient-0.9.3/Quotient/ssosession.h 2025-03-18 15:38:48.000000000 
+0100
@@ -36,6 +36,7 @@
     ~SsoSession() override = default;
 
     QUrl ssoUrl() const;
+    QUrl ssoUrlForRegistration() const;
     QUrl callbackUrl() const;
 
 private:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/gtad/gtad.yaml 
new/libQuotient-0.9.3/gtad/gtad.yaml
--- old/libQuotient-0.9.2/gtad/gtad.yaml        2024-12-29 11:43:12.000000000 
+0100
+++ new/libQuotient-0.9.3/gtad/gtad.yaml        2025-03-18 15:38:48.000000000 
+0100
@@ -13,6 +13,7 @@
     origin_server_ts: originServerTimestamp # Instead of originServerTs
     start: begin # Because start() is a method in BaseJob
     /^.*/m\.([a-z].*)$/: '$1' # Strip leading m. from all identifiers
+    /^.*/org\.matrix\.msc\d{4}\.([a-z].*)$/: '$1' # Strip m.org's unstable 
prefixes from identifiers
     m.3pid_changes: ThirdPartyIdChanges # Special case because there's a digit 
after m.
     AuthenticationData/additionalProperties: authInfo
     /^/(Location|Protocol|User)$/: 'ThirdParty$1'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libQuotient-0.9.2/quotest/quotest.cpp 
new/libQuotient-0.9.3/quotest/quotest.cpp
--- old/libQuotient-0.9.2/quotest/quotest.cpp   2024-12-29 11:43:12.000000000 
+0100
+++ new/libQuotient-0.9.3/quotest/quotest.cpp   2025-03-18 15:38:48.000000000 
+0100
@@ -184,14 +184,14 @@
     if (condition) {
         clog << item << " successful" << endl;
         if (targetRoom)
-            targetRoom->postMessage(origin % ": "_L1 % QString::fromUtf8(item) 
% " successful"_L1,
-                                    MessageEventType::Notice);
+            targetRoom->postText<MessageEventType::Notice>(
+                origin % ": "_L1 % QString::fromUtf8(item) % " successful"_L1);
     } else {
         clog << item << " FAILED at " << loc.file_name() << ":" << loc.line() 
<< endl;
         if (targetRoom)
-            targetRoom->postPlainText(origin % ": "_L1 % 
QString::fromUtf8(item) % " FAILED at "_L1
-                                      % QString::fromUtf8(loc.file_name()) % 
", line "_L1
-                                      % QString::number(loc.line()));
+            targetRoom->postText(origin % ": "_L1 % QString::fromUtf8(item) % 
" FAILED at "_L1
+                                 % QString::fromUtf8(loc.file_name()) % ", 
line "_L1
+                                 % QString::number(loc.line()));
     }
 
     emit finishedItem(item, condition);
@@ -380,7 +380,7 @@
 
 TEST_IMPL(sendMessage)
 {
-    auto txnId = targetRoom->postPlainText("Hello, "_L1 % origin % " is 
here"_L1);
+    auto txnId = targetRoom->postText("Hello, "_L1 % origin % " is here"_L1);
     if (!validatePendingEvent<RoomMessageEvent>(txnId)) {
         clog << "Invalid pending event right after submitting" << endl;
         FAIL_TEST();
@@ -478,7 +478,7 @@
             if (id != txnId)
                 return false;
 
-            targetRoom->postPlainText(origin % ": File upload failed: "_L1 % 
error);
+            targetRoom->postText(origin % ": File upload failed: "_L1 % error);
             tf->deleteLater();
             FAIL_TEST();
         });
@@ -906,7 +906,7 @@
 
 TEST_IMPL(thread)
 {
-    auto rootTxnId = targetRoom->postPlainText("Threadroot"_L1);
+    auto rootTxnId = targetRoom->postText("Threadroot"_L1);
     connect(targetRoom, &Room::pendingEventAboutToMerge, this, [this, 
thisTest, rootTxnId](Quotient::RoomEvent* rootEvt) {
         if (rootEvt->transactionId() == rootTxnId) {
             const auto relation = EventRelation::replyInThread(rootEvt->id(), 
true, rootEvt->id());
@@ -976,7 +976,7 @@
         htmlReport += "<br><strong>Did not finish:</strong>"_L1 + 
QString::fromUtf8(dnfList);
     }
 
-    auto txnId = room->postHtmlText(plainReport, htmlReport);
+    auto txnId = room->postText(plainReport, htmlReport);
     // Now just wait until all the pending events reach the server
     connectUntil(room, &Room::messageSent, this, [this, txnId, room, 
plainReport] {
         const auto& pendingEvents = room->pendingEvents();

Reply via email to