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();