Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package mtxclient for openSUSE:Factory checked in at 2025-08-11 13:54:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mtxclient (Old) and /work/SRC/openSUSE:Factory/.mtxclient.new.1085 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mtxclient" Mon Aug 11 13:54:08 2025 rev:3 rq:1298783 version:0.10.1 Changes: -------- --- /work/SRC/openSUSE:Factory/mtxclient/mtxclient.changes 2025-03-27 22:34:11.245290535 +0100 +++ /work/SRC/openSUSE:Factory/.mtxclient.new.1085/mtxclient.changes 2025-08-11 13:54:32.286170130 +0200 @@ -1,0 +2,13 @@ +Mon Aug 4 05:41:12 UTC 2025 - Dead Mozay <dead_mo...@opensuse.org> + +- Update to version 0.10.1: + * Fix v12 room ids without server name + * Experimental support for invite permissions + * Support new style join vias (instead of server_name) + * Redirects for media downloads (Karthik) + * Location messages (MTRNord) + * Build against fmt11 (Kefu Chai) + * Fix incompatibility with null aliases +- Remove patch fix-build-with-fmt11.patch as it is fixed upstream + +------------------------------------------------------------------- Old: ---- fix-build-with-fmt11.patch mtxclient-0.10.0.tar.gz New: ---- mtxclient-0.10.1.tar.gz ----------(Old B)---------- Old: * Fix incompatibility with null aliases - Remove patch fix-build-with-fmt11.patch as it is fixed upstream ----------(Old E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mtxclient.spec ++++++ --- /var/tmp/diff_new_pack.muheAE/_old 2025-08-11 13:54:33.458218483 +0200 +++ /var/tmp/diff_new_pack.muheAE/_new 2025-08-11 13:54:33.462218648 +0200 @@ -19,14 +19,13 @@ %define libname libmatrix_client%(echo %{version} | tr . _) %define sover 0 Name: mtxclient -Version: 0.10.0 +Version: 0.10.1 Release: 0 Summary: Client API library for Matrix, built on top of Boost.Asio License: MIT Group: Development/Libraries/C and C++ URL: https://github.com/Nheko-Reborn/mtxclient Source0: %{url}/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -Patch0: fix-build-with-fmt11.patch BuildRequires: cmake >= 3.13 BuildRequires: fdupes %if 0%{?suse_version} < 1600 ++++++ mtxclient-0.10.0.tar.gz -> mtxclient-0.10.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/.ci/adjust-config.sh new/mtxclient-0.10.1/.ci/adjust-config.sh --- old/mtxclient-0.10.0/.ci/adjust-config.sh 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/.ci/adjust-config.sh 2025-08-02 21:59:13.000000000 +0200 @@ -6,18 +6,46 @@ CMD="sudo" fi -$CMD perl -pi -w -e \ - 's/rc_messages_per_second.*/rc_messages_per_second: 1000/g;' data/homeserver.yaml -$CMD perl -pi -w -e \ - 's/rc_message_burst_count.*/rc_message_burst_count: 10000/g;' data/homeserver.yaml - ( cat <<HEREDOC +server_name: "localhost" +pid_file: /data/homeserver.pid +listeners: + - port: 8008 + tls: true + type: http + x_forwarded: true + resources: + - names: [client, federation] + compress: false + - port: 8009 + tls: false + type: http + x_forwarded: true + resources: + - names: [client, federation] + compress: false +database: + name: sqlite3 + args: + database: /data/homeserver.db +log_config: "/data/localhost.log.config" +media_store_path: /data/media_store +registration_shared_secret: "&=bz^dG2c34^NHZYMidt7crX~ZheXN0r1dV02uKapb9uxmktR:" +report_stats: false +macaroon_secret_key: "Ea#Ny0z,r=kv&2.H47au0QSsL&QDjpZqxYX0NcUe9EKsX~Eyrz" +form_secret: ";,kjZhkoUnRLbUq@H21PJcX#T+p&MuNi4O9qbH*gZk2+84ree+" +signing_key_path: "/data/localhost.signing.key" +trusted_key_servers: [] + enable_registration: true enable_registration_without_verification: true +room_list_publication_rules: + - action: allow + tls_certificate_path: "/data/localhost.tls.crt" tls_private_key_path: "/data/localhost.tls.key" @@ -52,14 +80,17 @@ per_second: 10000 burst_count: 100000 +rc_presence: + per_user: + per_second: 10000 + burst_count: 100000 + experimental_features: msc3266_enabled: true -HEREDOC -) | $CMD tee -a data/homeserver.yaml -$CMD perl -pi -w -e \ - 's/tls: false/tls: true/g;' data/homeserver.yaml +HEREDOC +) | $CMD tee data/homeserver.yaml $CMD openssl req -x509 -newkey rsa:4096 -keyout data/localhost.tls.key -out data/localhost.tls.crt -days 365 -subj '/CN=localhost' -nodes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/.ci/synapse/Dockerfile new/mtxclient-0.10.1/.ci/synapse/Dockerfile --- old/mtxclient-0.10.0/.ci/synapse/Dockerfile 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/.ci/synapse/Dockerfile 2025-08-02 21:59:13.000000000 +0200 @@ -1,4 +1,4 @@ -FROM matrixdotorg/synapse:v1.63.1 +FROM matrixdotorg/synapse:v1.135.0 COPY setup-synapse.sh /setup-synapse.sh COPY entrypoint.sh /entrypoint.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/.ci/synapse/service/postgresql/run new/mtxclient-0.10.1/.ci/synapse/service/postgresql/run --- old/mtxclient-0.10.0/.ci/synapse/service/postgresql/run 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/.ci/synapse/service/postgresql/run 2025-08-02 21:59:13.000000000 +0200 @@ -1,3 +1,3 @@ #!/bin/sh -exec chpst -u postgres:postgres /usr/lib/postgresql/13/bin/postgres -D '/data2/db' 2>&1 +exec chpst -u postgres:postgres /usr/lib/postgresql/15/bin/postgres -D '/data2/db' 2>&1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/.ci/synapse/setup-synapse.sh new/mtxclient-0.10.1/.ci/synapse/setup-synapse.sh --- old/mtxclient-0.10.0/.ci/synapse/setup-synapse.sh 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/.ci/synapse/setup-synapse.sh 2025-08-02 21:59:13.000000000 +0200 @@ -13,13 +13,12 @@ chown postgres /data2/db # Initialise & start the database -su -c '/usr/lib/postgresql/13/bin/initdb -D /data2/db -E "UTF-8" --lc-collate="C" --lc-ctype="C" --username=postgres' postgres -su -c '/usr/lib/postgresql/13/bin/pg_ctl -w -D /data2/db start' postgres -su -c '/usr/lib/postgresql/13/bin/createuser synapse_user' postgres -su -c '/usr/lib/postgresql/13/bin/createdb -O synapse_user synapse' postgres +su -c '/usr/lib/postgresql/15/bin/initdb -D /data2/db -E "UTF-8" --lc-collate="C" --lc-ctype="C" --username=postgres' postgres +su -c '/usr/lib/postgresql/15/bin/pg_ctl -w -D /data2/db start' postgres +su -c '/usr/lib/postgresql/15/bin/createuser synapse_user' postgres +su -c '/usr/lib/postgresql/15/bin/createdb -O synapse_user synapse' postgres sed -i 's,/data,/data2,g' /start.py -sed -i 's,/data,/data2,g' /conf/homeserver.yaml SYNAPSE_SERVER_NAME=synapse SYNAPSE_REPORT_STATS=no /start.py generate @@ -27,18 +26,25 @@ chmod 0777 data2/synapse.tls.crt chmod 0777 data2/synapse.tls.key -sed -i 's/tls: false/tls: true/g;' data2/homeserver.yaml - # yes, the empty line is needed cat <<EOF >> /data2/homeserver.yaml - - -enable_registration: true -enable_registration_without_verification: true - -tls_certificate_path: "/data2/synapse.tls.crt" -tls_private_key_path: "/data2/synapse.tls.key" - +server_name: "synapse" +pid_file: /data2/homeserver.pid +listeners: + - port: 8008 + tls: true + type: http + x_forwarded: true + resources: + - names: [client, federation] + compress: false + - port: 8009 + tls: false + type: http + x_forwarded: true + resources: + - names: [client, federation] + compress: false database: name: psycopg2 args: @@ -47,6 +53,24 @@ host: localhost cp_min: 5 cp_max: 10 +log_config: "/data2/synapse.log.config" +media_store_path: /data2/media_store +registration_shared_secret: "&=bz^dG2c34^NHZYMidt7crX~ZheXN0r1dV02uKapb9uxmktR:" +report_stats: false +macaroon_secret_key: "Ea#Ny0z,r=kv&2.H47au0QSsL&QDjpZqxYX0NcUe9EKsX~Eyrz" +form_secret: ";,kjZhkoUnRLbUq@H21PJcX#T+p&MuNi4O9qbH*gZk2+84ree+" +signing_key_path: "/data2/synapse.signing.key" +trusted_key_servers: [] + + +enable_registration: true +enable_registration_without_verification: true + +room_list_publication_rules: + - action: allow + +tls_certificate_path: "/data2/synapse.tls.crt" +tls_private_key_path: "/data2/synapse.tls.key" rc_message: per_second: 10000 @@ -79,6 +103,11 @@ per_second: 10000 burst_count: 100000 +rc_presence: + per_user: + per_second: 10000 + burst_count: 100000 + experimental_features: msc3266_enabled: true EOF @@ -89,11 +118,15 @@ echo Waiting for synapse to start... until curl -s -f -k https://localhost:8008/_matrix/client/versions; do echo "Checking ..."; sleep 2; done echo Register alice -register_new_matrix_user --admin -u alice -p secret -c /data2/homeserver.yaml https://localhost:8008 +register_new_matrix_user --admin -u alice -p secret -c /data2/homeserver.yaml http://localhost:8009 echo Register bob -register_new_matrix_user --admin -u bob -p secret -c /data2/homeserver.yaml https://localhost:8008 +register_new_matrix_user --admin -u bob -p secret -c /data2/homeserver.yaml http://localhost:8009 echo Register carl -register_new_matrix_user --admin -u carl -p secret -c /data2/homeserver.yaml https://localhost:8008 +register_new_matrix_user --admin -u carl -p secret -c /data2/homeserver.yaml http://localhost:8009 +echo Register presence +register_new_matrix_user --admin -u presence -p secret -c /data2/homeserver.yaml http://localhost:8009 +echo Register presencesync +register_new_matrix_user --admin -u presencesync -p secret -c /data2/homeserver.yaml http://localhost:8009 exit 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/.gitlab-ci.yml new/mtxclient-0.10.1/.gitlab-ci.yml --- old/mtxclient-0.10.0/.gitlab-ci.yml 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/.gitlab-ci.yml 2025-08-02 21:59:13.000000000 +0200 @@ -27,17 +27,23 @@ script: - mkdir -p /kaniko/.docker - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --whitelist-var-run=false --context $CI_PROJECT_DIR/.ci/synapse --dockerfile $CI_PROJECT_DIR/.ci/synapse/Dockerfile --destination $CI_REGISTRY_IMAGE/synapse-${M_ARCH}:latest + - /kaniko/executor --whitelist-var-run=false --context $CI_PROJECT_DIR/.ci/synapse --dockerfile $CI_PROJECT_DIR/.ci/synapse/Dockerfile --destination $CI_REGISTRY_IMAGE/synapse-${M_ARCH}:latest --force build synapse amd64: extends: .build-synapse-image tags: [docker] + image: + docker: + platform: amd64 variables: M_ARCH: x86_64 build synapse arm64: extends: .build-synapse-image - tags: [docker-arm64] + tags: [docker] + image: + docker: + platform: arm64 variables: M_ARCH: aarch64 @@ -50,6 +56,7 @@ alias: synapse variables: TRAVIS_OS_NAME: linux + RUNNER_AFTER_SCRIPT_TIMEOUT: 10m before_script: - apt-get update - apt-get install -y software-properties-common diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/CHANGELOG.md new/mtxclient-0.10.1/CHANGELOG.md --- old/mtxclient-0.10.0/CHANGELOG.md 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/CHANGELOG.md 2025-08-02 21:59:13.000000000 +0200 @@ -1,10 +1,20 @@ # Changelog +## [0.10.1] -- 2025-08-02 + +- Fix room ids without server name +- Experimental support for invite permissions +- Support new style join vias (instead of server_name) +- Redirects for media downloads (Karthik) +- Location messages (MTRNord) +- Build against fmt11 (Kefu Chai) +- Fix incompatibility with null avatars + ## [0.10.0] -- 2024-06-11 - Authentication for media (MSC3916, experimental) - Intentional mentions and associated push rules (event_property_is and event_property_contains) -- Woraround for Element setting "order" in tags as strings +- Workaround for Element setting "order" in tags as strings - Basic support for url previews (NepNep) - Support the "fixed" mac method of interactive verification - Various speedups for compilation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/CMakeLists.txt new/mtxclient-0.10.1/CMakeLists.txt --- old/mtxclient-0.10.0/CMakeLists.txt 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/CMakeLists.txt 2025-08-02 21:59:13.000000000 +0200 @@ -38,12 +38,12 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.12) project(matrix_client - VERSION 0.10.0 + VERSION 0.10.1 DESCRIPTION "Client API library for Matrix." HOMEPAGE_URL https://github.com/Nheko-Reborn/mtxclient) else() project(matrix_client - VERSION 0.10.0 + VERSION 0.10.1 DESCRIPTION "Client API library for Matrix.") endif() @@ -245,11 +245,13 @@ lib/structs/events/ephemeral/typing.cpp lib/structs/events/nheko_extensions/event_expiry.cpp lib/structs/events/nheko_extensions/hidden_events.cpp + lib/structs/events/nheko_extensions/invite_permissions.cpp lib/structs/events/messages/audio.cpp lib/structs/events/messages/elementeffect.cpp lib/structs/events/messages/emote.cpp lib/structs/events/messages/file.cpp lib/structs/events/messages/image.cpp + lib/structs/events/messages/location.cpp lib/structs/events/messages/notice.cpp lib/structs/events/messages/text.cpp lib/structs/events/messages/unknown.cpp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/Makefile new/mtxclient-0.10.1/Makefile --- old/mtxclient-0.10.0/Makefile 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/Makefile 2025-08-02 21:59:13.000000000 +0200 @@ -1,6 +1,6 @@ FILES=`find lib include tests examples -type f -type f \( -iname "*.cpp" -o -iname "*.hpp" \)` -SYNAPSE_IMAGE="matrixdotorg/synapse:v1.63.1" +SYNAPSE_IMAGE="matrixdotorg/synapse:v1.135.0" DEPS_BUILD_DIR=.deps DEPS_SOURCE_DIR=deps @@ -53,15 +53,20 @@ -p 443:8008 \ -p 8448:8008 \ -p 8008:8008 \ + -p 8009:8009 \ -v `pwd`/data:/data ${SYNAPSE_IMAGE} @echo Waiting for synapse to start... @until curl -s -f -k https://localhost:443/_matrix/client/versions; do echo "Checking ..."; sleep 2; done @echo Register alice - @docker exec synapse /bin/sh -c 'register_new_matrix_user --admin -u alice -p secret -c /data/homeserver.yaml https://localhost:8008' + @docker exec synapse /bin/sh -c 'register_new_matrix_user --admin -u alice -p secret -c /data/homeserver.yaml http://localhost:8009' @echo Register bob - @docker exec synapse /bin/sh -c 'register_new_matrix_user --admin -u bob -p secret -c /data/homeserver.yaml https://localhost:8008' + @docker exec synapse /bin/sh -c 'register_new_matrix_user --admin -u bob -p secret -c /data/homeserver.yaml http://localhost:8009' @echo Register carl - @docker exec synapse /bin/sh -c 'register_new_matrix_user --admin -u carl -p secret -c /data/homeserver.yaml https://localhost:8008' + @docker exec synapse /bin/sh -c 'register_new_matrix_user --admin -u carl -p secret -c /data/homeserver.yaml http://localhost:8009' + @echo Register presence + @docker exec synapse /bin/sh -c 'register_new_matrix_user --admin -u presence -p secret -c /data/homeserver.yaml http://localhost:8009' + @echo Register presencesync + @docker exec synapse /bin/sh -c 'register_new_matrix_user --admin -u presencesync -p secret -c /data/homeserver.yaml http://localhost:8009' stop-synapse: ## Stop any running instance of synapse @rm -rf ./data/* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/include/mtx/events/collections.hpp new/mtxclient-0.10.1/include/mtx/events/collections.hpp --- old/mtxclient-0.10.0/include/mtx/events/collections.hpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/include/mtx/events/collections.hpp 2025-08-02 21:59:13.000000000 +0200 @@ -25,6 +25,7 @@ #include "mtx/events/name.hpp" #include "mtx/events/nheko_extensions/event_expiry.hpp" #include "mtx/events/nheko_extensions/hidden_events.hpp" +#include "mtx/events/nheko_extensions/invite_permissions.hpp" #include "mtx/events/pinned_events.hpp" #include "mtx/events/policy_rules.hpp" #include "mtx/events/power_levels.hpp" @@ -45,6 +46,7 @@ #include "mtx/events/messages/emote.hpp" #include "mtx/events/messages/file.hpp" #include "mtx/events/messages/image.hpp" +#include "mtx/events/messages/location.hpp" #include "mtx/events/messages/notice.hpp" #include "mtx/events/messages/text.hpp" #include "mtx/events/messages/unknown.hpp" @@ -89,6 +91,7 @@ mtx::events::AccountDataEvent<mtx::pushrules::GlobalRuleset>, mtx::events::AccountDataEvent<mtx::events::account_data::nheko_extensions::HiddenEvents>, mtx::events::AccountDataEvent<mtx::events::account_data::nheko_extensions::EventExpiry>, + mtx::events::AccountDataEvent<mtx::events::account_data::nheko_extensions::InvitePermissions>, mtx::events::AccountDataEvent<mtx::events::msc2545::ImagePack>, mtx::events::AccountDataEvent<mtx::events::msc2545::ImagePackRooms>, mtx::events::AccountDataEvent<mtx::events::Unknown>> @@ -191,7 +194,7 @@ mtx::events::RoomEvent<mtx::events::msg::Emote>, mtx::events::RoomEvent<mtx::events::msg::File>, mtx::events::RoomEvent<mtx::events::msg::Image>, - // TODO: events::RoomEvent<mtx::events::msg::Location>, + mtx::events::RoomEvent<mtx::events::msg::Location>, mtx::events::RoomEvent<mtx::events::msg::Notice>, mtx::events::RoomEvent<mtx::events::msg::Text>, mtx::events::RoomEvent<mtx::events::msg::Unknown>, @@ -256,6 +259,9 @@ constexpr inline EventType message_content_to_type<mtx::events::msg::Image> = EventType::RoomMessage; template<> +constexpr inline EventType message_content_to_type<mtx::events::msg::Location> = + EventType::RoomMessage; +template<> constexpr inline EventType message_content_to_type<mtx::events::msg::Notice> = EventType::RoomMessage; template<> @@ -445,6 +451,10 @@ constexpr inline EventType account_data_content_to_type<mtx::events::account_data::nheko_extensions::EventExpiry> = EventType::NhekoEventExpiry; +template<> +constexpr inline EventType + account_data_content_to_type<mtx::events::account_data::nheko_extensions::InvitePermissions> = + EventType::NhekoInvitePermissions; } // namespace events } // namespace mtx diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/include/mtx/events/common.hpp new/mtxclient-0.10.1/include/mtx/events/common.hpp --- old/mtxclient-0.10.0/include/mtx/events/common.hpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/include/mtx/events/common.hpp 2025-08-02 21:59:13.000000000 +0200 @@ -142,14 +142,12 @@ ThumbnailInfo thumbnail_info; //! Encryption members. If present, they replace thumbnail_url. std::optional<crypto::EncryptedFile> thumbnail_file; - //! experimental blurhash, see MSC2448 - std::string blurhash; //! Deserialization method needed by @p nlohmann::json. - friend void from_json(const nlohmann::json &obj, ThumbnailInfo &info); + friend void from_json(const nlohmann::json &obj, LocationInfo &info); //! Serialization method needed by @p nlohmann::json. - friend void to_json(nlohmann::json &obj, const ThumbnailInfo &info); + friend void to_json(nlohmann::json &obj, const LocationInfo &info); }; /// @brief Mentions metadata diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/include/mtx/events/event_type.hpp new/mtxclient-0.10.1/include/mtx/events/event_type.hpp --- old/mtxclient-0.10.0/include/mtx/events/event_type.hpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/include/mtx/events/event_type.hpp 2025-08-02 21:59:13.000000000 +0200 @@ -139,6 +139,8 @@ NhekoHiddenEvents, // im.nheko.event_expiry NhekoEventExpiry, + // im.nheko.invite_permissions + NhekoInvitePermissions, // MSCs //! m.image_pack, currently im.ponies.room_emotes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/include/mtx/events/nheko_extensions/invite_permissions.hpp new/mtxclient-0.10.1/include/mtx/events/nheko_extensions/invite_permissions.hpp --- old/mtxclient-0.10.0/include/mtx/events/nheko_extensions/invite_permissions.hpp 1970-01-01 01:00:00.000000000 +0100 +++ new/mtxclient-0.10.1/include/mtx/events/nheko_extensions/invite_permissions.hpp 2025-08-02 21:59:13.000000000 +0200 @@ -0,0 +1,48 @@ +#pragma once + +/// @file +/// @brief A nheko specific event in account data used to block or allow list invites. + +#include <map> +#include <string> + +#if __has_include(<nlohmann/json_fwd.hpp>) +#include <nlohmann/json_fwd.hpp> +#else +#include <nlohmann/json.hpp> +#endif + +namespace mtx { +namespace events { +namespace account_data { +namespace nheko_extensions { +//! Custom event to allow or block invites. +struct InvitePermissions +{ + //! Default permissions + std::string default_; + + //! Server allowed to invite + std::map<std::string, std::string, std::less<>> server_allow; + //! Server denied from inviting + std::map<std::string, std::string, std::less<>> server_deny; + + //! Rooms the user accepts invites to + std::map<std::string, std::string, std::less<>> room_allow; + //! Rooms the user blocks invites to + std::map<std::string, std::string, std::less<>> room_deny; + + //! Users the user is accepting invites from + std::map<std::string, std::string, std::less<>> user_allow; + //! Users the user is blocking invites from + std::map<std::string, std::string, std::less<>> user_deny; + + [[nodiscard]] bool invite_allowed(std::string_view room_id, std::string_view inviter) const; + + friend void from_json(const nlohmann::json &obj, InvitePermissions &content); + friend void to_json(nlohmann::json &obj, const InvitePermissions &content); +}; +} +} // namespace account_data +} // namespace events +} // namespace mtx diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/include/mtx/identifiers.hpp new/mtxclient-0.10.1/include/mtx/identifiers.hpp --- old/mtxclient-0.10.0/include/mtx/identifiers.hpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/include/mtx/identifiers.hpp 2025-08-02 21:59:13.000000000 +0200 @@ -109,11 +109,12 @@ identifier.hostname_ = id.substr(parts + 1); identifier.id_ = id; return identifier; - } else if (Identifier::sigil == "$") { + } else if (Identifier::sigil == "$" || Identifier::sigil == "!") { // V3 event ids don't use ':' at all, don't parse them the same way. + // V12 rooms don't use a server host in the id. Identifier identifier{}; - identifier.localpart_ = id; - identifier.hostname_ = id; + identifier.localpart_ = id.substr(1); + identifier.hostname_ = ""; identifier.id_ = id; return identifier; } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/include/mtx.hpp new/mtxclient-0.10.1/include/mtx.hpp --- old/mtxclient-0.10.0/include/mtx.hpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/include/mtx.hpp 2025-08-02 21:59:13.000000000 +0200 @@ -28,6 +28,7 @@ #include "mtx/events/messages/emote.hpp" #include "mtx/events/messages/file.hpp" #include "mtx/events/messages/image.hpp" +#include "mtx/events/messages/location.hpp" #include "mtx/events/messages/notice.hpp" #include "mtx/events/messages/text.hpp" #include "mtx/events/messages/unknown.hpp" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/include/mtxclient/http/client.hpp new/mtxclient-0.10.1/include/mtxclient/http/client.hpp --- old/mtxclient-0.10.0/include/mtxclient/http/client.hpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/include/mtxclient/http/client.hpp 2025-08-02 21:59:13.000000000 +0200 @@ -908,6 +908,7 @@ MTXCLIENT_SEND_ROOM_MESSAGE_FWD(mtx::events::msg::Emote) MTXCLIENT_SEND_ROOM_MESSAGE_FWD(mtx::events::msg::File) MTXCLIENT_SEND_ROOM_MESSAGE_FWD(mtx::events::msg::Image) +MTXCLIENT_SEND_ROOM_MESSAGE_FWD(mtx::events::msg::Location) MTXCLIENT_SEND_ROOM_MESSAGE_FWD(mtx::events::msg::Notice) MTXCLIENT_SEND_ROOM_MESSAGE_FWD(mtx::events::msg::Text) MTXCLIENT_SEND_ROOM_MESSAGE_FWD(mtx::events::msg::Video) @@ -974,6 +975,7 @@ MTXCLIENT_ACCOUNT_DATA_FWD(mtx::events::msc2545::ImagePack) MTXCLIENT_ACCOUNT_DATA_FWD(mtx::events::msc2545::ImagePackRooms) MTXCLIENT_ACCOUNT_DATA_FWD(mtx::events::account_data::nheko_extensions::HiddenEvents) +MTXCLIENT_ACCOUNT_DATA_FWD(mtx::events::account_data::nheko_extensions::InvitePermissions) MTXCLIENT_ACCOUNT_DATA_FWD(mtx::events::account_data::nheko_extensions::EventExpiry) MTXCLIENT_ACCOUNT_DATA_FWD(mtx::events::account_data::Tags) MTXCLIENT_ACCOUNT_DATA_FWD(mtx::events::account_data::Direct) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/include/mtxclient/http/errors.hpp new/mtxclient-0.10.1/include/mtxclient/http/errors.hpp --- old/mtxclient-0.10.0/include/mtxclient/http/errors.hpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/include/mtxclient/http/errors.hpp 2025-08-02 21:59:13.000000000 +0200 @@ -87,7 +87,7 @@ // Formats the point p using the parsed format specification (presentation) // stored in this formatter. template<typename FormatContext> - auto format(const mtx::http::ClientError &e, FormatContext &ctx) -> decltype(ctx.out()) + auto format(const mtx::http::ClientError &e, FormatContext &ctx) const -> decltype(ctx.out()) { // ctx.out() is an output iterator to write to. bool prepend_comma = false; @@ -132,7 +132,7 @@ { // parse is inherited from formatter<string_view>. template<typename FormatContext> - auto format(std::optional<mtx::http::ClientError> c, FormatContext &ctx) + auto format(std::optional<mtx::http::ClientError> c, FormatContext &ctx) const { if (!c) return fmt::format_to(ctx.out(), "(no error)"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/lib/http/client.cpp new/mtxclient-0.10.1/lib/http/client.cpp --- old/mtxclient-0.10.0/lib/http/client.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/lib/http/client.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -542,6 +542,9 @@ for (size_t i = 1; i < via.size(); i++) { query += "&server_name=" + url_encode(via[i]); } + for (const auto &v : via) { + query += "&via=" + url_encode(v); + } } auto api_path = "/client/v3/join/" + url_encode(room) + query; @@ -565,6 +568,9 @@ for (size_t i = 1; i < via.size(); i++) { query += "&server_name=" + url_encode(via[i]); } + for (const auto &v : via) { + query += "&via=" + url_encode(v); + } } auto api_path = "/client/v3/knock/" + url_encode(room) + query; @@ -837,18 +843,21 @@ const auto api_path = "/client/v1/media/download/" + client::utils::url_encode(server) + "/" + client::utils::url_encode(media_id); - get<std::string>(api_path, - [_this = shared_from_this(), cb = std::move(cb), server, media_id]( - const std::string &res, HeaderFields fields, RequestErr err) { - if (!err || !(err->status_code == 404 || err->status_code == 400)) { - cb(res, fields, err); - } else { - const auto api_path = "/media/v3/download/" + - client::utils::url_encode(server) + "/" + - client::utils::url_encode(media_id); - _this->get<std::string>(api_path, std::move(cb)); - } - }); + get<std::string>( + api_path, + [_this = shared_from_this(), cb = std::move(cb), server, media_id]( + const std::string &res, HeaderFields fields, RequestErr err) { + if (!err || !(err->status_code == 404 || err->status_code == 400)) { + cb(res, fields, err); + } else { + const auto api_path = "/media/v3/download/" + client::utils::url_encode(server) + + "/" + client::utils::url_encode(media_id); + _this->get<std::string>(api_path, std::move(cb)); + } + }, + true, + "/_matrix", + 3); } void @@ -1804,6 +1813,7 @@ MTXCLIENT_SEND_ROOM_MESSAGE(mtx::events::msg::Emote) MTXCLIENT_SEND_ROOM_MESSAGE(mtx::events::msg::File) MTXCLIENT_SEND_ROOM_MESSAGE(mtx::events::msg::Image) +MTXCLIENT_SEND_ROOM_MESSAGE(mtx::events::msg::Location) MTXCLIENT_SEND_ROOM_MESSAGE(mtx::events::msg::Notice) MTXCLIENT_SEND_ROOM_MESSAGE(mtx::events::msg::Text) MTXCLIENT_SEND_ROOM_MESSAGE(mtx::events::msg::Unknown) @@ -1870,6 +1880,7 @@ MTXCLIENT_ACCOUNT_DATA(mtx::events::msc2545::ImagePack) MTXCLIENT_ACCOUNT_DATA(mtx::events::msc2545::ImagePackRooms) MTXCLIENT_ACCOUNT_DATA(mtx::events::account_data::nheko_extensions::HiddenEvents) +MTXCLIENT_ACCOUNT_DATA(mtx::events::account_data::nheko_extensions::InvitePermissions) MTXCLIENT_ACCOUNT_DATA(mtx::events::account_data::nheko_extensions::EventExpiry) MTXCLIENT_ACCOUNT_DATA(mtx::events::account_data::Tags) MTXCLIENT_ACCOUNT_DATA(mtx::events::account_data::Direct) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/lib/structs/events/canonical_alias.cpp new/mtxclient-0.10.1/lib/structs/events/canonical_alias.cpp --- old/mtxclient-0.10.0/lib/structs/events/canonical_alias.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/lib/structs/events/canonical_alias.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -23,6 +23,8 @@ void to_json(json &obj, const CanonicalAlias &canonical_alias) { + obj = nlohmann::json::object(); + if (!canonical_alias.alias.empty()) obj["alias"] = canonical_alias.alias; if (!canonical_alias.alt_aliases.empty()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/lib/structs/events/collections.cpp new/mtxclient-0.10.1/lib/structs/events/collections.cpp --- old/mtxclient-0.10.0/lib/structs/events/collections.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/lib/structs/events/collections.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -47,6 +47,7 @@ MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Emote) MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::File) MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Image) +MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Location) MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Notice) MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Text) MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Unknown) @@ -128,6 +129,8 @@ mtx::events::account_data::nheko_extensions::HiddenEvents) MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, mtx::events::account_data::nheko_extensions::EventExpiry) +MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, + mtx::events::account_data::nheko_extensions::InvitePermissions) MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, msc2545::ImagePackRooms) MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, msc2545::ImagePack) MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::Event, presence::Presence) @@ -322,8 +325,7 @@ break; } case MsgType::Location: { - /* events::RoomEvent<events::msg::Location> location = e; */ - /* container.emplace_back(location); */ + e = events::RoomEvent<events::msg::Location>(obj); break; } case MsgType::Notice: { @@ -405,6 +407,7 @@ case events::EventType::FullyRead: case events::EventType::IgnoredUsers: case events::EventType::NhekoHiddenEvents: + case events::EventType::NhekoInvitePermissions: case events::EventType::NhekoEventExpiry: case events::EventType::ImagePackInAccountData: case events::EventType::ImagePackRooms: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/lib/structs/events/common.cpp new/mtxclient-0.10.1/lib/structs/events/common.cpp --- old/mtxclient-0.10.0/lib/structs/events/common.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/lib/structs/events/common.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -170,6 +170,32 @@ } void +from_json(const json &obj, LocationInfo &info) +{ + if (obj.contains("thumbnail_url")) + info.thumbnail_url = obj.at("thumbnail_url").get<std::string>(); + + if (obj.contains("thumbnail_info")) + info.thumbnail_info = obj.at("thumbnail_info").get<ThumbnailInfo>(); + + if (obj.contains("thumbnail_file")) + info.thumbnail_file = obj.at("thumbnail_file").get<crypto::EncryptedFile>(); +} + +void +to_json(json &obj, const LocationInfo &info) +{ + if (!info.thumbnail_url.empty()) { + obj["thumbnail_url"] = info.thumbnail_url; + obj["thumbnail_info"] = info.thumbnail_info; + } + if (info.thumbnail_file) { + obj["thumbnail_file"] = info.thumbnail_file.value(); + obj["thumbnail_info"] = info.thumbnail_info; + } +} + +void from_json(const json &obj, Mentions &info) { info.room = obj.value("room", false); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/lib/structs/events/create.cpp new/mtxclient-0.10.1/lib/structs/events/create.cpp --- old/mtxclient-0.10.0/lib/structs/events/create.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/lib/structs/events/create.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -14,13 +14,14 @@ from_json(const json &obj, PreviousRoom &predecessor) { predecessor.room_id = obj.at("room_id").get<std::string>(); - predecessor.event_id = obj.at("event_id").get<std::string>(); + predecessor.event_id = obj.value("event_id", ""); } void to_json(json &obj, const PreviousRoom &predecessor) { - obj["room_id"] = predecessor.room_id; - obj["event_id"] = predecessor.event_id; + obj["room_id"] = predecessor.room_id; + if (!predecessor.event_id.empty()) + obj["event_id"] = predecessor.event_id; } void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/lib/structs/events/messages/location.cpp new/mtxclient-0.10.1/lib/structs/events/messages/location.cpp --- old/mtxclient-0.10.0/lib/structs/events/messages/location.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/mtxclient-0.10.1/lib/structs/events/messages/location.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -0,0 +1,40 @@ +#include <nlohmann/json.hpp> +#include <string> + +#include "mtx/events/common.hpp" +#include "mtx/events/messages/location.hpp" + +using json = nlohmann::json; + +namespace mtx { +namespace events { +namespace msg { + +void +from_json(const json &obj, Location &content) +{ + content.body = obj.at("body").get<std::string>(); + content.msgtype = obj.at("msgtype").get<std::string>(); + if (obj.find("geo_uri") != obj.end()) + content.geo_uri = obj.at("geo_uri").get<std::string>(); + + if (obj.find("info") != obj.end()) + content.info = obj.at("info").get<common::LocationInfo>(); + + content.relations = common::parse_relations(obj); +} + +void +to_json(json &obj, const Location &content) +{ + obj["msgtype"] = "m.location"; + obj["body"] = content.body; + + obj["geo_uri"] = content.geo_uri; + obj["info"] = content.info; + common::apply_relations(obj, content.relations); +} + +} // namespace msg +} // namespace events +} // namespace mtx diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/lib/structs/events/nheko_extensions/invite_permissions.cpp new/mtxclient-0.10.1/lib/structs/events/nheko_extensions/invite_permissions.cpp --- old/mtxclient-0.10.0/lib/structs/events/nheko_extensions/invite_permissions.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/mtxclient-0.10.1/lib/structs/events/nheko_extensions/invite_permissions.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -0,0 +1,98 @@ +#include "mtx/events/nheko_extensions/invite_permissions.hpp" + +#include <tuple> + +#include <nlohmann/json.hpp> + +#include <mtx/log.hpp> + +static std::tuple<std::map<std::string, std::string, std::less<>>, + std::map<std::string, std::string, std::less<>>> +parse_subset(const std::string &key, const nlohmann::json &obj) +{ + std::map<std::string, std::string, std::less<>> allow, deny; + + if (auto o = obj.find(key); o != obj.end()) { + auto a = o->value("allow", std::map<std::string, nlohmann::json>()); + auto d = o->value("deny", std::map<std::string, nlohmann::json>()); + + for (const auto &[k, v] : a) { + allow.emplace(k, v.dump()); + } + for (const auto &[k, v] : d) { + deny.emplace(k, v.dump()); + } + } + + return {allow, deny}; +} + +static void +emit_subset(nlohmann::json &obj, + std::string_view key, + const std::map<std::string, std::string, std::less<>> &allow, + const std::map<std::string, std::string, std::less<>> &deny) +{ + for (const auto &[k, v] : allow) { + obj[key]["allow"][k] = nlohmann::json::parse(v); + } + for (const auto &[k, v] : deny) { + obj[key]["deny"][k] = nlohmann::json::parse(v); + } +} + +namespace mtx { +namespace events { +namespace account_data { +namespace nheko_extensions { + +void +from_json(const nlohmann::json &obj, InvitePermissions &content) +{ + if (obj.contains("default")) { + content.default_ = obj.at("default").get<std::string>(); + } else { + content.default_ = "allow"; + } + + std::tie(content.server_allow, content.server_deny) = parse_subset("server", obj); + std::tie(content.room_allow, content.room_deny) = parse_subset("room", obj); + std::tie(content.user_allow, content.user_deny) = parse_subset("user", obj); +} + +void +to_json(nlohmann::json &obj, const InvitePermissions &content) +{ + obj["default"] = content.default_; + + emit_subset(obj, "server", content.server_allow, content.server_deny); + emit_subset(obj, "room", content.room_allow, content.room_deny); + emit_subset(obj, "user", content.user_allow, content.user_deny); +} + +bool +InvitePermissions::invite_allowed(std::string_view room_id, std::string_view inviter) const +{ + if (this->user_deny.contains(inviter)) + return false; + if (this->user_allow.contains(inviter)) + return true; + if (this->room_deny.contains(room_id)) + return false; + if (this->room_allow.contains(room_id)) + return true; + + if (auto pos = inviter.find_first_of(':'); pos != std::string_view::npos) { + auto server = inviter.substr(pos + 1); + if (this->server_deny.contains(server)) + return false; + if (this->server_allow.contains(server)) + return false; + } + + return this->default_ != "deny"; +} +} +} // namespace account_data +} // namespace events +} // namespace mtx diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/lib/structs/events.cpp new/mtxclient-0.10.1/lib/structs/events.cpp --- old/mtxclient-0.10.0/lib/structs/events.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/lib/structs/events.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -129,6 +129,8 @@ return EventType::NhekoHiddenEvents; else if (type == "im.nheko.event_expiry") return EventType::NhekoEventExpiry; + else if (type == "im.nheko.invite_permissions") + return EventType::NhekoInvitePermissions; else if (type == "im.ponies.room_emotes") return EventType::ImagePackInRoom; else if (type == "im.ponies.user_emotes") @@ -264,6 +266,8 @@ return "im.nheko.hidden_events"; case EventType::NhekoEventExpiry: return "im.nheko.event_expiry"; + case EventType::NhekoInvitePermissions: + return "im.nheko.invite_permissions"; case EventType::ImagePackInRoom: return "im.ponies.room_emotes"; case EventType::ImagePackInAccountData: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/lib/structs/responses/common.cpp new/mtxclient-0.10.1/lib/structs/responses/common.cpp --- old/mtxclient-0.10.0/lib/structs/responses/common.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/lib/structs/responses/common.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -140,6 +140,11 @@ container.emplace_back(events::AccountDataEvent<nheko_extensions::EventExpiry>(e)); break; } + case events::EventType::NhekoInvitePermissions: { + container.emplace_back( + events::AccountDataEvent<nheko_extensions::InvitePermissions>(e)); + break; + } case events::EventType::ImagePackRooms: { container.emplace_back( events::AccountDataEvent<events::msc2545::ImagePackRooms>(e)); @@ -424,8 +429,7 @@ break; } case MsgType::Location: { - /* events::RoomEvent<events::msg::Location> location = e; */ - /* container.emplace_back(location); */ + container.emplace_back(events::RoomEvent<events::msg::Location>(e)); break; } case MsgType::Notice: { @@ -528,6 +532,7 @@ case events::EventType::IgnoredUsers: case events::EventType::NhekoHiddenEvents: case events::EventType::NhekoEventExpiry: + case events::EventType::NhekoInvitePermissions: case events::EventType::ImagePackRooms: case events::EventType::ImagePackInAccountData: case events::EventType::Dummy: @@ -808,6 +813,7 @@ case events::EventType::IgnoredUsers: case events::EventType::NhekoHiddenEvents: case events::EventType::NhekoEventExpiry: + case events::EventType::NhekoInvitePermissions: case events::EventType::ImagePackRooms: case events::EventType::ImagePackInAccountData: case events::EventType::Dummy: @@ -977,6 +983,7 @@ case events::EventType::IgnoredUsers: case events::EventType::NhekoHiddenEvents: case events::EventType::NhekoEventExpiry: + case events::EventType::NhekoInvitePermissions: case events::EventType::ImagePackInAccountData: case events::EventType::ImagePackInRoom: case events::EventType::ImagePackRooms: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/meson.build new/mtxclient-0.10.1/meson.build --- old/mtxclient-0.10.0/meson.build 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/meson.build 2025-08-02 21:59:13.000000000 +0200 @@ -1,7 +1,7 @@ project( 'mtxclient', 'cpp', -version : '0.10.0', +version : '0.10.1', meson_version : '>=0.57.0', license : 'MIT', default_options : 'cpp_std=c++20' @@ -86,14 +86,16 @@ 'lib/structs/events/messages/emote.cpp', 'lib/structs/events/messages/file.cpp', 'lib/structs/events/messages/image.cpp', + 'lib/structs/events/messages/location.cpp', 'lib/structs/events/messages/notice.cpp', 'lib/structs/events/messages/text.cpp', 'lib/structs/events/messages/unknown.cpp', 'lib/structs/events/messages/video.cpp', 'lib/structs/events/mscs/image_packs.cpp', 'lib/structs/events/name.cpp', - 'lib/structs/events/nheko_extensions/hidden_events.cpp', 'lib/structs/events/nheko_extensions/event_expiry.cpp', + 'lib/structs/events/nheko_extensions/hidden_events.cpp', + 'lib/structs/events/nheko_extensions/invite_permissions.cpp', 'lib/structs/events/pinned_events.cpp', 'lib/structs/events/policy_rules.cpp', 'lib/structs/events/power_levels.cpp', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/tests/client_api.cpp new/mtxclient-0.10.1/tests/client_api.cpp --- old/mtxclient-0.10.0/tests/client_api.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/tests/client_api.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -968,7 +968,7 @@ mtx_client->versions([](const mtx::responses::Versions &res, RequestErr err) { check_error(err); - EXPECT_EQ(res.versions.size(), 10); + EXPECT_EQ(res.versions.size(), 20); EXPECT_EQ(res.versions.at(0), "r0.0.1"); EXPECT_EQ(res.versions.at(1), "r0.1.0"); EXPECT_EQ(res.versions.at(2), "r0.2.0"); @@ -1070,11 +1070,13 @@ { auto alice = make_test_client(); - alice->login( - "alice", "secret", [](const mtx::responses::Login &, RequestErr err) { check_error(err); }); + // special user just for presence + alice->login("presence", "secret", [](const mtx::responses::Login &, RequestErr err) { + check_error(err); + }); while (alice->access_token().empty()) - sleep(); + std::this_thread::yield(); alice->put_presence_status( mtx::presence::unavailable, "Is this thing on?", [alice](RequestErr err) { @@ -1112,8 +1114,9 @@ auto alice = make_test_client(); auto bob = make_test_client(); - alice->login( - "alice", "secret", [](const mtx::responses::Login &, RequestErr err) { check_error(err); }); + alice->login("presencesync", "secret", [](const mtx::responses::Login &, RequestErr err) { + check_error(err); + }); bob->login( "bob", "secret", [](const mtx::responses::Login &, RequestErr err) { check_error(err); }); @@ -1158,7 +1161,7 @@ bool found = false; for (const auto &p : s.presence) { - if (p.sender == "@alice:" + server_name()) { + if (p.sender == "@presencesync:" + server_name()) { found = true; EXPECT_EQ(p.content.presence, mtx::presence::online); EXPECT_EQ(p.content.status_msg, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/tests/events.cpp new/mtxclient-0.10.1/tests/events.cpp --- old/mtxclient-0.10.0/tests/events.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/tests/events.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -2067,6 +2067,59 @@ ASSERT_EQ(event.content.keep_only_latest, 100); } +TEST(RoomAccountData, NhekoInvitePermissions) +{ + json data = R"({ + "content": { + "default": "allow", + "room": { + "allow": { + "!abc:example.net": {} + }, + "deny": { + "!def:example.net": {} + } + }, + "user": { + "allow": { + "@abc:example.net": {} + }, + "deny": { + "@def:example.net": {} + } + }, + "server": { + "allow": { + "example.com": {}, + "nheko.im": {} + }, + "deny": { + "example.org": {} + } + } + }, + "type": "im.nheko.invite_permissions" + })"_json; + + ns::AccountDataEvent<ns::account_data::nheko_extensions::InvitePermissions> event = + data.get<ns::AccountDataEvent<ns::account_data::nheko_extensions::InvitePermissions>>(); + + EXPECT_EQ(data, json(event)); + + EXPECT_EQ(event.content.default_, "allow"); + EXPECT_TRUE(event.content.server_allow.contains("nheko.im")); + EXPECT_TRUE(event.content.server_deny.contains("example.org")); + EXPECT_TRUE(event.content.user_allow.contains("@abc:example.net")); + EXPECT_TRUE(event.content.user_deny.contains("@def:example.net")); + EXPECT_TRUE(event.content.room_allow.contains("!abc:example.net")); + EXPECT_TRUE(event.content.room_deny.contains("!def:example.net")); + + EXPECT_TRUE(event.content.invite_allowed("!abc:example.net", "@test:example.org")); + EXPECT_TRUE(event.content.invite_allowed("!def:example.net", "@abc:example.net")); + EXPECT_FALSE(event.content.invite_allowed("!random:example.net", "@abc:example.org")); + EXPECT_FALSE(event.content.invite_allowed("!def:example.net", "@abc:example.com")); +} + TEST(RoomAccountData, ImagePack) { json data = R"({ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/tests/identifiers.cpp new/mtxclient-0.10.1/tests/identifiers.cpp --- old/mtxclient-0.10.0/tests/identifiers.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/tests/identifiers.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -47,6 +47,11 @@ EXPECT_EQ(room2.to_string(), "!39fasdsdfsdf:example.com"); EXPECT_EQ(room2.localpart(), "39fasdsdfsdf"); EXPECT_EQ(room2.hostname(), "example.com"); + + Room room3 = parse<Room>("!39fasdsdfsdf"); + EXPECT_EQ(room3.to_string(), "!39fasdsdfsdf"); + EXPECT_EQ(room3.localpart(), "39fasdsdfsdf"); + EXPECT_EQ(room3.hostname(), ""); } TEST(MatrixIdentifiers, IdentifierInvalid) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mtxclient-0.10.0/tests/messages.cpp new/mtxclient-0.10.1/tests/messages.cpp --- old/mtxclient-0.10.0/tests/messages.cpp 2024-06-11 00:15:15.000000000 +0200 +++ new/mtxclient-0.10.1/tests/messages.cpp 2025-08-02 21:59:13.000000000 +0200 @@ -503,7 +503,53 @@ mtx::common::RelationType::InReplyTo); } -TEST(RoomEvents, LocationMessage) {} +TEST(RoomEvents, LocationMessage) +{ + json data = R"({ + "content": { + "body": "Big Ben, London, UK", + "geo_uri": "geo:51.5008,0.1247", + "info": { + "thumbnail_info": { + "h": 300, + "mimetype": "image/jpeg", + "size": 46144, + "w": 300 + }, + "thumbnail_url": "mxc://example.org/FHyPlCeYUSFFxlgbQYZmoEoe" + }, + "msgtype": "m.location", + "m.relates_to": { + "m.in_reply_to": { + "event_id": "$6GKhAfJOcwNd69lgSizdcTob8z2pWQgBOZPrnsWMA1E" + } + } + }, + "event_id": "$143273582443PhrSn:example.org", + "origin_server_ts": 1432735824653, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "sender": "@example:example.org", + "type": "m.room.message", + "unsigned": { + "age": 69168455 + } + } + )"_json; + RoomEvent<msg::Location> event = data.get<RoomEvent<msg::Location>>(); + + EXPECT_EQ(event.type, EventType::RoomMessage); + EXPECT_EQ(event.event_id, "$143273582443PhrSn:example.org"); + EXPECT_EQ(event.room_id, "!jEsUZKDJdhlrceRyVU:example.org"); + EXPECT_EQ(event.sender, "@example:example.org"); + EXPECT_EQ(event.origin_server_ts, 1432735824653); + EXPECT_EQ(event.unsigned_data.age, 69168455); + EXPECT_EQ(event.content.body, "Big Ben, London, UK"); + EXPECT_EQ(event.content.msgtype, "m.location"); + EXPECT_EQ(event.content.relations.relations.at(0).event_id, + "$6GKhAfJOcwNd69lgSizdcTob8z2pWQgBOZPrnsWMA1E"); + EXPECT_EQ(event.content.relations.relations.at(0).rel_type, + mtx::common::RelationType::InReplyTo); +} TEST(RoomEvents, NoticeMessage) {