├── logo.png
├── gtad
├── preamble.mustache
├── data.h.mustache
└── define_models.mustache
├── source_file.template
├── libquotientemojis.qrc
├── .gitmodules
├── quotest.pro
├── Quotient
├── events
│ ├── typingevent.h
│ ├── roomtombstoneevent.cpp
│ ├── directchatevent.h
│ ├── roomtombstoneevent.h
│ ├── redactionevent.h
│ ├── roomcreateevent.h
│ ├── directchatevent.cpp
│ ├── roomavatarevent.h
│ ├── receiptevent.h
│ ├── single_key_value.h
│ ├── roomcreateevent.cpp
│ ├── reactionevent.h
│ ├── roomkeyevent.h
│ ├── stateevent.cpp
│ ├── encryptionevent.cpp
│ ├── encryptionevent.h
│ ├── accountdataevents.h
│ ├── roomcanonicalaliasevent.h
│ ├── stickerevent.h
│ ├── roommemberevent.h
│ ├── eventrelation.cpp
│ ├── roompowerlevelsevent.cpp
│ ├── simplestateevents.h
│ └── eventrelation.h
├── csapi
│ ├── openid.cpp
│ ├── wellknown.cpp
│ ├── refresh.cpp
│ ├── voip.cpp
│ ├── versions.cpp
│ ├── support.cpp
│ ├── admin.cpp
│ ├── whoami.cpp
│ ├── kicking.cpp
│ ├── list_joined_rooms.cpp
│ ├── room_send.cpp
│ ├── room_upgrades.cpp
│ ├── capabilities.cpp
│ ├── inviting.cpp
│ ├── login_token.cpp
│ ├── redaction.cpp
│ ├── to_device.cpp
│ ├── room_state.cpp
│ ├── typing.cpp
│ ├── receipts.cpp
│ ├── users.cpp
│ ├── report_content.cpp
│ ├── appservice_room_directory.cpp
│ ├── search.cpp
│ ├── definitions
│ │ ├── tag.h
│ │ ├── wellknown
│ │ │ ├── homeserver.h
│ │ │ ├── identity_server.h
│ │ │ └── full.h
│ │ ├── room_key_backup.h
│ │ ├── user_identifier.h
│ │ ├── push_ruleset.h
│ │ ├── auth_data.h
│ │ ├── third_party_signed.h
│ │ ├── client_device.h
│ │ ├── openid_token.h
│ │ ├── cross_signing_key.h
│ │ ├── request_token_response.h
│ │ ├── key_backup_data.h
│ │ ├── push_rule.h
│ │ └── device_keys.h
│ ├── read_markers.cpp
│ ├── logout.cpp
│ ├── third_party_membership.cpp
│ ├── room_upgrades.h
│ ├── knocking.cpp
│ ├── banning.cpp
│ ├── leaving.cpp
│ ├── voip.h
│ ├── filter.cpp
│ ├── list_joined_rooms.h
│ ├── peeking_events.cpp
│ ├── registration_tokens.cpp
│ ├── presence.cpp
│ ├── typing.h
│ ├── to_device.h
│ ├── notifications.cpp
│ ├── room_event_by_timestamp.cpp
│ ├── kicking.h
│ ├── cross_signing.cpp
│ ├── event_context.cpp
│ ├── threads_list.cpp
│ ├── read_markers.h
│ ├── report_content.h
│ ├── wellknown.h
│ ├── receipts.h
│ ├── inviting.h
│ ├── login.cpp
│ ├── registration_tokens.h
│ ├── pusher.cpp
│ ├── appservice_room_directory.h
│ ├── room_send.h
│ ├── message_pagination.cpp
│ ├── joining.cpp
│ ├── tags.cpp
│ ├── sso_login_redirect.cpp
│ ├── space_hierarchy.cpp
│ ├── create_room.cpp
│ ├── openid.h
│ ├── redaction.h
│ ├── directory.cpp
│ ├── banning.h
│ ├── device_management.cpp
│ ├── room_state.h
│ ├── logout.h
│ ├── knocking.h
│ ├── leaving.h
│ └── filter.h
├── thread.h
├── networksettings.cpp
├── thread.cpp
├── expected.h
├── e2ee
│ ├── qolmmessage.cpp
│ ├── qolmmessage.h
│ ├── qolmutility.h
│ ├── qolmutility.cpp
│ ├── sssshandler.h
│ ├── qolmoutboundsession.h
│ └── qolmsession.h
├── networksettings.h
├── mxcreply.h
├── eventitem.cpp
├── converters.cpp
├── jobs
│ ├── requestdata.h
│ ├── syncjob.h
│ ├── downloadfilejob.h
│ ├── requestdata.cpp
│ ├── mediathumbnailjob.h
│ └── syncjob.cpp
├── quotient_export.h
├── application-service
│ └── definitions
│ │ ├── location.h
│ │ └── user.h
├── roomstateview.cpp
├── logging_categories_p.h
├── keyimport.h
├── avatar.h
├── connectiondata.h
├── networkaccessmanager.h
└── ssosession.h
├── Quotient.pc.in
├── autotests
├── testgroupsession.h
├── testolmutility.h
├── testolmsession.h
├── data
│ ├── test-threadroot-event.json
│ ├── test-thread1-event.json
│ └── test-thread2-event.json
├── register-users.sh
├── testolmaccount.h
├── adjust-config.sh
├── CMakeLists.txt
├── key-export.data
├── testutils.h
├── testutils.cpp
├── testkeyimport.cpp
├── callcandidateseventtest.cpp
├── setup-tests.sh
└── testgroupsession.cpp
├── sonar-project.properties
├── .gitignore
├── .github
├── ISSUE_TEMPLATE
│ ├── change-request.md
│ └── bug_report.md
└── workflows
│ └── static.yml
├── cmake
└── QuotientConfig.cmake.in
├── quotest
├── .valgrind.supp
└── CMakeLists.txt
└── SECURITY.md
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quotient-im/libQuotient/HEAD/logo.png
--------------------------------------------------------------------------------
/gtad/preamble.mustache:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
--------------------------------------------------------------------------------
/source_file.template:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: The Quotient Project Contributors
2 | // SPDX-License-Identifier: LGPL-3.0-or-later
3 |
--------------------------------------------------------------------------------
/libquotientemojis.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | sas-emoji.json
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "gtad/gtad"]
2 | path = gtad/gtad
3 | url = https://github.com/quotient-im/gtad.git
4 | [submodule "doxygen-awesome-css"]
5 | path = doxygen-awesome-css
6 | url = https://github.com/jothepro/doxygen-awesome-css.git
7 |
--------------------------------------------------------------------------------
/quotest.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = app
2 |
3 | include(libquotient.pri)
4 |
5 | QT += testlib
6 |
7 | CONFIG *= c++1z warn_on object_parallel_to_source
8 |
9 | windows { CONFIG *= console }
10 |
11 | SOURCES += tests/quotest.cpp
12 |
13 | DISTFILES += \
14 | .valgrind.supp
15 |
--------------------------------------------------------------------------------
/Quotient/events/typingevent.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2017 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "event.h"
7 |
8 | namespace Quotient {
9 | DEFINE_SIMPLE_EVENT(TypingEvent, Event, "m.typing", QStringList, users, "user_ids")
10 | } // namespace Quotient
11 |
--------------------------------------------------------------------------------
/Quotient.pc.in:
--------------------------------------------------------------------------------
1 | prefix=@CMAKE_INSTALL_PREFIX@
2 | exec_prefix=${prefix}
3 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
4 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
5 |
6 | Name: Quotient
7 | Description: A Qt library to write cross-platfrom clients for Matrix
8 | Version: @API_VERSION@
9 | Cflags: -I${includedir}
10 | Libs: -L${libdir} -lQuotient
11 |
--------------------------------------------------------------------------------
/gtad/data.h.mustache:
--------------------------------------------------------------------------------
1 | {{!
2 | SPDX-FileCopyrightText: 2020 Kitsune Ral
3 | SPDX-License-Identifier: LGPL-2.1-or-later
4 | }}{{>preamble}}
5 | #pragma once
6 |
7 | #include
8 | {{#imports}}
9 | #include {{_}}{{/imports}}
10 |
11 | namespace Quotient {
12 | {{>define_models}}
13 | } // namespace Quotient
14 |
--------------------------------------------------------------------------------
/autotests/testgroupsession.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2021 Carl Schwan
2 | //
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #include
6 |
7 | class TestGroupSession : public QObject
8 | {
9 | Q_OBJECT
10 |
11 | private Q_SLOTS:
12 | void groupSessionPicklingValid();
13 | void groupSessionCryptoValid();
14 | };
15 |
--------------------------------------------------------------------------------
/sonar-project.properties:
--------------------------------------------------------------------------------
1 | sonar.projectKey=quotient-im_libQuotient
2 | sonar.organization=quotient-im
3 |
4 | # This is the name and version displayed in the SonarCloud UI.
5 | sonar.projectName=libQuotient
6 | sonar.projectVersion=0.8
7 |
8 | sonar.sources=Quotient
9 |
10 | # Encoding of the source code. Default is default system encoding
11 | #sonar.sourceEncoding=UTF-8
12 |
--------------------------------------------------------------------------------
/autotests/testolmutility.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2021 Carl Schwan
2 | //
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #include
6 |
7 | class TestOlmUtility : public QObject
8 | {
9 | Q_OBJECT
10 |
11 | private Q_SLOTS:
12 | void canonicalJSON();
13 | void verifySignedOneTimeKey();
14 | void validUploadKeysRequest();
15 | };
16 |
--------------------------------------------------------------------------------
/autotests/testolmsession.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2021 Carl Schwan
2 | //
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #include
6 |
7 | class TestOlmSession : public QObject
8 | {
9 | Q_OBJECT
10 | private Q_SLOTS:
11 | void olmOutboundSessionCreation();
12 | void olmEncryptDecrypt();
13 | void correctSessionOrdering();
14 | };
15 |
--------------------------------------------------------------------------------
/autotests/data/test-threadroot-event.json:
--------------------------------------------------------------------------------
1 | {
2 | "content": {
3 | "body": "Thread root event",
4 | "msgtype": "m.text"
5 | },
6 | "event_id": "$threadroot:example.org",
7 | "origin_server_ts": 1432735824654,
8 | "room_id": "!test:example.org",
9 | "sender": "@example:example.org",
10 | "type": "m.room.message",
11 | "unsigned": {
12 | "age": 1234
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Quotient/csapi/openid.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "openid.h"
4 |
5 | using namespace Quotient;
6 |
7 | RequestOpenIdTokenJob::RequestOpenIdTokenJob(const QString& userId, const QJsonObject& dontUse)
8 | : BaseJob(HttpVerb::Post, u"RequestOpenIdTokenJob"_s,
9 | makePath("/_matrix/client/v3", "/user/", userId, "/openid/request_token"))
10 | {
11 | setRequestData({ toJson(dontUse) });
12 | }
13 |
--------------------------------------------------------------------------------
/Quotient/events/roomtombstoneevent.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2019 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "roomtombstoneevent.h"
5 |
6 | using namespace Quotient;
7 |
8 | QString RoomTombstoneEvent::serverMessage() const
9 | {
10 | return contentPart("body"_L1);
11 | }
12 |
13 | QString RoomTombstoneEvent::successorRoomId() const
14 | {
15 | return contentPart("replacement_room"_L1);
16 | }
17 |
--------------------------------------------------------------------------------
/Quotient/csapi/wellknown.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "wellknown.h"
4 |
5 | using namespace Quotient;
6 |
7 | QUrl GetWellknownJob::makeRequestUrl(const HomeserverData& hsData)
8 | {
9 | return BaseJob::makeRequestUrl(hsData, makePath("/.well-known", "/matrix/client"));
10 | }
11 |
12 | GetWellknownJob::GetWellknownJob()
13 | : BaseJob(HttpVerb::Get, u"GetWellknownJob"_s, makePath("/.well-known", "/matrix/client"), false)
14 | {}
15 |
--------------------------------------------------------------------------------
/Quotient/events/directchatevent.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "event.h"
7 |
8 | namespace Quotient {
9 | class QUOTIENT_API DirectChatEvent : public Event {
10 | public:
11 | QUO_EVENT(DirectChatEvent, "m.direct")
12 |
13 | using Event::Event;
14 |
15 | QMultiHash usersToDirectChats() const;
16 | };
17 | } // namespace Quotient
18 |
--------------------------------------------------------------------------------
/Quotient/csapi/refresh.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "refresh.h"
4 |
5 | using namespace Quotient;
6 |
7 | RefreshJob::RefreshJob(const QString& refreshToken)
8 | : BaseJob(HttpVerb::Post, u"RefreshJob"_s, makePath("/_matrix/client/v3", "/refresh"), false)
9 | {
10 | QJsonObject _dataJson;
11 | addParam(_dataJson, "refresh_token"_L1, refreshToken);
12 | setRequestData({ _dataJson });
13 | addExpectedKey(u"access_token"_s);
14 | }
15 |
--------------------------------------------------------------------------------
/Quotient/csapi/voip.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "voip.h"
4 |
5 | using namespace Quotient;
6 |
7 | QUrl GetTurnServerJob::makeRequestUrl(const HomeserverData& hsData)
8 | {
9 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/voip/turnServer"));
10 | }
11 |
12 | GetTurnServerJob::GetTurnServerJob()
13 | : BaseJob(HttpVerb::Get, u"GetTurnServerJob"_s,
14 | makePath("/_matrix/client/v3", "/voip/turnServer"))
15 | {}
16 |
--------------------------------------------------------------------------------
/Quotient/csapi/versions.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "versions.h"
4 |
5 | using namespace Quotient;
6 |
7 | QUrl GetVersionsJob::makeRequestUrl(const HomeserverData& hsData)
8 | {
9 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client", "/versions"));
10 | }
11 |
12 | GetVersionsJob::GetVersionsJob()
13 | : BaseJob(HttpVerb::Get, u"GetVersionsJob"_s, makePath("/_matrix/client", "/versions"))
14 | {
15 | addExpectedKey(u"versions"_s);
16 | }
17 |
--------------------------------------------------------------------------------
/Quotient/csapi/support.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "support.h"
4 |
5 | using namespace Quotient;
6 |
7 | QUrl GetWellknownSupportJob::makeRequestUrl(const HomeserverData& hsData)
8 | {
9 | return BaseJob::makeRequestUrl(hsData, makePath("/.well-known", "/matrix/support"));
10 | }
11 |
12 | GetWellknownSupportJob::GetWellknownSupportJob()
13 | : BaseJob(HttpVerb::Get, u"GetWellknownSupportJob"_s,
14 | makePath("/.well-known", "/matrix/support"), false)
15 | {}
16 |
--------------------------------------------------------------------------------
/Quotient/events/roomtombstoneevent.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2019 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "stateevent.h"
7 |
8 | namespace Quotient {
9 | class QUOTIENT_API RoomTombstoneEvent : public StateEvent {
10 | public:
11 | QUO_EVENT(RoomTombstoneEvent, "m.room.tombstone")
12 |
13 | using StateEvent::StateEvent;
14 |
15 | QString serverMessage() const;
16 | QString successorRoomId() const;
17 | };
18 | } // namespace Quotient
19 |
--------------------------------------------------------------------------------
/Quotient/csapi/admin.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "admin.h"
4 |
5 | using namespace Quotient;
6 |
7 | QUrl GetWhoIsJob::makeRequestUrl(const HomeserverData& hsData, const QString& userId)
8 | {
9 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/admin/whois/", userId));
10 | }
11 |
12 | GetWhoIsJob::GetWhoIsJob(const QString& userId)
13 | : BaseJob(HttpVerb::Get, u"GetWhoIsJob"_s,
14 | makePath("/_matrix/client/v3", "/admin/whois/", userId))
15 | {}
16 |
--------------------------------------------------------------------------------
/Quotient/csapi/whoami.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "whoami.h"
4 |
5 | using namespace Quotient;
6 |
7 | QUrl GetTokenOwnerJob::makeRequestUrl(const HomeserverData& hsData)
8 | {
9 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/account/whoami"));
10 | }
11 |
12 | GetTokenOwnerJob::GetTokenOwnerJob()
13 | : BaseJob(HttpVerb::Get, u"GetTokenOwnerJob"_s,
14 | makePath("/_matrix/client/v3", "/account/whoami"))
15 | {
16 | addExpectedKey(u"user_id"_s);
17 | }
18 |
--------------------------------------------------------------------------------
/autotests/data/test-thread1-event.json:
--------------------------------------------------------------------------------
1 | {
2 | "content": {
3 | "body": "Thread reply 1 event",
4 | "msgtype": "m.text",
5 | "m.relates_to": {
6 | "rel_type": "m.thread",
7 | "event_id": "$threadroot:example.org"
8 | }
9 | },
10 | "event_id": "$thread1:example.org",
11 | "origin_server_ts": 1432735824654,
12 | "room_id": "!test:example.org",
13 | "sender": "@example:example.org",
14 | "type": "m.room.message",
15 | "unsigned": {
16 | "age": 1234
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/autotests/data/test-thread2-event.json:
--------------------------------------------------------------------------------
1 | {
2 | "content": {
3 | "body": "Thread reply 2 event",
4 | "msgtype": "m.text",
5 | "m.relates_to": {
6 | "rel_type": "m.thread",
7 | "event_id": "$threadroot:example.org"
8 | }
9 | },
10 | "event_id": "$thread2:example.org",
11 | "origin_server_ts": 1432735824654,
12 | "room_id": "!test:example.org",
13 | "sender": "@example:example.org",
14 | "type": "m.room.message",
15 | "unsigned": {
16 | "age": 1234
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Quotient/csapi/kicking.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "kicking.h"
4 |
5 | using namespace Quotient;
6 |
7 | KickJob::KickJob(const QString& roomId, const QString& userId, const QString& reason)
8 | : BaseJob(HttpVerb::Post, u"KickJob"_s,
9 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/kick"))
10 | {
11 | QJsonObject _dataJson;
12 | addParam(_dataJson, "user_id"_L1, userId);
13 | addParam(_dataJson, "reason"_L1, reason);
14 | setRequestData({ _dataJson });
15 | }
16 |
--------------------------------------------------------------------------------
/Quotient/csapi/list_joined_rooms.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "list_joined_rooms.h"
4 |
5 | using namespace Quotient;
6 |
7 | QUrl GetJoinedRoomsJob::makeRequestUrl(const HomeserverData& hsData)
8 | {
9 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/joined_rooms"));
10 | }
11 |
12 | GetJoinedRoomsJob::GetJoinedRoomsJob()
13 | : BaseJob(HttpVerb::Get, u"GetJoinedRoomsJob"_s, makePath("/_matrix/client/v3", "/joined_rooms"))
14 | {
15 | addExpectedKey(u"joined_rooms"_s);
16 | }
17 |
--------------------------------------------------------------------------------
/Quotient/csapi/room_send.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "room_send.h"
4 |
5 | using namespace Quotient;
6 |
7 | SendMessageJob::SendMessageJob(const QString& roomId, const QString& eventType,
8 | const QString& txnId, const QJsonObject& content)
9 | : BaseJob(HttpVerb::Put, u"SendMessageJob"_s,
10 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/send/", eventType, "/", txnId))
11 | {
12 | setRequestData({ toJson(content) });
13 | addExpectedKey(u"event_id"_s);
14 | }
15 |
--------------------------------------------------------------------------------
/Quotient/csapi/room_upgrades.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "room_upgrades.h"
4 |
5 | using namespace Quotient;
6 |
7 | UpgradeRoomJob::UpgradeRoomJob(const QString& roomId, const QString& newVersion)
8 | : BaseJob(HttpVerb::Post, u"UpgradeRoomJob"_s,
9 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/upgrade"))
10 | {
11 | QJsonObject _dataJson;
12 | addParam(_dataJson, "new_version"_L1, newVersion);
13 | setRequestData({ _dataJson });
14 | addExpectedKey(u"replacement_room"_s);
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # usual build directory names
2 | build
3 | build_dir
4 |
5 | # IDE project files/directories
6 | *.kdev4
7 | .directory
8 | *.user*
9 | .idea
10 |
11 | # qmake derivatives
12 | Makefile*
13 | object_script.*
14 | .qmake*
15 | debug/
16 | release/
17 |
18 | # CMake derivatives and user data
19 | CMakeCache.txt
20 | cmake_install.cmake
21 | Makefile
22 | Quotient_autogen/
23 | .cmake/
24 | tests/.cmake/
25 | autotests/synapse-data
26 | CMakeUserPresets.json
27 |
28 | # clangd
29 | .cache/
30 | compile_commands.json
31 |
32 | # Created by doxygen
33 | html/
34 | latex/
35 |
--------------------------------------------------------------------------------
/Quotient/csapi/capabilities.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "capabilities.h"
4 |
5 | using namespace Quotient;
6 |
7 | QUrl GetCapabilitiesJob::makeRequestUrl(const HomeserverData& hsData)
8 | {
9 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/capabilities"));
10 | }
11 |
12 | GetCapabilitiesJob::GetCapabilitiesJob()
13 | : BaseJob(HttpVerb::Get, u"GetCapabilitiesJob"_s,
14 | makePath("/_matrix/client/v3", "/capabilities"))
15 | {
16 | addExpectedKey(u"capabilities"_s);
17 | }
18 |
--------------------------------------------------------------------------------
/Quotient/csapi/inviting.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "inviting.h"
4 |
5 | using namespace Quotient;
6 |
7 | InviteUserJob::InviteUserJob(const QString& roomId, const QString& userId, const QString& reason)
8 | : BaseJob(HttpVerb::Post, u"InviteUserJob"_s,
9 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/invite"))
10 | {
11 | QJsonObject _dataJson;
12 | addParam(_dataJson, "user_id"_L1, userId);
13 | addParam(_dataJson, "reason"_L1, reason);
14 | setRequestData({ _dataJson });
15 | }
16 |
--------------------------------------------------------------------------------
/Quotient/events/redactionevent.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2017 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "roomevent.h"
7 |
8 | namespace Quotient {
9 | class QUOTIENT_API RedactionEvent : public RoomEvent {
10 | public:
11 | QUO_EVENT(RedactionEvent, "m.room.redaction")
12 |
13 | using RoomEvent::RoomEvent;
14 |
15 | QString redactedEvent() const
16 | {
17 | return fullJson()["redacts"_L1].toString();
18 | }
19 | QUO_CONTENT_GETTER(QString, reason)
20 | };
21 | } // namespace Quotient
22 |
--------------------------------------------------------------------------------
/Quotient/thread.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2024 James Graham
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include
7 |
8 | #include "quotient_export.h"
9 |
10 | namespace Quotient {
11 |
12 | class RoomEvent;
13 |
14 | class QUOTIENT_API Thread {
15 | public:
16 | QString threadRootId = {};
17 | QString latestEventId = {};
18 | int size = 0;
19 | bool localUserParticipated = {};
20 |
21 | bool addEvent(const RoomEvent* event, bool isLatest, bool isLocalUser);
22 | };
23 |
24 | } // namespace Quotient
25 |
--------------------------------------------------------------------------------
/Quotient/csapi/login_token.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "login_token.h"
4 |
5 | using namespace Quotient;
6 |
7 | GenerateLoginTokenJob::GenerateLoginTokenJob(const std::optional& auth)
8 | : BaseJob(HttpVerb::Post, u"GenerateLoginTokenJob"_s,
9 | makePath("/_matrix/client/v1", "/login/get_token"))
10 | {
11 | QJsonObject _dataJson;
12 | addParam(_dataJson, "auth"_L1, auth);
13 | setRequestData({ _dataJson });
14 | addExpectedKey(u"login_token"_s);
15 | addExpectedKey(u"expires_in_ms"_s);
16 | }
17 |
--------------------------------------------------------------------------------
/Quotient/csapi/redaction.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "redaction.h"
4 |
5 | using namespace Quotient;
6 |
7 | RedactEventJob::RedactEventJob(const QString& roomId, const QString& eventId, const QString& txnId,
8 | const QString& reason)
9 | : BaseJob(HttpVerb::Put, u"RedactEventJob"_s,
10 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/redact/", eventId, "/", txnId))
11 | {
12 | QJsonObject _dataJson;
13 | addParam(_dataJson, "reason"_L1, reason);
14 | setRequestData({ _dataJson });
15 | }
16 |
--------------------------------------------------------------------------------
/Quotient/csapi/to_device.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "to_device.h"
4 |
5 | using namespace Quotient;
6 |
7 | SendToDeviceJob::SendToDeviceJob(const QString& eventType, const QString& txnId,
8 | const QHash>& messages)
9 | : BaseJob(HttpVerb::Put, u"SendToDeviceJob"_s,
10 | makePath("/_matrix/client/v3", "/sendToDevice/", eventType, "/", txnId))
11 | {
12 | QJsonObject _dataJson;
13 | addParam(_dataJson, "messages"_L1, messages);
14 | setRequestData({ _dataJson });
15 | }
16 |
--------------------------------------------------------------------------------
/Quotient/csapi/room_state.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "room_state.h"
4 |
5 | using namespace Quotient;
6 |
7 | SetRoomStateWithKeyJob::SetRoomStateWithKeyJob(const QString& roomId, const QString& eventType,
8 | const QString& stateKey, const QJsonObject& content)
9 | : BaseJob(HttpVerb::Put, u"SetRoomStateWithKeyJob"_s,
10 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/state/", eventType, "/", stateKey))
11 | {
12 | setRequestData({ toJson(content) });
13 | addExpectedKey(u"event_id"_s);
14 | }
15 |
--------------------------------------------------------------------------------
/Quotient/csapi/typing.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "typing.h"
4 |
5 | using namespace Quotient;
6 |
7 | SetTypingJob::SetTypingJob(const QString& userId, const QString& roomId, bool typing,
8 | std::optional timeout)
9 | : BaseJob(HttpVerb::Put, u"SetTypingJob"_s,
10 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/typing/", userId))
11 | {
12 | QJsonObject _dataJson;
13 | addParam(_dataJson, "typing"_L1, typing);
14 | addParam(_dataJson, "timeout"_L1, timeout);
15 | setRequestData({ _dataJson });
16 | }
17 |
--------------------------------------------------------------------------------
/Quotient/csapi/receipts.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "receipts.h"
4 |
5 | using namespace Quotient;
6 |
7 | PostReceiptJob::PostReceiptJob(const QString& roomId, const QString& receiptType,
8 | const QString& eventId, const QString& threadId)
9 | : BaseJob(HttpVerb::Post, u"PostReceiptJob"_s,
10 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/receipt/", receiptType, "/",
11 | eventId))
12 | {
13 | QJsonObject _dataJson;
14 | addParam(_dataJson, "thread_id"_L1, threadId);
15 | setRequestData({ _dataJson });
16 | }
17 |
--------------------------------------------------------------------------------
/autotests/register-users.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | if [ ! -x register_new_matrix_user ]; then
6 | echo "This script is meant to be executed in a Synapse container"
7 | fi
8 |
9 | echo Register alice
10 | for i in 1 2 3 4 5 6 7 8 9; do
11 | register_new_matrix_user --admin -u alice$i -p secret -c /data/homeserver.yaml https://localhost:8008
12 | done
13 | echo Register bob
14 | for i in 1 2 3; do
15 | register_new_matrix_user --admin -u bob$i -p secret -c /data/homeserver.yaml https://localhost:8008
16 | done
17 | echo Register carl
18 | register_new_matrix_user --admin -u carl -p secret -c /data/homeserver.yaml https://localhost:8008
19 |
20 |
--------------------------------------------------------------------------------
/Quotient/csapi/users.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "users.h"
4 |
5 | using namespace Quotient;
6 |
7 | SearchUserDirectoryJob::SearchUserDirectoryJob(const QString& searchTerm, std::optional limit)
8 | : BaseJob(HttpVerb::Post, u"SearchUserDirectoryJob"_s,
9 | makePath("/_matrix/client/v3", "/user_directory/search"))
10 | {
11 | QJsonObject _dataJson;
12 | addParam(_dataJson, "search_term"_L1, searchTerm);
13 | addParam(_dataJson, "limit"_L1, limit);
14 | setRequestData({ _dataJson });
15 | addExpectedKey(u"results"_s);
16 | addExpectedKey(u"limited"_s);
17 | }
18 |
--------------------------------------------------------------------------------
/Quotient/csapi/report_content.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "report_content.h"
4 |
5 | using namespace Quotient;
6 |
7 | ReportContentJob::ReportContentJob(const QString& roomId, const QString& eventId,
8 | std::optional score, const QString& reason)
9 | : BaseJob(HttpVerb::Post, u"ReportContentJob"_s,
10 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/report/", eventId))
11 | {
12 | QJsonObject _dataJson;
13 | addParam(_dataJson, "score"_L1, score);
14 | addParam(_dataJson, "reason"_L1, reason);
15 | setRequestData({ _dataJson });
16 | }
17 |
--------------------------------------------------------------------------------
/Quotient/csapi/appservice_room_directory.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "appservice_room_directory.h"
4 |
5 | using namespace Quotient;
6 |
7 | UpdateAppserviceRoomDirectoryVisibilityJob::UpdateAppserviceRoomDirectoryVisibilityJob(
8 | const QString& networkId, const QString& roomId, const QString& visibility)
9 | : BaseJob(HttpVerb::Put, u"UpdateAppserviceRoomDirectoryVisibilityJob"_s,
10 | makePath("/_matrix/client/v3", "/directory/list/appservice/", networkId, "/", roomId),
11 | false)
12 | {
13 | QJsonObject _dataJson;
14 | addParam(_dataJson, "visibility"_L1, visibility);
15 | setRequestData({ _dataJson });
16 | }
17 |
--------------------------------------------------------------------------------
/Quotient/csapi/search.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "search.h"
4 |
5 | using namespace Quotient;
6 |
7 | auto queryToSearch(const QString& nextBatch)
8 | {
9 | QUrlQuery _q;
10 | addParam(_q, u"next_batch"_s, nextBatch);
11 | return _q;
12 | }
13 |
14 | SearchJob::SearchJob(const Categories& searchCategories, const QString& nextBatch)
15 | : BaseJob(HttpVerb::Post, u"SearchJob"_s, makePath("/_matrix/client/v3", "/search"),
16 | queryToSearch(nextBatch))
17 | {
18 | QJsonObject _dataJson;
19 | addParam(_dataJson, "search_categories"_L1, searchCategories);
20 | setRequestData({ _dataJson });
21 | addExpectedKey(u"search_categories"_s);
22 | }
23 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/change-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Change request
3 | about: Suggest an idea or improvement for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your request related to a problem?**
11 |
12 |
13 | **Describe the suggested change/improvement you'd like**
14 |
15 |
16 | **Describe alternatives you've considered**
17 |
18 |
19 | **Additional context**
20 |
21 |
--------------------------------------------------------------------------------
/Quotient/csapi/definitions/tag.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | struct QUOTIENT_API Tag {
10 | //! A number in a range `[0,1]` describing a relative
11 | //! position of the room under the given tag.
12 | std::optional order{};
13 | };
14 |
15 | template <>
16 | struct JsonObjectConverter {
17 | static void dumpTo(QJsonObject& jo, const Tag& pod)
18 | {
19 | addParam(jo, "order"_L1, pod.order);
20 | }
21 | static void fillFrom(const QJsonObject& jo, Tag& pod)
22 | {
23 | fillFromJson(jo.value("order"_L1), pod.order);
24 | }
25 | };
26 |
27 | } // namespace Quotient
28 |
--------------------------------------------------------------------------------
/Quotient/csapi/read_markers.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "read_markers.h"
4 |
5 | using namespace Quotient;
6 |
7 | SetReadMarkerJob::SetReadMarkerJob(const QString& roomId, const QString& fullyRead,
8 | const QString& read, const QString& readPrivate)
9 | : BaseJob(HttpVerb::Post, u"SetReadMarkerJob"_s,
10 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/read_markers"))
11 | {
12 | QJsonObject _dataJson;
13 | addParam(_dataJson, "m.fully_read"_L1, fullyRead);
14 | addParam(_dataJson, "m.read"_L1, read);
15 | addParam(_dataJson, "m.read.private"_L1, readPrivate);
16 | setRequestData({ _dataJson });
17 | }
18 |
--------------------------------------------------------------------------------
/Quotient/csapi/logout.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "logout.h"
4 |
5 | using namespace Quotient;
6 |
7 | QUrl LogoutJob::makeRequestUrl(const HomeserverData& hsData)
8 | {
9 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/logout"));
10 | }
11 |
12 | LogoutJob::LogoutJob()
13 | : BaseJob(HttpVerb::Post, u"LogoutJob"_s, makePath("/_matrix/client/v3", "/logout"))
14 | {}
15 |
16 | QUrl LogoutAllJob::makeRequestUrl(const HomeserverData& hsData)
17 | {
18 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/logout/all"));
19 | }
20 |
21 | LogoutAllJob::LogoutAllJob()
22 | : BaseJob(HttpVerb::Post, u"LogoutAllJob"_s, makePath("/_matrix/client/v3", "/logout/all"))
23 | {}
24 |
--------------------------------------------------------------------------------
/Quotient/networksettings.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2017 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "networksettings.h"
5 |
6 | using namespace Quotient;
7 |
8 | void NetworkSettings::setupApplicationProxy() const
9 | {
10 | QNetworkProxy::setApplicationProxy(
11 | { proxyType(), proxyHostName(), proxyPort() });
12 | }
13 |
14 | QUO_DEFINE_SETTING(NetworkSettings, QNetworkProxy::ProxyType, proxyType,
15 | "proxy_type", QNetworkProxy::DefaultProxy, setProxyType)
16 | QUO_DEFINE_SETTING(NetworkSettings, QString, proxyHostName, "proxy_hostname",
17 | {}, setProxyHostName)
18 | QUO_DEFINE_SETTING(NetworkSettings, quint16, proxyPort, "proxy_port", -1,
19 | setProxyPort)
20 |
--------------------------------------------------------------------------------
/Quotient/thread.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2024 James Graham
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "thread.h"
5 |
6 | #include "events/roomevent.h"
7 |
8 | using namespace Quotient;
9 |
10 | bool Thread::addEvent(const RoomEvent* event, bool isLatest, bool isLocalUser)
11 | {
12 | // Note: the root event may not have the thread aggregation in its unsigned on creation
13 | // hence checking the event id.
14 | if (event->threadRootEventId() != threadRootId && event->id() != threadRootId) {
15 | return false;
16 | }
17 | if (isLatest || latestEventId.isEmpty()) {
18 | latestEventId = event->id();
19 | }
20 | ++size;
21 | localUserParticipated |= isLocalUser;
22 |
23 | return true;
24 | }
25 |
--------------------------------------------------------------------------------
/Quotient/events/roomcreateevent.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2019 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "stateevent.h"
7 | #include
8 |
9 | namespace Quotient {
10 | class QUOTIENT_API RoomCreateEvent : public StateEvent {
11 | public:
12 | QUO_EVENT(RoomCreateEvent, "m.room.create")
13 |
14 | using StateEvent::StateEvent;
15 |
16 | struct Predecessor {
17 | QString roomId;
18 | QString eventId;
19 | };
20 |
21 | bool isFederated() const;
22 | QString version() const;
23 | Predecessor predecessor() const;
24 | bool isUpgrade() const;
25 | RoomType roomType() const;
26 | QStringList additionalCreators() const;
27 | };
28 | } // namespace Quotient
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 |
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behaviour, and the description of the actual result:
15 | 1.
16 | 2.
17 | 3.
18 |
19 | **Expected behavior**
20 |
21 |
22 | **Is it environment-specific?**
23 |
24 | - OS: [e.g. Windows 11]
25 | - Version of the library [e.g. 0.6.10]
26 | - Linkage: static, dynamic, any
27 |
28 | **Additional context**
29 |
30 |
--------------------------------------------------------------------------------
/Quotient/csapi/definitions/wellknown/homeserver.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 | //! Used by clients to discover homeserver information.
9 | struct QUOTIENT_API HomeserverInformation {
10 | //! The base URL for the homeserver for client-server connections.
11 | QUrl baseUrl;
12 | };
13 |
14 | template <>
15 | struct JsonObjectConverter {
16 | static void dumpTo(QJsonObject& jo, const HomeserverInformation& pod)
17 | {
18 | addParam(jo, "base_url"_L1, pod.baseUrl);
19 | }
20 | static void fillFrom(const QJsonObject& jo, HomeserverInformation& pod)
21 | {
22 | fillFromJson(jo.value("base_url"_L1), pod.baseUrl);
23 | }
24 | };
25 |
26 | } // namespace Quotient
27 |
--------------------------------------------------------------------------------
/Quotient/expected.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2022 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include
7 |
8 | namespace Quotient {
9 |
10 | template
11 | requires (!std::is_same_v)
12 | class [[deprecated("Use std::expected instead")]] Expected : public std::expected {
13 | public:
14 | using std::expected::expected;
15 |
16 | template X>
17 | explicit(false) Expected(X&& x) : std::expected(std::unexpect, std::forward(x))
18 | {}
19 |
20 | T&& move_value_or(T&& fallback)
21 | {
22 | if (this->has_value())
23 | return std::move(this->value());
24 | return std::move(fallback);
25 | }
26 | };
27 |
28 | } // namespace Quotient
29 |
--------------------------------------------------------------------------------
/Quotient/e2ee/qolmmessage.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2021 Alexey Andreyev
2 | //
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #include "qolmmessage.h"
6 |
7 | #include
8 |
9 | using namespace Quotient;
10 |
11 | QOlmMessage::QOlmMessage(QByteArray ciphertext, QOlmMessage::Type type)
12 | : QByteArray(std::move(ciphertext))
13 | , m_messageType(type)
14 | {
15 | Q_ASSERT_X(!isEmpty(), "olm message", "Ciphertext is empty");
16 | }
17 |
18 | QOlmMessage::Type QOlmMessage::type() const
19 | {
20 | return m_messageType;
21 | }
22 |
23 | QByteArray QOlmMessage::toCiphertext() const
24 | {
25 | return SLICE(*this, QByteArray);
26 | }
27 |
28 | QOlmMessage QOlmMessage::fromCiphertext(const QByteArray &ciphertext)
29 | {
30 | return QOlmMessage(ciphertext, QOlmMessage::General);
31 | }
32 |
--------------------------------------------------------------------------------
/Quotient/csapi/definitions/room_key_backup.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | #include
8 |
9 | namespace Quotient {
10 | //! The backed up keys for a room.
11 | struct QUOTIENT_API RoomKeyBackup {
12 | //! A map of session IDs to key data.
13 | QHash sessions;
14 | };
15 |
16 | template <>
17 | struct JsonObjectConverter {
18 | static void dumpTo(QJsonObject& jo, const RoomKeyBackup& pod)
19 | {
20 | addParam(jo, "sessions"_L1, pod.sessions);
21 | }
22 | static void fillFrom(const QJsonObject& jo, RoomKeyBackup& pod)
23 | {
24 | fillFromJson(jo.value("sessions"_L1), pod.sessions);
25 | }
26 | };
27 |
28 | } // namespace Quotient
29 |
--------------------------------------------------------------------------------
/Quotient/csapi/third_party_membership.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "third_party_membership.h"
4 |
5 | using namespace Quotient;
6 |
7 | InviteBy3PIDJob::InviteBy3PIDJob(const QString& roomId, const QString& idServer,
8 | const QString& idAccessToken, const QString& medium,
9 | const QString& address)
10 | : BaseJob(HttpVerb::Post, u"InviteBy3PIDJob"_s,
11 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/invite"))
12 | {
13 | QJsonObject _dataJson;
14 | addParam(_dataJson, "id_server"_L1, idServer);
15 | addParam(_dataJson, "id_access_token"_L1, idAccessToken);
16 | addParam(_dataJson, "medium"_L1, medium);
17 | addParam(_dataJson, "address"_L1, address);
18 | setRequestData({ _dataJson });
19 | }
20 |
--------------------------------------------------------------------------------
/autotests/testolmaccount.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2021 Carl Schwan
2 | //
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #include
6 | #include
7 |
8 | namespace Quotient {
9 | class Connection;
10 | }
11 |
12 | class TestOlmAccount : public QObject
13 | {
14 | Q_OBJECT
15 |
16 | private Q_SLOTS:
17 | void pickleUnpickledTest();
18 | void identityKeysValid();
19 | void signatureValid();
20 | void oneTimeKeysValid();
21 | //void removeOneTimeKeys();
22 | void deviceKeys();
23 | void encryptedFile();
24 | void uploadIdentityKey();
25 | void uploadOneTimeKeys();
26 | void uploadSignedOneTimeKeys();
27 | void uploadKeys();
28 | void queryTest();
29 | void claimKeys();
30 | void claimMultipleKeys();
31 | void enableEncryption();
32 | };
33 |
--------------------------------------------------------------------------------
/Quotient/events/directchatevent.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "directchatevent.h"
5 |
6 | using namespace Quotient;
7 |
8 | QMultiHash DirectChatEvent::usersToDirectChats() const
9 | {
10 | QMultiHash result;
11 | const auto& json = contentJson();
12 | for (auto it = json.begin(); it != json.end(); ++it) {
13 | // Beware of range-for's over temporary returned from temporary
14 | // (see the bottom of
15 | // http://en.cppreference.com/w/cpp/language/range-for#Explanation)
16 | const auto roomIds = it.value().toArray();
17 | for (const auto& roomIdValue : roomIds)
18 | result.insert(it.key(), roomIdValue.toString());
19 | }
20 | return result;
21 | }
22 |
--------------------------------------------------------------------------------
/Quotient/csapi/definitions/wellknown/identity_server.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 | //! Used by clients to discover identity server information.
9 | struct QUOTIENT_API IdentityServerInformation {
10 | //! The base URL for the identity server for client-server connections.
11 | QUrl baseUrl;
12 | };
13 |
14 | template <>
15 | struct JsonObjectConverter {
16 | static void dumpTo(QJsonObject& jo, const IdentityServerInformation& pod)
17 | {
18 | addParam(jo, "base_url"_L1, pod.baseUrl);
19 | }
20 | static void fillFrom(const QJsonObject& jo, IdentityServerInformation& pod)
21 | {
22 | fillFromJson(jo.value("base_url"_L1), pod.baseUrl);
23 | }
24 | };
25 |
26 | } // namespace Quotient
27 |
--------------------------------------------------------------------------------
/Quotient/networksettings.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2017 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "settings.h"
7 |
8 | #include
9 |
10 | Q_DECLARE_METATYPE(QNetworkProxy::ProxyType)
11 |
12 | namespace Quotient {
13 | class QUOTIENT_API NetworkSettings : public SettingsGroup {
14 | Q_OBJECT
15 | QUO_DECLARE_SETTING(QNetworkProxy::ProxyType, proxyType, setProxyType)
16 | QUO_DECLARE_SETTING(QString, proxyHostName, setProxyHostName)
17 | QUO_DECLARE_SETTING(quint16, proxyPort, setProxyPort)
18 | Q_PROPERTY(QString proxyHost READ proxyHostName WRITE setProxyHostName)
19 | public:
20 | explicit NetworkSettings() : SettingsGroup(u"Network"_s) {}
21 |
22 | Q_INVOKABLE void setupApplicationProxy() const;
23 | };
24 | } // namespace Quotient
25 |
--------------------------------------------------------------------------------
/Quotient/mxcreply.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: Tobias Fella
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "util.h"
7 |
8 | #include "events/filesourceinfo.h"
9 |
10 | #include
11 |
12 | namespace Quotient {
13 | class QUOTIENT_API MxcReply : public QNetworkReply
14 | {
15 | Q_OBJECT
16 | public:
17 | explicit MxcReply();
18 | explicit MxcReply(QNetworkReply* reply,
19 | const EncryptedFileMetadata& fileMetadata);
20 |
21 | qint64 bytesAvailable() const override;
22 |
23 | public Q_SLOTS:
24 | void abort() override;
25 |
26 | protected:
27 | qint64 readData(char* data, qint64 maxlen) override;
28 | void ignoreSslErrorsImplementation(const QList &) override;
29 |
30 | private:
31 | class Private;
32 | ImplPtr d;
33 | };
34 | }
35 |
--------------------------------------------------------------------------------
/cmake/QuotientConfig.cmake.in:
--------------------------------------------------------------------------------
1 | include(CMakeFindDependencyMacro)
2 |
3 | find_dependency(@Qt@Core)
4 | if (@Qt@Core_VERSION VERSION_GREATER_EQUAL 6.10)
5 | find_dependency(@Qt@CorePrivate)
6 | endif()
7 | find_dependency(@Qt@Gui)
8 | find_dependency(@Qt@Network)
9 | find_dependency(@Qt@Keychain)
10 | find_dependency(Olm)
11 | find_dependency(OpenSSL)
12 | find_dependency(@Qt@Sql)
13 |
14 | if(NOT @BUILD_SHARED_LIBS@ AND @Qt@Core_VERSION VERSION_GREATER_EQUAL 6.10)
15 | find_dependency(@Qt@CorePrivate)
16 | endif()
17 |
18 | include("${CMAKE_CURRENT_LIST_DIR}/@QUOTIENT_LIB_NAME@Targets.cmake")
19 |
20 | if (NOT QUOTIENT_FORCE_NAMESPACED_INCLUDES)
21 | get_target_property(_include_dir @QUOTIENT_LIB_NAME@ INTERFACE_INCLUDE_DIRECTORIES)
22 | list(APPEND _include_dir "${_include_dir}/Quotient")
23 | set_target_properties(@QUOTIENT_LIB_NAME@ PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_include_dir}")
24 | endif()
25 |
--------------------------------------------------------------------------------
/Quotient/csapi/room_upgrades.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | //! \brief Upgrades a room to a new room version.
10 | //!
11 | //! Upgrades the given room to a particular room version.
12 | class QUOTIENT_API UpgradeRoomJob : public BaseJob {
13 | public:
14 | //! \param roomId
15 | //! The ID of the room to upgrade.
16 | //!
17 | //! \param newVersion
18 | //! The new version for the room.
19 | explicit UpgradeRoomJob(const QString& roomId, const QString& newVersion);
20 |
21 | // Result properties
22 |
23 | //! The ID of the new room.
24 | QString replacementRoom() const { return loadFromJson("replacement_room"_L1); }
25 | };
26 |
27 | inline auto collectResponse(const UpgradeRoomJob* job) { return job->replacementRoom(); }
28 |
29 | } // namespace Quotient
30 |
--------------------------------------------------------------------------------
/Quotient/csapi/knocking.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "knocking.h"
4 |
5 | using namespace Quotient;
6 |
7 | auto queryToKnockRoom(const QStringList& serverName, const QStringList& via)
8 | {
9 | QUrlQuery _q;
10 | addParam(_q, u"server_name"_s, serverName);
11 | addParam(_q, u"via"_s, via);
12 | return _q;
13 | }
14 |
15 | KnockRoomJob::KnockRoomJob(const QString& roomIdOrAlias, const QStringList& serverName,
16 | const QStringList& via, const QString& reason)
17 | : BaseJob(HttpVerb::Post, u"KnockRoomJob"_s,
18 | makePath("/_matrix/client/v3", "/knock/", roomIdOrAlias),
19 | queryToKnockRoom(serverName, via))
20 | {
21 | QJsonObject _dataJson;
22 | addParam(_dataJson, "reason"_L1, reason);
23 | setRequestData({ _dataJson });
24 | addExpectedKey(u"room_id"_s);
25 | }
26 |
--------------------------------------------------------------------------------
/Quotient/events/roomavatarevent.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2017 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "eventcontent.h"
7 | #include "stateevent.h"
8 |
9 | namespace Quotient {
10 | class QUOTIENT_API RoomAvatarEvent
11 | : public KeylessStateEventBase {
13 | // It's a bit of an overkill to use a full-fledged ImageContent
14 | // because in reality m.room.avatar usually only has a single URL,
15 | // without a thumbnail. But The Spec says there be thumbnails, and
16 | // we follow The Spec (and ImageContent is very convenient to reuse here).
17 | public:
18 | QUO_EVENT(RoomAvatarEvent, "m.room.avatar")
19 | using KeylessStateEventBase::KeylessStateEventBase;
20 |
21 | QUrl url() const { return content().url(); }
22 | };
23 | } // namespace Quotient
24 |
--------------------------------------------------------------------------------
/Quotient/csapi/banning.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "banning.h"
4 |
5 | using namespace Quotient;
6 |
7 | BanJob::BanJob(const QString& roomId, const QString& userId, const QString& reason)
8 | : BaseJob(HttpVerb::Post, u"BanJob"_s, makePath("/_matrix/client/v3", "/rooms/", roomId, "/ban"))
9 | {
10 | QJsonObject _dataJson;
11 | addParam(_dataJson, "user_id"_L1, userId);
12 | addParam(_dataJson, "reason"_L1, reason);
13 | setRequestData({ _dataJson });
14 | }
15 |
16 | UnbanJob::UnbanJob(const QString& roomId, const QString& userId, const QString& reason)
17 | : BaseJob(HttpVerb::Post, u"UnbanJob"_s,
18 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/unban"))
19 | {
20 | QJsonObject _dataJson;
21 | addParam(_dataJson, "user_id"_L1, userId);
22 | addParam(_dataJson, "reason"_L1, reason);
23 | setRequestData({ _dataJson });
24 | }
25 |
--------------------------------------------------------------------------------
/Quotient/events/receiptevent.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "event.h"
7 |
8 | #include
9 | #include
10 |
11 | namespace Quotient {
12 | struct UserTimestamp {
13 | QString userId;
14 | QDateTime timestamp;
15 | };
16 | struct ReceiptsForEvent {
17 | QString evtId;
18 | QVector receipts;
19 | };
20 | using EventsWithReceipts = QVector;
21 |
22 | template <>
23 | QUOTIENT_API EventsWithReceipts fromJson(const QJsonObject& json);
24 | QUOTIENT_API QJsonObject toJson(const EventsWithReceipts& ewrs);
25 |
26 | class QUOTIENT_API ReceiptEvent
27 | : public EventTemplate {
28 | public:
29 | QUO_EVENT(ReceiptEvent, "m.receipt")
30 | using EventTemplate::EventTemplate;
31 | };
32 | } // namespace Quotient
33 |
--------------------------------------------------------------------------------
/Quotient/csapi/leaving.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "leaving.h"
4 |
5 | using namespace Quotient;
6 |
7 | LeaveRoomJob::LeaveRoomJob(const QString& roomId, const QString& reason)
8 | : BaseJob(HttpVerb::Post, u"LeaveRoomJob"_s,
9 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/leave"))
10 | {
11 | QJsonObject _dataJson;
12 | addParam(_dataJson, "reason"_L1, reason);
13 | setRequestData({ _dataJson });
14 | }
15 |
16 | QUrl ForgetRoomJob::makeRequestUrl(const HomeserverData& hsData, const QString& roomId)
17 | {
18 | return BaseJob::makeRequestUrl(hsData,
19 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/forget"));
20 | }
21 |
22 | ForgetRoomJob::ForgetRoomJob(const QString& roomId)
23 | : BaseJob(HttpVerb::Post, u"ForgetRoomJob"_s,
24 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/forget"))
25 | {}
26 |
--------------------------------------------------------------------------------
/Quotient/eventitem.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "eventitem.h"
5 |
6 | #include "events/roomavatarevent.h"
7 | #include "events/roommessageevent.h"
8 |
9 | using namespace Quotient;
10 |
11 | void PendingEventItem::setFileUploaded(const FileSourceInfo& uploadedFileData)
12 | {
13 | if (auto* rme = getAs())
14 | rme->updateFileSourceInfo(uploadedFileData);
15 |
16 | if (auto* rae = getAs()) {
17 | rae->editContent([&uploadedFileData](EventContent::FileInfo& fi) {
18 | fi.source = uploadedFileData;
19 | });
20 | }
21 | setStatus(EventStatus::FileUploaded);
22 | }
23 |
24 | // Not exactly sure why but this helps with the linker not finding
25 | // Quotient::EventStatus::staticMetaObject when building Quaternion
26 | #include "moc_eventitem.cpp" // NOLINT(bugprone-suspicious-include)
27 |
--------------------------------------------------------------------------------
/Quotient/converters.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "converters.h"
5 |
6 | #include "logging_categories_p.h"
7 |
8 | #include
9 |
10 | void Quotient::_impl::reportEnumOutOfBounds(uint32_t v, const char* enumTypeName)
11 | {
12 | qCritical(MAIN).noquote()
13 | << "Value" << v << "is out of bounds for enumeration" << enumTypeName;
14 | }
15 |
16 | QJsonValue Quotient::JsonConverter::dump(const QVariant& v)
17 | {
18 | return QJsonValue::fromVariant(v);
19 | }
20 |
21 | QVariant Quotient::JsonConverter::load(const QJsonValue& jv)
22 | {
23 | return jv.toVariant();
24 | }
25 |
26 | QJsonObject Quotient::toJson(const QVariantHash& vh)
27 | {
28 | return QJsonObject::fromVariantHash(vh);
29 | }
30 |
31 | template<>
32 | QVariantHash Quotient::fromJson(const QJsonValue& jv)
33 | {
34 | return jv.toObject().toVariantHash();
35 | }
36 |
--------------------------------------------------------------------------------
/Quotient/csapi/voip.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | //! \brief Obtain TURN server credentials.
10 | //!
11 | //! This API provides credentials for the client to use when initiating
12 | //! calls.
13 | class QUOTIENT_API GetTurnServerJob : public BaseJob {
14 | public:
15 | explicit GetTurnServerJob();
16 |
17 | //! \brief Construct a URL without creating a full-fledged job object
18 | //!
19 | //! This function can be used when a URL for GetTurnServerJob
20 | //! is necessary but the job itself isn't.
21 | static QUrl makeRequestUrl(const HomeserverData& hsData);
22 |
23 | // Result properties
24 |
25 | //! The TURN server credentials.
26 | QJsonObject data() const { return fromJson(jsonData()); }
27 | };
28 |
29 | inline auto collectResponse(const GetTurnServerJob* job) { return job->data(); }
30 |
31 | } // namespace Quotient
32 |
--------------------------------------------------------------------------------
/Quotient/events/single_key_value.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | namespace Quotient {
6 |
7 | namespace EventContent {
8 | template
9 | struct SingleKeyValue {
10 | Q_IMPLICIT SingleKeyValue(const T& v = {}) : value(v) {}
11 | Q_IMPLICIT SingleKeyValue(T&& v) : value(std::move(v)) {}
12 | T value;
13 | };
14 | } // namespace EventContent
15 |
16 | template
17 | struct JsonConverter> {
18 | using content_type = EventContent::SingleKeyValue;
19 | static content_type load(const QJsonValue& jv)
20 | {
21 | return fromJson(jv.toObject().value(JsonKey));
22 | }
23 | static QJsonObject dump(const content_type& c)
24 | {
25 | return { { JsonKey, toJson(c.value) } };
26 | }
27 | static inline const auto JsonKey = toSnakeCase(KeyStr);
28 | };
29 | } // namespace Quotient
30 |
--------------------------------------------------------------------------------
/Quotient/csapi/filter.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "filter.h"
4 |
5 | using namespace Quotient;
6 |
7 | DefineFilterJob::DefineFilterJob(const QString& userId, const Filter& filter)
8 | : BaseJob(HttpVerb::Post, u"DefineFilterJob"_s,
9 | makePath("/_matrix/client/v3", "/user/", userId, "/filter"))
10 | {
11 | setRequestData({ toJson(filter) });
12 | addExpectedKey(u"filter_id"_s);
13 | }
14 |
15 | QUrl GetFilterJob::makeRequestUrl(const HomeserverData& hsData, const QString& userId,
16 | const QString& filterId)
17 | {
18 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/user/", userId,
19 | "/filter/", filterId));
20 | }
21 |
22 | GetFilterJob::GetFilterJob(const QString& userId, const QString& filterId)
23 | : BaseJob(HttpVerb::Get, u"GetFilterJob"_s,
24 | makePath("/_matrix/client/v3", "/user/", userId, "/filter/", filterId))
25 | {}
26 |
--------------------------------------------------------------------------------
/Quotient/jobs/requestdata.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include
7 |
8 | class QJsonObject;
9 | class QJsonArray;
10 | class QJsonDocument;
11 | class QIODevice;
12 |
13 | namespace Quotient {
14 | /**
15 | * A simple wrapper that represents the request body.
16 | * Provides a unified interface to dump an unstructured byte stream
17 | * as well as JSON (and possibly other structures in the future) to
18 | * a QByteArray consumed by QNetworkAccessManager request methods.
19 | */
20 | class QUOTIENT_API RequestData {
21 | public:
22 | Q_IMPLICIT RequestData(const QByteArray& a = {});
23 | Q_IMPLICIT RequestData(const QJsonObject& jo);
24 | Q_IMPLICIT RequestData(const QJsonArray& ja);
25 | Q_IMPLICIT RequestData(QIODevice* source);
26 |
27 | QIODevice* source() const { return _source.get(); }
28 |
29 | private:
30 | ImplPtr _source;
31 | };
32 | } // namespace Quotient
33 |
--------------------------------------------------------------------------------
/Quotient/quotient_export.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2021 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include
7 |
8 | #ifdef QUOTIENT_STATIC
9 | #define QUOTIENT_API
10 | #define QUOTIENT_HIDDEN
11 | #else
12 | #ifndef QUOTIENT_API
13 | #ifdef BUILDING_SHARED_QUOTIENT // Building this library
14 | #ifdef Q_OS_WIN
15 | #define QUOTIENT_API Q_DECL_EXPORT
16 | #else
17 | // On non-Windows, Q_DECL_EXPORT can apply protected visibility and the current
18 | // code for event types is incompatible with it (see #692).
19 | #define QUOTIENT_API __attribute__((visibility("default")))
20 | #endif
21 | #else // Using this library
22 | #define QUOTIENT_API Q_DECL_IMPORT
23 | #endif
24 | #endif
25 |
26 | #ifndef QUOTIENT_HIDDEN
27 | #define QUOTIENT_HIDDEN Q_DECL_HIDDEN
28 | #endif
29 | #endif
30 |
--------------------------------------------------------------------------------
/Quotient/csapi/list_joined_rooms.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | //! \brief Lists the user's current rooms.
10 | //!
11 | //! This API returns a list of the user's current rooms.
12 | class QUOTIENT_API GetJoinedRoomsJob : public BaseJob {
13 | public:
14 | explicit GetJoinedRoomsJob();
15 |
16 | //! \brief Construct a URL without creating a full-fledged job object
17 | //!
18 | //! This function can be used when a URL for GetJoinedRoomsJob
19 | //! is necessary but the job itself isn't.
20 | static QUrl makeRequestUrl(const HomeserverData& hsData);
21 |
22 | // Result properties
23 |
24 | //! The ID of each room in which the user has `joined` membership.
25 | QStringList joinedRooms() const { return loadFromJson("joined_rooms"_L1); }
26 | };
27 |
28 | inline auto collectResponse(const GetJoinedRoomsJob* job) { return job->joinedRooms(); }
29 |
30 | } // namespace Quotient
31 |
--------------------------------------------------------------------------------
/Quotient/csapi/definitions/user_identifier.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 | //! Identification information for a user
9 | struct QUOTIENT_API UserIdentifier {
10 | //! The type of identification. See [Identifier types](/client-server-api/#identifier-types)
11 | //! for supported values and additional property descriptions.
12 | QString type;
13 |
14 | //! Keys dependent on the identification type.
15 | QVariantHash additionalProperties{};
16 | };
17 |
18 | template <>
19 | struct JsonObjectConverter {
20 | static void dumpTo(QJsonObject& jo, const UserIdentifier& pod)
21 | {
22 | fillJson(jo, pod.additionalProperties);
23 | addParam(jo, "type"_L1, pod.type);
24 | }
25 | static void fillFrom(QJsonObject jo, UserIdentifier& pod)
26 | {
27 | fillFromJson(jo.take("type"_L1), pod.type);
28 | fromJson(jo, pod.additionalProperties);
29 | }
30 | };
31 |
32 | } // namespace Quotient
33 |
--------------------------------------------------------------------------------
/Quotient/jobs/syncjob.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2016 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "../csapi/definitions/sync_filter.h"
7 | #include "../syncdata.h"
8 | #include "basejob.h"
9 |
10 | namespace Quotient {
11 | class QUOTIENT_API SyncJob : public BaseJob {
12 | public:
13 | static constexpr auto defaultTimeout = std::chrono::seconds(30);
14 | static constexpr auto defaultTimeoutMillis =
15 | std::chrono::milliseconds(defaultTimeout).count();
16 |
17 | explicit SyncJob(const QString& since = {}, const QString& filter = {},
18 | int timeout = defaultTimeoutMillis, const QString& presence = {});
19 | explicit SyncJob(const QString& since, const Filter& filter, int timeout = defaultTimeoutMillis,
20 | const QString& presence = {});
21 |
22 | SyncData takeData() { return std::move(d); }
23 |
24 | protected:
25 | Status prepareResult() override;
26 |
27 | private:
28 | SyncData d;
29 | };
30 | } // namespace Quotient
31 |
--------------------------------------------------------------------------------
/.github/workflows/static.yml:
--------------------------------------------------------------------------------
1 | name: Deploy docs to Github pages
2 |
3 | on:
4 | push:
5 | branches: ["dev"]
6 |
7 | workflow_dispatch:
8 |
9 | permissions:
10 | contents: read
11 | pages: write
12 | id-token: write
13 |
14 | concurrency:
15 | group: "pages"
16 | cancel-in-progress: false
17 |
18 | jobs:
19 | deploy:
20 | environment:
21 | name: github-pages
22 | url: ${{ steps.deployment.outputs.page_url }}
23 | runs-on: ubuntu-latest
24 | steps:
25 | - name: Install doxygen
26 | run: sudo apt-get -qq install doxygen graphviz
27 | - name: Checkout
28 | uses: actions/checkout@v4
29 | - name: Update submodules
30 | run: git submodule update --init
31 | - name: Build docs
32 | run: doxygen
33 | - name: Setup Pages
34 | uses: actions/configure-pages@v5
35 | - name: Upload artifact
36 | uses: actions/upload-pages-artifact@v3
37 | with:
38 | path: 'html'
39 | - name: Deploy to GitHub Pages
40 | id: deployment
41 | uses: actions/deploy-pages@v4
42 |
--------------------------------------------------------------------------------
/Quotient/csapi/peeking_events.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "peeking_events.h"
4 |
5 | using namespace Quotient;
6 |
7 | auto queryToPeekEvents(const QString& from, std::optional timeout, const QString& roomId)
8 | {
9 | QUrlQuery _q;
10 | addParam(_q, u"from"_s, from);
11 | addParam(_q, u"timeout"_s, timeout);
12 | addParam(_q, u"room_id"_s, roomId);
13 | return _q;
14 | }
15 |
16 | QUrl PeekEventsJob::makeRequestUrl(const HomeserverData& hsData, const QString& from,
17 | std::optional timeout, const QString& roomId)
18 | {
19 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/events"),
20 | queryToPeekEvents(from, timeout, roomId));
21 | }
22 |
23 | PeekEventsJob::PeekEventsJob(const QString& from, std::optional timeout, const QString& roomId)
24 | : BaseJob(HttpVerb::Get, u"PeekEventsJob"_s, makePath("/_matrix/client/v3", "/events"),
25 | queryToPeekEvents(from, timeout, roomId))
26 | {}
27 |
--------------------------------------------------------------------------------
/Quotient/events/roomcreateevent.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2019 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "roomcreateevent.h"
5 |
6 | using namespace Quotient;
7 |
8 | bool RoomCreateEvent::isFederated() const
9 | {
10 | return contentPart("m.federate"_L1);
11 | }
12 |
13 | QString RoomCreateEvent::version() const
14 | {
15 | return contentPart("room_version"_L1);
16 | }
17 |
18 | RoomCreateEvent::Predecessor RoomCreateEvent::predecessor() const
19 | {
20 | const auto predJson = contentPart("predecessor"_L1);
21 | return { fromJson(predJson[RoomIdKey]),
22 | fromJson(predJson[EventIdKey]) };
23 | }
24 |
25 | bool RoomCreateEvent::isUpgrade() const
26 | {
27 | return contentJson().contains("predecessor"_L1);
28 | }
29 |
30 | RoomType RoomCreateEvent::roomType() const
31 | {
32 | return contentPart("type"_L1);
33 | }
34 |
35 | QStringList RoomCreateEvent::additionalCreators() const
36 | {
37 | return contentPart("additional_creators"_L1);
38 | }
39 |
--------------------------------------------------------------------------------
/Quotient/csapi/registration_tokens.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "registration_tokens.h"
4 |
5 | using namespace Quotient;
6 |
7 | auto queryToRegistrationTokenValidity(const QString& token)
8 | {
9 | QUrlQuery _q;
10 | addParam(_q, u"token"_s, token);
11 | return _q;
12 | }
13 |
14 | QUrl RegistrationTokenValidityJob::makeRequestUrl(const HomeserverData& hsData, const QString& token)
15 | {
16 | return BaseJob::makeRequestUrl(hsData,
17 | makePath("/_matrix/client/v1",
18 | "/register/m.login.registration_token/validity"),
19 | queryToRegistrationTokenValidity(token));
20 | }
21 |
22 | RegistrationTokenValidityJob::RegistrationTokenValidityJob(const QString& token)
23 | : BaseJob(HttpVerb::Get, u"RegistrationTokenValidityJob"_s,
24 | makePath("/_matrix/client/v1", "/register/m.login.registration_token/validity"),
25 | queryToRegistrationTokenValidity(token), {}, false)
26 | {
27 | addExpectedKey(u"valid"_s);
28 | }
29 |
--------------------------------------------------------------------------------
/Quotient/csapi/presence.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "presence.h"
4 |
5 | using namespace Quotient;
6 |
7 | SetPresenceJob::SetPresenceJob(const QString& userId, const QString& presence,
8 | const QString& statusMsg)
9 | : BaseJob(HttpVerb::Put, u"SetPresenceJob"_s,
10 | makePath("/_matrix/client/v3", "/presence/", userId, "/status"))
11 | {
12 | QJsonObject _dataJson;
13 | addParam(_dataJson, "presence"_L1, presence);
14 | addParam(_dataJson, "status_msg"_L1, statusMsg);
15 | setRequestData({ _dataJson });
16 | }
17 |
18 | QUrl GetPresenceJob::makeRequestUrl(const HomeserverData& hsData, const QString& userId)
19 | {
20 | return BaseJob::makeRequestUrl(hsData,
21 | makePath("/_matrix/client/v3", "/presence/", userId, "/status"));
22 | }
23 |
24 | GetPresenceJob::GetPresenceJob(const QString& userId)
25 | : BaseJob(HttpVerb::Get, u"GetPresenceJob"_s,
26 | makePath("/_matrix/client/v3", "/presence/", userId, "/status"))
27 | {
28 | addExpectedKey(u"presence"_s);
29 | }
30 |
--------------------------------------------------------------------------------
/autotests/adjust-config.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | CMD=""
4 |
5 | $CMD sed -i 's/tls: false/tls: true/g' homeserver.yaml
6 |
7 | (
8 | cat <
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "roomevent.h"
7 | #include "eventrelation.h"
8 |
9 | namespace Quotient {
10 |
11 | class QUOTIENT_API ReactionEvent
12 | : public EventTemplate<
13 | ReactionEvent, RoomEvent,
14 | EventContent::SingleKeyValue> {
15 | public:
16 | QUO_EVENT(ReactionEvent, "m.reaction")
17 | static bool isValid(const QJsonObject& fullJson)
18 | {
19 | return fullJson[ContentKey][RelatesToKey][RelTypeKey].toString()
20 | == EventRelation::AnnotationType;
21 | }
22 |
23 | ReactionEvent(const QString& eventId, const QString& reactionKey)
24 | : EventTemplate(EventRelation::annotate(eventId, reactionKey))
25 | {}
26 |
27 | QString eventId() const { return content().value.eventId; }
28 | QString key() const { return content().value.key; }
29 |
30 | private:
31 | explicit ReactionEvent(const QJsonObject& json) : EventTemplate(json) {}
32 | };
33 |
34 | } // namespace Quotient
35 |
--------------------------------------------------------------------------------
/Quotient/application-service/definitions/location.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | struct QUOTIENT_API ThirdPartyLocation {
10 | //! An alias for a matrix room.
11 | QString alias;
12 |
13 | //! The protocol ID that the third-party location is a part of.
14 | QString protocol;
15 |
16 | //! Information used to identify this third-party location.
17 | QJsonObject fields;
18 | };
19 |
20 | template <>
21 | struct JsonObjectConverter {
22 | static void dumpTo(QJsonObject& jo, const ThirdPartyLocation& pod)
23 | {
24 | addParam(jo, "alias"_L1, pod.alias);
25 | addParam(jo, "protocol"_L1, pod.protocol);
26 | addParam(jo, "fields"_L1, pod.fields);
27 | }
28 | static void fillFrom(const QJsonObject& jo, ThirdPartyLocation& pod)
29 | {
30 | fillFromJson(jo.value("alias"_L1), pod.alias);
31 | fillFromJson(jo.value("protocol"_L1), pod.protocol);
32 | fillFromJson(jo.value("fields"_L1), pod.fields);
33 | }
34 | };
35 |
36 | } // namespace Quotient
37 |
--------------------------------------------------------------------------------
/Quotient/roomstateview.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2021 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "roomstateview.h"
5 |
6 | using namespace Quotient;
7 |
8 | const StateEvent* RoomStateView::get(const QString& evtType,
9 | const QString& stateKey) const
10 | {
11 | return value({ evtType, stateKey });
12 | }
13 |
14 | bool RoomStateView::contains(const QString& evtType,
15 | const QString& stateKey) const
16 | {
17 | return contains({ evtType, stateKey });
18 | }
19 |
20 | QJsonObject RoomStateView::contentJson(const QString& evtType,
21 | const QString& stateKey) const
22 | {
23 | return queryOr(evtType, stateKey, &Event::contentJson, QJsonObject());
24 | }
25 |
26 | const QVector RoomStateView::eventsOfType(
27 | const QString& evtType) const
28 | {
29 | auto vals = QVector();
30 | for (auto it = cbegin(); it != cend(); ++it)
31 | if (it.key().first == evtType)
32 | vals.append(it.value());
33 |
34 | return vals;
35 | }
36 |
--------------------------------------------------------------------------------
/gtad/define_models.mustache:
--------------------------------------------------------------------------------
1 | {{#models}}
2 | {{#model}}
3 | {{>structDefinition}}
4 |
5 | template <> struct JsonObjectConverter<{{name}}>
6 | {
7 | {{#in?}}
8 | static void dumpTo(QJsonObject& jo, const {{name}}& pod)
9 | { {{#propertyMap}}
10 | fillJson(jo, pod.{{nameCamelCase}});
11 | {{/propertyMap}}{{#parents}}
12 | fillJson<{{name}}>(jo, pod);
13 | {{/parents}}{{#vars}}
14 | addParam{{^required?}}{{/required?}}(jo, "{{baseName}}"_L1,
15 | pod.{{nameCamelCase}});
16 | {{/vars}}
17 | }
18 | {{/in?}}
19 | {{#out?}}
20 | static void fillFrom({{>maybeCrefJsonObject}} jo, {{name}}& pod)
21 | { {{#parents}}
22 | fillFromJson<{{qualifiedName}}>(jo, pod);
23 | {{/parents}}{{#vars}}
24 | fillFromJson(jo.{{>takeOrValue}}("{{baseName}}"_L1), pod.{{nameCamelCase}});
25 | {{/vars}}{{#propertyMap}}
26 | fromJson(jo, pod.{{nameCamelCase}});
27 | {{/propertyMap}}
28 | }
29 | {{/out?}}
30 | };
31 |
32 | {{/model}}
33 | {{/models}}
34 |
--------------------------------------------------------------------------------
/Quotient/application-service/definitions/user.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | struct QUOTIENT_API ThirdPartyUser {
10 | //! A Matrix User ID representing a third-party user.
11 | QString userid;
12 |
13 | //! The protocol ID that the third-party location is a part of.
14 | QString protocol;
15 |
16 | //! Information used to identify this third-party location.
17 | QJsonObject fields;
18 | };
19 |
20 | template <>
21 | struct JsonObjectConverter {
22 | static void dumpTo(QJsonObject& jo, const ThirdPartyUser& pod)
23 | {
24 | addParam(jo, "userid"_L1, pod.userid);
25 | addParam(jo, "protocol"_L1, pod.protocol);
26 | addParam(jo, "fields"_L1, pod.fields);
27 | }
28 | static void fillFrom(const QJsonObject& jo, ThirdPartyUser& pod)
29 | {
30 | fillFromJson(jo.value("userid"_L1), pod.userid);
31 | fillFromJson(jo.value("protocol"_L1), pod.protocol);
32 | fillFromJson(jo.value("fields"_L1), pod.fields);
33 | }
34 | };
35 |
36 | } // namespace Quotient
37 |
--------------------------------------------------------------------------------
/Quotient/jobs/downloadfilejob.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "basejob.h"
7 |
8 | namespace Quotient {
9 | struct EncryptedFileMetadata;
10 |
11 | class QUOTIENT_API DownloadFileJob : public BaseJob {
12 | public:
13 | static QUrl makeRequestUrl(const HomeserverData& hsData, const QUrl& mxcUri);
14 | static QUrl makeRequestUrl(const HomeserverData& hsData, const QString& serverName,
15 | const QString& mediaId);
16 |
17 | DownloadFileJob(QString serverName, QString mediaId, const QString& localFilename = {});
18 |
19 | DownloadFileJob(QString serverName, QString mediaId, const EncryptedFileMetadata& file,
20 | const QString& localFilename = {});
21 | QString targetFileName() const;
22 |
23 | private:
24 | class Private;
25 | ImplPtr d;
26 |
27 | void doPrepare(const ConnectionData* connectionData) override;
28 | void onSentRequest(QNetworkReply* reply) override;
29 | void beforeAbandon() override;
30 | Status prepareResult() override;
31 | };
32 | } // namespace Quotient
33 |
--------------------------------------------------------------------------------
/Quotient/logging_categories_p.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2017 Elvis Angelaccio
2 | // SPDX-FileCopyrightText: 2017 Kitsune Ral
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #pragma once
6 |
7 | #include
8 |
9 | #define QUO_LOGGING_CATEGORY(Name, Id) \
10 | inline Q_LOGGING_CATEGORY((Name), (Id), QtInfoMsg)
11 |
12 | namespace Quotient {
13 |
14 | QUO_LOGGING_CATEGORY(MAIN, "quotient.main")
15 | QUO_LOGGING_CATEGORY(EVENTS, "quotient.events")
16 | QUO_LOGGING_CATEGORY(STATE, "quotient.events.state")
17 | QUO_LOGGING_CATEGORY(MEMBERS, "quotient.events.members")
18 | QUO_LOGGING_CATEGORY(MESSAGES, "quotient.events.messages")
19 | QUO_LOGGING_CATEGORY(EPHEMERAL, "quotient.events.ephemeral")
20 | QUO_LOGGING_CATEGORY(E2EE, "quotient.e2ee")
21 | QUO_LOGGING_CATEGORY(JOBS, "quotient.jobs")
22 | QUO_LOGGING_CATEGORY(SYNCJOB, "quotient.jobs.sync")
23 | QUO_LOGGING_CATEGORY(THUMBNAILJOB, "quotient.jobs.thumbnail")
24 | QUO_LOGGING_CATEGORY(NETWORK, "quotient.network")
25 | QUO_LOGGING_CATEGORY(PROFILER, "quotient.profiler")
26 | QUO_LOGGING_CATEGORY(DATABASE, "quotient.database")
27 |
28 | } // namespace Quotient
29 |
30 |
--------------------------------------------------------------------------------
/Quotient/csapi/typing.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | //! \brief Informs the server that the user has started or stopped typing.
10 | //!
11 | //! This tells the server that the user is typing for the next N
12 | //! milliseconds where N is the value specified in the `timeout` key.
13 | //! Alternatively, if `typing` is `false`, it tells the server that the
14 | //! user has stopped typing.
15 | class QUOTIENT_API SetTypingJob : public BaseJob {
16 | public:
17 | //! \param userId
18 | //! The user who has started to type.
19 | //!
20 | //! \param roomId
21 | //! The room in which the user is typing.
22 | //!
23 | //! \param typing
24 | //! Whether the user is typing or not. If `false`, the `timeout`
25 | //! key can be omitted.
26 | //!
27 | //! \param timeout
28 | //! The length of time in milliseconds to mark this user as typing.
29 | explicit SetTypingJob(const QString& userId, const QString& roomId, bool typing,
30 | std::optional timeout = std::nullopt);
31 | };
32 |
33 | } // namespace Quotient
34 |
--------------------------------------------------------------------------------
/Quotient/e2ee/qolmmessage.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2021 Alexey Andreyev
2 | //
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #pragma once
6 |
7 | #include
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | namespace Quotient {
14 |
15 | /*! \brief A wrapper around an olm encrypted message
16 | *
17 | * This class encapsulates a Matrix olm encrypted message,
18 | * passed in either of 2 forms: a general message or a pre-key message.
19 | *
20 | * The class provides functions to get a type and the ciphertext.
21 | */
22 | class QUOTIENT_API QOlmMessage : public QByteArray {
23 | Q_GADGET
24 | public:
25 | enum Type {
26 | PreKey = OLM_MESSAGE_TYPE_PRE_KEY,
27 | General = OLM_MESSAGE_TYPE_MESSAGE,
28 | };
29 | Q_ENUM(Type)
30 |
31 | explicit QOlmMessage(QByteArray ciphertext, Type type = General);
32 |
33 | static QOlmMessage fromCiphertext(const QByteArray &ciphertext);
34 |
35 | Q_INVOKABLE Type type() const;
36 | Q_INVOKABLE QByteArray toCiphertext() const;
37 |
38 | private:
39 | Type m_messageType = General;
40 | };
41 |
42 | } //namespace Quotient
43 |
--------------------------------------------------------------------------------
/Quotient/events/roomkeyevent.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2019 Alexey Andreyev
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "event.h"
7 |
8 | namespace Quotient {
9 | class QUOTIENT_API RoomKeyEvent : public Event
10 | {
11 | public:
12 | QUO_EVENT(RoomKeyEvent, "m.room_key")
13 |
14 | using Event::Event;
15 | explicit RoomKeyEvent(const QString& algorithm, const QString& roomId,
16 | const QString& sessionId, const QString& sessionKey)
17 | : Event(basicJson(TypeId, {
18 | { "algorithm"_L1, algorithm },
19 | { "room_id"_L1, roomId },
20 | { "session_id"_L1, sessionId },
21 | { "session_key"_L1, sessionKey },
22 | }))
23 | {}
24 |
25 | QUO_CONTENT_GETTER(QString, algorithm)
26 | QUO_CONTENT_GETTER(QString, roomId)
27 | QUO_CONTENT_GETTER(QString, sessionId)
28 | QByteArray sessionKey() const
29 | {
30 | return contentPart("session_key"_L1).toLatin1();
31 | }
32 | };
33 | } // namespace Quotient
34 |
--------------------------------------------------------------------------------
/Quotient/csapi/to_device.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | //! \brief Send an event to a given set of devices.
10 | //!
11 | //! This endpoint is used to send send-to-device events to a set of
12 | //! client devices.
13 | class QUOTIENT_API SendToDeviceJob : public BaseJob {
14 | public:
15 | //! \param eventType
16 | //! The type of event to send.
17 | //!
18 | //! \param txnId
19 | //! The [transaction ID](/client-server-api/#transaction-identifiers) for this event. Clients
20 | //! should generate an ID unique across requests with the same access token; it will be used
21 | //! by the server to ensure idempotency of requests.
22 | //!
23 | //! \param messages
24 | //! The messages to send. A map from user ID, to a map from
25 | //! device ID to message body. The device ID may also be `*`,
26 | //! meaning all known devices for the user.
27 | explicit SendToDeviceJob(const QString& eventType, const QString& txnId,
28 | const QHash>& messages);
29 | };
30 |
31 | } // namespace Quotient
32 |
--------------------------------------------------------------------------------
/Quotient/jobs/requestdata.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "requestdata.h"
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | using namespace Quotient;
14 |
15 | auto bufferFromData(const QByteArray& data)
16 | {
17 | auto source = makeImpl();
18 | source->setData(data);
19 | source->open(QIODevice::ReadOnly);
20 | return source;
21 | }
22 |
23 | template
24 | requires std::constructible_from
25 | inline auto bufferFromJson(const JsonDataT& jdata)
26 | {
27 | return bufferFromData(QJsonDocument(jdata).toJson(QJsonDocument::Compact));
28 | }
29 |
30 | RequestData::RequestData(const QByteArray& a) : _source(bufferFromData(a)) {}
31 |
32 | RequestData::RequestData(const QJsonObject& jo) : _source(bufferFromJson(jo)) {}
33 |
34 | RequestData::RequestData(const QJsonArray& ja) : _source(bufferFromJson(ja)) {}
35 |
36 | RequestData::RequestData(QIODevice* source)
37 | : _source(acquireImpl(source))
38 | {}
39 |
--------------------------------------------------------------------------------
/Quotient/csapi/notifications.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "notifications.h"
4 |
5 | using namespace Quotient;
6 |
7 | auto queryToGetNotifications(const QString& from, std::optional limit, const QString& only)
8 | {
9 | QUrlQuery _q;
10 | addParam(_q, u"from"_s, from);
11 | addParam(_q, u"limit"_s, limit);
12 | addParam(_q, u"only"_s, only);
13 | return _q;
14 | }
15 |
16 | QUrl GetNotificationsJob::makeRequestUrl(const HomeserverData& hsData, const QString& from,
17 | std::optional limit, const QString& only)
18 | {
19 | return BaseJob::makeRequestUrl(hsData, makePath("/_matrix/client/v3", "/notifications"),
20 | queryToGetNotifications(from, limit, only));
21 | }
22 |
23 | GetNotificationsJob::GetNotificationsJob(const QString& from, std::optional limit,
24 | const QString& only)
25 | : BaseJob(HttpVerb::Get, u"GetNotificationsJob"_s,
26 | makePath("/_matrix/client/v3", "/notifications"),
27 | queryToGetNotifications(from, limit, only))
28 | {
29 | addExpectedKey(u"notifications"_s);
30 | }
31 |
--------------------------------------------------------------------------------
/Quotient/csapi/room_event_by_timestamp.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "room_event_by_timestamp.h"
4 |
5 | using namespace Quotient;
6 |
7 | auto queryToGetEventByTimestamp(int ts, const QString& dir)
8 | {
9 | QUrlQuery _q;
10 | addParam(_q, u"ts"_s, ts);
11 | addParam(_q, u"dir"_s, dir);
12 | return _q;
13 | }
14 |
15 | QUrl GetEventByTimestampJob::makeRequestUrl(const HomeserverData& hsData, const QString& roomId,
16 | int ts, const QString& dir)
17 | {
18 | return BaseJob::makeRequestUrl(hsData,
19 | makePath("/_matrix/client/v1", "/rooms/", roomId,
20 | "/timestamp_to_event"),
21 | queryToGetEventByTimestamp(ts, dir));
22 | }
23 |
24 | GetEventByTimestampJob::GetEventByTimestampJob(const QString& roomId, int ts, const QString& dir)
25 | : BaseJob(HttpVerb::Get, u"GetEventByTimestampJob"_s,
26 | makePath("/_matrix/client/v1", "/rooms/", roomId, "/timestamp_to_event"),
27 | queryToGetEventByTimestamp(ts, dir))
28 | {
29 | addExpectedKey(u"event_id"_s);
30 | addExpectedKey(u"origin_server_ts"_s);
31 | }
32 |
--------------------------------------------------------------------------------
/Quotient/csapi/kicking.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | //! \brief Kick a user from the room.
10 | //!
11 | //! Kick a user from the room.
12 | //!
13 | //! The caller must have the required power level in order to perform this operation.
14 | //!
15 | //! Kicking a user adjusts the target member's membership state to be `leave` with an
16 | //! optional `reason`. Like with other membership changes, a user can directly adjust
17 | //! the target member's state by making a request to `/rooms//state/m.room.member/`.
19 | class QUOTIENT_API KickJob : public BaseJob {
20 | public:
21 | //! \param roomId
22 | //! The room identifier (not alias) from which the user should be kicked.
23 | //!
24 | //! \param userId
25 | //! The fully qualified user ID of the user being kicked.
26 | //!
27 | //! \param reason
28 | //! The reason the user has been kicked. This will be supplied as the
29 | //! `reason` on the target's updated [`m.room.member`](/client-server-api/#mroommember) event.
30 | explicit KickJob(const QString& roomId, const QString& userId, const QString& reason = {});
31 | };
32 |
33 | } // namespace Quotient
34 |
--------------------------------------------------------------------------------
/Quotient/events/stateevent.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2018 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #include "stateevent.h"
5 |
6 | using namespace Quotient;
7 |
8 | StateEvent::StateEvent(const QJsonObject& json)
9 | : RoomEvent(json)
10 | {
11 | Q_ASSERT_X(json.contains(StateKeyKey), __FUNCTION__,
12 | "Attempt to create a state event without state key");
13 | }
14 |
15 | StateEvent::StateEvent(event_type_t type, const QString& stateKey,
16 | const QJsonObject& contentJson)
17 | : RoomEvent(basicJson(type, stateKey, contentJson))
18 | {}
19 |
20 | bool StateEvent::repeatsState() const
21 | {
22 | return contentJson() == unsignedPart(PrevContentKey);
23 | }
24 |
25 | QString StateEvent::replacedState() const
26 | {
27 | return unsignedPart("replaces_state"_L1);
28 | }
29 |
30 | void StateEvent::dumpTo(QDebug dbg) const
31 | {
32 | if (!stateKey().isEmpty())
33 | dbg << '<' << stateKey() << "> ";
34 | if (const auto prevContentJson = unsignedPart(PrevContentKey);
35 | !prevContentJson.isEmpty())
36 | dbg << QJsonDocument(prevContentJson).toJson(QJsonDocument::Compact)
37 | << " -> ";
38 | RoomEvent::dumpTo(dbg);
39 | }
40 |
--------------------------------------------------------------------------------
/Quotient/csapi/cross_signing.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "cross_signing.h"
4 |
5 | using namespace Quotient;
6 |
7 | UploadCrossSigningKeysJob::UploadCrossSigningKeysJob(
8 | const std::optional& masterKey,
9 | const std::optional& selfSigningKey,
10 | const std::optional& userSigningKey,
11 | const std::optional& auth)
12 | : BaseJob(HttpVerb::Post, u"UploadCrossSigningKeysJob"_s,
13 | makePath("/_matrix/client/v3", "/keys/device_signing/upload"))
14 | {
15 | QJsonObject _dataJson;
16 | addParam(_dataJson, "master_key"_L1, masterKey);
17 | addParam(_dataJson, "self_signing_key"_L1, selfSigningKey);
18 | addParam(_dataJson, "user_signing_key"_L1, userSigningKey);
19 | addParam(_dataJson, "auth"_L1, auth);
20 | setRequestData({ _dataJson });
21 | }
22 |
23 | UploadCrossSigningSignaturesJob::UploadCrossSigningSignaturesJob(
24 | const QHash>& signatures)
25 | : BaseJob(HttpVerb::Post, u"UploadCrossSigningSignaturesJob"_s,
26 | makePath("/_matrix/client/v3", "/keys/signatures/upload"))
27 | {
28 | setRequestData({ toJson(signatures) });
29 | }
30 |
--------------------------------------------------------------------------------
/Quotient/csapi/event_context.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "event_context.h"
4 |
5 | using namespace Quotient;
6 |
7 | auto queryToGetEventContext(std::optional limit, const QString& filter)
8 | {
9 | QUrlQuery _q;
10 | addParam(_q, u"limit"_s, limit);
11 | addParam(_q, u"filter"_s, filter);
12 | return _q;
13 | }
14 |
15 | QUrl GetEventContextJob::makeRequestUrl(const HomeserverData& hsData, const QString& roomId,
16 | const QString& eventId, std::optional limit,
17 | const QString& filter)
18 | {
19 | return BaseJob::makeRequestUrl(hsData,
20 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/context/",
21 | eventId),
22 | queryToGetEventContext(limit, filter));
23 | }
24 |
25 | GetEventContextJob::GetEventContextJob(const QString& roomId, const QString& eventId,
26 | std::optional limit, const QString& filter)
27 | : BaseJob(HttpVerb::Get, u"GetEventContextJob"_s,
28 | makePath("/_matrix/client/v3", "/rooms/", roomId, "/context/", eventId),
29 | queryToGetEventContext(limit, filter))
30 | {}
31 |
--------------------------------------------------------------------------------
/Quotient/keyimport.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2024 Tobias Fella
2 | // SPDX-License-Identifier: LGPL-2.0-or-later
3 |
4 | #pragma once
5 |
6 | #include "expected.h" // Only here to not break client code still using Expected
7 | #include "quotient_export.h"
8 |
9 | #include
10 |
11 | class TestKeyImport;
12 |
13 | namespace Quotient
14 | {
15 | class Connection;
16 | }
17 |
18 | namespace Quotient
19 | {
20 |
21 | class QUOTIENT_API KeyImport : public QObject
22 | {
23 | Q_OBJECT
24 |
25 | public:
26 | enum Error {
27 | Success,
28 | InvalidPassphrase,
29 | InvalidData,
30 | OtherError,
31 | };
32 | Q_ENUM(Error)
33 |
34 | using QObject::QObject;
35 |
36 | Q_INVOKABLE Error importKeys(QString data, const QString& passphrase,
37 | const Quotient::Connection* connection);
38 | Q_INVOKABLE std::expected exportKeys(const QString& passphrase,
39 | const Quotient::Connection* connection);
40 |
41 | friend class ::TestKeyImport;
42 |
43 | private:
44 | std::expected decrypt(QString data, const QString& passphrase);
45 | std::expected encrypt(QJsonArray sessions, const QString& passphrase);
46 | };
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/Quotient/events/encryptionevent.cpp:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2017 Kitsune Ral
2 | // SPDX-FileCopyrightText: 2019 Alexey Andreyev
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #include "encryptionevent.h"
6 |
7 | #include "../e2ee/e2ee_common.h"
8 |
9 | using namespace Quotient;
10 |
11 | EncryptionEventContent::EncryptionEventContent(const QJsonObject& json)
12 | : encryption(fromJson(json[AlgorithmKeyL]))
13 | , algorithm(sanitized(json[AlgorithmKeyL].toString()))
14 | {
15 | // NB: fillFromJson only fills the variable if the JSON key exists
16 | fillFromJson(json[RotationPeriodMsKeyL], rotationPeriodMs);
17 | fillFromJson(json[RotationPeriodMsgsKeyL], rotationPeriodMsgs);
18 | }
19 |
20 | EncryptionEventContent::EncryptionEventContent(Quotient::EncryptionType et)
21 | : encryption(et)
22 | {
23 | if(encryption != Quotient::EncryptionType::Undefined) {
24 | algorithm = Quotient::toJson(encryption);
25 | }
26 | }
27 |
28 | QJsonObject EncryptionEventContent::toJson() const
29 | {
30 | QJsonObject o;
31 | if (encryption != Quotient::EncryptionType::Undefined)
32 | o.insert(AlgorithmKey, algorithm);
33 | o.insert(RotationPeriodMsKey, rotationPeriodMs);
34 | o.insert(RotationPeriodMsgsKey, rotationPeriodMsgs);
35 | return o;
36 | }
37 |
--------------------------------------------------------------------------------
/Quotient/avatar.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2017 Kitsune Ral
2 | // SPDX-License-Identifier: LGPL-2.1-or-later
3 |
4 | #pragma once
5 |
6 | #include "util.h"
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | namespace Quotient {
15 | class Connection;
16 |
17 | class QUOTIENT_API Avatar {
18 | public:
19 | explicit Avatar(Connection* parent, const QUrl& url = {});
20 |
21 | #ifdef __cpp_lib_move_only_function // AppleClang 15 doesn't have it
22 | using get_callback_t = std::move_only_function;
23 | using upload_callback_t = std::move_only_function;
24 | #else
25 | using get_callback_t = std::function;
26 | using upload_callback_t = std::function;
27 | #endif
28 |
29 |
30 | QImage get(int dimension, get_callback_t callback) const;
31 | QImage get(int width, int height, get_callback_t callback) const;
32 |
33 | QFuture upload(const QString& fileName) const;
34 | QFuture upload(QIODevice* source) const;
35 |
36 | bool isEmpty() const;
37 | QString mediaId() const;
38 | QUrl url() const;
39 | bool updateUrl(const QUrl& newUrl);
40 |
41 | static bool isUrlValid(const QUrl& u);
42 |
43 | private:
44 | class Private;
45 | ImplPtr d;
46 | };
47 | } // namespace Quotient
48 |
--------------------------------------------------------------------------------
/quotest/.valgrind.supp:
--------------------------------------------------------------------------------
1 | {
2 | libc_dirty_free_on_exit
3 | Memcheck:Free
4 | fun:free
5 | fun:__libc_freeres
6 | fun:_vgnU_freeres
7 | fun:__run_exit_handlers
8 | fun:exit
9 | }
10 |
11 | {
12 | QAuthenticator
13 | Memcheck:Leak
14 | match-leak-kinds: possible
15 | ...
16 | fun:_ZN14QAuthenticator6detachEv
17 | }
18 |
19 | {
20 | QTimer
21 | Memcheck:Leak
22 | match-leak-kinds: possible
23 | fun:_Znwm
24 | fun:_ZN7QObjectC1EPS_
25 | fun:_ZN6QTimerC1EP7QObject
26 | }
27 |
28 | {
29 | QSslConfiguration
30 | Memcheck:Leak
31 | match-leak-kinds: possible
32 | fun:_Znwm
33 | ...
34 | fun:_ZN17QSslConfigurationC1Ev
35 | }
36 |
37 | {
38 | libcrypto_ASN1
39 | Memcheck:Leak
40 | match-leak-kinds: definite
41 | fun:malloc
42 | ...
43 | fun:ASN1_item_ex_d2i
44 | }
45 |
46 | {
47 | malloc_from_libcrypto
48 | Memcheck:Leak
49 | match-leak-kinds: possible
50 | fun:malloc
51 | fun:CRYPTO_malloc
52 | ...
53 | obj:/lib/x86_64-linux-gnu/libcrypto.so.*
54 | }
55 |
56 | {
57 | Slot_activation_from_QtNetwork
58 | Memcheck:Leak
59 | match-leak-kinds: definite
60 | fun:malloc
61 | fun:inflateInit2_
62 | obj:/*/*/*/libQt5Network.so.*
63 | ...
64 | fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
65 | ...
66 | fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
67 | obj:/*/*/*/libQt5Network.so.*
68 | }
--------------------------------------------------------------------------------
/Quotient/csapi/threads_list.cpp:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #include "threads_list.h"
4 |
5 | using namespace Quotient;
6 |
7 | auto queryToGetThreadRoots(const QString& include, std::optional limit, const QString& from)
8 | {
9 | QUrlQuery _q;
10 | addParam(_q, u"include"_s, include);
11 | addParam(_q, u"limit"_s, limit);
12 | addParam(_q, u"from"_s, from);
13 | return _q;
14 | }
15 |
16 | QUrl GetThreadRootsJob::makeRequestUrl(const HomeserverData& hsData, const QString& roomId,
17 | const QString& include, std::optional limit,
18 | const QString& from)
19 | {
20 | return BaseJob::makeRequestUrl(hsData,
21 | makePath("/_matrix/client/v1", "/rooms/", roomId, "/threads"),
22 | queryToGetThreadRoots(include, limit, from));
23 | }
24 |
25 | GetThreadRootsJob::GetThreadRootsJob(const QString& roomId, const QString& include,
26 | std::optional limit, const QString& from)
27 | : BaseJob(HttpVerb::Get, u"GetThreadRootsJob"_s,
28 | makePath("/_matrix/client/v1", "/rooms/", roomId, "/threads"),
29 | queryToGetThreadRoots(include, limit, from))
30 | {
31 | addExpectedKey(u"chunk"_s);
32 | }
33 |
--------------------------------------------------------------------------------
/Quotient/e2ee/qolmutility.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2021 Carl Schwan
2 | //
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #pragma once
6 |
7 | #include
8 |
9 | #include
10 |
11 | struct OlmUtility;
12 |
13 | namespace Quotient {
14 |
15 | //! Allows you to make use of crytographic hashing via SHA-2 and
16 | //! verifying ed25519 signatures.
17 | class QUOTIENT_API QOlmUtility
18 | {
19 | public:
20 | QOlmUtility();
21 |
22 | //! Returns a sha256 of the supplied byte slice.
23 | QString sha256Bytes(const QByteArray& inputBuf) const;
24 |
25 | //! Convenience function that converts the UTF-8 message
26 | //! to bytes and then calls `sha256Bytes()`, returning its output.
27 | QString sha256Utf8Msg(const QString& message) const;
28 |
29 | //! Verify a ed25519 signature.
30 | //! \param key QByteArray The public part of the ed25519 key that signed the message.
31 | //! \param message QByteArray The message that was signed.
32 | //! \param signature QByteArray The signature of the message.
33 | bool ed25519Verify(const QByteArray& key, const QByteArray& message,
34 | QByteArray signature) const;
35 |
36 | OlmErrorCode lastErrorCode() const;
37 | const char* lastError() const;
38 |
39 | private:
40 | CStructPtr olmDataHolder;
41 | };
42 | } // namespace Quotient
43 |
--------------------------------------------------------------------------------
/Quotient/csapi/read_markers.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 |
9 | //! \brief Set the position of the read marker for a room.
10 | //!
11 | //! Sets the position of the read marker for a given room, and optionally
12 | //! the read receipt's location.
13 | class QUOTIENT_API SetReadMarkerJob : public BaseJob {
14 | public:
15 | //! \param roomId
16 | //! The room ID to set the read marker in for the user.
17 | //!
18 | //! \param fullyRead
19 | //! The event ID the read marker should be located at. The
20 | //! event MUST belong to the room.
21 | //!
22 | //! \param read
23 | //! The event ID to set the read receipt location at. This is
24 | //! equivalent to calling `/receipt/m.read/$elsewhere:example.org`
25 | //! and is provided here to save that extra call.
26 | //!
27 | //! \param readPrivate
28 | //! The event ID to set the *private* read receipt location at. This
29 | //! equivalent to calling `/receipt/m.read.private/$elsewhere:example.org`
30 | //! and is provided here to save that extra call.
31 | explicit SetReadMarkerJob(const QString& roomId, const QString& fullyRead = {},
32 | const QString& read = {}, const QString& readPrivate = {});
33 | };
34 |
35 | } // namespace Quotient
36 |
--------------------------------------------------------------------------------
/Quotient/csapi/definitions/push_ruleset.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | #include
8 |
9 | namespace Quotient {
10 |
11 | struct QUOTIENT_API PushRuleset {
12 | QVector content{};
13 |
14 | QVector override{};
15 |
16 | QVector room{};
17 |
18 | QVector sender{};
19 |
20 | QVector underride{};
21 | };
22 |
23 | template <>
24 | struct JsonObjectConverter {
25 | static void dumpTo(QJsonObject& jo, const PushRuleset& pod)
26 | {
27 | addParam(jo, "content"_L1, pod.content);
28 | addParam(jo, "override"_L1, pod.override);
29 | addParam(jo, "room"_L1, pod.room);
30 | addParam(jo, "sender"_L1, pod.sender);
31 | addParam(jo, "underride"_L1, pod.underride);
32 | }
33 | static void fillFrom(const QJsonObject& jo, PushRuleset& pod)
34 | {
35 | fillFromJson(jo.value("content"_L1), pod.content);
36 | fillFromJson(jo.value("override"_L1), pod.override);
37 | fillFromJson(jo.value("room"_L1), pod.room);
38 | fillFromJson(jo.value("sender"_L1), pod.sender);
39 | fillFromJson(jo.value("underride"_L1), pod.underride);
40 | }
41 | };
42 |
43 | } // namespace Quotient
44 |
--------------------------------------------------------------------------------
/Quotient/events/encryptionevent.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2017 Kitsune Ral
2 | // SPDX-FileCopyrightText: 2019 Alexey Andreyev
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #pragma once
6 |
7 | #include
8 | #include "stateevent.h"
9 |
10 | namespace Quotient {
11 | class QUOTIENT_API EncryptionEventContent {
12 | public:
13 | Q_IMPLICIT EncryptionEventContent(Quotient::EncryptionType et);
14 | explicit EncryptionEventContent(const QJsonObject& json);
15 |
16 | QJsonObject toJson() const;
17 |
18 | Quotient::EncryptionType encryption;
19 | QString algorithm {};
20 | int rotationPeriodMs = 604'800'000;
21 | int rotationPeriodMsgs = 100;
22 | };
23 |
24 | class QUOTIENT_API EncryptionEvent
25 | : public KeylessStateEventBase {
26 | public:
27 | QUO_EVENT(EncryptionEvent, "m.room.encryption")
28 |
29 | using KeylessStateEventBase::KeylessStateEventBase;
30 |
31 | Quotient::EncryptionType encryption() const { return content().encryption; }
32 | QString algorithm() const { return content().algorithm; }
33 | int rotationPeriodMs() const { return content().rotationPeriodMs; }
34 | int rotationPeriodMsgs() const { return content().rotationPeriodMsgs; }
35 |
36 | bool useEncryption() const { return !algorithm().isEmpty(); }
37 | };
38 | } // namespace Quotient
39 |
--------------------------------------------------------------------------------
/Quotient/connectiondata.h:
--------------------------------------------------------------------------------
1 | // SPDX-FileCopyrightText: 2015 Felix Rohrbach
2 | // SPDX-FileCopyrightText: 2016 Kitsune Ral
3 | // SPDX-License-Identifier: LGPL-2.1-or-later
4 |
5 | #pragma once
6 |
7 | #include "util.h"
8 |
9 | #include
10 |
11 | #include
12 |
13 | namespace Quotient {
14 |
15 | class NetworkAccessManager;
16 | class BaseJob;
17 |
18 | class QUOTIENT_API ConnectionData {
19 | public:
20 | explicit ConnectionData(QUrl baseUrl);
21 | Q_DISABLE_COPY_MOVE(ConnectionData)
22 | virtual ~ConnectionData();
23 |
24 | void submit(BaseJob* job);
25 | void limitRate(std::chrono::milliseconds nextCallAfter);
26 |
27 | QByteArray accessToken() const;
28 | QUrl baseUrl() const;
29 | const QString& deviceId() const;
30 | const QString& userId() const;
31 | HomeserverData homeserverData() const;
32 | Quotient::NetworkAccessManager *nam() const;
33 |
34 | void setBaseUrl(QUrl baseUrl);
35 | void setIdentity(const QString& userId, const QString& deviceId, QByteArray accessToken = {});
36 | void setAccessToken(QByteArray accessToken);
37 | void setSupportedSpecVersions(QStringList versions);
38 |
39 | QString lastEvent() const;
40 | void setLastEvent(QString identifier);
41 |
42 | QString generateTxnId() const;
43 |
44 | private:
45 | class Private;
46 | ImplPtr d;
47 | };
48 | } // namespace Quotient
49 |
--------------------------------------------------------------------------------
/Quotient/csapi/definitions/auth_data.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | namespace Quotient {
8 | //! Used by clients to submit authentication information to the interactive-authentication API
9 | struct QUOTIENT_API AuthenticationData {
10 | //! The authentication type that the client is attempting to complete.
11 | //! May be omitted if `session` is given, and the client is reissuing a
12 | //! request which it believes has been completed out-of-band (for example,
13 | //! via the [fallback mechanism](#fallback)).
14 | QString type{};
15 |
16 | //! The value of the session key given by the homeserver.
17 | QString session{};
18 |
19 | //! Keys dependent on the login type
20 | QVariantHash authInfo{};
21 | };
22 |
23 | template <>
24 | struct JsonObjectConverter {
25 | static void dumpTo(QJsonObject& jo, const AuthenticationData& pod)
26 | {
27 | fillJson(jo, pod.authInfo);
28 | addParam(jo, "type"_L1, pod.type);
29 | addParam(jo, "session"_L1, pod.session);
30 | }
31 | static void fillFrom(QJsonObject jo, AuthenticationData& pod)
32 | {
33 | fillFromJson(jo.take("type"_L1), pod.type);
34 | fillFromJson(jo.take("session"_L1), pod.session);
35 | fromJson(jo, pod.authInfo);
36 | }
37 | };
38 |
39 | } // namespace Quotient
40 |
--------------------------------------------------------------------------------
/Quotient/csapi/definitions/wellknown/full.h:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
2 |
3 | #pragma once
4 |
5 | #include
6 | #include