aboutsummaryrefslogtreecommitdiff
path: root/lib/csapi
diff options
context:
space:
mode:
authorn-peugnet <n.peugnet@free.fr>2022-10-06 19:27:24 +0200
committern-peugnet <n.peugnet@free.fr>2022-10-06 19:27:24 +0200
commit08632625e1a04257b5c7d4a9db2246ac07436748 (patch)
tree9ddadf219a7e352ddd3549ad1683282c944adfb6 /lib/csapi
parente9c2e2a26d3711e755aa5eb8a8478917c71d612b (diff)
parentd911b207f49e936b3e992200796110f0749ed150 (diff)
downloadlibquotient-08632625e1a04257b5c7d4a9db2246ac07436748.tar.gz
libquotient-08632625e1a04257b5c7d4a9db2246ac07436748.zip
Update upstream source from tag 'upstream/0.7.0'
Update to upstream version '0.7.0' with Debian dir 30dcb77a77433e4a54eab77c0b82ae925dead2d8
Diffstat (limited to 'lib/csapi')
-rw-r--r--lib/csapi/account-data.cpp32
-rw-r--r--lib/csapi/account-data.h69
-rw-r--r--lib/csapi/admin.cpp8
-rw-r--r--lib/csapi/admin.h2
-rw-r--r--lib/csapi/administrative_contact.cpp79
-rw-r--r--lib/csapi/administrative_contact.h42
-rw-r--r--lib/csapi/appservice_room_directory.cpp20
-rw-r--r--lib/csapi/appservice_room_directory.h8
-rw-r--r--lib/csapi/banning.cpp25
-rw-r--r--lib/csapi/banning.h11
-rw-r--r--lib/csapi/capabilities.cpp9
-rw-r--r--lib/csapi/capabilities.h2
-rw-r--r--lib/csapi/content-repo.cpp64
-rw-r--r--lib/csapi/content-repo.h26
-rw-r--r--lib/csapi/create_room.cpp34
-rw-r--r--lib/csapi/create_room.h48
-rw-r--r--lib/csapi/cross_signing.cpp33
-rw-r--r--lib/csapi/cross_signing.h78
-rw-r--r--lib/csapi/definitions/auth_data.h7
-rw-r--r--lib/csapi/definitions/cross_signing_key.h47
-rw-r--r--lib/csapi/definitions/openid_token.h8
-rw-r--r--lib/csapi/definitions/public_rooms_response.h61
-rw-r--r--lib/csapi/definitions/push_condition.h4
-rw-r--r--lib/csapi/definitions/request_token_response.h2
-rw-r--r--lib/csapi/definitions/room_event_filter.h9
-rw-r--r--lib/csapi/definitions/wellknown/homeserver.h2
-rw-r--r--lib/csapi/definitions/wellknown/identity_server.h2
-rw-r--r--lib/csapi/device_management.cpp39
-rw-r--r--lib/csapi/device_management.h13
-rw-r--r--lib/csapi/directory.cpp32
-rw-r--r--lib/csapi/directory.h8
-rw-r--r--lib/csapi/event_context.cpp13
-rw-r--r--lib/csapi/event_context.h5
-rw-r--r--lib/csapi/filter.cpp15
-rw-r--r--lib/csapi/filter.h4
-rw-r--r--lib/csapi/inviting.cpp15
-rw-r--r--lib/csapi/inviting.h11
-rw-r--r--lib/csapi/joining.cpp28
-rw-r--r--lib/csapi/joining.h28
-rw-r--r--lib/csapi/keys.cpp48
-rw-r--r--lib/csapi/keys.h74
-rw-r--r--lib/csapi/kicking.cpp12
-rw-r--r--lib/csapi/kicking.h2
-rw-r--r--lib/csapi/knocking.cpp26
-rw-r--r--lib/csapi/knocking.h55
-rw-r--r--lib/csapi/leaving.cpp25
-rw-r--r--lib/csapi/leaving.h15
-rw-r--r--lib/csapi/list_joined_rooms.cpp9
-rw-r--r--lib/csapi/list_joined_rooms.h2
-rw-r--r--lib/csapi/list_public_rooms.cpp44
-rw-r--r--lib/csapi/list_public_rooms.h18
-rw-r--r--lib/csapi/login.cpp34
-rw-r--r--lib/csapi/login.h34
-rw-r--r--lib/csapi/logout.cpp14
-rw-r--r--lib/csapi/logout.h4
-rw-r--r--lib/csapi/message_pagination.cpp22
-rw-r--r--lib/csapi/message_pagination.h59
-rw-r--r--lib/csapi/notifications.cpp10
-rw-r--r--lib/csapi/notifications.h9
-rw-r--r--lib/csapi/openid.cpp8
-rw-r--r--lib/csapi/openid.h7
-rw-r--r--lib/csapi/peeking_events.cpp9
-rw-r--r--lib/csapi/peeking_events.h8
-rw-r--r--lib/csapi/presence.cpp20
-rw-r--r--lib/csapi/presence.h4
-rw-r--r--lib/csapi/profile.cpp44
-rw-r--r--lib/csapi/profile.h16
-rw-r--r--lib/csapi/pusher.cpp32
-rw-r--r--lib/csapi/pusher.h8
-rw-r--r--lib/csapi/pushrules.cpp83
-rw-r--r--lib/csapi/pushrules.h16
-rw-r--r--lib/csapi/read_markers.cpp18
-rw-r--r--lib/csapi/read_markers.h13
-rw-r--r--lib/csapi/receipts.cpp8
-rw-r--r--lib/csapi/receipts.h10
-rw-r--r--lib/csapi/redaction.cpp12
-rw-r--r--lib/csapi/redaction.h8
-rw-r--r--lib/csapi/refresh.cpp18
-rw-r--r--lib/csapi/refresh.h65
-rw-r--r--lib/csapi/registration.cpp87
-rw-r--r--lib/csapi/registration.h71
-rw-r--r--lib/csapi/registration_tokens.cpp33
-rw-r--r--lib/csapi/registration_tokens.h44
-rw-r--r--lib/csapi/relations.cpp118
-rw-r--r--lib/csapi/relations.h298
-rw-r--r--lib/csapi/report_content.cpp16
-rw-r--r--lib/csapi/report_content.h5
-rw-r--r--lib/csapi/room_send.cpp8
-rw-r--r--lib/csapi/room_send.h12
-rw-r--r--lib/csapi/room_state.cpp8
-rw-r--r--lib/csapi/room_state.h2
-rw-r--r--lib/csapi/room_upgrades.cpp11
-rw-r--r--lib/csapi/room_upgrades.h2
-rw-r--r--lib/csapi/rooms.cpp43
-rw-r--r--lib/csapi/rooms.h28
-rw-r--r--lib/csapi/search.cpp26
-rw-r--r--lib/csapi/search.h307
-rw-r--r--lib/csapi/space_hierarchy.cpp43
-rw-r--r--lib/csapi/space_hierarchy.h152
-rw-r--r--lib/csapi/sso_login_redirect.cpp33
-rw-r--r--lib/csapi/sso_login_redirect.h34
-rw-r--r--lib/csapi/tags.cpp32
-rw-r--r--lib/csapi/tags.h6
-rw-r--r--lib/csapi/third_party_lookup.cpp49
-rw-r--r--lib/csapi/third_party_lookup.h12
-rw-r--r--lib/csapi/third_party_membership.cpp17
-rw-r--r--lib/csapi/third_party_membership.h4
-rw-r--r--lib/csapi/threads_list.cpp37
-rw-r--r--lib/csapi/threads_list.h76
-rw-r--r--lib/csapi/to_device.cpp12
-rw-r--r--lib/csapi/to_device.h11
-rw-r--r--lib/csapi/typing.cpp14
-rw-r--r--lib/csapi/typing.h2
-rw-r--r--lib/csapi/users.cpp12
-rw-r--r--lib/csapi/users.h4
-rw-r--r--lib/csapi/versions.cpp7
-rw-r--r--lib/csapi/versions.h10
-rw-r--r--lib/csapi/voip.cpp9
-rw-r--r--lib/csapi/voip.h2
-rw-r--r--lib/csapi/wellknown.cpp7
-rw-r--r--lib/csapi/wellknown.h2
-rw-r--r--lib/csapi/whoami.cpp9
-rw-r--r--lib/csapi/whoami.h16
123 files changed, 2581 insertions, 1016 deletions
diff --git a/lib/csapi/account-data.cpp b/lib/csapi/account-data.cpp
index 6a40e908..8c71f6c5 100644
--- a/lib/csapi/account-data.cpp
+++ b/lib/csapi/account-data.cpp
@@ -4,31 +4,29 @@
#include "account-data.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SetAccountDataJob::SetAccountDataJob(const QString& userId, const QString& type,
const QJsonObject& content)
: BaseJob(HttpVerb::Put, QStringLiteral("SetAccountDataJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/account_data/" % type)
+ makePath("/_matrix/client/v3", "/user/", userId, "/account_data/",
+ type))
{
- setRequestData(Data(toJson(content)));
+ setRequestData({ toJson(content) });
}
QUrl GetAccountDataJob::makeRequestUrl(QUrl baseUrl, const QString& userId,
const QString& type)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0") % "/user/"
- % userId % "/account_data/" % type);
+ makePath("/_matrix/client/v3", "/user/",
+ userId, "/account_data/", type));
}
GetAccountDataJob::GetAccountDataJob(const QString& userId, const QString& type)
: BaseJob(HttpVerb::Get, QStringLiteral("GetAccountDataJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/account_data/" % type)
+ makePath("/_matrix/client/v3", "/user/", userId, "/account_data/",
+ type))
{}
SetAccountDataPerRoomJob::SetAccountDataPerRoomJob(const QString& userId,
@@ -36,10 +34,10 @@ SetAccountDataPerRoomJob::SetAccountDataPerRoomJob(const QString& userId,
const QString& type,
const QJsonObject& content)
: BaseJob(HttpVerb::Put, QStringLiteral("SetAccountDataPerRoomJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/rooms/" % roomId % "/account_data/" % type)
+ makePath("/_matrix/client/v3", "/user/", userId, "/rooms/",
+ roomId, "/account_data/", type))
{
- setRequestData(Data(toJson(content)));
+ setRequestData({ toJson(content) });
}
QUrl GetAccountDataPerRoomJob::makeRequestUrl(QUrl baseUrl,
@@ -48,15 +46,15 @@ QUrl GetAccountDataPerRoomJob::makeRequestUrl(QUrl baseUrl,
const QString& type)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/user/" % userId % "/rooms/" % roomId
- % "/account_data/" % type);
+ makePath("/_matrix/client/v3", "/user/",
+ userId, "/rooms/", roomId,
+ "/account_data/", type));
}
GetAccountDataPerRoomJob::GetAccountDataPerRoomJob(const QString& userId,
const QString& roomId,
const QString& type)
: BaseJob(HttpVerb::Get, QStringLiteral("GetAccountDataPerRoomJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/rooms/" % roomId % "/account_data/" % type)
+ makePath("/_matrix/client/v3", "/user/", userId, "/rooms/",
+ roomId, "/account_data/", type))
{}
diff --git a/lib/csapi/account-data.h b/lib/csapi/account-data.h
index 0c760e80..70d4e492 100644
--- a/lib/csapi/account-data.h
+++ b/lib/csapi/account-data.h
@@ -8,46 +8,47 @@
namespace Quotient {
-/*! \brief Set some account_data for the user.
+/*! \brief Set some account data for the user.
*
- * Set some account_data for the client. This config is only visible to the user
- * that set the account_data. The config will be synced to clients in the
- * top-level `account_data`.
+ * Set some account data for the client. This config is only visible to the user
+ * that set the account data. The config will be available to clients through
+ * the top-level `account_data` field in the homeserver response to
+ * [/sync](#get_matrixclientv3sync).
*/
-class SetAccountDataJob : public BaseJob {
+class QUOTIENT_API SetAccountDataJob : public BaseJob {
public:
- /*! \brief Set some account_data for the user.
+ /*! \brief Set some account data for the user.
*
* \param userId
- * The ID of the user to set account_data for. The access token must be
+ * The ID of the user to set account data for. The access token must be
* authorized to make requests for this user ID.
*
* \param type
- * The event type of the account_data to set. Custom types should be
+ * The event type of the account data to set. Custom types should be
* namespaced to avoid clashes.
*
* \param content
- * The content of the account_data
+ * The content of the account data.
*/
explicit SetAccountDataJob(const QString& userId, const QString& type,
const QJsonObject& content = {});
};
-/*! \brief Get some account_data for the user.
+/*! \brief Get some account data for the user.
*
- * Get some account_data for the client. This config is only visible to the user
- * that set the account_data.
+ * Get some account data for the client. This config is only visible to the user
+ * that set the account data.
*/
-class GetAccountDataJob : public BaseJob {
+class QUOTIENT_API GetAccountDataJob : public BaseJob {
public:
- /*! \brief Get some account_data for the user.
+ /*! \brief Get some account data for the user.
*
* \param userId
- * The ID of the user to get account_data for. The access token must be
+ * The ID of the user to get account data for. The access token must be
* authorized to make requests for this user ID.
*
* \param type
- * The event type of the account_data to get. Custom types should be
+ * The event type of the account data to get. Custom types should be
* namespaced to avoid clashes.
*/
explicit GetAccountDataJob(const QString& userId, const QString& type);
@@ -61,53 +62,53 @@ public:
const QString& type);
};
-/*! \brief Set some account_data for the user.
+/*! \brief Set some account data for the user that is specific to a room.
*
- * Set some account_data for the client on a given room. This config is only
- * visible to the user that set the account_data. The config will be synced to
- * clients in the per-room `account_data`.
+ * Set some account data for the client on a given room. This config is only
+ * visible to the user that set the account data. The config will be delivered
+ * to clients in the per-room entries via [/sync](#get_matrixclientv3sync).
*/
-class SetAccountDataPerRoomJob : public BaseJob {
+class QUOTIENT_API SetAccountDataPerRoomJob : public BaseJob {
public:
- /*! \brief Set some account_data for the user.
+ /*! \brief Set some account data for the user that is specific to a room.
*
* \param userId
- * The ID of the user to set account_data for. The access token must be
+ * The ID of the user to set account data for. The access token must be
* authorized to make requests for this user ID.
*
* \param roomId
- * The ID of the room to set account_data on.
+ * The ID of the room to set account data on.
*
* \param type
- * The event type of the account_data to set. Custom types should be
+ * The event type of the account data to set. Custom types should be
* namespaced to avoid clashes.
*
* \param content
- * The content of the account_data
+ * The content of the account data.
*/
explicit SetAccountDataPerRoomJob(const QString& userId,
const QString& roomId, const QString& type,
const QJsonObject& content = {});
};
-/*! \brief Get some account_data for the user.
+/*! \brief Get some account data for the user that is specific to a room.
*
- * Get some account_data for the client on a given room. This config is only
- * visible to the user that set the account_data.
+ * Get some account data for the client on a given room. This config is only
+ * visible to the user that set the account data.
*/
-class GetAccountDataPerRoomJob : public BaseJob {
+class QUOTIENT_API GetAccountDataPerRoomJob : public BaseJob {
public:
- /*! \brief Get some account_data for the user.
+ /*! \brief Get some account data for the user that is specific to a room.
*
* \param userId
- * The ID of the user to set account_data for. The access token must be
+ * The ID of the user to get account data for. The access token must be
* authorized to make requests for this user ID.
*
* \param roomId
- * The ID of the room to get account_data for.
+ * The ID of the room to get account data for.
*
* \param type
- * The event type of the account_data to get. Custom types should be
+ * The event type of the account data to get. Custom types should be
* namespaced to avoid clashes.
*/
explicit GetAccountDataPerRoomJob(const QString& userId,
diff --git a/lib/csapi/admin.cpp b/lib/csapi/admin.cpp
index 9619c441..322212db 100644
--- a/lib/csapi/admin.cpp
+++ b/lib/csapi/admin.cpp
@@ -4,18 +4,16 @@
#include "admin.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetWhoIsJob::makeRequestUrl(QUrl baseUrl, const QString& userId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/admin/whois/" % userId);
+ makePath("/_matrix/client/v3",
+ "/admin/whois/", userId));
}
GetWhoIsJob::GetWhoIsJob(const QString& userId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetWhoIsJob"),
- QStringLiteral("/_matrix/client/r0") % "/admin/whois/" % userId)
+ makePath("/_matrix/client/v3", "/admin/whois/", userId))
{}
diff --git a/lib/csapi/admin.h b/lib/csapi/admin.h
index 570bf24a..c53ddd7e 100644
--- a/lib/csapi/admin.h
+++ b/lib/csapi/admin.h
@@ -16,7 +16,7 @@ namespace Quotient {
* up, or by a server admin. Server-local administrator privileges are not
* specified in this document.
*/
-class GetWhoIsJob : public BaseJob {
+class QUOTIENT_API GetWhoIsJob : public BaseJob {
public:
// Inner data structures
diff --git a/lib/csapi/administrative_contact.cpp b/lib/csapi/administrative_contact.cpp
index fa4f475a..aa55d934 100644
--- a/lib/csapi/administrative_contact.cpp
+++ b/lib/csapi/administrative_contact.cpp
@@ -4,67 +4,64 @@
#include "administrative_contact.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetAccount3PIDsJob::makeRequestUrl(QUrl baseUrl)
{
- return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/account/3pid");
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl), makePath("/_matrix/client/v3", "/account/3pid"));
}
GetAccount3PIDsJob::GetAccount3PIDsJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetAccount3PIDsJob"),
- QStringLiteral("/_matrix/client/r0") % "/account/3pid")
+ makePath("/_matrix/client/v3", "/account/3pid"))
{}
Post3PIDsJob::Post3PIDsJob(const ThreePidCredentials& threePidCreds)
: BaseJob(HttpVerb::Post, QStringLiteral("Post3PIDsJob"),
- QStringLiteral("/_matrix/client/r0") % "/account/3pid")
+ makePath("/_matrix/client/v3", "/account/3pid"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("three_pid_creds"), threePidCreds);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("three_pid_creds"), threePidCreds);
+ setRequestData({ _dataJson });
}
Add3PIDJob::Add3PIDJob(const QString& clientSecret, const QString& sid,
const Omittable<AuthenticationData>& auth)
: BaseJob(HttpVerb::Post, QStringLiteral("Add3PIDJob"),
- QStringLiteral("/_matrix/client/r0") % "/account/3pid/add")
+ makePath("/_matrix/client/v3", "/account/3pid/add"))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
- addParam<>(_data, QStringLiteral("client_secret"), clientSecret);
- addParam<>(_data, QStringLiteral("sid"), sid);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("auth"), auth);
+ addParam<>(_dataJson, QStringLiteral("client_secret"), clientSecret);
+ addParam<>(_dataJson, QStringLiteral("sid"), sid);
+ setRequestData({ _dataJson });
}
Bind3PIDJob::Bind3PIDJob(const QString& clientSecret, const QString& idServer,
const QString& idAccessToken, const QString& sid)
: BaseJob(HttpVerb::Post, QStringLiteral("Bind3PIDJob"),
- QStringLiteral("/_matrix/client/r0") % "/account/3pid/bind")
+ makePath("/_matrix/client/v3", "/account/3pid/bind"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("client_secret"), clientSecret);
- addParam<>(_data, QStringLiteral("id_server"), idServer);
- addParam<>(_data, QStringLiteral("id_access_token"), idAccessToken);
- addParam<>(_data, QStringLiteral("sid"), sid);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("client_secret"), clientSecret);
+ addParam<>(_dataJson, QStringLiteral("id_server"), idServer);
+ addParam<>(_dataJson, QStringLiteral("id_access_token"), idAccessToken);
+ addParam<>(_dataJson, QStringLiteral("sid"), sid);
+ setRequestData({ _dataJson });
}
Delete3pidFromAccountJob::Delete3pidFromAccountJob(const QString& medium,
const QString& address,
const QString& idServer)
: BaseJob(HttpVerb::Post, QStringLiteral("Delete3pidFromAccountJob"),
- QStringLiteral("/_matrix/client/r0") % "/account/3pid/delete")
+ makePath("/_matrix/client/v3", "/account/3pid/delete"))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("id_server"), idServer);
- addParam<>(_data, QStringLiteral("medium"), medium);
- addParam<>(_data, QStringLiteral("address"), address);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("id_server"), idServer);
+ addParam<>(_dataJson, QStringLiteral("medium"), medium);
+ addParam<>(_dataJson, QStringLiteral("address"), address);
+ setRequestData({ _dataJson });
addExpectedKey("id_server_unbind_result");
}
@@ -72,32 +69,32 @@ Unbind3pidFromAccountJob::Unbind3pidFromAccountJob(const QString& medium,
const QString& address,
const QString& idServer)
: BaseJob(HttpVerb::Post, QStringLiteral("Unbind3pidFromAccountJob"),
- QStringLiteral("/_matrix/client/r0") % "/account/3pid/unbind")
+ makePath("/_matrix/client/v3", "/account/3pid/unbind"))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("id_server"), idServer);
- addParam<>(_data, QStringLiteral("medium"), medium);
- addParam<>(_data, QStringLiteral("address"), address);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("id_server"), idServer);
+ addParam<>(_dataJson, QStringLiteral("medium"), medium);
+ addParam<>(_dataJson, QStringLiteral("address"), address);
+ setRequestData({ _dataJson });
addExpectedKey("id_server_unbind_result");
}
RequestTokenTo3PIDEmailJob::RequestTokenTo3PIDEmailJob(
const EmailValidationData& body)
: BaseJob(HttpVerb::Post, QStringLiteral("RequestTokenTo3PIDEmailJob"),
- QStringLiteral("/_matrix/client/r0")
- % "/account/3pid/email/requestToken",
+ makePath("/_matrix/client/v3",
+ "/account/3pid/email/requestToken"),
false)
{
- setRequestData(Data(toJson(body)));
+ setRequestData({ toJson(body) });
}
RequestTokenTo3PIDMSISDNJob::RequestTokenTo3PIDMSISDNJob(
const MsisdnValidationData& body)
: BaseJob(HttpVerb::Post, QStringLiteral("RequestTokenTo3PIDMSISDNJob"),
- QStringLiteral("/_matrix/client/r0")
- % "/account/3pid/msisdn/requestToken",
+ makePath("/_matrix/client/v3",
+ "/account/3pid/msisdn/requestToken"),
false)
{
- setRequestData(Data(toJson(body)));
+ setRequestData({ toJson(body) });
}
diff --git a/lib/csapi/administrative_contact.h b/lib/csapi/administrative_contact.h
index e436971d..27334850 100644
--- a/lib/csapi/administrative_contact.h
+++ b/lib/csapi/administrative_contact.h
@@ -24,7 +24,7 @@ namespace Quotient {
* Identifiers in this list may be used by the homeserver as, for example,
* identifiers that it will accept to reset the user's account password.
*/
-class GetAccount3PIDsJob : public BaseJob {
+class QUOTIENT_API GetAccount3PIDsJob : public BaseJob {
public:
// Inner data structures
@@ -102,7 +102,7 @@ struct JsonObjectConverter<GetAccount3PIDsJob::ThirdPartyIdentifier> {
* This results in this endpoint being an equivalent to `/3pid/bind` rather
* than dual-purpose.
*/
-class Post3PIDsJob : public BaseJob {
+class QUOTIENT_API Post3PIDsJob : public BaseJob {
public:
// Inner data structures
@@ -128,6 +128,22 @@ public:
* The third party credentials to associate with the account.
*/
explicit Post3PIDsJob(const ThreePidCredentials& threePidCreds);
+
+ // Result properties
+
+ /// An optional field containing a URL where the client must
+ /// submit the validation token to, with identical parameters
+ /// to the Identity Service API's `POST
+ /// /validate/email/submitToken` endpoint (without the requirement
+ /// for an access token). The homeserver must send this token to the
+ /// user (if applicable), who should then be prompted to provide it
+ /// to the client.
+ ///
+ /// If this field is not present, the client can assume that
+ /// verification will happen without the client's involvement
+ /// provided the homeserver advertises this specification version
+ /// in the `/versions` response (ie: r0.5.0).
+ QUrl submitUrl() const { return loadFromJson<QUrl>("submit_url"_ls); }
};
template <>
@@ -154,7 +170,7 @@ struct JsonObjectConverter<Post3PIDsJob::ThreePidCredentials> {
* Homeservers should prevent the caller from adding a 3PID to their account if
* it has already been added to another user's account on the homeserver.
*/
-class Add3PIDJob : public BaseJob {
+class QUOTIENT_API Add3PIDJob : public BaseJob {
public:
/*! \brief Adds contact information to the user's account.
*
@@ -182,7 +198,7 @@ public:
*
* Homeservers should track successful binds so they can be unbound later.
*/
-class Bind3PIDJob : public BaseJob {
+class QUOTIENT_API Bind3PIDJob : public BaseJob {
public:
/*! \brief Binds a 3PID to the user's account through an Identity Service.
*
@@ -211,7 +227,7 @@ public:
* parameter because the homeserver is expected to sign the request to the
* identity server instead.
*/
-class Delete3pidFromAccountJob : public BaseJob {
+class QUOTIENT_API Delete3pidFromAccountJob : public BaseJob {
public:
/*! \brief Deletes a third party identifier from the user's account
*
@@ -235,7 +251,7 @@ public:
/// An indicator as to whether or not the homeserver was able to unbind
/// the 3PID from the identity server. `success` indicates that the
- /// indentity server has unbound the identifier whereas `no-support`
+ /// identity server has unbound the identifier whereas `no-support`
/// indicates that the identity server refuses to support the request
/// or the homeserver was not able to determine an identity server to
/// unbind from.
@@ -254,7 +270,7 @@ public:
* parameter because the homeserver is expected to sign the request to the
* identity server instead.
*/
-class Unbind3pidFromAccountJob : public BaseJob {
+class QUOTIENT_API Unbind3pidFromAccountJob : public BaseJob {
public:
/*! \brief Removes a user's third party identifier from an identity server.
*
@@ -295,12 +311,12 @@ public:
* be used to request validation tokens when adding an email address to an
* account. This API's parameters and response are identical to that of
* the
- * [`/register/email/requestToken`](/client-server-api/#post_matrixclientr0registeremailrequesttoken)
+ * [`/register/email/requestToken`](/client-server-api/#post_matrixclientv3registeremailrequesttoken)
* endpoint. The homeserver should validate
* the email itself, either by sending a validation email itself or by using
* a service it has control over.
*/
-class RequestTokenTo3PIDEmailJob : public BaseJob {
+class QUOTIENT_API RequestTokenTo3PIDEmailJob : public BaseJob {
public:
/*! \brief Begins the validation process for an email address for
* association with the user's account.
@@ -311,7 +327,7 @@ public:
* be used to request validation tokens when adding an email address to an
* account. This API's parameters and response are identical to that of
* the
- * [`/register/email/requestToken`](/client-server-api/#post_matrixclientr0registeremailrequesttoken)
+ * [`/register/email/requestToken`](/client-server-api/#post_matrixclientv3registeremailrequesttoken)
* endpoint. The homeserver should validate
* the email itself, either by sending a validation email itself or by
* using a service it has control over.
@@ -337,12 +353,12 @@ public:
* be used to request validation tokens when adding a phone number to an
* account. This API's parameters and response are identical to that of
* the
- * [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientr0registermsisdnrequesttoken)
+ * [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientv3registermsisdnrequesttoken)
* endpoint. The homeserver should validate
* the phone number itself, either by sending a validation message itself or by
* using a service it has control over.
*/
-class RequestTokenTo3PIDMSISDNJob : public BaseJob {
+class QUOTIENT_API RequestTokenTo3PIDMSISDNJob : public BaseJob {
public:
/*! \brief Begins the validation process for a phone number for association
* with the user's account.
@@ -353,7 +369,7 @@ public:
* be used to request validation tokens when adding a phone number to an
* account. This API's parameters and response are identical to that of
* the
- * [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientr0registermsisdnrequesttoken)
+ * [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientv3registermsisdnrequesttoken)
* endpoint. The homeserver should validate
* the phone number itself, either by sending a validation message itself
* or by using a service it has control over.
diff --git a/lib/csapi/appservice_room_directory.cpp b/lib/csapi/appservice_room_directory.cpp
index e8ec55bf..dff7e032 100644
--- a/lib/csapi/appservice_room_directory.cpp
+++ b/lib/csapi/appservice_room_directory.cpp
@@ -4,18 +4,18 @@
#include "appservice_room_directory.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
-UpdateAppserviceRoomDirectoryVsibilityJob::UpdateAppserviceRoomDirectoryVsibilityJob(
- const QString& networkId, const QString& roomId, const QString& visibility)
+UpdateAppserviceRoomDirectoryVisibilityJob::
+ UpdateAppserviceRoomDirectoryVisibilityJob(const QString& networkId,
+ const QString& roomId,
+ const QString& visibility)
: BaseJob(HttpVerb::Put,
- QStringLiteral("UpdateAppserviceRoomDirectoryVsibilityJob"),
- QStringLiteral("/_matrix/client/r0")
- % "/directory/list/appservice/" % networkId % "/" % roomId)
+ QStringLiteral("UpdateAppserviceRoomDirectoryVisibilityJob"),
+ makePath("/_matrix/client/v3", "/directory/list/appservice/",
+ networkId, "/", roomId))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("visibility"), visibility);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("visibility"), visibility);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/appservice_room_directory.h b/lib/csapi/appservice_room_directory.h
index 2631f38c..d6268979 100644
--- a/lib/csapi/appservice_room_directory.h
+++ b/lib/csapi/appservice_room_directory.h
@@ -21,7 +21,7 @@ namespace Quotient {
* instead of a typical client's access_token. This API cannot be invoked by
* users who are not identified as application services.
*/
-class UpdateAppserviceRoomDirectoryVsibilityJob : public BaseJob {
+class QUOTIENT_API UpdateAppserviceRoomDirectoryVisibilityJob : public BaseJob {
public:
/*! \brief Updates a room's visibility in the application service's room
* directory.
@@ -38,9 +38,9 @@ public:
* Whether the room should be visible (public) in the directory
* or not (private).
*/
- explicit UpdateAppserviceRoomDirectoryVsibilityJob(const QString& networkId,
- const QString& roomId,
- const QString& visibility);
+ explicit UpdateAppserviceRoomDirectoryVisibilityJob(
+ const QString& networkId, const QString& roomId,
+ const QString& visibility);
};
} // namespace Quotient
diff --git a/lib/csapi/banning.cpp b/lib/csapi/banning.cpp
index 8a8ec664..e04075b7 100644
--- a/lib/csapi/banning.cpp
+++ b/lib/csapi/banning.cpp
@@ -4,27 +4,26 @@
#include "banning.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
BanJob::BanJob(const QString& roomId, const QString& userId,
const QString& reason)
: BaseJob(HttpVerb::Post, QStringLiteral("BanJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId % "/ban")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/ban"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("user_id"), userId);
- addParam<IfNotEmpty>(_data, QStringLiteral("reason"), reason);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("user_id"), userId);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
}
-UnbanJob::UnbanJob(const QString& roomId, const QString& userId)
+UnbanJob::UnbanJob(const QString& roomId, const QString& userId,
+ const QString& reason)
: BaseJob(HttpVerb::Post, QStringLiteral("UnbanJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/unban")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/unban"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("user_id"), userId);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("user_id"), userId);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/banning.h b/lib/csapi/banning.h
index 48c054c2..e4c60ce3 100644
--- a/lib/csapi/banning.h
+++ b/lib/csapi/banning.h
@@ -18,7 +18,7 @@ namespace Quotient {
* The caller must have the required power level in order to perform this
* operation.
*/
-class BanJob : public BaseJob {
+class QUOTIENT_API BanJob : public BaseJob {
public:
/*! \brief Ban a user in the room.
*
@@ -46,7 +46,7 @@ public:
* The caller must have the required power level in order to perform this
* operation.
*/
-class UnbanJob : public BaseJob {
+class QUOTIENT_API UnbanJob : public BaseJob {
public:
/*! \brief Unban a user from the room.
*
@@ -55,8 +55,13 @@ public:
*
* \param userId
* The fully qualified user ID of the user being unbanned.
+ *
+ * \param reason
+ * Optional reason to be included as the `reason` on the subsequent
+ * membership event.
*/
- explicit UnbanJob(const QString& roomId, const QString& userId);
+ explicit UnbanJob(const QString& roomId, const QString& userId,
+ const QString& reason = {});
};
} // namespace Quotient
diff --git a/lib/csapi/capabilities.cpp b/lib/csapi/capabilities.cpp
index 33a53cad..ca2a543f 100644
--- a/lib/csapi/capabilities.cpp
+++ b/lib/csapi/capabilities.cpp
@@ -4,20 +4,17 @@
#include "capabilities.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetCapabilitiesJob::makeRequestUrl(QUrl baseUrl)
{
- return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/capabilities");
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl), makePath("/_matrix/client/v3", "/capabilities"));
}
GetCapabilitiesJob::GetCapabilitiesJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetCapabilitiesJob"),
- QStringLiteral("/_matrix/client/r0") % "/capabilities")
+ makePath("/_matrix/client/v3", "/capabilities"))
{
addExpectedKey("capabilities");
}
diff --git a/lib/csapi/capabilities.h b/lib/csapi/capabilities.h
index da50c8c1..81b47cd4 100644
--- a/lib/csapi/capabilities.h
+++ b/lib/csapi/capabilities.h
@@ -13,7 +13,7 @@ namespace Quotient {
* Gets information about the server's supported feature set
* and other relevant capabilities.
*/
-class GetCapabilitiesJob : public BaseJob {
+class QUOTIENT_API GetCapabilitiesJob : public BaseJob {
public:
// Inner data structures
diff --git a/lib/csapi/content-repo.cpp b/lib/csapi/content-repo.cpp
index 7ae89739..6f6738af 100644
--- a/lib/csapi/content-repo.cpp
+++ b/lib/csapi/content-repo.cpp
@@ -4,13 +4,11 @@
#include "content-repo.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
auto queryToUploadContent(const QString& filename)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("filename"), filename);
return _q;
}
@@ -18,17 +16,17 @@ auto queryToUploadContent(const QString& filename)
UploadContentJob::UploadContentJob(QIODevice* content, const QString& filename,
const QString& contentType)
: BaseJob(HttpVerb::Post, QStringLiteral("UploadContentJob"),
- QStringLiteral("/_matrix/media/r0") % "/upload",
+ makePath("/_matrix/media/v3", "/upload"),
queryToUploadContent(filename))
{
setRequestHeader("Content-Type", contentType.toLatin1());
- setRequestData(Data(content));
+ setRequestData({ content });
addExpectedKey("content_uri");
}
auto queryToGetContent(bool allowRemote)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("allow_remote"), allowRemote);
return _q;
}
@@ -37,17 +35,16 @@ QUrl GetContentJob::makeRequestUrl(QUrl baseUrl, const QString& serverName,
const QString& mediaId, bool allowRemote)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/media/r0")
- % "/download/" % serverName % "/"
- % mediaId,
+ makePath("/_matrix/media/v3", "/download/",
+ serverName, "/", mediaId),
queryToGetContent(allowRemote));
}
GetContentJob::GetContentJob(const QString& serverName, const QString& mediaId,
bool allowRemote)
: BaseJob(HttpVerb::Get, QStringLiteral("GetContentJob"),
- QStringLiteral("/_matrix/media/r0") % "/download/" % serverName
- % "/" % mediaId,
+ makePath("/_matrix/media/v3", "/download/", serverName, "/",
+ mediaId),
queryToGetContent(allowRemote), {}, false)
{
setExpectedContentTypes({ "*/*" });
@@ -55,7 +52,7 @@ GetContentJob::GetContentJob(const QString& serverName, const QString& mediaId,
auto queryToGetContentOverrideName(bool allowRemote)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("allow_remote"), allowRemote);
return _q;
}
@@ -67,9 +64,9 @@ QUrl GetContentOverrideNameJob::makeRequestUrl(QUrl baseUrl,
bool allowRemote)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/media/r0")
- % "/download/" % serverName % "/"
- % mediaId % "/" % fileName,
+ makePath("/_matrix/media/v3", "/download/",
+ serverName, "/", mediaId, "/",
+ fileName),
queryToGetContentOverrideName(allowRemote));
}
@@ -78,8 +75,8 @@ GetContentOverrideNameJob::GetContentOverrideNameJob(const QString& serverName,
const QString& fileName,
bool allowRemote)
: BaseJob(HttpVerb::Get, QStringLiteral("GetContentOverrideNameJob"),
- QStringLiteral("/_matrix/media/r0") % "/download/" % serverName
- % "/" % mediaId % "/" % fileName,
+ makePath("/_matrix/media/v3", "/download/", serverName, "/",
+ mediaId, "/", fileName),
queryToGetContentOverrideName(allowRemote), {}, false)
{
setExpectedContentTypes({ "*/*" });
@@ -88,7 +85,7 @@ GetContentOverrideNameJob::GetContentOverrideNameJob(const QString& serverName,
auto queryToGetContentThumbnail(int width, int height, const QString& method,
bool allowRemote)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<>(_q, QStringLiteral("width"), width);
addParam<>(_q, QStringLiteral("height"), height);
addParam<IfNotEmpty>(_q, QStringLiteral("method"), method);
@@ -104,55 +101,54 @@ QUrl GetContentThumbnailJob::makeRequestUrl(QUrl baseUrl,
{
return BaseJob::makeRequestUrl(
std::move(baseUrl),
- QStringLiteral("/_matrix/media/r0") % "/thumbnail/" % serverName % "/"
- % mediaId,
+ makePath("/_matrix/media/v3", "/thumbnail/", serverName, "/", mediaId),
queryToGetContentThumbnail(width, height, method, allowRemote));
}
GetContentThumbnailJob::GetContentThumbnailJob(const QString& serverName,
- const QString& mediaId, int width,
- int height, const QString& method,
+ const QString& mediaId,
+ int width, int height,
+ const QString& method,
bool allowRemote)
: BaseJob(HttpVerb::Get, QStringLiteral("GetContentThumbnailJob"),
- QStringLiteral("/_matrix/media/r0") % "/thumbnail/" % serverName
- % "/" % mediaId,
+ makePath("/_matrix/media/v3", "/thumbnail/", serverName, "/",
+ mediaId),
queryToGetContentThumbnail(width, height, method, allowRemote),
{}, false)
{
setExpectedContentTypes({ "image/jpeg", "image/png" });
}
-auto queryToGetUrlPreview(const QString& url, Omittable<qint64> ts)
+auto queryToGetUrlPreview(const QUrl& url, Omittable<qint64> ts)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<>(_q, QStringLiteral("url"), url);
addParam<IfNotEmpty>(_q, QStringLiteral("ts"), ts);
return _q;
}
-QUrl GetUrlPreviewJob::makeRequestUrl(QUrl baseUrl, const QString& url,
+QUrl GetUrlPreviewJob::makeRequestUrl(QUrl baseUrl, const QUrl& url,
Omittable<qint64> ts)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/media/r0")
- % "/preview_url",
+ makePath("/_matrix/media/v3",
+ "/preview_url"),
queryToGetUrlPreview(url, ts));
}
-GetUrlPreviewJob::GetUrlPreviewJob(const QString& url, Omittable<qint64> ts)
+GetUrlPreviewJob::GetUrlPreviewJob(const QUrl& url, Omittable<qint64> ts)
: BaseJob(HttpVerb::Get, QStringLiteral("GetUrlPreviewJob"),
- QStringLiteral("/_matrix/media/r0") % "/preview_url",
+ makePath("/_matrix/media/v3", "/preview_url"),
queryToGetUrlPreview(url, ts))
{}
QUrl GetConfigJob::makeRequestUrl(QUrl baseUrl)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/media/r0")
- % "/config");
+ makePath("/_matrix/media/v3", "/config"));
}
GetConfigJob::GetConfigJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetConfigJob"),
- QStringLiteral("/_matrix/media/r0") % "/config")
+ makePath("/_matrix/media/v3", "/config"))
{}
diff --git a/lib/csapi/content-repo.h b/lib/csapi/content-repo.h
index f3d7309a..2ba66a35 100644
--- a/lib/csapi/content-repo.h
+++ b/lib/csapi/content-repo.h
@@ -14,7 +14,7 @@ namespace Quotient {
/*! \brief Upload some content to the content repository.
*
*/
-class UploadContentJob : public BaseJob {
+class QUOTIENT_API UploadContentJob : public BaseJob {
public:
/*! \brief Upload some content to the content repository.
*
@@ -34,16 +34,13 @@ public:
/// The [MXC URI](/client-server-api/#matrix-content-mxc-uris) to the
/// uploaded content.
- QString contentUri() const
- {
- return loadFromJson<QString>("content_uri"_ls);
- }
+ QUrl contentUri() const { return loadFromJson<QUrl>("content_uri"_ls); }
};
/*! \brief Download content from the content repository.
*
*/
-class GetContentJob : public BaseJob {
+class QUOTIENT_API GetContentJob : public BaseJob {
public:
/*! \brief Download content from the content repository.
*
@@ -90,7 +87,7 @@ public:
* the previous endpoint) but replace the target file name with the one
* provided by the caller.
*/
-class GetContentOverrideNameJob : public BaseJob {
+class QUOTIENT_API GetContentOverrideNameJob : public BaseJob {
public:
/*! \brief Download content from the content repository overriding the file
* name
@@ -145,7 +142,7 @@ public:
* See the [Thumbnails](/client-server-api/#thumbnails) section for more
* information.
*/
-class GetContentThumbnailJob : public BaseJob {
+class QUOTIENT_API GetContentThumbnailJob : public BaseJob {
public:
/*! \brief Download a thumbnail of content from the content repository
*
@@ -165,7 +162,8 @@ public:
*
* \param method
* The desired resizing method. See the
- * [Thumbnails](/client-server-api/#thumbnails) section for more information.
+ * [Thumbnails](/client-server-api/#thumbnails) section for more
+ * information.
*
* \param allowRemote
* Indicates to the server that it should not attempt to fetch
@@ -207,7 +205,7 @@ public:
* do not want to share with the homeserver, and this can mean that the URLs
* being shared should also not be shared with the homeserver.
*/
-class GetUrlPreviewJob : public BaseJob {
+class QUOTIENT_API GetUrlPreviewJob : public BaseJob {
public:
/*! \brief Get information about a URL for a client
*
@@ -219,14 +217,14 @@ public:
* return a newer version if it does not have the requested version
* available.
*/
- explicit GetUrlPreviewJob(const QString& url, Omittable<qint64> ts = none);
+ explicit GetUrlPreviewJob(const QUrl& url, Omittable<qint64> ts = none);
/*! \brief Construct a URL without creating a full-fledged job object
*
* This function can be used when a URL for GetUrlPreviewJob
* is necessary but the job itself isn't.
*/
- static QUrl makeRequestUrl(QUrl baseUrl, const QString& url,
+ static QUrl makeRequestUrl(QUrl baseUrl, const QUrl& url,
Omittable<qint64> ts = none);
// Result properties
@@ -239,7 +237,7 @@ public:
/// An [MXC URI](/client-server-api/#matrix-content-mxc-uris) to the image.
/// Omitted if there is no image.
- QString ogImage() const { return loadFromJson<QString>("og:image"_ls); }
+ QUrl ogImage() const { return loadFromJson<QUrl>("og:image"_ls); }
};
/*! \brief Get the configuration for the content repository.
@@ -255,7 +253,7 @@ public:
* content repository APIs, for example, proxies may enforce a lower upload size
* limit than is advertised by the server on this endpoint.
*/
-class GetConfigJob : public BaseJob {
+class QUOTIENT_API GetConfigJob : public BaseJob {
public:
/// Get the configuration for the content repository.
explicit GetConfigJob();
diff --git a/lib/csapi/create_room.cpp b/lib/csapi/create_room.cpp
index a94f9951..afae80af 100644
--- a/lib/csapi/create_room.cpp
+++ b/lib/csapi/create_room.cpp
@@ -4,8 +4,6 @@
#include "create_room.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
CreateRoomJob::CreateRoomJob(const QString& visibility,
@@ -18,24 +16,26 @@ CreateRoomJob::CreateRoomJob(const QString& visibility,
const QString& preset, Omittable<bool> isDirect,
const QJsonObject& powerLevelContentOverride)
: BaseJob(HttpVerb::Post, QStringLiteral("CreateRoomJob"),
- QStringLiteral("/_matrix/client/r0") % "/createRoom")
+ makePath("/_matrix/client/v3", "/createRoom"))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("visibility"), visibility);
- addParam<IfNotEmpty>(_data, QStringLiteral("room_alias_name"),
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("visibility"), visibility);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("room_alias_name"),
roomAliasName);
- addParam<IfNotEmpty>(_data, QStringLiteral("name"), name);
- addParam<IfNotEmpty>(_data, QStringLiteral("topic"), topic);
- addParam<IfNotEmpty>(_data, QStringLiteral("invite"), invite);
- addParam<IfNotEmpty>(_data, QStringLiteral("invite_3pid"), invite3pid);
- addParam<IfNotEmpty>(_data, QStringLiteral("room_version"), roomVersion);
- addParam<IfNotEmpty>(_data, QStringLiteral("creation_content"),
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("name"), name);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("topic"), topic);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("invite"), invite);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("invite_3pid"), invite3pid);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("room_version"), roomVersion);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("creation_content"),
creationContent);
- addParam<IfNotEmpty>(_data, QStringLiteral("initial_state"), initialState);
- addParam<IfNotEmpty>(_data, QStringLiteral("preset"), preset);
- addParam<IfNotEmpty>(_data, QStringLiteral("is_direct"), isDirect);
- addParam<IfNotEmpty>(_data, QStringLiteral("power_level_content_override"),
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("initial_state"),
+ initialState);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("preset"), preset);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("is_direct"), isDirect);
+ addParam<IfNotEmpty>(_dataJson,
+ QStringLiteral("power_level_content_override"),
powerLevelContentOverride);
- setRequestData(std::move(_data));
+ setRequestData({ _dataJson });
addExpectedKey("room_id");
}
diff --git a/lib/csapi/create_room.h b/lib/csapi/create_room.h
index 81dfbffc..336b9767 100644
--- a/lib/csapi/create_room.h
+++ b/lib/csapi/create_room.h
@@ -26,16 +26,18 @@ namespace Quotient {
* (and not other members) permission to send state events. Overridden
* by the `power_level_content_override` parameter.
*
- * 4. Events set by the `preset`. Currently these are the `m.room.join_rules`,
+ * 4. An `m.room.canonical_alias` event if `room_alias_name` is given.
+ *
+ * 5. Events set by the `preset`. Currently these are the `m.room.join_rules`,
* `m.room.history_visibility`, and `m.room.guest_access` state events.
*
- * 5. Events listed in `initial_state`, in the order that they are
+ * 6. Events listed in `initial_state`, in the order that they are
* listed.
*
- * 6. Events implied by `name` and `topic` (`m.room.name` and `m.room.topic`
+ * 7. Events implied by `name` and `topic` (`m.room.name` and `m.room.topic`
* state events).
*
- * 7. Invite events implied by `invite` and `invite_3pid` (`m.room.member` with
+ * 8. Invite events implied by `invite` and `invite_3pid` (`m.room.member` with
* `membership: invite` and `m.room.third_party_invite`).
*
* The available presets do the following with respect to room state:
@@ -53,7 +55,7 @@ namespace Quotient {
* requesting user as the creator, alongside other keys provided in the
* `creation_content`.
*/
-class CreateRoomJob : public BaseJob {
+class QUOTIENT_API CreateRoomJob : public BaseJob {
public:
// Inner data structures
@@ -73,17 +75,20 @@ public:
/// (and not other members) permission to send state events. Overridden
/// by the `power_level_content_override` parameter.
///
- /// 4. Events set by the `preset`. Currently these are the
+ /// 4. An `m.room.canonical_alias` event if `room_alias_name` is given.
+ ///
+ /// 5. Events set by the `preset`. Currently these are the
/// `m.room.join_rules`,
/// `m.room.history_visibility`, and `m.room.guest_access` state events.
///
- /// 5. Events listed in `initial_state`, in the order that they are
+ /// 6. Events listed in `initial_state`, in the order that they are
/// listed.
///
- /// 6. Events implied by `name` and `topic` (`m.room.name` and `m.room.topic`
+ /// 7. Events implied by `name` and `topic` (`m.room.name` and
+ /// `m.room.topic`
/// state events).
///
- /// 7. Invite events implied by `invite` and `invite_3pid` (`m.room.member`
+ /// 8. Invite events implied by `invite` and `invite_3pid` (`m.room.member`
/// with
/// `membership: invite` and `m.room.third_party_invite`).
///
@@ -132,17 +137,20 @@ public:
/// (and not other members) permission to send state events. Overridden
/// by the `power_level_content_override` parameter.
///
- /// 4. Events set by the `preset`. Currently these are the
+ /// 4. An `m.room.canonical_alias` event if `room_alias_name` is given.
+ ///
+ /// 5. Events set by the `preset`. Currently these are the
/// `m.room.join_rules`,
/// `m.room.history_visibility`, and `m.room.guest_access` state events.
///
- /// 5. Events listed in `initial_state`, in the order that they are
+ /// 6. Events listed in `initial_state`, in the order that they are
/// listed.
///
- /// 6. Events implied by `name` and `topic` (`m.room.name` and `m.room.topic`
+ /// 7. Events implied by `name` and `topic` (`m.room.name` and
+ /// `m.room.topic`
/// state events).
///
- /// 7. Invite events implied by `invite` and `invite_3pid` (`m.room.member`
+ /// 8. Invite events implied by `invite` and `invite_3pid` (`m.room.member`
/// with
/// `membership: invite` and `m.room.third_party_invite`).
///
@@ -190,7 +198,8 @@ public:
* would be `#foo:example.com`.
*
* The complete room alias will become the canonical alias for
- * the room.
+ * the room and an `m.room.canonical_alias` event will be sent
+ * into the room.
*
* \param name
* If this is included, an `m.room.name` event will be sent
@@ -218,9 +227,10 @@ public:
*
* \param creationContent
* Extra keys, such as `m.federate`, to be added to the content
- * of the [`m.room.create`](client-server-api/#mroomcreate) event. The
- * server will clobber the following keys: `creator`, `room_version`. Future
- * versions of the specification may allow the server to clobber other keys.
+ * of the [`m.room.create`](/client-server-api/#mroomcreate) event. The
+ * server will overwrite the following keys: `creator`, `room_version`.
+ * Future versions of the specification may allow the server to overwrite
+ * other keys.
*
* \param initialState
* A list of state events to set in the new room. This allows
@@ -229,7 +239,7 @@ public:
* with type, state_key and content keys set.
*
* Takes precedence over events set by `preset`, but gets
- * overriden by `name` and `topic` keys.
+ * overridden by `name` and `topic` keys.
*
* \param preset
* Convenience parameter for setting various default state events
@@ -249,7 +259,7 @@ public:
* \param powerLevelContentOverride
* The power level content to override in the default power level
* event. This object is applied on top of the generated
- * [`m.room.power_levels`](client-server-api/#mroompower_levels)
+ * [`m.room.power_levels`](/client-server-api/#mroompower_levels)
* event content prior to it being sent to the room. Defaults to
* overriding nothing.
*/
diff --git a/lib/csapi/cross_signing.cpp b/lib/csapi/cross_signing.cpp
new file mode 100644
index 00000000..83136d71
--- /dev/null
+++ b/lib/csapi/cross_signing.cpp
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#include "cross_signing.h"
+
+using namespace Quotient;
+
+UploadCrossSigningKeysJob::UploadCrossSigningKeysJob(
+ const Omittable<CrossSigningKey>& masterKey,
+ const Omittable<CrossSigningKey>& selfSigningKey,
+ const Omittable<CrossSigningKey>& userSigningKey,
+ const Omittable<AuthenticationData>& auth)
+ : BaseJob(HttpVerb::Post, QStringLiteral("UploadCrossSigningKeysJob"),
+ makePath("/_matrix/client/v3", "/keys/device_signing/upload"))
+{
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("master_key"), masterKey);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("self_signing_key"),
+ selfSigningKey);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("user_signing_key"),
+ userSigningKey);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("auth"), auth);
+ setRequestData({ _dataJson });
+}
+
+UploadCrossSigningSignaturesJob::UploadCrossSigningSignaturesJob(
+ const QHash<QString, QHash<QString, QJsonObject>>& signatures)
+ : BaseJob(HttpVerb::Post, QStringLiteral("UploadCrossSigningSignaturesJob"),
+ makePath("/_matrix/client/v3", "/keys/signatures/upload"))
+{
+ setRequestData({ toJson(signatures) });
+}
diff --git a/lib/csapi/cross_signing.h b/lib/csapi/cross_signing.h
new file mode 100644
index 00000000..6cea73e6
--- /dev/null
+++ b/lib/csapi/cross_signing.h
@@ -0,0 +1,78 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "csapi/definitions/auth_data.h"
+#include "csapi/definitions/cross_signing_key.h"
+
+#include "jobs/basejob.h"
+
+namespace Quotient {
+
+/*! \brief Upload cross-signing keys.
+ *
+ * Publishes cross-signing keys for the user.
+ *
+ * This API endpoint uses the [User-Interactive Authentication
+ * API](/client-server-api/#user-interactive-authentication-api).
+ */
+class QUOTIENT_API UploadCrossSigningKeysJob : public BaseJob {
+public:
+ /*! \brief Upload cross-signing keys.
+ *
+ * \param masterKey
+ * Optional. The user\'s master key.
+ *
+ * \param selfSigningKey
+ * Optional. The user\'s self-signing key. Must be signed by
+ * the accompanying master key, or by the user\'s most recently
+ * uploaded master key if no master key is included in the
+ * request.
+ *
+ * \param userSigningKey
+ * Optional. The user\'s user-signing key. Must be signed by
+ * the accompanying master key, or by the user\'s most recently
+ * uploaded master key if no master key is included in the
+ * request.
+ *
+ * \param auth
+ * Additional authentication information for the
+ * user-interactive authentication API.
+ */
+ explicit UploadCrossSigningKeysJob(
+ const Omittable<CrossSigningKey>& masterKey = none,
+ const Omittable<CrossSigningKey>& selfSigningKey = none,
+ const Omittable<CrossSigningKey>& userSigningKey = none,
+ const Omittable<AuthenticationData>& auth = none);
+};
+
+/*! \brief Upload cross-signing signatures.
+ *
+ * Publishes cross-signing signatures for the user. The request body is a
+ * map from user ID to key ID to signed JSON object.
+ */
+class QUOTIENT_API UploadCrossSigningSignaturesJob : public BaseJob {
+public:
+ /*! \brief Upload cross-signing signatures.
+ *
+ * \param signatures
+ * The signatures to be published.
+ */
+ explicit UploadCrossSigningSignaturesJob(
+ const QHash<QString, QHash<QString, QJsonObject>>& signatures);
+
+ // Result properties
+
+ /// A map from user ID to key ID to an error for any signatures
+ /// that failed. If a signature was invalid, the `errcode` will
+ /// be set to `M_INVALID_SIGNATURE`.
+ QHash<QString, QHash<QString, QJsonObject>> failures() const
+ {
+ return loadFromJson<QHash<QString, QHash<QString, QJsonObject>>>(
+ "failures"_ls);
+ }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/definitions/auth_data.h b/lib/csapi/definitions/auth_data.h
index e92596d0..a9972323 100644
--- a/lib/csapi/definitions/auth_data.h
+++ b/lib/csapi/definitions/auth_data.h
@@ -10,7 +10,10 @@ namespace Quotient {
/// Used by clients to submit authentication information to the
/// interactive-authentication API
struct AuthenticationData {
- /// The login type that the client is attempting to complete.
+ /// The authentication type that the client is attempting to complete.
+ /// May be omitted if `session` is given, and the client is reissuing a
+ /// request which it believes has been completed out-of-band (for example,
+ /// via the [fallback mechanism](#fallback)).
QString type;
/// The value of the session key given by the homeserver.
@@ -25,7 +28,7 @@ struct JsonObjectConverter<AuthenticationData> {
static void dumpTo(QJsonObject& jo, const AuthenticationData& pod)
{
fillJson(jo, pod.authInfo);
- addParam<>(jo, QStringLiteral("type"), pod.type);
+ addParam<IfNotEmpty>(jo, QStringLiteral("type"), pod.type);
addParam<IfNotEmpty>(jo, QStringLiteral("session"), pod.session);
}
static void fillFrom(QJsonObject jo, AuthenticationData& pod)
diff --git a/lib/csapi/definitions/cross_signing_key.h b/lib/csapi/definitions/cross_signing_key.h
new file mode 100644
index 00000000..0cec8161
--- /dev/null
+++ b/lib/csapi/definitions/cross_signing_key.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "converters.h"
+
+namespace Quotient {
+/// Cross signing key
+struct CrossSigningKey {
+ /// The ID of the user the key belongs to.
+ QString userId;
+
+ /// What the key is used for.
+ QStringList usage;
+
+ /// The public key. The object must have exactly one property, whose name
+ /// is in the form `<algorithm>:<unpadded_base64_public_key>`, and whose
+ /// value is the unpadded base64 public key.
+ QHash<QString, QString> keys;
+
+ /// Signatures of the key, calculated using the process described at
+ /// [Signing JSON](/appendices/#signing-json). Optional for the master key.
+ /// Other keys must be signed by the user\'s master key.
+ QJsonObject signatures;
+};
+
+template <>
+struct JsonObjectConverter<CrossSigningKey> {
+ static void dumpTo(QJsonObject& jo, const CrossSigningKey& pod)
+ {
+ addParam<>(jo, QStringLiteral("user_id"), pod.userId);
+ addParam<>(jo, QStringLiteral("usage"), pod.usage);
+ addParam<>(jo, QStringLiteral("keys"), pod.keys);
+ addParam<IfNotEmpty>(jo, QStringLiteral("signatures"), pod.signatures);
+ }
+ static void fillFrom(const QJsonObject& jo, CrossSigningKey& pod)
+ {
+ fromJson(jo.value("user_id"_ls), pod.userId);
+ fromJson(jo.value("usage"_ls), pod.usage);
+ fromJson(jo.value("keys"_ls), pod.keys);
+ fromJson(jo.value("signatures"_ls), pod.signatures);
+ }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/definitions/openid_token.h b/lib/csapi/definitions/openid_token.h
index 3c447321..9b026dea 100644
--- a/lib/csapi/definitions/openid_token.h
+++ b/lib/csapi/definitions/openid_token.h
@@ -8,7 +8,7 @@
namespace Quotient {
-struct OpenidToken {
+struct OpenIdCredentials {
/// An access token the consumer may use to verify the identity of
/// the person who generated the token. This is given to the federation
/// API `GET /openid/userinfo` to verify the user's identity.
@@ -27,8 +27,8 @@ struct OpenidToken {
};
template <>
-struct JsonObjectConverter<OpenidToken> {
- static void dumpTo(QJsonObject& jo, const OpenidToken& pod)
+struct JsonObjectConverter<OpenIdCredentials> {
+ static void dumpTo(QJsonObject& jo, const OpenIdCredentials& pod)
{
addParam<>(jo, QStringLiteral("access_token"), pod.accessToken);
addParam<>(jo, QStringLiteral("token_type"), pod.tokenType);
@@ -36,7 +36,7 @@ struct JsonObjectConverter<OpenidToken> {
pod.matrixServerName);
addParam<>(jo, QStringLiteral("expires_in"), pod.expiresIn);
}
- static void fillFrom(const QJsonObject& jo, OpenidToken& pod)
+ static void fillFrom(const QJsonObject& jo, OpenIdCredentials& pod)
{
fromJson(jo.value("access_token"_ls), pod.accessToken);
fromJson(jo.value("token_type"_ls), pod.tokenType);
diff --git a/lib/csapi/definitions/public_rooms_response.h b/lib/csapi/definitions/public_rooms_response.h
index 8f30e607..7c7d9cc6 100644
--- a/lib/csapi/definitions/public_rooms_response.h
+++ b/lib/csapi/definitions/public_rooms_response.h
@@ -9,9 +9,6 @@
namespace Quotient {
struct PublicRoomsChunk {
- /// Aliases of the room. May be empty.
- QStringList aliases;
-
/// The canonical alias of the room, if any.
QString canonicalAlias;
@@ -36,14 +33,23 @@ struct PublicRoomsChunk {
bool guestCanJoin;
/// The URL for the room's avatar, if one is set.
- QString avatarUrl;
+ QUrl avatarUrl;
+
+ /// The `type` of room (from
+ /// [`m.room.create`](/client-server-api/#mroomcreate)), if any.
+ QString roomType;
+
+ /// The room's join rule. When not present, the room is assumed to
+ /// be `public`. Note that rooms with `invite` join rules are not
+ /// expected here, but rooms with `knock` rules are given their
+ /// near-public nature.
+ QString joinRule;
};
template <>
struct JsonObjectConverter<PublicRoomsChunk> {
static void dumpTo(QJsonObject& jo, const PublicRoomsChunk& pod)
{
- addParam<IfNotEmpty>(jo, QStringLiteral("aliases"), pod.aliases);
addParam<IfNotEmpty>(jo, QStringLiteral("canonical_alias"),
pod.canonicalAlias);
addParam<IfNotEmpty>(jo, QStringLiteral("name"), pod.name);
@@ -54,10 +60,11 @@ struct JsonObjectConverter<PublicRoomsChunk> {
addParam<>(jo, QStringLiteral("world_readable"), pod.worldReadable);
addParam<>(jo, QStringLiteral("guest_can_join"), pod.guestCanJoin);
addParam<IfNotEmpty>(jo, QStringLiteral("avatar_url"), pod.avatarUrl);
+ addParam<IfNotEmpty>(jo, QStringLiteral("room_type"), pod.roomType);
+ addParam<IfNotEmpty>(jo, QStringLiteral("join_rule"), pod.joinRule);
}
static void fillFrom(const QJsonObject& jo, PublicRoomsChunk& pod)
{
- fromJson(jo.value("aliases"_ls), pod.aliases);
fromJson(jo.value("canonical_alias"_ls), pod.canonicalAlias);
fromJson(jo.value("name"_ls), pod.name);
fromJson(jo.value("num_joined_members"_ls), pod.numJoinedMembers);
@@ -66,46 +73,8 @@ struct JsonObjectConverter<PublicRoomsChunk> {
fromJson(jo.value("world_readable"_ls), pod.worldReadable);
fromJson(jo.value("guest_can_join"_ls), pod.guestCanJoin);
fromJson(jo.value("avatar_url"_ls), pod.avatarUrl);
- }
-};
-
-/// A list of the rooms on the server.
-struct PublicRoomsResponse {
- /// A paginated chunk of public rooms.
- QVector<PublicRoomsChunk> chunk;
-
- /// A pagination token for the response. The absence of this token
- /// means there are no more results to fetch and the client should
- /// stop paginating.
- QString nextBatch;
-
- /// A pagination token that allows fetching previous results. The
- /// absence of this token means there are no results before this
- /// batch, i.e. this is the first batch.
- QString prevBatch;
-
- /// An estimate on the total number of public rooms, if the
- /// server has an estimate.
- Omittable<int> totalRoomCountEstimate;
-};
-
-template <>
-struct JsonObjectConverter<PublicRoomsResponse> {
- static void dumpTo(QJsonObject& jo, const PublicRoomsResponse& pod)
- {
- addParam<>(jo, QStringLiteral("chunk"), pod.chunk);
- addParam<IfNotEmpty>(jo, QStringLiteral("next_batch"), pod.nextBatch);
- addParam<IfNotEmpty>(jo, QStringLiteral("prev_batch"), pod.prevBatch);
- addParam<IfNotEmpty>(jo, QStringLiteral("total_room_count_estimate"),
- pod.totalRoomCountEstimate);
- }
- static void fillFrom(const QJsonObject& jo, PublicRoomsResponse& pod)
- {
- fromJson(jo.value("chunk"_ls), pod.chunk);
- fromJson(jo.value("next_batch"_ls), pod.nextBatch);
- fromJson(jo.value("prev_batch"_ls), pod.prevBatch);
- fromJson(jo.value("total_room_count_estimate"_ls),
- pod.totalRoomCountEstimate);
+ fromJson(jo.value("room_type"_ls), pod.roomType);
+ fromJson(jo.value("join_rule"_ls), pod.joinRule);
}
};
diff --git a/lib/csapi/definitions/push_condition.h b/lib/csapi/definitions/push_condition.h
index ce66d075..6a048ba8 100644
--- a/lib/csapi/definitions/push_condition.h
+++ b/lib/csapi/definitions/push_condition.h
@@ -24,9 +24,7 @@ struct PushCondition {
QString key;
/// Required for `event_match` conditions. The glob-style pattern to
- /// match against. Patterns with no special glob characters should be
- /// treated as having asterisks prepended and appended when testing the
- /// condition.
+ /// match against.
QString pattern;
/// Required for `room_member_count` conditions. A decimal integer
diff --git a/lib/csapi/definitions/request_token_response.h b/lib/csapi/definitions/request_token_response.h
index f9981100..d5fbbadb 100644
--- a/lib/csapi/definitions/request_token_response.h
+++ b/lib/csapi/definitions/request_token_response.h
@@ -25,7 +25,7 @@ struct RequestTokenResponse {
/// will happen without the client's involvement provided the homeserver
/// advertises this specification version in the `/versions` response
/// (ie: r0.5.0).
- QString submitUrl;
+ QUrl submitUrl;
};
template <>
diff --git a/lib/csapi/definitions/room_event_filter.h b/lib/csapi/definitions/room_event_filter.h
index 91caf667..293e5492 100644
--- a/lib/csapi/definitions/room_event_filter.h
+++ b/lib/csapi/definitions/room_event_filter.h
@@ -11,6 +11,11 @@
namespace Quotient {
struct RoomEventFilter : EventFilter {
+ /// If `true`, enables per-[thread](/client-server-api/#threading)
+ /// notification counts. Only applies to the `/sync` endpoint. Defaults to
+ /// `false`.
+ Omittable<bool> unreadThreadNotifications;
+
/// If `true`, enables lazy-loading of membership events. See
/// [Lazy-loading room
/// members](/client-server-api/#lazy-loading-room-members) for more
@@ -44,6 +49,8 @@ struct JsonObjectConverter<RoomEventFilter> {
static void dumpTo(QJsonObject& jo, const RoomEventFilter& pod)
{
fillJson<EventFilter>(jo, pod);
+ addParam<IfNotEmpty>(jo, QStringLiteral("unread_thread_notifications"),
+ pod.unreadThreadNotifications);
addParam<IfNotEmpty>(jo, QStringLiteral("lazy_load_members"),
pod.lazyLoadMembers);
addParam<IfNotEmpty>(jo, QStringLiteral("include_redundant_members"),
@@ -56,6 +63,8 @@ struct JsonObjectConverter<RoomEventFilter> {
static void fillFrom(const QJsonObject& jo, RoomEventFilter& pod)
{
fillFromJson<EventFilter>(jo, pod);
+ fromJson(jo.value("unread_thread_notifications"_ls),
+ pod.unreadThreadNotifications);
fromJson(jo.value("lazy_load_members"_ls), pod.lazyLoadMembers);
fromJson(jo.value("include_redundant_members"_ls),
pod.includeRedundantMembers);
diff --git a/lib/csapi/definitions/wellknown/homeserver.h b/lib/csapi/definitions/wellknown/homeserver.h
index 5cfaca24..b7db4182 100644
--- a/lib/csapi/definitions/wellknown/homeserver.h
+++ b/lib/csapi/definitions/wellknown/homeserver.h
@@ -10,7 +10,7 @@ namespace Quotient {
/// Used by clients to discover homeserver information.
struct HomeserverInformation {
/// The base URL for the homeserver for client-server connections.
- QString baseUrl;
+ QUrl baseUrl;
};
template <>
diff --git a/lib/csapi/definitions/wellknown/identity_server.h b/lib/csapi/definitions/wellknown/identity_server.h
index 3bd07bd1..885e3d34 100644
--- a/lib/csapi/definitions/wellknown/identity_server.h
+++ b/lib/csapi/definitions/wellknown/identity_server.h
@@ -10,7 +10,7 @@ namespace Quotient {
/// Used by clients to discover identity server information.
struct IdentityServerInformation {
/// The base URL for the identity server for client-server connections.
- QString baseUrl;
+ QUrl baseUrl;
};
template <>
diff --git a/lib/csapi/device_management.cpp b/lib/csapi/device_management.cpp
index eac9a545..6f2badee 100644
--- a/lib/csapi/device_management.cpp
+++ b/lib/csapi/device_management.cpp
@@ -4,61 +4,58 @@
#include "device_management.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetDevicesJob::makeRequestUrl(QUrl baseUrl)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/devices");
+ makePath("/_matrix/client/v3", "/devices"));
}
GetDevicesJob::GetDevicesJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetDevicesJob"),
- QStringLiteral("/_matrix/client/r0") % "/devices")
+ makePath("/_matrix/client/v3", "/devices"))
{}
QUrl GetDeviceJob::makeRequestUrl(QUrl baseUrl, const QString& deviceId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/devices/" % deviceId);
+ makePath("/_matrix/client/v3", "/devices/",
+ deviceId));
}
GetDeviceJob::GetDeviceJob(const QString& deviceId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetDeviceJob"),
- QStringLiteral("/_matrix/client/r0") % "/devices/" % deviceId)
+ makePath("/_matrix/client/v3", "/devices/", deviceId))
{}
UpdateDeviceJob::UpdateDeviceJob(const QString& deviceId,
const QString& displayName)
: BaseJob(HttpVerb::Put, QStringLiteral("UpdateDeviceJob"),
- QStringLiteral("/_matrix/client/r0") % "/devices/" % deviceId)
+ makePath("/_matrix/client/v3", "/devices/", deviceId))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("display_name"), displayName);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("display_name"), displayName);
+ setRequestData({ _dataJson });
}
DeleteDeviceJob::DeleteDeviceJob(const QString& deviceId,
const Omittable<AuthenticationData>& auth)
: BaseJob(HttpVerb::Delete, QStringLiteral("DeleteDeviceJob"),
- QStringLiteral("/_matrix/client/r0") % "/devices/" % deviceId)
+ makePath("/_matrix/client/v3", "/devices/", deviceId))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("auth"), auth);
+ setRequestData({ _dataJson });
}
DeleteDevicesJob::DeleteDevicesJob(const QStringList& devices,
const Omittable<AuthenticationData>& auth)
: BaseJob(HttpVerb::Post, QStringLiteral("DeleteDevicesJob"),
- QStringLiteral("/_matrix/client/r0") % "/delete_devices")
+ makePath("/_matrix/client/v3", "/delete_devices"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("devices"), devices);
- addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("devices"), devices);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("auth"), auth);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/device_management.h b/lib/csapi/device_management.h
index 7fb69873..c10389b3 100644
--- a/lib/csapi/device_management.h
+++ b/lib/csapi/device_management.h
@@ -15,7 +15,7 @@ namespace Quotient {
*
* Gets information about all devices for the current user.
*/
-class GetDevicesJob : public BaseJob {
+class QUOTIENT_API GetDevicesJob : public BaseJob {
public:
/// List registered devices for the current user
explicit GetDevicesJob();
@@ -40,7 +40,7 @@ public:
*
* Gets information on a single device, by device id.
*/
-class GetDeviceJob : public BaseJob {
+class QUOTIENT_API GetDeviceJob : public BaseJob {
public:
/*! \brief Get a single device
*
@@ -66,7 +66,7 @@ public:
*
* Updates the metadata on the given device.
*/
-class UpdateDeviceJob : public BaseJob {
+class QUOTIENT_API UpdateDeviceJob : public BaseJob {
public:
/*! \brief Update a device
*
@@ -86,9 +86,10 @@ public:
* This API endpoint uses the [User-Interactive Authentication
* API](/client-server-api/#user-interactive-authentication-api).
*
- * Deletes the given device, and invalidates any access token associated with it.
+ * Deletes the given device, and invalidates any access token associated with
+ * it.
*/
-class DeleteDeviceJob : public BaseJob {
+class QUOTIENT_API DeleteDeviceJob : public BaseJob {
public:
/*! \brief Delete a device
*
@@ -111,7 +112,7 @@ public:
* Deletes the given devices, and invalidates any access token associated with
* them.
*/
-class DeleteDevicesJob : public BaseJob {
+class QUOTIENT_API DeleteDevicesJob : public BaseJob {
public:
/*! \brief Bulk deletion of devices
*
diff --git a/lib/csapi/directory.cpp b/lib/csapi/directory.cpp
index 25ea82e2..c1255bb1 100644
--- a/lib/csapi/directory.cpp
+++ b/lib/csapi/directory.cpp
@@ -4,58 +4,52 @@
#include "directory.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SetRoomAliasJob::SetRoomAliasJob(const QString& roomAlias, const QString& roomId)
: BaseJob(HttpVerb::Put, QStringLiteral("SetRoomAliasJob"),
- QStringLiteral("/_matrix/client/r0") % "/directory/room/"
- % roomAlias)
+ makePath("/_matrix/client/v3", "/directory/room/", roomAlias))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("room_id"), roomId);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("room_id"), roomId);
+ setRequestData({ _dataJson });
}
QUrl GetRoomIdByAliasJob::makeRequestUrl(QUrl baseUrl, const QString& roomAlias)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/directory/room/" % roomAlias);
+ makePath("/_matrix/client/v3",
+ "/directory/room/", roomAlias));
}
GetRoomIdByAliasJob::GetRoomIdByAliasJob(const QString& roomAlias)
: BaseJob(HttpVerb::Get, QStringLiteral("GetRoomIdByAliasJob"),
- QStringLiteral("/_matrix/client/r0") % "/directory/room/"
- % roomAlias,
+ makePath("/_matrix/client/v3", "/directory/room/", roomAlias),
false)
{}
QUrl DeleteRoomAliasJob::makeRequestUrl(QUrl baseUrl, const QString& roomAlias)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/directory/room/" % roomAlias);
+ makePath("/_matrix/client/v3",
+ "/directory/room/", roomAlias));
}
DeleteRoomAliasJob::DeleteRoomAliasJob(const QString& roomAlias)
: BaseJob(HttpVerb::Delete, QStringLiteral("DeleteRoomAliasJob"),
- QStringLiteral("/_matrix/client/r0") % "/directory/room/"
- % roomAlias)
+ makePath("/_matrix/client/v3", "/directory/room/", roomAlias))
{}
QUrl GetLocalAliasesJob::makeRequestUrl(QUrl baseUrl, const QString& roomId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/rooms/" % roomId % "/aliases");
+ makePath("/_matrix/client/v3", "/rooms/",
+ roomId, "/aliases"));
}
GetLocalAliasesJob::GetLocalAliasesJob(const QString& roomId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetLocalAliasesJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/aliases")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/aliases"))
{
addExpectedKey("aliases");
}
diff --git a/lib/csapi/directory.h b/lib/csapi/directory.h
index 93a31595..0bd13a76 100644
--- a/lib/csapi/directory.h
+++ b/lib/csapi/directory.h
@@ -11,7 +11,7 @@ namespace Quotient {
/*! \brief Create a new mapping from room alias to room ID.
*
*/
-class SetRoomAliasJob : public BaseJob {
+class QUOTIENT_API SetRoomAliasJob : public BaseJob {
public:
/*! \brief Create a new mapping from room alias to room ID.
*
@@ -32,7 +32,7 @@ public:
* domain part of the alias does not correspond to the server's own
* domain.
*/
-class GetRoomIdByAliasJob : public BaseJob {
+class QUOTIENT_API GetRoomIdByAliasJob : public BaseJob {
public:
/*! \brief Get the room ID corresponding to this room alias.
*
@@ -76,7 +76,7 @@ public:
* return a successful response even if the user does not have permission to
* update the `m.room.canonical_alias` event.
*/
-class DeleteRoomAliasJob : public BaseJob {
+class QUOTIENT_API DeleteRoomAliasJob : public BaseJob {
public:
/*! \brief Remove a mapping of room alias to room ID.
*
@@ -112,7 +112,7 @@ public:
* as they are not curated, unlike those listed in the `m.room.canonical_alias`
* state event.
*/
-class GetLocalAliasesJob : public BaseJob {
+class QUOTIENT_API GetLocalAliasesJob : public BaseJob {
public:
/*! \brief Get a list of local aliases on a given room.
*
diff --git a/lib/csapi/event_context.cpp b/lib/csapi/event_context.cpp
index d2a5f522..4ebbbf98 100644
--- a/lib/csapi/event_context.cpp
+++ b/lib/csapi/event_context.cpp
@@ -4,13 +4,11 @@
#include "event_context.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
auto queryToGetEventContext(Omittable<int> limit, const QString& filter)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
addParam<IfNotEmpty>(_q, QStringLiteral("filter"), filter);
return _q;
@@ -22,9 +20,8 @@ QUrl GetEventContextJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
const QString& filter)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/rooms/" % roomId % "/context/"
- % eventId,
+ makePath("/_matrix/client/v3", "/rooms/",
+ roomId, "/context/", eventId),
queryToGetEventContext(limit, filter));
}
@@ -33,7 +30,7 @@ GetEventContextJob::GetEventContextJob(const QString& roomId,
Omittable<int> limit,
const QString& filter)
: BaseJob(HttpVerb::Get, QStringLiteral("GetEventContextJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/context/" % eventId,
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/context/",
+ eventId),
queryToGetEventContext(limit, filter))
{}
diff --git a/lib/csapi/event_context.h b/lib/csapi/event_context.h
index 4e50edf3..1614c7ed 100644
--- a/lib/csapi/event_context.h
+++ b/lib/csapi/event_context.h
@@ -4,7 +4,8 @@
#pragma once
-#include "events/eventloader.h"
+#include "events/roomevent.h"
+#include "events/stateevent.h"
#include "jobs/basejob.h"
namespace Quotient {
@@ -19,7 +20,7 @@ namespace Quotient {
* [Lazy-loading room members](/client-server-api/#lazy-loading-room-members)
* for more information.
*/
-class GetEventContextJob : public BaseJob {
+class QUOTIENT_API GetEventContextJob : public BaseJob {
public:
/*! \brief Get events and state around the specified event.
*
diff --git a/lib/csapi/filter.cpp b/lib/csapi/filter.cpp
index bb3a893f..2469fbd1 100644
--- a/lib/csapi/filter.cpp
+++ b/lib/csapi/filter.cpp
@@ -4,16 +4,13 @@
#include "filter.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
DefineFilterJob::DefineFilterJob(const QString& userId, const Filter& filter)
: BaseJob(HttpVerb::Post, QStringLiteral("DefineFilterJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/filter")
+ makePath("/_matrix/client/v3", "/user/", userId, "/filter"))
{
- setRequestData(Data(toJson(filter)));
+ setRequestData({ toJson(filter) });
addExpectedKey("filter_id");
}
@@ -21,12 +18,12 @@ QUrl GetFilterJob::makeRequestUrl(QUrl baseUrl, const QString& userId,
const QString& filterId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0") % "/user/"
- % userId % "/filter/" % filterId);
+ makePath("/_matrix/client/v3", "/user/",
+ userId, "/filter/", filterId));
}
GetFilterJob::GetFilterJob(const QString& userId, const QString& filterId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetFilterJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/filter/" % filterId)
+ makePath("/_matrix/client/v3", "/user/", userId, "/filter/",
+ filterId))
{}
diff --git a/lib/csapi/filter.h b/lib/csapi/filter.h
index 01bec36b..9518a461 100644
--- a/lib/csapi/filter.h
+++ b/lib/csapi/filter.h
@@ -16,7 +16,7 @@ namespace Quotient {
* Returns a filter ID that may be used in future requests to
* restrict which events are returned to the client.
*/
-class DefineFilterJob : public BaseJob {
+class QUOTIENT_API DefineFilterJob : public BaseJob {
public:
/*! \brief Upload a new filter.
*
@@ -41,7 +41,7 @@ public:
/*! \brief Download a filter
*
*/
-class GetFilterJob : public BaseJob {
+class QUOTIENT_API GetFilterJob : public BaseJob {
public:
/*! \brief Download a filter
*
diff --git a/lib/csapi/inviting.cpp b/lib/csapi/inviting.cpp
index 01620f9e..41a8b5be 100644
--- a/lib/csapi/inviting.cpp
+++ b/lib/csapi/inviting.cpp
@@ -4,16 +4,15 @@
#include "inviting.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
-InviteUserJob::InviteUserJob(const QString& roomId, const QString& userId)
+InviteUserJob::InviteUserJob(const QString& roomId, const QString& userId,
+ const QString& reason)
: BaseJob(HttpVerb::Post, QStringLiteral("InviteUserJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/invite")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/invite"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("user_id"), userId);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("user_id"), userId);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/inviting.h b/lib/csapi/inviting.h
index 1e65ecff..cb9d052b 100644
--- a/lib/csapi/inviting.h
+++ b/lib/csapi/inviting.h
@@ -14,7 +14,7 @@ namespace Quotient {
* This version of the API requires that the inviter knows the Matrix
* identifier of the invitee. The other is documented in the*
* [third party invites
- * section](/client-server-api/#post_matrixclientr0roomsroomidinvite-1).
+ * section](/client-server-api/#post_matrixclientv3roomsroomidinvite-1).
*
* This API invites a user to participate in a particular room.
* They do not start participating in the room until they actually join the
@@ -26,7 +26,7 @@ namespace Quotient {
* If the user was invited to the room, the homeserver will append a
* `m.room.member` event to the room.
*/
-class InviteUserJob : public BaseJob {
+class QUOTIENT_API InviteUserJob : public BaseJob {
public:
/*! \brief Invite a user to participate in a particular room.
*
@@ -35,8 +35,13 @@ public:
*
* \param userId
* The fully qualified user ID of the invitee.
+ *
+ * \param reason
+ * Optional reason to be included as the `reason` on the subsequent
+ * membership event.
*/
- explicit InviteUserJob(const QString& roomId, const QString& userId);
+ explicit InviteUserJob(const QString& roomId, const QString& userId,
+ const QString& reason = {});
};
} // namespace Quotient
diff --git a/lib/csapi/joining.cpp b/lib/csapi/joining.cpp
index 4761e949..cdba95e9 100644
--- a/lib/csapi/joining.cpp
+++ b/lib/csapi/joining.cpp
@@ -4,39 +4,41 @@
#include "joining.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
JoinRoomByIdJob::JoinRoomByIdJob(
- const QString& roomId, const Omittable<ThirdPartySigned>& thirdPartySigned)
+ const QString& roomId, const Omittable<ThirdPartySigned>& thirdPartySigned,
+ const QString& reason)
: BaseJob(HttpVerb::Post, QStringLiteral("JoinRoomByIdJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId % "/join")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/join"))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("third_party_signed"),
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("third_party_signed"),
thirdPartySigned);
- setRequestData(std::move(_data));
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
addExpectedKey("room_id");
}
auto queryToJoinRoom(const QStringList& serverName)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("server_name"), serverName);
return _q;
}
JoinRoomJob::JoinRoomJob(const QString& roomIdOrAlias,
const QStringList& serverName,
- const Omittable<ThirdPartySigned>& thirdPartySigned)
+ const Omittable<ThirdPartySigned>& thirdPartySigned,
+ const QString& reason)
: BaseJob(HttpVerb::Post, QStringLiteral("JoinRoomJob"),
- QStringLiteral("/_matrix/client/r0") % "/join/" % roomIdOrAlias,
+ makePath("/_matrix/client/v3", "/join/", roomIdOrAlias),
queryToJoinRoom(serverName))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("third_party_signed"),
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("third_party_signed"),
thirdPartySigned);
- setRequestData(std::move(_data));
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
addExpectedKey("room_id");
}
diff --git a/lib/csapi/joining.h b/lib/csapi/joining.h
index 1b6f99e4..c86baa90 100644
--- a/lib/csapi/joining.h
+++ b/lib/csapi/joining.h
@@ -22,10 +22,10 @@ namespace Quotient {
*
* After a user has joined a room, the room will appear as an entry in the
* response of the
- * [`/initialSync`](/client-server-api/#get_matrixclientr0initialsync) and
- * [`/sync`](/client-server-api/#get_matrixclientr0sync) APIs.
+ * [`/initialSync`](/client-server-api/#get_matrixclientv3initialsync) and
+ * [`/sync`](/client-server-api/#get_matrixclientv3sync) APIs.
*/
-class JoinRoomByIdJob : public BaseJob {
+class QUOTIENT_API JoinRoomByIdJob : public BaseJob {
public:
/*! \brief Start the requesting user participating in a particular room.
*
@@ -36,10 +36,15 @@ public:
* If supplied, the homeserver must verify that it matches a pending
* `m.room.third_party_invite` event in the room, and perform
* key validity checking if required by the event.
+ *
+ * \param reason
+ * Optional reason to be included as the `reason` on the subsequent
+ * membership event.
*/
explicit JoinRoomByIdJob(
const QString& roomId,
- const Omittable<ThirdPartySigned>& thirdPartySigned = none);
+ const Omittable<ThirdPartySigned>& thirdPartySigned = none,
+ const QString& reason = {});
// Result properties
@@ -50,7 +55,7 @@ public:
/*! \brief Start the requesting user participating in a particular room.
*
* *Note that this API takes either a room ID or alias, unlike*
- * `/room/{roomId}/join`.
+ * `/rooms/{roomId}/join`.
*
* This API starts a user participating in a particular room, if that user
* is allowed to participate in that room. After this call, the client is
@@ -59,10 +64,10 @@ public:
*
* After a user has joined a room, the room will appear as an entry in the
* response of the
- * [`/initialSync`](/client-server-api/#get_matrixclientr0initialsync) and
- * [`/sync`](/client-server-api/#get_matrixclientr0sync) APIs.
+ * [`/initialSync`](/client-server-api/#get_matrixclientv3initialsync) and
+ * [`/sync`](/client-server-api/#get_matrixclientv3sync) APIs.
*/
-class JoinRoomJob : public BaseJob {
+class QUOTIENT_API JoinRoomJob : public BaseJob {
public:
/*! \brief Start the requesting user participating in a particular room.
*
@@ -77,10 +82,15 @@ public:
* If a `third_party_signed` was supplied, the homeserver must verify
* that it matches a pending `m.room.third_party_invite` event in the
* room, and perform key validity checking if required by the event.
+ *
+ * \param reason
+ * Optional reason to be included as the `reason` on the subsequent
+ * membership event.
*/
explicit JoinRoomJob(
const QString& roomIdOrAlias, const QStringList& serverName = {},
- const Omittable<ThirdPartySigned>& thirdPartySigned = none);
+ const Omittable<ThirdPartySigned>& thirdPartySigned = none,
+ const QString& reason = {});
// Result properties
diff --git a/lib/csapi/keys.cpp b/lib/csapi/keys.cpp
index 34ab47c9..2e4978f2 100644
--- a/lib/csapi/keys.cpp
+++ b/lib/csapi/keys.cpp
@@ -4,50 +4,52 @@
#include "keys.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
UploadKeysJob::UploadKeysJob(const Omittable<DeviceKeys>& deviceKeys,
- const QHash<QString, QVariant>& oneTimeKeys)
+ const OneTimeKeys& oneTimeKeys,
+ const OneTimeKeys& fallbackKeys)
: BaseJob(HttpVerb::Post, QStringLiteral("UploadKeysJob"),
- QStringLiteral("/_matrix/client/r0") % "/keys/upload")
+ makePath("/_matrix/client/v3", "/keys/upload"))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("device_keys"), deviceKeys);
- addParam<IfNotEmpty>(_data, QStringLiteral("one_time_keys"), oneTimeKeys);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("device_keys"), deviceKeys);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("one_time_keys"),
+ oneTimeKeys);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("fallback_keys"),
+ fallbackKeys);
+ setRequestData({ _dataJson });
addExpectedKey("one_time_key_counts");
}
QueryKeysJob::QueryKeysJob(const QHash<QString, QStringList>& deviceKeys,
Omittable<int> timeout, const QString& token)
: BaseJob(HttpVerb::Post, QStringLiteral("QueryKeysJob"),
- QStringLiteral("/_matrix/client/r0") % "/keys/query")
+ makePath("/_matrix/client/v3", "/keys/query"))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("timeout"), timeout);
- addParam<>(_data, QStringLiteral("device_keys"), deviceKeys);
- addParam<IfNotEmpty>(_data, QStringLiteral("token"), token);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("timeout"), timeout);
+ addParam<>(_dataJson, QStringLiteral("device_keys"), deviceKeys);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("token"), token);
+ setRequestData({ _dataJson });
}
ClaimKeysJob::ClaimKeysJob(
const QHash<QString, QHash<QString, QString>>& oneTimeKeys,
Omittable<int> timeout)
: BaseJob(HttpVerb::Post, QStringLiteral("ClaimKeysJob"),
- QStringLiteral("/_matrix/client/r0") % "/keys/claim")
+ makePath("/_matrix/client/v3", "/keys/claim"))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("timeout"), timeout);
- addParam<>(_data, QStringLiteral("one_time_keys"), oneTimeKeys);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("timeout"), timeout);
+ addParam<>(_dataJson, QStringLiteral("one_time_keys"), oneTimeKeys);
+ setRequestData({ _dataJson });
addExpectedKey("one_time_keys");
}
auto queryToGetKeysChanges(const QString& from, const QString& to)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<>(_q, QStringLiteral("from"), from);
addParam<>(_q, QStringLiteral("to"), to);
return _q;
@@ -57,13 +59,13 @@ QUrl GetKeysChangesJob::makeRequestUrl(QUrl baseUrl, const QString& from,
const QString& to)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/keys/changes",
+ makePath("/_matrix/client/v3",
+ "/keys/changes"),
queryToGetKeysChanges(from, to));
}
GetKeysChangesJob::GetKeysChangesJob(const QString& from, const QString& to)
: BaseJob(HttpVerb::Get, QStringLiteral("GetKeysChangesJob"),
- QStringLiteral("/_matrix/client/r0") % "/keys/changes",
+ makePath("/_matrix/client/v3", "/keys/changes"),
queryToGetKeysChanges(from, to))
{}
diff --git a/lib/csapi/keys.h b/lib/csapi/keys.h
index 621945eb..b28de305 100644
--- a/lib/csapi/keys.h
+++ b/lib/csapi/keys.h
@@ -4,8 +4,11 @@
#pragma once
+#include "csapi/definitions/cross_signing_key.h"
#include "csapi/definitions/device_keys.h"
+#include "e2ee/e2ee.h"
+
#include "jobs/basejob.h"
namespace Quotient {
@@ -14,7 +17,7 @@ namespace Quotient {
*
* Publishes end-to-end encryption keys for the device.
*/
-class UploadKeysJob : public BaseJob {
+class QUOTIENT_API UploadKeysJob : public BaseJob {
public:
/*! \brief Upload end-to-end encryption keys.
*
@@ -29,14 +32,32 @@ public:
* by the [key algorithm](/client-server-api/#key-algorithms).
*
* May be absent if no new one-time keys are required.
+ *
+ * \param fallbackKeys
+ * The public key which should be used if the device's one-time keys
+ * are exhausted. The fallback key is not deleted once used, but should
+ * be replaced when additional one-time keys are being uploaded. The
+ * server will notify the client of the fallback key being used through
+ * `/sync`.
+ *
+ * There can only be at most one key per algorithm uploaded, and the
+ * server will only persist one key per algorithm.
+ *
+ * When uploading a signed key, an additional `fallback: true` key should
+ * be included to denote that the key is a fallback key.
+ *
+ * May be absent if a new fallback key is not required.
*/
explicit UploadKeysJob(const Omittable<DeviceKeys>& deviceKeys = none,
- const QHash<QString, QVariant>& oneTimeKeys = {});
+ const OneTimeKeys& oneTimeKeys = {},
+ const OneTimeKeys& fallbackKeys = {});
// Result properties
/// For each key algorithm, the number of unclaimed one-time keys
/// of that type currently held on the server for this device.
+ /// If an algorithm is not listed, the count for that algorithm
+ /// is to be assumed zero.
QHash<QString, int> oneTimeKeyCounts() const
{
return loadFromJson<QHash<QString, int>>("one_time_key_counts"_ls);
@@ -47,7 +68,7 @@ public:
*
* Returns the current devices and identity keys for the given users.
*/
-class QueryKeysJob : public BaseJob {
+class QUOTIENT_API QueryKeysJob : public BaseJob {
public:
// Inner data structures
@@ -114,6 +135,38 @@ public:
return loadFromJson<QHash<QString, QHash<QString, DeviceInformation>>>(
"device_keys"_ls);
}
+
+ /// Information on the master cross-signing keys of the queried users.
+ /// A map from user ID, to master key information. For each key, the
+ /// information returned will be the same as uploaded via
+ /// `/keys/device_signing/upload`, along with the signatures
+ /// uploaded via `/keys/signatures/upload` that the requesting user
+ /// is allowed to see.
+ QHash<QString, CrossSigningKey> masterKeys() const
+ {
+ return loadFromJson<QHash<QString, CrossSigningKey>>("master_keys"_ls);
+ }
+
+ /// Information on the self-signing keys of the queried users. A map
+ /// from user ID, to self-signing key information. For each key, the
+ /// information returned will be the same as uploaded via
+ /// `/keys/device_signing/upload`.
+ QHash<QString, CrossSigningKey> selfSigningKeys() const
+ {
+ return loadFromJson<QHash<QString, CrossSigningKey>>(
+ "self_signing_keys"_ls);
+ }
+
+ /// Information on the user-signing key of the user making the
+ /// request, if they queried their own device information. A map
+ /// from user ID, to user-signing key information. The
+ /// information returned will be the same as uploaded via
+ /// `/keys/device_signing/upload`.
+ QHash<QString, CrossSigningKey> userSigningKeys() const
+ {
+ return loadFromJson<QHash<QString, CrossSigningKey>>(
+ "user_signing_keys"_ls);
+ }
};
template <>
@@ -139,7 +192,7 @@ struct JsonObjectConverter<QueryKeysJob::DeviceInformation> {
*
* Claims one-time keys for use in pre-key messages.
*/
-class ClaimKeysJob : public BaseJob {
+class QUOTIENT_API ClaimKeysJob : public BaseJob {
public:
/*! \brief Claim one-time encryption keys.
*
@@ -174,9 +227,12 @@ public:
///
/// See the [key algorithms](/client-server-api/#key-algorithms) section for
/// information on the Key Object format.
- QHash<QString, QHash<QString, QVariant>> oneTimeKeys() const
+ ///
+ /// If necessary, the claimed key might be a fallback key. Fallback
+ /// keys are re-used by the server until replaced by the device.
+ QHash<QString, QHash<QString, OneTimeKeys>> oneTimeKeys() const
{
- return loadFromJson<QHash<QString, QHash<QString, QVariant>>>(
+ return loadFromJson<QHash<QString, QHash<QString, OneTimeKeys>>>(
"one_time_keys"_ls);
}
};
@@ -193,14 +249,14 @@ public:
* * added new device identity keys or removed an existing device with
* identity keys, between `from` and `to`.
*/
-class GetKeysChangesJob : public BaseJob {
+class QUOTIENT_API GetKeysChangesJob : public BaseJob {
public:
/*! \brief Query users with recent device key updates.
*
* \param from
* The desired start point of the list. Should be the `next_batch` field
* from a response to an earlier call to
- * [`/sync`](/client-server-api/#get_matrixclientr0sync). Users who have not
+ * [`/sync`](/client-server-api/#get_matrixclientv3sync). Users who have not
* uploaded new device identity keys since this point, nor deleted
* existing devices with identity keys since then, will be excluded
* from the results.
@@ -208,7 +264,7 @@ public:
* \param to
* The desired end point of the list. Should be the `next_batch`
* field from a recent call to
- * [`/sync`](/client-server-api/#get_matrixclientr0sync) - typically the
+ * [`/sync`](/client-server-api/#get_matrixclientv3sync) - typically the
* most recent such call. This may be used by the server as a hint to check
* its caches are up to date.
*/
diff --git a/lib/csapi/kicking.cpp b/lib/csapi/kicking.cpp
index 7de5ce01..4ca39c4c 100644
--- a/lib/csapi/kicking.cpp
+++ b/lib/csapi/kicking.cpp
@@ -4,17 +4,15 @@
#include "kicking.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
KickJob::KickJob(const QString& roomId, const QString& userId,
const QString& reason)
: BaseJob(HttpVerb::Post, QStringLiteral("KickJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId % "/kick")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/kick"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("user_id"), userId);
- addParam<IfNotEmpty>(_data, QStringLiteral("reason"), reason);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("user_id"), userId);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/kicking.h b/lib/csapi/kicking.h
index 11018368..6ac106e2 100644
--- a/lib/csapi/kicking.h
+++ b/lib/csapi/kicking.h
@@ -20,7 +20,7 @@ namespace Quotient {
* directly adjust the target member's state by making a request to
* `/rooms/<room id>/state/m.room.member/<user id>`.
*/
-class KickJob : public BaseJob {
+class QUOTIENT_API KickJob : public BaseJob {
public:
/*! \brief Kick a user from the room.
*
diff --git a/lib/csapi/knocking.cpp b/lib/csapi/knocking.cpp
new file mode 100644
index 00000000..b9da4b9b
--- /dev/null
+++ b/lib/csapi/knocking.cpp
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#include "knocking.h"
+
+using namespace Quotient;
+
+auto queryToKnockRoom(const QStringList& serverName)
+{
+ QUrlQuery _q;
+ addParam<IfNotEmpty>(_q, QStringLiteral("server_name"), serverName);
+ return _q;
+}
+
+KnockRoomJob::KnockRoomJob(const QString& roomIdOrAlias,
+ const QStringList& serverName, const QString& reason)
+ : BaseJob(HttpVerb::Post, QStringLiteral("KnockRoomJob"),
+ makePath("/_matrix/client/v3", "/knock/", roomIdOrAlias),
+ queryToKnockRoom(serverName))
+{
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
+ addExpectedKey("room_id");
+}
diff --git a/lib/csapi/knocking.h b/lib/csapi/knocking.h
new file mode 100644
index 00000000..f43033a8
--- /dev/null
+++ b/lib/csapi/knocking.h
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "jobs/basejob.h"
+
+namespace Quotient {
+
+/*! \brief Knock on a room, requesting permission to join.
+ *
+ * *Note that this API takes either a room ID or alias, unlike other membership
+ * APIs.*
+ *
+ * This API "knocks" on the room to ask for permission to join, if the user
+ * is allowed to knock on the room. Acceptance of the knock happens out of
+ * band from this API, meaning that the client will have to watch for updates
+ * regarding the acceptance/rejection of the knock.
+ *
+ * If the room history settings allow, the user will still be able to see
+ * history of the room while being in the "knock" state. The user will have
+ * to accept the invitation to join the room (acceptance of knock) to see
+ * messages reliably. See the `/join` endpoints for more information about
+ * history visibility to the user.
+ *
+ * The knock will appear as an entry in the response of the
+ * [`/sync`](/client-server-api/#get_matrixclientv3sync) API.
+ */
+class QUOTIENT_API KnockRoomJob : public BaseJob {
+public:
+ /*! \brief Knock on a room, requesting permission to join.
+ *
+ * \param roomIdOrAlias
+ * The room identifier or alias to knock upon.
+ *
+ * \param serverName
+ * The servers to attempt to knock on the room through. One of the servers
+ * must be participating in the room.
+ *
+ * \param reason
+ * Optional reason to be included as the `reason` on the subsequent
+ * membership event.
+ */
+ explicit KnockRoomJob(const QString& roomIdOrAlias,
+ const QStringList& serverName = {},
+ const QString& reason = {});
+
+ // Result properties
+
+ /// The knocked room ID.
+ QString roomId() const { return loadFromJson<QString>("room_id"_ls); }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/leaving.cpp b/lib/csapi/leaving.cpp
index 8bd170bf..ba91f26a 100644
--- a/lib/csapi/leaving.cpp
+++ b/lib/csapi/leaving.cpp
@@ -4,32 +4,25 @@
#include "leaving.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
-QUrl LeaveRoomJob::makeRequestUrl(QUrl baseUrl, const QString& roomId)
+LeaveRoomJob::LeaveRoomJob(const QString& roomId, const QString& reason)
+ : BaseJob(HttpVerb::Post, QStringLiteral("LeaveRoomJob"),
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/leave"))
{
- return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/rooms/" % roomId % "/leave");
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
}
-LeaveRoomJob::LeaveRoomJob(const QString& roomId)
- : BaseJob(HttpVerb::Post, QStringLiteral("LeaveRoomJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/leave")
-{}
-
QUrl ForgetRoomJob::makeRequestUrl(QUrl baseUrl, const QString& roomId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/rooms/" % roomId % "/forget");
+ makePath("/_matrix/client/v3", "/rooms/",
+ roomId, "/forget"));
}
ForgetRoomJob::ForgetRoomJob(const QString& roomId)
: BaseJob(HttpVerb::Post, QStringLiteral("ForgetRoomJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/forget")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/forget"))
{}
diff --git a/lib/csapi/leaving.h b/lib/csapi/leaving.h
index 1bea7e41..19cac3f0 100644
--- a/lib/csapi/leaving.h
+++ b/lib/csapi/leaving.h
@@ -22,21 +22,18 @@ namespace Quotient {
* The user will still be allowed to retrieve history from the room which
* they were previously allowed to see.
*/
-class LeaveRoomJob : public BaseJob {
+class QUOTIENT_API LeaveRoomJob : public BaseJob {
public:
/*! \brief Stop the requesting user participating in a particular room.
*
* \param roomId
* The room identifier to leave.
- */
- explicit LeaveRoomJob(const QString& roomId);
-
- /*! \brief Construct a URL without creating a full-fledged job object
*
- * This function can be used when a URL for LeaveRoomJob
- * is necessary but the job itself isn't.
+ * \param reason
+ * Optional reason to be included as the `reason` on the subsequent
+ * membership event.
*/
- static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId);
+ explicit LeaveRoomJob(const QString& roomId, const QString& reason = {});
};
/*! \brief Stop the requesting user remembering about a particular room.
@@ -51,7 +48,7 @@ public:
* If the user is currently joined to the room, they must leave the room
* before calling this API.
*/
-class ForgetRoomJob : public BaseJob {
+class QUOTIENT_API ForgetRoomJob : public BaseJob {
public:
/*! \brief Stop the requesting user remembering about a particular room.
*
diff --git a/lib/csapi/list_joined_rooms.cpp b/lib/csapi/list_joined_rooms.cpp
index 8d7e267f..cdcf3eb2 100644
--- a/lib/csapi/list_joined_rooms.cpp
+++ b/lib/csapi/list_joined_rooms.cpp
@@ -4,20 +4,17 @@
#include "list_joined_rooms.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetJoinedRoomsJob::makeRequestUrl(QUrl baseUrl)
{
- return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/joined_rooms");
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl), makePath("/_matrix/client/v3", "/joined_rooms"));
}
GetJoinedRoomsJob::GetJoinedRoomsJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetJoinedRoomsJob"),
- QStringLiteral("/_matrix/client/r0") % "/joined_rooms")
+ makePath("/_matrix/client/v3", "/joined_rooms"))
{
addExpectedKey("joined_rooms");
}
diff --git a/lib/csapi/list_joined_rooms.h b/lib/csapi/list_joined_rooms.h
index 59a24a49..aea68afd 100644
--- a/lib/csapi/list_joined_rooms.h
+++ b/lib/csapi/list_joined_rooms.h
@@ -12,7 +12,7 @@ namespace Quotient {
*
* This API returns a list of the user's current rooms.
*/
-class GetJoinedRoomsJob : public BaseJob {
+class QUOTIENT_API GetJoinedRoomsJob : public BaseJob {
public:
/// Lists the user's current rooms.
explicit GetJoinedRoomsJob();
diff --git a/lib/csapi/list_public_rooms.cpp b/lib/csapi/list_public_rooms.cpp
index 415d816c..4deecfc2 100644
--- a/lib/csapi/list_public_rooms.cpp
+++ b/lib/csapi/list_public_rooms.cpp
@@ -4,41 +4,37 @@
#include "list_public_rooms.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetRoomVisibilityOnDirectoryJob::makeRequestUrl(QUrl baseUrl,
const QString& roomId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/directory/list/room/" % roomId);
+ makePath("/_matrix/client/v3",
+ "/directory/list/room/", roomId));
}
GetRoomVisibilityOnDirectoryJob::GetRoomVisibilityOnDirectoryJob(
const QString& roomId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetRoomVisibilityOnDirectoryJob"),
- QStringLiteral("/_matrix/client/r0") % "/directory/list/room/"
- % roomId,
+ makePath("/_matrix/client/v3", "/directory/list/room/", roomId),
false)
{}
SetRoomVisibilityOnDirectoryJob::SetRoomVisibilityOnDirectoryJob(
const QString& roomId, const QString& visibility)
: BaseJob(HttpVerb::Put, QStringLiteral("SetRoomVisibilityOnDirectoryJob"),
- QStringLiteral("/_matrix/client/r0") % "/directory/list/room/"
- % roomId)
+ makePath("/_matrix/client/v3", "/directory/list/room/", roomId))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("visibility"), visibility);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("visibility"), visibility);
+ setRequestData({ _dataJson });
}
auto queryToGetPublicRooms(Omittable<int> limit, const QString& since,
const QString& server)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
addParam<IfNotEmpty>(_q, QStringLiteral("since"), since);
addParam<IfNotEmpty>(_q, QStringLiteral("server"), server);
@@ -50,15 +46,15 @@ QUrl GetPublicRoomsJob::makeRequestUrl(QUrl baseUrl, Omittable<int> limit,
const QString& server)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/publicRooms",
+ makePath("/_matrix/client/v3",
+ "/publicRooms"),
queryToGetPublicRooms(limit, since, server));
}
GetPublicRoomsJob::GetPublicRoomsJob(Omittable<int> limit, const QString& since,
const QString& server)
: BaseJob(HttpVerb::Get, QStringLiteral("GetPublicRoomsJob"),
- QStringLiteral("/_matrix/client/r0") % "/publicRooms",
+ makePath("/_matrix/client/v3", "/publicRooms"),
queryToGetPublicRooms(limit, since, server), {}, false)
{
addExpectedKey("chunk");
@@ -66,7 +62,7 @@ GetPublicRoomsJob::GetPublicRoomsJob(Omittable<int> limit, const QString& since,
auto queryToQueryPublicRooms(const QString& server)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("server"), server);
return _q;
}
@@ -78,17 +74,17 @@ QueryPublicRoomsJob::QueryPublicRoomsJob(const QString& server,
Omittable<bool> includeAllNetworks,
const QString& thirdPartyInstanceId)
: BaseJob(HttpVerb::Post, QStringLiteral("QueryPublicRoomsJob"),
- QStringLiteral("/_matrix/client/r0") % "/publicRooms",
+ makePath("/_matrix/client/v3", "/publicRooms"),
queryToQueryPublicRooms(server))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("limit"), limit);
- addParam<IfNotEmpty>(_data, QStringLiteral("since"), since);
- addParam<IfNotEmpty>(_data, QStringLiteral("filter"), filter);
- addParam<IfNotEmpty>(_data, QStringLiteral("include_all_networks"),
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("since"), since);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("filter"), filter);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("include_all_networks"),
includeAllNetworks);
- addParam<IfNotEmpty>(_data, QStringLiteral("third_party_instance_id"),
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("third_party_instance_id"),
thirdPartyInstanceId);
- setRequestData(std::move(_data));
+ setRequestData({ _dataJson });
addExpectedKey("chunk");
}
diff --git a/lib/csapi/list_public_rooms.h b/lib/csapi/list_public_rooms.h
index 963c8b56..3b6b91b9 100644
--- a/lib/csapi/list_public_rooms.h
+++ b/lib/csapi/list_public_rooms.h
@@ -14,7 +14,7 @@ namespace Quotient {
*
* Gets the visibility of a given room on the server's public room directory.
*/
-class GetRoomVisibilityOnDirectoryJob : public BaseJob {
+class QUOTIENT_API GetRoomVisibilityOnDirectoryJob : public BaseJob {
public:
/*! \brief Gets the visibility of a room in the directory
*
@@ -48,7 +48,7 @@ public:
* here, for instance that room visibility can only be changed by
* the room creator or a server administrator.
*/
-class SetRoomVisibilityOnDirectoryJob : public BaseJob {
+class QUOTIENT_API SetRoomVisibilityOnDirectoryJob : public BaseJob {
public:
/*! \brief Sets the visibility of a room in the room directory
*
@@ -70,7 +70,7 @@ public:
* This API returns paginated responses. The rooms are ordered by the number
* of joined members, with the largest rooms first.
*/
-class GetPublicRoomsJob : public BaseJob {
+class QUOTIENT_API GetPublicRoomsJob : public BaseJob {
public:
/*! \brief Lists the public rooms on the server.
*
@@ -133,15 +133,20 @@ public:
* This API returns paginated responses. The rooms are ordered by the number
* of joined members, with the largest rooms first.
*/
-class QueryPublicRoomsJob : public BaseJob {
+class QUOTIENT_API QueryPublicRoomsJob : public BaseJob {
public:
// Inner data structures
/// Filter to apply to the results.
struct Filter {
- /// A string to search for in the room metadata, e.g. name,
- /// topic, canonical alias etc. (Optional).
+ /// An optional string to search for in the room metadata, e.g. name,
+ /// topic, canonical alias, etc.
QString genericSearchTerm;
+ /// An optional list of [room types](/client-server-api/#types) to
+ /// search for. To include rooms without a room type, specify `null`
+ /// within this list. When not specified, all applicable rooms
+ /// (regardless of type) are returned.
+ QStringList roomTypes;
};
// Construction/destruction
@@ -211,6 +216,7 @@ struct JsonObjectConverter<QueryPublicRoomsJob::Filter> {
{
addParam<IfNotEmpty>(jo, QStringLiteral("generic_search_term"),
pod.genericSearchTerm);
+ addParam<IfNotEmpty>(jo, QStringLiteral("room_types"), pod.roomTypes);
}
};
diff --git a/lib/csapi/login.cpp b/lib/csapi/login.cpp
index a5bac9ea..7bb74e29 100644
--- a/lib/csapi/login.cpp
+++ b/lib/csapi/login.cpp
@@ -4,37 +4,41 @@
#include "login.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetLoginFlowsJob::makeRequestUrl(QUrl baseUrl)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/login");
+ makePath("/_matrix/client/v3", "/login"));
}
GetLoginFlowsJob::GetLoginFlowsJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetLoginFlowsJob"),
- QStringLiteral("/_matrix/client/r0") % "/login", false)
+ makePath("/_matrix/client/v3", "/login"), false)
{}
LoginJob::LoginJob(const QString& type,
const Omittable<UserIdentifier>& identifier,
const QString& password, const QString& token,
const QString& deviceId,
- const QString& initialDeviceDisplayName)
+ const QString& initialDeviceDisplayName,
+ Omittable<bool> refreshToken)
: BaseJob(HttpVerb::Post, QStringLiteral("LoginJob"),
- QStringLiteral("/_matrix/client/r0") % "/login", false)
+ makePath("/_matrix/client/v3", "/login"), false)
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("type"), type);
- addParam<IfNotEmpty>(_data, QStringLiteral("identifier"), identifier);
- addParam<IfNotEmpty>(_data, QStringLiteral("password"), password);
- addParam<IfNotEmpty>(_data, QStringLiteral("token"), token);
- addParam<IfNotEmpty>(_data, QStringLiteral("device_id"), deviceId);
- addParam<IfNotEmpty>(_data, QStringLiteral("initial_device_display_name"),
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("type"), type);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("identifier"), identifier);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("password"), password);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("token"), token);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("device_id"), deviceId);
+ addParam<IfNotEmpty>(_dataJson,
+ QStringLiteral("initial_device_display_name"),
initialDeviceDisplayName);
- setRequestData(std::move(_data));
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("refresh_token"),
+ refreshToken);
+ setRequestData({ _dataJson });
+ addExpectedKey("user_id");
+ addExpectedKey("access_token");
+ addExpectedKey("device_id");
}
diff --git a/lib/csapi/login.h b/lib/csapi/login.h
index b35db1eb..b9f14266 100644
--- a/lib/csapi/login.h
+++ b/lib/csapi/login.h
@@ -16,7 +16,7 @@ namespace Quotient {
* Gets the homeserver's supported login types to authenticate users. Clients
* should pick one of these and supply it as the `type` when logging in.
*/
-class GetLoginFlowsJob : public BaseJob {
+class QUOTIENT_API GetLoginFlowsJob : public BaseJob {
public:
// Inner data structures
@@ -73,7 +73,7 @@ struct JsonObjectConverter<GetLoginFlowsJob::LoginFlow> {
* [Relationship between access tokens and
* devices](/client-server-api/#relationship-between-access-tokens-and-devices).
*/
-class LoginJob : public BaseJob {
+class QUOTIENT_API LoginJob : public BaseJob {
public:
/*! \brief Authenticates the user.
*
@@ -111,12 +111,16 @@ public:
* \param initialDeviceDisplayName
* A display name to assign to the newly-created device. Ignored
* if `device_id` corresponds to a known device.
+ *
+ * \param refreshToken
+ * If true, the client supports refresh tokens.
*/
explicit LoginJob(const QString& type,
const Omittable<UserIdentifier>& identifier = none,
const QString& password = {}, const QString& token = {},
const QString& deviceId = {},
- const QString& initialDeviceDisplayName = {});
+ const QString& initialDeviceDisplayName = {},
+ Omittable<bool> refreshToken = none);
// Result properties
@@ -130,15 +134,23 @@ public:
return loadFromJson<QString>("access_token"_ls);
}
- /// The server_name of the homeserver on which the account has
- /// been registered.
- ///
- /// **Deprecated**. Clients should extract the server_name from
- /// `user_id` (by splitting at the first colon) if they require
- /// it. Note also that `homeserver` is not spelt this way.
- QString homeServer() const
+ /// A refresh token for the account. This token can be used to
+ /// obtain a new access token when it expires by calling the
+ /// `/refresh` endpoint.
+ QString refreshToken() const
+ {
+ return loadFromJson<QString>("refresh_token"_ls);
+ }
+
+ /// The lifetime of the access token, in milliseconds. Once
+ /// the access token has expired a new access token can be
+ /// obtained by using the provided refresh token. If no
+ /// refresh token is provided, the client will need to re-log in
+ /// to obtain a new access token. If not given, the client can
+ /// assume that the access token will not expire.
+ Omittable<int> expiresInMs() const
{
- return loadFromJson<QString>("home_server"_ls);
+ return loadFromJson<Omittable<int>>("expires_in_ms"_ls);
}
/// ID of the logged-in device. Will be the same as the
diff --git a/lib/csapi/logout.cpp b/lib/csapi/logout.cpp
index 9583b8ec..9ec54c71 100644
--- a/lib/csapi/logout.cpp
+++ b/lib/csapi/logout.cpp
@@ -4,30 +4,26 @@
#include "logout.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl LogoutJob::makeRequestUrl(QUrl baseUrl)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/logout");
+ makePath("/_matrix/client/v3", "/logout"));
}
LogoutJob::LogoutJob()
: BaseJob(HttpVerb::Post, QStringLiteral("LogoutJob"),
- QStringLiteral("/_matrix/client/r0") % "/logout")
+ makePath("/_matrix/client/v3", "/logout"))
{}
QUrl LogoutAllJob::makeRequestUrl(QUrl baseUrl)
{
- return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/logout/all");
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl), makePath("/_matrix/client/v3", "/logout/all"));
}
LogoutAllJob::LogoutAllJob()
: BaseJob(HttpVerb::Post, QStringLiteral("LogoutAllJob"),
- QStringLiteral("/_matrix/client/r0") % "/logout/all")
+ makePath("/_matrix/client/v3", "/logout/all"))
{}
diff --git a/lib/csapi/logout.h b/lib/csapi/logout.h
index 2e4c2692..3f1ac7fa 100644
--- a/lib/csapi/logout.h
+++ b/lib/csapi/logout.h
@@ -15,7 +15,7 @@ namespace Quotient {
* [Device keys](/client-server-api/#device-keys) for the device are deleted
* alongside the device.
*/
-class LogoutJob : public BaseJob {
+class QUOTIENT_API LogoutJob : public BaseJob {
public:
/// Invalidates a user access token
explicit LogoutJob();
@@ -44,7 +44,7 @@ public:
* used in the request, and therefore the attacker is unable to take over the
* account in this way.
*/
-class LogoutAllJob : public BaseJob {
+class QUOTIENT_API LogoutAllJob : public BaseJob {
public:
/// Invalidates all access tokens for a user
explicit LogoutAllJob();
diff --git a/lib/csapi/message_pagination.cpp b/lib/csapi/message_pagination.cpp
index 855c051f..0b2c99ce 100644
--- a/lib/csapi/message_pagination.cpp
+++ b/lib/csapi/message_pagination.cpp
@@ -4,16 +4,14 @@
#include "message_pagination.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
auto queryToGetRoomEvents(const QString& from, const QString& to,
const QString& dir, Omittable<int> limit,
const QString& filter)
{
- BaseJob::Query _q;
- addParam<>(_q, QStringLiteral("from"), from);
+ QUrlQuery _q;
+ addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
addParam<IfNotEmpty>(_q, QStringLiteral("to"), to);
addParam<>(_q, QStringLiteral("dir"), dir);
addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
@@ -22,21 +20,23 @@ auto queryToGetRoomEvents(const QString& from, const QString& to,
}
QUrl GetRoomEventsJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
- const QString& from, const QString& dir,
+ const QString& dir, const QString& from,
const QString& to, Omittable<int> limit,
const QString& filter)
{
return BaseJob::makeRequestUrl(
std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId % "/messages",
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/messages"),
queryToGetRoomEvents(from, to, dir, limit, filter));
}
-GetRoomEventsJob::GetRoomEventsJob(const QString& roomId, const QString& from,
- const QString& dir, const QString& to,
+GetRoomEventsJob::GetRoomEventsJob(const QString& roomId, const QString& dir,
+ const QString& from, const QString& to,
Omittable<int> limit, const QString& filter)
: BaseJob(HttpVerb::Get, QStringLiteral("GetRoomEventsJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/messages",
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/messages"),
queryToGetRoomEvents(from, to, dir, limit, filter))
-{}
+{
+ addExpectedKey("start");
+ addExpectedKey("chunk");
+}
diff --git a/lib/csapi/message_pagination.h b/lib/csapi/message_pagination.h
index 363e4d99..b4f3a38a 100644
--- a/lib/csapi/message_pagination.h
+++ b/lib/csapi/message_pagination.h
@@ -4,7 +4,7 @@
#pragma once
-#include "events/eventloader.h"
+#include "events/roomevent.h"
#include "jobs/basejob.h"
namespace Quotient {
@@ -18,27 +18,37 @@ namespace Quotient {
* [Lazy-loading room members](/client-server-api/#lazy-loading-room-members)
* for more information.
*/
-class GetRoomEventsJob : public BaseJob {
+class QUOTIENT_API GetRoomEventsJob : public BaseJob {
public:
/*! \brief Get a list of events for this room
*
* \param roomId
* The room to get events from.
*
+ * \param dir
+ * The direction to return events from. If this is set to `f`, events
+ * will be returned in chronological order starting at `from`. If it
+ * is set to `b`, events will be returned in *reverse* chronological
+ * order, again starting at `from`.
+ *
* \param from
* The token to start returning events from. This token can be obtained
- * from a `prev_batch` token returned for each room by the sync API,
- * or from a `start` or `end` token returned by a previous request
- * to this endpoint.
+ * from a `prev_batch` or `next_batch` token returned by the `/sync`
+ * endpoint, or from an `end` token returned by a previous request to this
+ * endpoint.
*
- * \param dir
- * The direction to return events from.
+ * This endpoint can also accept a value returned as a `start` token
+ * by a previous request to this endpoint, though servers are not
+ * required to support this. Clients should not rely on the behaviour.
+ *
+ * If it is not provided, the homeserver shall return a list of messages
+ * from the first or last (per the value of the `dir` parameter) visible
+ * event in the room history for the requesting user.
*
* \param to
* The token to stop returning events at. This token can be obtained from
- * a `prev_batch` token returned for each room by the sync endpoint,
- * or from a `start` or `end` token returned by a previous request to
- * this endpoint.
+ * a `prev_batch` or `next_batch` token returned by the `/sync` endpoint,
+ * or from an `end` token returned by a previous request to this endpoint.
*
* \param limit
* The maximum number of events to return. Default: 10.
@@ -46,8 +56,8 @@ public:
* \param filter
* A JSON RoomEventFilter to filter returned events with.
*/
- explicit GetRoomEventsJob(const QString& roomId, const QString& from,
- const QString& dir, const QString& to = {},
+ explicit GetRoomEventsJob(const QString& roomId, const QString& dir,
+ const QString& from = {}, const QString& to = {},
Omittable<int> limit = none,
const QString& filter = {});
@@ -57,25 +67,34 @@ public:
* is necessary but the job itself isn't.
*/
static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId,
- const QString& from, const QString& dir,
+ const QString& dir, const QString& from = {},
const QString& to = {},
Omittable<int> limit = none,
const QString& filter = {});
// Result properties
- /// The token the pagination starts from. If `dir=b` this will be
- /// the token supplied in `from`.
+ /// A token corresponding to the start of `chunk`. This will be the same as
+ /// the value given in `from`.
QString begin() const { return loadFromJson<QString>("start"_ls); }
- /// The token the pagination ends at. If `dir=b` this token should
- /// be used again to request even earlier events.
+ /// A token corresponding to the end of `chunk`. This token can be passed
+ /// back to this endpoint to request further events.
+ ///
+ /// If no further events are available (either because we have
+ /// reached the start of the timeline, or because the user does
+ /// not have permission to see any more events), this property
+ /// is omitted from the response.
QString end() const { return loadFromJson<QString>("end"_ls); }
/// A list of room events. The order depends on the `dir` parameter.
/// For `dir=b` events will be in reverse-chronological order,
- /// for `dir=f` in chronological order, so that events start
- /// at the `from` point.
+ /// for `dir=f` in chronological order. (The exact definition of
+ /// `chronological` is dependent on the server implementation.)
+ ///
+ /// Note that an empty `chunk` does not *necessarily* imply that no more
+ /// events are available. Clients should continue to paginate until no `end`
+ /// property is returned.
RoomEvents chunk() { return takeFromJson<RoomEvents>("chunk"_ls); }
/// A list of state events relevant to showing the `chunk`. For example, if
@@ -86,7 +105,7 @@ public:
/// may remove membership events which would have already been
/// sent to the client in prior calls to this endpoint, assuming
/// the membership of those members has not changed.
- StateEvents state() { return takeFromJson<StateEvents>("state"_ls); }
+ RoomEvents state() { return takeFromJson<RoomEvents>("state"_ls); }
};
} // namespace Quotient
diff --git a/lib/csapi/notifications.cpp b/lib/csapi/notifications.cpp
index a479d500..38aed174 100644
--- a/lib/csapi/notifications.cpp
+++ b/lib/csapi/notifications.cpp
@@ -4,14 +4,12 @@
#include "notifications.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
auto queryToGetNotifications(const QString& from, Omittable<int> limit,
const QString& only)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
addParam<IfNotEmpty>(_q, QStringLiteral("only"), only);
@@ -23,8 +21,8 @@ QUrl GetNotificationsJob::makeRequestUrl(QUrl baseUrl, const QString& from,
const QString& only)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/notifications",
+ makePath("/_matrix/client/v3",
+ "/notifications"),
queryToGetNotifications(from, limit, only));
}
@@ -32,7 +30,7 @@ GetNotificationsJob::GetNotificationsJob(const QString& from,
Omittable<int> limit,
const QString& only)
: BaseJob(HttpVerb::Get, QStringLiteral("GetNotificationsJob"),
- QStringLiteral("/_matrix/client/r0") % "/notifications",
+ makePath("/_matrix/client/v3", "/notifications"),
queryToGetNotifications(from, limit, only))
{
addExpectedKey("notifications");
diff --git a/lib/csapi/notifications.h b/lib/csapi/notifications.h
index 0999fece..ff8aa47f 100644
--- a/lib/csapi/notifications.h
+++ b/lib/csapi/notifications.h
@@ -4,7 +4,7 @@
#pragma once
-#include "events/eventloader.h"
+#include "events/event.h"
#include "jobs/basejob.h"
namespace Quotient {
@@ -14,7 +14,7 @@ namespace Quotient {
* This API is used to paginate through the list of events that the
* user has been, or would have been notified about.
*/
-class GetNotificationsJob : public BaseJob {
+class QUOTIENT_API GetNotificationsJob : public BaseJob {
public:
// Inner data structures
@@ -35,7 +35,7 @@ public:
QString roomId;
/// The unix timestamp at which the event notification was sent,
/// in milliseconds.
- int ts;
+ qint64 ts;
};
// Construction/destruction
@@ -43,7 +43,8 @@ public:
/*! \brief Gets a list of events that the user has been notified about
*
* \param from
- * Pagination token given to retrieve the next set of events.
+ * Pagination token to continue from. This should be the `next_token`
+ * returned from an earlier call to this endpoint.
*
* \param limit
* Limit on the number of events to return in this request.
diff --git a/lib/csapi/openid.cpp b/lib/csapi/openid.cpp
index 3941e9c0..7e89b8a6 100644
--- a/lib/csapi/openid.cpp
+++ b/lib/csapi/openid.cpp
@@ -4,15 +4,13 @@
#include "openid.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
RequestOpenIdTokenJob::RequestOpenIdTokenJob(const QString& userId,
const QJsonObject& body)
: BaseJob(HttpVerb::Post, QStringLiteral("RequestOpenIdTokenJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/openid/request_token")
+ makePath("/_matrix/client/v3", "/user/", userId,
+ "/openid/request_token"))
{
- setRequestData(Data(toJson(body)));
+ setRequestData({ toJson(body) });
}
diff --git a/lib/csapi/openid.h b/lib/csapi/openid.h
index 0be39c8c..b3f72a25 100644
--- a/lib/csapi/openid.h
+++ b/lib/csapi/openid.h
@@ -21,7 +21,7 @@ namespace Quotient {
* be used to request another OpenID access token or call `/sync`, for
* example.
*/
-class RequestOpenIdTokenJob : public BaseJob {
+class QUOTIENT_API RequestOpenIdTokenJob : public BaseJob {
public:
/*! \brief Get an OpenID token object to verify the requester's identity.
*
@@ -43,7 +43,10 @@ public:
/// Specification](http://openid.net/specs/openid-connect-core-1_0.html#TokenResponse)
/// with the only difference being the lack of an `id_token`. Instead,
/// the Matrix homeserver's name is provided.
- OpenidToken tokenData() const { return fromJson<OpenidToken>(jsonData()); }
+ OpenIdCredentials tokenData() const
+ {
+ return fromJson<OpenIdCredentials>(jsonData());
+ }
};
} // namespace Quotient
diff --git a/lib/csapi/peeking_events.cpp b/lib/csapi/peeking_events.cpp
index 70a5b6f3..9dd1445e 100644
--- a/lib/csapi/peeking_events.cpp
+++ b/lib/csapi/peeking_events.cpp
@@ -4,14 +4,12 @@
#include "peeking_events.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
auto queryToPeekEvents(const QString& from, Omittable<int> timeout,
const QString& roomId)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
addParam<IfNotEmpty>(_q, QStringLiteral("timeout"), timeout);
addParam<IfNotEmpty>(_q, QStringLiteral("room_id"), roomId);
@@ -22,14 +20,13 @@ QUrl PeekEventsJob::makeRequestUrl(QUrl baseUrl, const QString& from,
Omittable<int> timeout, const QString& roomId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/events",
+ makePath("/_matrix/client/v3", "/events"),
queryToPeekEvents(from, timeout, roomId));
}
PeekEventsJob::PeekEventsJob(const QString& from, Omittable<int> timeout,
const QString& roomId)
: BaseJob(HttpVerb::Get, QStringLiteral("PeekEventsJob"),
- QStringLiteral("/_matrix/client/r0") % "/events",
+ makePath("/_matrix/client/v3", "/events"),
queryToPeekEvents(from, timeout, roomId))
{}
diff --git a/lib/csapi/peeking_events.h b/lib/csapi/peeking_events.h
index 885ff340..a67d2e4a 100644
--- a/lib/csapi/peeking_events.h
+++ b/lib/csapi/peeking_events.h
@@ -4,12 +4,12 @@
#pragma once
-#include "events/eventloader.h"
+#include "events/roomevent.h"
#include "jobs/basejob.h"
namespace Quotient {
-/*! \brief Listen on the event stream.
+/*! \brief Listen on the event stream of a particular room.
*
* This will listen for new events related to a particular room and return
* them to the caller. This will block until an event is received, or until
@@ -22,9 +22,9 @@ namespace Quotient {
* API will also be deprecated at some point, but its replacement is not
* yet known.
*/
-class PeekEventsJob : public BaseJob {
+class QUOTIENT_API PeekEventsJob : public BaseJob {
public:
- /*! \brief Listen on the event stream.
+ /*! \brief Listen on the event stream of a particular room.
*
* \param from
* The token to stream from. This token is either from a previous
diff --git a/lib/csapi/presence.cpp b/lib/csapi/presence.cpp
index 58d0d157..828ccfb7 100644
--- a/lib/csapi/presence.cpp
+++ b/lib/csapi/presence.cpp
@@ -4,33 +4,29 @@
#include "presence.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SetPresenceJob::SetPresenceJob(const QString& userId, const QString& presence,
const QString& statusMsg)
: BaseJob(HttpVerb::Put, QStringLiteral("SetPresenceJob"),
- QStringLiteral("/_matrix/client/r0") % "/presence/" % userId
- % "/status")
+ makePath("/_matrix/client/v3", "/presence/", userId, "/status"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("presence"), presence);
- addParam<IfNotEmpty>(_data, QStringLiteral("status_msg"), statusMsg);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("presence"), presence);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("status_msg"), statusMsg);
+ setRequestData({ _dataJson });
}
QUrl GetPresenceJob::makeRequestUrl(QUrl baseUrl, const QString& userId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/presence/" % userId % "/status");
+ makePath("/_matrix/client/v3", "/presence/",
+ userId, "/status"));
}
GetPresenceJob::GetPresenceJob(const QString& userId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetPresenceJob"),
- QStringLiteral("/_matrix/client/r0") % "/presence/" % userId
- % "/status")
+ makePath("/_matrix/client/v3", "/presence/", userId, "/status"))
{
addExpectedKey("presence");
}
diff --git a/lib/csapi/presence.h b/lib/csapi/presence.h
index 4ab50e25..52445205 100644
--- a/lib/csapi/presence.h
+++ b/lib/csapi/presence.h
@@ -15,7 +15,7 @@ namespace Quotient {
* not need to specify the `last_active_ago` field. You cannot set the
* presence state of another user.
*/
-class SetPresenceJob : public BaseJob {
+class QUOTIENT_API SetPresenceJob : public BaseJob {
public:
/*! \brief Update this user's presence state.
*
@@ -36,7 +36,7 @@ public:
*
* Get the given user's presence state.
*/
-class GetPresenceJob : public BaseJob {
+class QUOTIENT_API GetPresenceJob : public BaseJob {
public:
/*! \brief Get this user's presence state.
*
diff --git a/lib/csapi/profile.cpp b/lib/csapi/profile.cpp
index 8436b8e6..f024ed82 100644
--- a/lib/csapi/profile.cpp
+++ b/lib/csapi/profile.cpp
@@ -4,67 +4,63 @@
#include "profile.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SetDisplayNameJob::SetDisplayNameJob(const QString& userId,
const QString& displayname)
: BaseJob(HttpVerb::Put, QStringLiteral("SetDisplayNameJob"),
- QStringLiteral("/_matrix/client/r0") % "/profile/" % userId
- % "/displayname")
+ makePath("/_matrix/client/v3", "/profile/", userId,
+ "/displayname"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("displayname"), displayname);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("displayname"), displayname);
+ setRequestData({ _dataJson });
}
QUrl GetDisplayNameJob::makeRequestUrl(QUrl baseUrl, const QString& userId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/profile/" % userId % "/displayname");
+ makePath("/_matrix/client/v3", "/profile/",
+ userId, "/displayname"));
}
GetDisplayNameJob::GetDisplayNameJob(const QString& userId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetDisplayNameJob"),
- QStringLiteral("/_matrix/client/r0") % "/profile/" % userId
- % "/displayname",
+ makePath("/_matrix/client/v3", "/profile/", userId,
+ "/displayname"),
false)
{}
-SetAvatarUrlJob::SetAvatarUrlJob(const QString& userId, const QString& avatarUrl)
+SetAvatarUrlJob::SetAvatarUrlJob(const QString& userId, const QUrl& avatarUrl)
: BaseJob(HttpVerb::Put, QStringLiteral("SetAvatarUrlJob"),
- QStringLiteral("/_matrix/client/r0") % "/profile/" % userId
- % "/avatar_url")
+ makePath("/_matrix/client/v3", "/profile/", userId, "/avatar_url"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("avatar_url"), avatarUrl);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("avatar_url"), avatarUrl);
+ setRequestData({ _dataJson });
}
QUrl GetAvatarUrlJob::makeRequestUrl(QUrl baseUrl, const QString& userId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/profile/" % userId % "/avatar_url");
+ makePath("/_matrix/client/v3", "/profile/",
+ userId, "/avatar_url"));
}
GetAvatarUrlJob::GetAvatarUrlJob(const QString& userId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetAvatarUrlJob"),
- QStringLiteral("/_matrix/client/r0") % "/profile/" % userId
- % "/avatar_url",
+ makePath("/_matrix/client/v3", "/profile/", userId, "/avatar_url"),
false)
{}
QUrl GetUserProfileJob::makeRequestUrl(QUrl baseUrl, const QString& userId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/profile/" % userId);
+ makePath("/_matrix/client/v3", "/profile/",
+ userId));
}
GetUserProfileJob::GetUserProfileJob(const QString& userId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetUserProfileJob"),
- QStringLiteral("/_matrix/client/r0") % "/profile/" % userId, false)
+ makePath("/_matrix/client/v3", "/profile/", userId), false)
{}
diff --git a/lib/csapi/profile.h b/lib/csapi/profile.h
index 8bbe4f8c..b00c944b 100644
--- a/lib/csapi/profile.h
+++ b/lib/csapi/profile.h
@@ -13,7 +13,7 @@ namespace Quotient {
* This API sets the given user's display name. You must have permission to
* set this user's display name, e.g. you need to have their `access_token`.
*/
-class SetDisplayNameJob : public BaseJob {
+class QUOTIENT_API SetDisplayNameJob : public BaseJob {
public:
/*! \brief Set the user's display name.
*
@@ -33,7 +33,7 @@ public:
* own displayname or to query the name of other users; either locally or
* on remote homeservers.
*/
-class GetDisplayNameJob : public BaseJob {
+class QUOTIENT_API GetDisplayNameJob : public BaseJob {
public:
/*! \brief Get the user's display name.
*
@@ -63,7 +63,7 @@ public:
* This API sets the given user's avatar URL. You must have permission to
* set this user's avatar URL, e.g. you need to have their `access_token`.
*/
-class SetAvatarUrlJob : public BaseJob {
+class QUOTIENT_API SetAvatarUrlJob : public BaseJob {
public:
/*! \brief Set the user's avatar URL.
*
@@ -73,7 +73,7 @@ public:
* \param avatarUrl
* The new avatar URL for this user.
*/
- explicit SetAvatarUrlJob(const QString& userId, const QString& avatarUrl);
+ explicit SetAvatarUrlJob(const QString& userId, const QUrl& avatarUrl);
};
/*! \brief Get the user's avatar URL.
@@ -82,7 +82,7 @@ public:
* own avatar URL or to query the URL of other users; either locally or
* on remote homeservers.
*/
-class GetAvatarUrlJob : public BaseJob {
+class QUOTIENT_API GetAvatarUrlJob : public BaseJob {
public:
/*! \brief Get the user's avatar URL.
*
@@ -101,7 +101,7 @@ public:
// Result properties
/// The user's avatar URL if they have set one, otherwise not present.
- QString avatarUrl() const { return loadFromJson<QString>("avatar_url"_ls); }
+ QUrl avatarUrl() const { return loadFromJson<QUrl>("avatar_url"_ls); }
};
/*! \brief Get this user's profile information.
@@ -111,7 +111,7 @@ public:
* locally or on remote homeservers. This API may return keys which are not
* limited to `displayname` or `avatar_url`.
*/
-class GetUserProfileJob : public BaseJob {
+class QUOTIENT_API GetUserProfileJob : public BaseJob {
public:
/*! \brief Get this user's profile information.
*
@@ -130,7 +130,7 @@ public:
// Result properties
/// The user's avatar URL if they have set one, otherwise not present.
- QString avatarUrl() const { return loadFromJson<QString>("avatar_url"_ls); }
+ QUrl avatarUrl() const { return loadFromJson<QUrl>("avatar_url"_ls); }
/// The user's display name if they have set one, otherwise not present.
QString displayname() const
diff --git a/lib/csapi/pusher.cpp b/lib/csapi/pusher.cpp
index 028022c5..fb6595fc 100644
--- a/lib/csapi/pusher.cpp
+++ b/lib/csapi/pusher.cpp
@@ -4,20 +4,17 @@
#include "pusher.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetPushersJob::makeRequestUrl(QUrl baseUrl)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/pushers");
+ makePath("/_matrix/client/v3", "/pushers"));
}
GetPushersJob::GetPushersJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetPushersJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushers")
+ makePath("/_matrix/client/v3", "/pushers"))
{}
PostPusherJob::PostPusherJob(const QString& pushkey, const QString& kind,
@@ -26,17 +23,18 @@ PostPusherJob::PostPusherJob(const QString& pushkey, const QString& kind,
const QString& lang, const PusherData& data,
const QString& profileTag, Omittable<bool> append)
: BaseJob(HttpVerb::Post, QStringLiteral("PostPusherJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushers/set")
+ makePath("/_matrix/client/v3", "/pushers/set"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("pushkey"), pushkey);
- addParam<>(_data, QStringLiteral("kind"), kind);
- addParam<>(_data, QStringLiteral("app_id"), appId);
- addParam<>(_data, QStringLiteral("app_display_name"), appDisplayName);
- addParam<>(_data, QStringLiteral("device_display_name"), deviceDisplayName);
- addParam<IfNotEmpty>(_data, QStringLiteral("profile_tag"), profileTag);
- addParam<>(_data, QStringLiteral("lang"), lang);
- addParam<>(_data, QStringLiteral("data"), data);
- addParam<IfNotEmpty>(_data, QStringLiteral("append"), append);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("pushkey"), pushkey);
+ addParam<>(_dataJson, QStringLiteral("kind"), kind);
+ addParam<>(_dataJson, QStringLiteral("app_id"), appId);
+ addParam<>(_dataJson, QStringLiteral("app_display_name"), appDisplayName);
+ addParam<>(_dataJson, QStringLiteral("device_display_name"),
+ deviceDisplayName);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("profile_tag"), profileTag);
+ addParam<>(_dataJson, QStringLiteral("lang"), lang);
+ addParam<>(_dataJson, QStringLiteral("data"), data);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("append"), append);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/pusher.h b/lib/csapi/pusher.h
index 13c9ec25..d859ffc4 100644
--- a/lib/csapi/pusher.h
+++ b/lib/csapi/pusher.h
@@ -12,7 +12,7 @@ namespace Quotient {
*
* Gets all currently active pushers for the authenticated user.
*/
-class GetPushersJob : public BaseJob {
+class QUOTIENT_API GetPushersJob : public BaseJob {
public:
// Inner data structures
@@ -21,7 +21,7 @@ public:
struct PusherData {
/// Required if `kind` is `http`. The URL to use to send
/// notifications to.
- QString url;
+ QUrl url;
/// The format to use when sending notifications to the Push
/// Gateway.
QString format;
@@ -108,7 +108,7 @@ struct JsonObjectConverter<GetPushersJob::Pusher> {
* [pushers](/client-server-api/#push-notifications) for this user ID. The
* behaviour of this endpoint varies depending on the values in the JSON body.
*/
-class PostPusherJob : public BaseJob {
+class QUOTIENT_API PostPusherJob : public BaseJob {
public:
// Inner data structures
@@ -119,7 +119,7 @@ public:
/// Required if `kind` is `http`. The URL to use to send
/// notifications to. MUST be an HTTPS URL with a path of
/// `/_matrix/push/v1/notify`.
- QString url;
+ QUrl url;
/// The format to send notifications in to Push Gateways if the
/// `kind` is `http`. The details about what fields the
/// homeserver should send to the push gateway are defined in the
diff --git a/lib/csapi/pushrules.cpp b/lib/csapi/pushrules.cpp
index 86165744..2376654a 100644
--- a/lib/csapi/pushrules.cpp
+++ b/lib/csapi/pushrules.cpp
@@ -4,20 +4,17 @@
#include "pushrules.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetPushRulesJob::makeRequestUrl(QUrl baseUrl)
{
- return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/pushrules");
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl), makePath("/_matrix/client/v3", "/pushrules"));
}
GetPushRulesJob::GetPushRulesJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetPushRulesJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushrules")
+ makePath("/_matrix/client/v3", "/pushrules"))
{
addExpectedKey("global");
}
@@ -26,16 +23,15 @@ QUrl GetPushRuleJob::makeRequestUrl(QUrl baseUrl, const QString& scope,
const QString& kind, const QString& ruleId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/pushrules/" % scope % "/" % kind
- % "/" % ruleId);
+ makePath("/_matrix/client/v3", "/pushrules/",
+ scope, "/", kind, "/", ruleId));
}
GetPushRuleJob::GetPushRuleJob(const QString& scope, const QString& kind,
const QString& ruleId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetPushRuleJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushrules/" % scope % "/"
- % kind % "/" % ruleId)
+ makePath("/_matrix/client/v3", "/pushrules/", scope, "/", kind,
+ "/", ruleId))
{}
QUrl DeletePushRuleJob::makeRequestUrl(QUrl baseUrl, const QString& scope,
@@ -43,21 +39,20 @@ QUrl DeletePushRuleJob::makeRequestUrl(QUrl baseUrl, const QString& scope,
const QString& ruleId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/pushrules/" % scope % "/" % kind
- % "/" % ruleId);
+ makePath("/_matrix/client/v3", "/pushrules/",
+ scope, "/", kind, "/", ruleId));
}
DeletePushRuleJob::DeletePushRuleJob(const QString& scope, const QString& kind,
const QString& ruleId)
: BaseJob(HttpVerb::Delete, QStringLiteral("DeletePushRuleJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushrules/" % scope % "/"
- % kind % "/" % ruleId)
+ makePath("/_matrix/client/v3", "/pushrules/", scope, "/", kind,
+ "/", ruleId))
{}
auto queryToSetPushRule(const QString& before, const QString& after)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("before"), before);
addParam<IfNotEmpty>(_q, QStringLiteral("after"), after);
return _q;
@@ -70,15 +65,15 @@ SetPushRuleJob::SetPushRuleJob(const QString& scope, const QString& kind,
const QVector<PushCondition>& conditions,
const QString& pattern)
: BaseJob(HttpVerb::Put, QStringLiteral("SetPushRuleJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushrules/" % scope % "/"
- % kind % "/" % ruleId,
+ makePath("/_matrix/client/v3", "/pushrules/", scope, "/", kind,
+ "/", ruleId),
queryToSetPushRule(before, after))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("actions"), actions);
- addParam<IfNotEmpty>(_data, QStringLiteral("conditions"), conditions);
- addParam<IfNotEmpty>(_data, QStringLiteral("pattern"), pattern);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("actions"), actions);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("conditions"), conditions);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("pattern"), pattern);
+ setRequestData({ _dataJson });
}
QUrl IsPushRuleEnabledJob::makeRequestUrl(QUrl baseUrl, const QString& scope,
@@ -86,17 +81,17 @@ QUrl IsPushRuleEnabledJob::makeRequestUrl(QUrl baseUrl, const QString& scope,
const QString& ruleId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/pushrules/" % scope % "/" % kind
- % "/" % ruleId % "/enabled");
+ makePath("/_matrix/client/v3", "/pushrules/",
+ scope, "/", kind, "/", ruleId,
+ "/enabled"));
}
IsPushRuleEnabledJob::IsPushRuleEnabledJob(const QString& scope,
const QString& kind,
const QString& ruleId)
: BaseJob(HttpVerb::Get, QStringLiteral("IsPushRuleEnabledJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushrules/" % scope % "/"
- % kind % "/" % ruleId % "/enabled")
+ makePath("/_matrix/client/v3", "/pushrules/", scope, "/", kind,
+ "/", ruleId, "/enabled"))
{
addExpectedKey("enabled");
}
@@ -105,12 +100,12 @@ SetPushRuleEnabledJob::SetPushRuleEnabledJob(const QString& scope,
const QString& kind,
const QString& ruleId, bool enabled)
: BaseJob(HttpVerb::Put, QStringLiteral("SetPushRuleEnabledJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushrules/" % scope % "/"
- % kind % "/" % ruleId % "/enabled")
+ makePath("/_matrix/client/v3", "/pushrules/", scope, "/", kind,
+ "/", ruleId, "/enabled"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("enabled"), enabled);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("enabled"), enabled);
+ setRequestData({ _dataJson });
}
QUrl GetPushRuleActionsJob::makeRequestUrl(QUrl baseUrl, const QString& scope,
@@ -118,17 +113,17 @@ QUrl GetPushRuleActionsJob::makeRequestUrl(QUrl baseUrl, const QString& scope,
const QString& ruleId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/pushrules/" % scope % "/" % kind
- % "/" % ruleId % "/actions");
+ makePath("/_matrix/client/v3", "/pushrules/",
+ scope, "/", kind, "/", ruleId,
+ "/actions"));
}
GetPushRuleActionsJob::GetPushRuleActionsJob(const QString& scope,
const QString& kind,
const QString& ruleId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetPushRuleActionsJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushrules/" % scope % "/"
- % kind % "/" % ruleId % "/actions")
+ makePath("/_matrix/client/v3", "/pushrules/", scope, "/", kind,
+ "/", ruleId, "/actions"))
{
addExpectedKey("actions");
}
@@ -138,10 +133,10 @@ SetPushRuleActionsJob::SetPushRuleActionsJob(const QString& scope,
const QString& ruleId,
const QVector<QVariant>& actions)
: BaseJob(HttpVerb::Put, QStringLiteral("SetPushRuleActionsJob"),
- QStringLiteral("/_matrix/client/r0") % "/pushrules/" % scope % "/"
- % kind % "/" % ruleId % "/actions")
+ makePath("/_matrix/client/v3", "/pushrules/", scope, "/", kind,
+ "/", ruleId, "/actions"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("actions"), actions);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("actions"), actions);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/pushrules.h b/lib/csapi/pushrules.h
index a5eb48f0..d6c57efd 100644
--- a/lib/csapi/pushrules.h
+++ b/lib/csapi/pushrules.h
@@ -19,7 +19,7 @@ namespace Quotient {
* `/pushrules/global/`. This will return a subset of this data under the
* specified key e.g. the `global` key.
*/
-class GetPushRulesJob : public BaseJob {
+class QUOTIENT_API GetPushRulesJob : public BaseJob {
public:
/// Retrieve all push rulesets.
explicit GetPushRulesJob();
@@ -44,7 +44,7 @@ public:
*
* Retrieve a single specified push rule.
*/
-class GetPushRuleJob : public BaseJob {
+class QUOTIENT_API GetPushRuleJob : public BaseJob {
public:
/*! \brief Retrieve a push rule.
*
@@ -79,7 +79,7 @@ public:
*
* This endpoint removes the push rule defined in the path.
*/
-class DeletePushRuleJob : public BaseJob {
+class QUOTIENT_API DeletePushRuleJob : public BaseJob {
public:
/*! \brief Delete a push rule.
*
@@ -112,7 +112,7 @@ public:
*
* When creating push rules, they MUST be enabled by default.
*/
-class SetPushRuleJob : public BaseJob {
+class QUOTIENT_API SetPushRuleJob : public BaseJob {
public:
/*! \brief Add or change a push rule.
*
@@ -160,7 +160,7 @@ public:
*
* This endpoint gets whether the specified push rule is enabled.
*/
-class IsPushRuleEnabledJob : public BaseJob {
+class QUOTIENT_API IsPushRuleEnabledJob : public BaseJob {
public:
/*! \brief Get whether a push rule is enabled
*
@@ -195,7 +195,7 @@ public:
*
* This endpoint allows clients to enable or disable the specified push rule.
*/
-class SetPushRuleEnabledJob : public BaseJob {
+class QUOTIENT_API SetPushRuleEnabledJob : public BaseJob {
public:
/*! \brief Enable or disable a push rule.
*
@@ -219,7 +219,7 @@ public:
*
* This endpoint get the actions for the specified push rule.
*/
-class GetPushRuleActionsJob : public BaseJob {
+class QUOTIENT_API GetPushRuleActionsJob : public BaseJob {
public:
/*! \brief The actions for a push rule
*
@@ -258,7 +258,7 @@ public:
* This endpoint allows clients to change the actions of a push rule.
* This can be used to change the actions of builtin rules.
*/
-class SetPushRuleActionsJob : public BaseJob {
+class QUOTIENT_API SetPushRuleActionsJob : public BaseJob {
public:
/*! \brief Set the actions for a push rule.
*
diff --git a/lib/csapi/read_markers.cpp b/lib/csapi/read_markers.cpp
index 39e4d148..febd6d3a 100644
--- a/lib/csapi/read_markers.cpp
+++ b/lib/csapi/read_markers.cpp
@@ -4,19 +4,19 @@
#include "read_markers.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SetReadMarkerJob::SetReadMarkerJob(const QString& roomId,
const QString& mFullyRead,
- const QString& mRead)
+ const QString& mRead,
+ const QString& mReadPrivate)
: BaseJob(HttpVerb::Post, QStringLiteral("SetReadMarkerJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/read_markers")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/read_markers"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("m.fully_read"), mFullyRead);
- addParam<IfNotEmpty>(_data, QStringLiteral("m.read"), mRead);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("m.fully_read"), mFullyRead);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("m.read"), mRead);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("m.read.private"),
+ mReadPrivate);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/read_markers.h b/lib/csapi/read_markers.h
index 00a2aa0d..1024076f 100644
--- a/lib/csapi/read_markers.h
+++ b/lib/csapi/read_markers.h
@@ -13,7 +13,7 @@ namespace Quotient {
* Sets the position of the read marker for a given room, and optionally
* the read receipt's location.
*/
-class SetReadMarkerJob : public BaseJob {
+class QUOTIENT_API SetReadMarkerJob : public BaseJob {
public:
/*! \brief Set the position of the read marker for a room.
*
@@ -28,9 +28,16 @@ public:
* The event ID to set the read receipt location at. This is
* equivalent to calling `/receipt/m.read/$elsewhere:example.org`
* and is provided here to save that extra call.
+ *
+ * \param mReadPrivate
+ * The event ID to set the *private* read receipt location at. This
+ * equivalent to calling `/receipt/m.read.private/$elsewhere:example.org`
+ * and is provided here to save that extra call.
*/
- explicit SetReadMarkerJob(const QString& roomId, const QString& mFullyRead,
- const QString& mRead = {});
+ explicit SetReadMarkerJob(const QString& roomId,
+ const QString& mFullyRead = {},
+ const QString& mRead = {},
+ const QString& mReadPrivate = {});
};
} // namespace Quotient
diff --git a/lib/csapi/receipts.cpp b/lib/csapi/receipts.cpp
index 00d1c28a..0194603d 100644
--- a/lib/csapi/receipts.cpp
+++ b/lib/csapi/receipts.cpp
@@ -4,16 +4,14 @@
#include "receipts.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
PostReceiptJob::PostReceiptJob(const QString& roomId, const QString& receiptType,
const QString& eventId,
const QJsonObject& receipt)
: BaseJob(HttpVerb::Post, QStringLiteral("PostReceiptJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/receipt/" % receiptType % "/" % eventId)
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/receipt/",
+ receiptType, "/", eventId))
{
- setRequestData(Data(toJson(receipt)));
+ setRequestData({ toJson(receipt) });
}
diff --git a/lib/csapi/receipts.h b/lib/csapi/receipts.h
index 7ac093cd..98bc5004 100644
--- a/lib/csapi/receipts.h
+++ b/lib/csapi/receipts.h
@@ -13,7 +13,7 @@ namespace Quotient {
* This API updates the marker for the given receipt type to the event ID
* specified.
*/
-class PostReceiptJob : public BaseJob {
+class QUOTIENT_API PostReceiptJob : public BaseJob {
public:
/*! \brief Send a receipt for the given event ID.
*
@@ -21,7 +21,13 @@ public:
* The room in which to send the event.
*
* \param receiptType
- * The type of receipt to send.
+ * The type of receipt to send. This can also be `m.fully_read` as an
+ * alternative to
+ * [`/read_makers`](/client-server-api/#post_matrixclientv3roomsroomidread_markers).
+ *
+ * Note that `m.fully_read` does not appear under `m.receipt`: this
+ * endpoint effectively calls `/read_markers` internally when presented with
+ * a receipt type of `m.fully_read`.
*
* \param eventId
* The event ID to acknowledge up to.
diff --git a/lib/csapi/redaction.cpp b/lib/csapi/redaction.cpp
index 91497064..154abd9b 100644
--- a/lib/csapi/redaction.cpp
+++ b/lib/csapi/redaction.cpp
@@ -4,17 +4,15 @@
#include "redaction.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
RedactEventJob::RedactEventJob(const QString& roomId, const QString& eventId,
const QString& txnId, const QString& reason)
: BaseJob(HttpVerb::Put, QStringLiteral("RedactEventJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/redact/" % eventId % "/" % txnId)
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/redact/",
+ eventId, "/", txnId))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("reason"), reason);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/redaction.h b/lib/csapi/redaction.h
index f0db9f9f..2f85793e 100644
--- a/lib/csapi/redaction.h
+++ b/lib/csapi/redaction.h
@@ -22,7 +22,7 @@ namespace Quotient {
*
* Server administrators may redact events sent by users on their server.
*/
-class RedactEventJob : public BaseJob {
+class QUOTIENT_API RedactEventJob : public BaseJob {
public:
/*! \brief Strips all non-integrity-critical information out of an event.
*
@@ -33,9 +33,9 @@ public:
* The ID of the event to redact
*
* \param txnId
- * The transaction ID for this event. Clients should generate a
- * unique ID; it will be used by the server to ensure idempotency of
- * requests.
+ * The [transaction ID](/client-server-api/#transaction-identifiers) for
+ * this event. Clients should generate a unique ID; it will be used by the
+ * server to ensure idempotency of requests.
*
* \param reason
* The reason for the event being redacted.
diff --git a/lib/csapi/refresh.cpp b/lib/csapi/refresh.cpp
new file mode 100644
index 00000000..284ae4ff
--- /dev/null
+++ b/lib/csapi/refresh.cpp
@@ -0,0 +1,18 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#include "refresh.h"
+
+using namespace Quotient;
+
+RefreshJob::RefreshJob(const QString& refreshToken)
+ : BaseJob(HttpVerb::Post, QStringLiteral("RefreshJob"),
+ makePath("/_matrix/client/v3", "/refresh"), false)
+{
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("refresh_token"),
+ refreshToken);
+ setRequestData({ _dataJson });
+ addExpectedKey("access_token");
+}
diff --git a/lib/csapi/refresh.h b/lib/csapi/refresh.h
new file mode 100644
index 00000000..d432802c
--- /dev/null
+++ b/lib/csapi/refresh.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "jobs/basejob.h"
+
+namespace Quotient {
+
+/*! \brief Refresh an access token
+ *
+ * Refresh an access token. Clients should use the returned access token
+ * when making subsequent API calls, and store the returned refresh token
+ * (if given) in order to refresh the new access token when necessary.
+ *
+ * After an access token has been refreshed, a server can choose to
+ * invalidate the old access token immediately, or can choose not to, for
+ * example if the access token would expire soon anyways. Clients should
+ * not make any assumptions about the old access token still being valid,
+ * and should use the newly provided access token instead.
+ *
+ * The old refresh token remains valid until the new access token or refresh
+ * token is used, at which point the old refresh token is revoked.
+ *
+ * Note that this endpoint does not require authentication via an
+ * access token. Authentication is provided via the refresh token.
+ *
+ * Application Service identity assertion is disabled for this endpoint.
+ */
+class QUOTIENT_API RefreshJob : public BaseJob {
+public:
+ /*! \brief Refresh an access token
+ *
+ * \param refreshToken
+ * The refresh token
+ */
+ explicit RefreshJob(const QString& refreshToken = {});
+
+ // Result properties
+
+ /// The new access token to use.
+ QString accessToken() const
+ {
+ return loadFromJson<QString>("access_token"_ls);
+ }
+
+ /// The new refresh token to use when the access token needs to
+ /// be refreshed again. If not given, the old refresh token can
+ /// be re-used.
+ QString refreshToken() const
+ {
+ return loadFromJson<QString>("refresh_token"_ls);
+ }
+
+ /// The lifetime of the access token, in milliseconds. If not
+ /// given, the client can assume that the access token will not
+ /// expire.
+ Omittable<int> expiresInMs() const
+ {
+ return loadFromJson<Omittable<int>>("expires_in_ms"_ls);
+ }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/registration.cpp b/lib/csapi/registration.cpp
index b80abc84..04c0fe12 100644
--- a/lib/csapi/registration.cpp
+++ b/lib/csapi/registration.cpp
@@ -4,13 +4,11 @@
#include "registration.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
auto queryToRegister(const QString& kind)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("kind"), kind);
return _q;
}
@@ -20,93 +18,97 @@ RegisterJob::RegisterJob(const QString& kind,
const QString& username, const QString& password,
const QString& deviceId,
const QString& initialDeviceDisplayName,
- Omittable<bool> inhibitLogin)
+ Omittable<bool> inhibitLogin,
+ Omittable<bool> refreshToken)
: BaseJob(HttpVerb::Post, QStringLiteral("RegisterJob"),
- QStringLiteral("/_matrix/client/r0") % "/register",
+ makePath("/_matrix/client/v3", "/register"),
queryToRegister(kind), {}, false)
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
- addParam<IfNotEmpty>(_data, QStringLiteral("username"), username);
- addParam<IfNotEmpty>(_data, QStringLiteral("password"), password);
- addParam<IfNotEmpty>(_data, QStringLiteral("device_id"), deviceId);
- addParam<IfNotEmpty>(_data, QStringLiteral("initial_device_display_name"),
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("auth"), auth);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("username"), username);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("password"), password);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("device_id"), deviceId);
+ addParam<IfNotEmpty>(_dataJson,
+ QStringLiteral("initial_device_display_name"),
initialDeviceDisplayName);
- addParam<IfNotEmpty>(_data, QStringLiteral("inhibit_login"), inhibitLogin);
- setRequestData(std::move(_data));
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("inhibit_login"),
+ inhibitLogin);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("refresh_token"),
+ refreshToken);
+ setRequestData({ _dataJson });
addExpectedKey("user_id");
}
RequestTokenToRegisterEmailJob::RequestTokenToRegisterEmailJob(
const EmailValidationData& body)
: BaseJob(HttpVerb::Post, QStringLiteral("RequestTokenToRegisterEmailJob"),
- QStringLiteral("/_matrix/client/r0")
- % "/register/email/requestToken",
+ makePath("/_matrix/client/v3", "/register/email/requestToken"),
false)
{
- setRequestData(Data(toJson(body)));
+ setRequestData({ toJson(body) });
}
RequestTokenToRegisterMSISDNJob::RequestTokenToRegisterMSISDNJob(
const MsisdnValidationData& body)
: BaseJob(HttpVerb::Post, QStringLiteral("RequestTokenToRegisterMSISDNJob"),
- QStringLiteral("/_matrix/client/r0")
- % "/register/msisdn/requestToken",
+ makePath("/_matrix/client/v3", "/register/msisdn/requestToken"),
false)
{
- setRequestData(Data(toJson(body)));
+ setRequestData({ toJson(body) });
}
ChangePasswordJob::ChangePasswordJob(const QString& newPassword,
- Omittable<bool> logoutDevices,
+ bool logoutDevices,
const Omittable<AuthenticationData>& auth)
: BaseJob(HttpVerb::Post, QStringLiteral("ChangePasswordJob"),
- QStringLiteral("/_matrix/client/r0") % "/account/password")
+ makePath("/_matrix/client/v3", "/account/password"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("new_password"), newPassword);
- addParam<IfNotEmpty>(_data, QStringLiteral("logout_devices"), logoutDevices);
- addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("new_password"), newPassword);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("logout_devices"),
+ logoutDevices);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("auth"), auth);
+ setRequestData({ _dataJson });
}
RequestTokenToResetPasswordEmailJob::RequestTokenToResetPasswordEmailJob(
const EmailValidationData& body)
: BaseJob(HttpVerb::Post,
QStringLiteral("RequestTokenToResetPasswordEmailJob"),
- QStringLiteral("/_matrix/client/r0")
- % "/account/password/email/requestToken",
+ makePath("/_matrix/client/v3",
+ "/account/password/email/requestToken"),
false)
{
- setRequestData(Data(toJson(body)));
+ setRequestData({ toJson(body) });
}
RequestTokenToResetPasswordMSISDNJob::RequestTokenToResetPasswordMSISDNJob(
const MsisdnValidationData& body)
: BaseJob(HttpVerb::Post,
QStringLiteral("RequestTokenToResetPasswordMSISDNJob"),
- QStringLiteral("/_matrix/client/r0")
- % "/account/password/msisdn/requestToken",
+ makePath("/_matrix/client/v3",
+ "/account/password/msisdn/requestToken"),
false)
{
- setRequestData(Data(toJson(body)));
+ setRequestData({ toJson(body) });
}
DeactivateAccountJob::DeactivateAccountJob(
const Omittable<AuthenticationData>& auth, const QString& idServer)
: BaseJob(HttpVerb::Post, QStringLiteral("DeactivateAccountJob"),
- QStringLiteral("/_matrix/client/r0") % "/account/deactivate")
+ makePath("/_matrix/client/v3", "/account/deactivate"))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
- addParam<IfNotEmpty>(_data, QStringLiteral("id_server"), idServer);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("auth"), auth);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("id_server"), idServer);
+ setRequestData({ _dataJson });
addExpectedKey("id_server_unbind_result");
}
auto queryToCheckUsernameAvailability(const QString& username)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<>(_q, QStringLiteral("username"), username);
return _q;
}
@@ -115,13 +117,14 @@ QUrl CheckUsernameAvailabilityJob::makeRequestUrl(QUrl baseUrl,
const QString& username)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/register/available",
+ makePath("/_matrix/client/v3",
+ "/register/available"),
queryToCheckUsernameAvailability(username));
}
-CheckUsernameAvailabilityJob::CheckUsernameAvailabilityJob(const QString& username)
+CheckUsernameAvailabilityJob::CheckUsernameAvailabilityJob(
+ const QString& username)
: BaseJob(HttpVerb::Get, QStringLiteral("CheckUsernameAvailabilityJob"),
- QStringLiteral("/_matrix/client/r0") % "/register/available",
+ makePath("/_matrix/client/v3", "/register/available"),
queryToCheckUsernameAvailability(username), {}, false)
{}
diff --git a/lib/csapi/registration.h b/lib/csapi/registration.h
index ae8fc162..21d7f9d7 100644
--- a/lib/csapi/registration.h
+++ b/lib/csapi/registration.h
@@ -59,7 +59,7 @@ namespace Quotient {
* Any user ID returned by this API must conform to the grammar given in the
* [Matrix specification](/appendices/#user-identifiers).
*/
-class RegisterJob : public BaseJob {
+class QUOTIENT_API RegisterJob : public BaseJob {
public:
/*! \brief Register for an account on this homeserver.
*
@@ -93,6 +93,9 @@ public:
* If true, an `access_token` and `device_id` should not be
* returned from this call, therefore preventing an automatic
* login. Defaults to false.
+ *
+ * \param refreshToken
+ * If true, the client supports refresh tokens.
*/
explicit RegisterJob(const QString& kind = QStringLiteral("user"),
const Omittable<AuthenticationData>& auth = none,
@@ -100,7 +103,8 @@ public:
const QString& password = {},
const QString& deviceId = {},
const QString& initialDeviceDisplayName = {},
- Omittable<bool> inhibitLogin = none);
+ Omittable<bool> inhibitLogin = none,
+ Omittable<bool> refreshToken = none);
// Result properties
@@ -118,15 +122,27 @@ public:
return loadFromJson<QString>("access_token"_ls);
}
- /// The server_name of the homeserver on which the account has
- /// been registered.
+ /// A refresh token for the account. This token can be used to
+ /// obtain a new access token when it expires by calling the
+ /// `/refresh` endpoint.
+ ///
+ /// Omitted if the `inhibit_login` option is true.
+ QString refreshToken() const
+ {
+ return loadFromJson<QString>("refresh_token"_ls);
+ }
+
+ /// The lifetime of the access token, in milliseconds. Once
+ /// the access token has expired a new access token can be
+ /// obtained by using the provided refresh token. If no
+ /// refresh token is provided, the client will need to re-log in
+ /// to obtain a new access token. If not given, the client can
+ /// assume that the access token will not expire.
///
- /// **Deprecated**. Clients should extract the server_name from
- /// `user_id` (by splitting at the first colon) if they require
- /// it. Note also that `homeserver` is not spelt this way.
- QString homeServer() const
+ /// Omitted if the `inhibit_login` option is true.
+ Omittable<int> expiresInMs() const
{
- return loadFromJson<QString>("home_server"_ls);
+ return loadFromJson<Omittable<int>>("expires_in_ms"_ls);
}
/// ID of the registered device. Will be the same as the
@@ -143,7 +159,7 @@ public:
* should validate the email itself, either by sending a validation email
* itself or by using a service it has control over.
*/
-class RequestTokenToRegisterEmailJob : public BaseJob {
+class QUOTIENT_API RequestTokenToRegisterEmailJob : public BaseJob {
public:
/*! \brief Begins the validation process for an email to be used during
* registration.
@@ -175,7 +191,7 @@ public:
* should validate the phone number itself, either by sending a validation
* message itself or by using a service it has control over.
*/
-class RequestTokenToRegisterMSISDNJob : public BaseJob {
+class QUOTIENT_API RequestTokenToRegisterMSISDNJob : public BaseJob {
public:
/*! \brief Requests a validation token be sent to the given phone number for
* the purpose of registering an account
@@ -215,7 +231,7 @@ public:
* access token provided in the request. Whether other access tokens for
* the user are revoked depends on the request parameters.
*/
-class ChangePasswordJob : public BaseJob {
+class QUOTIENT_API ChangePasswordJob : public BaseJob {
public:
/*! \brief Changes a user's password.
*
@@ -227,14 +243,15 @@ public:
* should be revoked if the request succeeds.
*
* When `false`, the server can still take advantage of the [soft logout
- * method](/client-server-api/#soft-logout) for the user's remaining devices.
+ * method](/client-server-api/#soft-logout) for the user's remaining
+ * devices.
*
* \param auth
* Additional authentication information for the user-interactive
* authentication API.
*/
explicit ChangePasswordJob(const QString& newPassword,
- Omittable<bool> logoutDevices = none,
+ bool logoutDevices = true,
const Omittable<AuthenticationData>& auth = none);
};
@@ -247,7 +264,7 @@ public:
* `/account/password` endpoint.
*
* This API's parameters and response are identical to that of the
- * [`/register/email/requestToken`](/client-server-api/#post_matrixclientr0registeremailrequesttoken)
+ * [`/register/email/requestToken`](/client-server-api/#post_matrixclientv3registeremailrequesttoken)
* endpoint, except that
* `M_THREEPID_NOT_FOUND` may be returned if no account matching the
* given email address could be found. The server may instead send an
@@ -257,7 +274,7 @@ public:
* The homeserver should validate the email itself, either by sending a
* validation email itself or by using a service it has control over.
*/
-class RequestTokenToResetPasswordEmailJob : public BaseJob {
+class QUOTIENT_API RequestTokenToResetPasswordEmailJob : public BaseJob {
public:
/*! \brief Requests a validation token be sent to the given email address
* for the purpose of resetting a user's password
@@ -269,7 +286,7 @@ public:
* `/account/password` endpoint.
*
* This API's parameters and response are identical to that of the
- * [`/register/email/requestToken`](/client-server-api/#post_matrixclientr0registeremailrequesttoken)
+ * [`/register/email/requestToken`](/client-server-api/#post_matrixclientv3registeremailrequesttoken)
* endpoint, except that
* `M_THREEPID_NOT_FOUND` may be returned if no account matching the
* given email address could be found. The server may instead send an
@@ -299,7 +316,7 @@ public:
* `/account/password` endpoint.
*
* This API's parameters and response are identical to that of the
- * [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientr0registermsisdnrequesttoken)
+ * [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientv3registermsisdnrequesttoken)
* endpoint, except that
* `M_THREEPID_NOT_FOUND` may be returned if no account matching the
* given phone number could be found. The server may instead send the SMS
@@ -309,7 +326,7 @@ public:
* The homeserver should validate the phone number itself, either by sending a
* validation message itself or by using a service it has control over.
*/
-class RequestTokenToResetPasswordMSISDNJob : public BaseJob {
+class QUOTIENT_API RequestTokenToResetPasswordMSISDNJob : public BaseJob {
public:
/*! \brief Requests a validation token be sent to the given phone number for
* the purpose of resetting a user's password.
@@ -321,15 +338,16 @@ public:
* `/account/password` endpoint.
*
* This API's parameters and response are identical to that of the
- * [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientr0registermsisdnrequesttoken)
+ * [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientv3registermsisdnrequesttoken)
* endpoint, except that
* `M_THREEPID_NOT_FOUND` may be returned if no account matching the
* given phone number could be found. The server may instead send the SMS
* to the given phone number prompting the user to create an account.
* `M_THREEPID_IN_USE` may not be returned.
*
- * The homeserver should validate the phone number itself, either by sending
- * a validation message itself or by using a service it has control over.
+ * The homeserver should validate the phone number itself, either by
+ * sending a validation message itself or by using a service it has control
+ * over.
*/
explicit RequestTokenToResetPasswordMSISDNJob(
const MsisdnValidationData& body);
@@ -361,7 +379,7 @@ public:
* parameter because the homeserver is expected to sign the request to the
* identity server instead.
*/
-class DeactivateAccountJob : public BaseJob {
+class QUOTIENT_API DeactivateAccountJob : public BaseJob {
public:
/*! \brief Deactivate a user's account.
*
@@ -377,8 +395,9 @@ public:
* it must return an `id_server_unbind_result` of
* `no-support`.
*/
- explicit DeactivateAccountJob(const Omittable<AuthenticationData>& auth = none,
- const QString& idServer = {});
+ explicit DeactivateAccountJob(
+ const Omittable<AuthenticationData>& auth = none,
+ const QString& idServer = {});
// Result properties
@@ -411,7 +430,7 @@ public:
* reserve the username. This can mean that the username becomes unavailable
* between checking its availability and attempting to register it.
*/
-class CheckUsernameAvailabilityJob : public BaseJob {
+class QUOTIENT_API CheckUsernameAvailabilityJob : public BaseJob {
public:
/*! \brief Checks to see if a username is available on the server.
*
diff --git a/lib/csapi/registration_tokens.cpp b/lib/csapi/registration_tokens.cpp
new file mode 100644
index 00000000..9c1f0587
--- /dev/null
+++ b/lib/csapi/registration_tokens.cpp
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#include "registration_tokens.h"
+
+using namespace Quotient;
+
+auto queryToRegistrationTokenValidity(const QString& token)
+{
+ QUrlQuery _q;
+ addParam<>(_q, QStringLiteral("token"), token);
+ return _q;
+}
+
+QUrl RegistrationTokenValidityJob::makeRequestUrl(QUrl baseUrl,
+ const QString& token)
+{
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl),
+ makePath("/_matrix/client/v1",
+ "/register/m.login.registration_token/validity"),
+ queryToRegistrationTokenValidity(token));
+}
+
+RegistrationTokenValidityJob::RegistrationTokenValidityJob(const QString& token)
+ : BaseJob(HttpVerb::Get, QStringLiteral("RegistrationTokenValidityJob"),
+ makePath("/_matrix/client/v1",
+ "/register/m.login.registration_token/validity"),
+ queryToRegistrationTokenValidity(token), {}, false)
+{
+ addExpectedKey("valid");
+}
diff --git a/lib/csapi/registration_tokens.h b/lib/csapi/registration_tokens.h
new file mode 100644
index 00000000..e3008dd4
--- /dev/null
+++ b/lib/csapi/registration_tokens.h
@@ -0,0 +1,44 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "jobs/basejob.h"
+
+namespace Quotient {
+
+/*! \brief Query if a given registration token is still valid.
+ *
+ * Queries the server to determine if a given registration token is still
+ * valid at the time of request. This is a point-in-time check where the
+ * token might still expire by the time it is used.
+ *
+ * Servers should be sure to rate limit this endpoint to avoid brute force
+ * attacks.
+ */
+class QUOTIENT_API RegistrationTokenValidityJob : public BaseJob {
+public:
+ /*! \brief Query if a given registration token is still valid.
+ *
+ * \param token
+ * The token to check validity of.
+ */
+ explicit RegistrationTokenValidityJob(const QString& token);
+
+ /*! \brief Construct a URL without creating a full-fledged job object
+ *
+ * This function can be used when a URL for RegistrationTokenValidityJob
+ * is necessary but the job itself isn't.
+ */
+ static QUrl makeRequestUrl(QUrl baseUrl, const QString& token);
+
+ // Result properties
+
+ /// True if the token is still valid, false otherwise. This should
+ /// additionally be false if the token is not a recognised token by
+ /// the server.
+ bool valid() const { return loadFromJson<bool>("valid"_ls); }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/relations.cpp b/lib/csapi/relations.cpp
new file mode 100644
index 00000000..1d8febcc
--- /dev/null
+++ b/lib/csapi/relations.cpp
@@ -0,0 +1,118 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#include "relations.h"
+
+using namespace Quotient;
+
+auto queryToGetRelatingEvents(const QString& from, const QString& to,
+ Omittable<int> limit, const QString& dir)
+{
+ QUrlQuery _q;
+ addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
+ addParam<IfNotEmpty>(_q, QStringLiteral("to"), to);
+ addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("dir"), dir);
+ return _q;
+}
+
+QUrl GetRelatingEventsJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ const QString& eventId,
+ const QString& from, const QString& to,
+ Omittable<int> limit,
+ const QString& dir)
+{
+ return BaseJob::makeRequestUrl(std::move(baseUrl),
+ makePath("/_matrix/client/v1", "/rooms/",
+ roomId, "/relations/", eventId),
+ queryToGetRelatingEvents(from, to, limit,
+ dir));
+}
+
+GetRelatingEventsJob::GetRelatingEventsJob(
+ const QString& roomId, const QString& eventId, const QString& from,
+ const QString& to, Omittable<int> limit, const QString& dir)
+ : BaseJob(HttpVerb::Get, QStringLiteral("GetRelatingEventsJob"),
+ makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
+ eventId),
+ queryToGetRelatingEvents(from, to, limit, dir))
+{
+ addExpectedKey("chunk");
+}
+
+auto queryToGetRelatingEventsWithRelType(const QString& from, const QString& to,
+ Omittable<int> limit,
+ const QString& dir)
+{
+ QUrlQuery _q;
+ addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
+ addParam<IfNotEmpty>(_q, QStringLiteral("to"), to);
+ addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("dir"), dir);
+ return _q;
+}
+
+QUrl GetRelatingEventsWithRelTypeJob::makeRequestUrl(
+ QUrl baseUrl, const QString& roomId, const QString& eventId,
+ const QString& relType, const QString& from, const QString& to,
+ Omittable<int> limit, const QString& dir)
+{
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl),
+ makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
+ eventId, "/", relType),
+ queryToGetRelatingEventsWithRelType(from, to, limit, dir));
+}
+
+GetRelatingEventsWithRelTypeJob::GetRelatingEventsWithRelTypeJob(
+ const QString& roomId, const QString& eventId, const QString& relType,
+ const QString& from, const QString& to, Omittable<int> limit,
+ const QString& dir)
+ : BaseJob(HttpVerb::Get, QStringLiteral("GetRelatingEventsWithRelTypeJob"),
+ makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
+ eventId, "/", relType),
+ queryToGetRelatingEventsWithRelType(from, to, limit, dir))
+{
+ addExpectedKey("chunk");
+}
+
+auto queryToGetRelatingEventsWithRelTypeAndEventType(const QString& from,
+ const QString& to,
+ Omittable<int> limit,
+ const QString& dir)
+{
+ QUrlQuery _q;
+ addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
+ addParam<IfNotEmpty>(_q, QStringLiteral("to"), to);
+ addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("dir"), dir);
+ return _q;
+}
+
+QUrl GetRelatingEventsWithRelTypeAndEventTypeJob::makeRequestUrl(
+ QUrl baseUrl, const QString& roomId, const QString& eventId,
+ const QString& relType, const QString& eventType, const QString& from,
+ const QString& to, Omittable<int> limit, const QString& dir)
+{
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl),
+ makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
+ eventId, "/", relType, "/", eventType),
+ queryToGetRelatingEventsWithRelTypeAndEventType(from, to, limit, dir));
+}
+
+GetRelatingEventsWithRelTypeAndEventTypeJob::
+ GetRelatingEventsWithRelTypeAndEventTypeJob(
+ const QString& roomId, const QString& eventId, const QString& relType,
+ const QString& eventType, const QString& from, const QString& to,
+ Omittable<int> limit, const QString& dir)
+ : BaseJob(HttpVerb::Get,
+ QStringLiteral("GetRelatingEventsWithRelTypeAndEventTypeJob"),
+ makePath("/_matrix/client/v1", "/rooms/", roomId, "/relations/",
+ eventId, "/", relType, "/", eventType),
+ queryToGetRelatingEventsWithRelTypeAndEventType(from, to, limit,
+ dir))
+{
+ addExpectedKey("chunk");
+}
diff --git a/lib/csapi/relations.h b/lib/csapi/relations.h
new file mode 100644
index 00000000..5d6efd1c
--- /dev/null
+++ b/lib/csapi/relations.h
@@ -0,0 +1,298 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "events/roomevent.h"
+#include "jobs/basejob.h"
+
+namespace Quotient {
+
+/*! \brief Get the child events for a given parent event.
+ *
+ * Retrieve all of the child events for a given parent event.
+ *
+ * Note that when paginating the `from` token should be "after" the `to` token
+ * in terms of topological ordering, because it is only possible to paginate
+ * "backwards" through events, starting at `from`.
+ *
+ * For example, passing a `from` token from page 2 of the results, and a `to`
+ * token from page 1, would return the empty set. The caller can use a `from`
+ * token from page 1 and a `to` token from page 2 to paginate over the same
+ * range, however.
+ */
+class QUOTIENT_API GetRelatingEventsJob : public BaseJob {
+public:
+ /*! \brief Get the child events for a given parent event.
+ *
+ * \param roomId
+ * The ID of the room containing the parent event.
+ *
+ * \param eventId
+ * The ID of the parent event whose child events are to be returned.
+ *
+ * \param from
+ * The pagination token to start returning results from. If not supplied,
+ * results start at the most recent topological event known to the server.
+ *
+ * Can be a `next_batch` or `prev_batch` token from a previous call, or a
+ * returned `start` token from
+ * [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages),
+ * or a `next_batch` token from
+ * [`/sync`](/client-server-api/#get_matrixclientv3sync).
+ *
+ * \param to
+ * The pagination token to stop returning results at. If not supplied,
+ * results continue up to `limit` or until there are no more events.
+ *
+ * Like `from`, this can be a previous token from a prior call to this
+ * endpoint or from `/messages` or `/sync`.
+ *
+ * \param limit
+ * The maximum number of results to return in a single `chunk`. The server
+ * can and should apply a maximum value to this parameter to avoid large
+ * responses.
+ *
+ * Similarly, the server should apply a default value when not supplied.
+ *
+ * \param dir
+ * Optional (default `b`) direction to return events from. If this is set
+ * to `f`, events will be returned in chronological order starting at
+ * `from`. If it is set to `b`, events will be returned in *reverse*
+ * chronological order, again starting at `from`.
+ */
+ explicit GetRelatingEventsJob(const QString& roomId, const QString& eventId,
+ const QString& from = {},
+ const QString& to = {},
+ Omittable<int> limit = none,
+ const QString& dir = {});
+
+ /*! \brief Construct a URL without creating a full-fledged job object
+ *
+ * This function can be used when a URL for GetRelatingEventsJob
+ * is necessary but the job itself isn't.
+ */
+ static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ const QString& eventId, const QString& from = {},
+ const QString& to = {},
+ Omittable<int> limit = none,
+ const QString& dir = {});
+
+ // Result properties
+
+ /// The child events of the requested event, ordered topologically
+ /// most-recent first.
+ RoomEvents chunk() { return takeFromJson<RoomEvents>("chunk"_ls); }
+
+ /// An opaque string representing a pagination token. The absence of this
+ /// token means there are no more results to fetch and the client should
+ /// stop paginating.
+ QString nextBatch() const { return loadFromJson<QString>("next_batch"_ls); }
+
+ /// An opaque string representing a pagination token. The absence of this
+ /// token means this is the start of the result set, i.e. this is the first
+ /// batch/page.
+ QString prevBatch() const { return loadFromJson<QString>("prev_batch"_ls); }
+};
+
+/*! \brief Get the child events for a given parent event, with a given
+ * `relType`.
+ *
+ * Retrieve all of the child events for a given parent event which relate to the
+ * parent using the given `relType`.
+ *
+ * Note that when paginating the `from` token should be "after" the `to` token
+ * in terms of topological ordering, because it is only possible to paginate
+ * "backwards" through events, starting at `from`.
+ *
+ * For example, passing a `from` token from page 2 of the results, and a `to`
+ * token from page 1, would return the empty set. The caller can use a `from`
+ * token from page 1 and a `to` token from page 2 to paginate over the same
+ * range, however.
+ */
+class QUOTIENT_API GetRelatingEventsWithRelTypeJob : public BaseJob {
+public:
+ /*! \brief Get the child events for a given parent event, with a given
+ * `relType`.
+ *
+ * \param roomId
+ * The ID of the room containing the parent event.
+ *
+ * \param eventId
+ * The ID of the parent event whose child events are to be returned.
+ *
+ * \param relType
+ * The [relationship type](/client-server-api/#relationship-types) to
+ * search for.
+ *
+ * \param from
+ * The pagination token to start returning results from. If not supplied,
+ * results start at the most recent topological event known to the server.
+ *
+ * Can be a `next_batch` or `prev_batch` token from a previous call, or a
+ * returned `start` token from
+ * [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages),
+ * or a `next_batch` token from
+ * [`/sync`](/client-server-api/#get_matrixclientv3sync).
+ *
+ * \param to
+ * The pagination token to stop returning results at. If not supplied,
+ * results continue up to `limit` or until there are no more events.
+ *
+ * Like `from`, this can be a previous token from a prior call to this
+ * endpoint or from `/messages` or `/sync`.
+ *
+ * \param limit
+ * The maximum number of results to return in a single `chunk`. The server
+ * can and should apply a maximum value to this parameter to avoid large
+ * responses.
+ *
+ * Similarly, the server should apply a default value when not supplied.
+ *
+ * \param dir
+ * Optional (default `b`) direction to return events from. If this is set
+ * to `f`, events will be returned in chronological order starting at
+ * `from`. If it is set to `b`, events will be returned in *reverse*
+ * chronological order, again starting at `from`.
+ */
+ explicit GetRelatingEventsWithRelTypeJob(
+ const QString& roomId, const QString& eventId, const QString& relType,
+ const QString& from = {}, const QString& to = {},
+ Omittable<int> limit = none, const QString& dir = {});
+
+ /*! \brief Construct a URL without creating a full-fledged job object
+ *
+ * This function can be used when a URL for GetRelatingEventsWithRelTypeJob
+ * is necessary but the job itself isn't.
+ */
+ static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ const QString& eventId, const QString& relType,
+ const QString& from = {}, const QString& to = {},
+ Omittable<int> limit = none,
+ const QString& dir = {});
+
+ // Result properties
+
+ /// The child events of the requested event, ordered topologically
+ /// most-recent first. The events returned will match the `relType`
+ /// supplied in the URL.
+ RoomEvents chunk() { return takeFromJson<RoomEvents>("chunk"_ls); }
+
+ /// An opaque string representing a pagination token. The absence of this
+ /// token means there are no more results to fetch and the client should
+ /// stop paginating.
+ QString nextBatch() const { return loadFromJson<QString>("next_batch"_ls); }
+
+ /// An opaque string representing a pagination token. The absence of this
+ /// token means this is the start of the result set, i.e. this is the first
+ /// batch/page.
+ QString prevBatch() const { return loadFromJson<QString>("prev_batch"_ls); }
+};
+
+/*! \brief Get the child events for a given parent event, with a given `relType`
+ * and `eventType`.
+ *
+ * Retrieve all of the child events for a given parent event which relate to the
+ * parent using the given `relType` and have the given `eventType`.
+ *
+ * Note that when paginating the `from` token should be "after" the `to` token
+ * in terms of topological ordering, because it is only possible to paginate
+ * "backwards" through events, starting at `from`.
+ *
+ * For example, passing a `from` token from page 2 of the results, and a `to`
+ * token from page 1, would return the empty set. The caller can use a `from`
+ * token from page 1 and a `to` token from page 2 to paginate over the same
+ * range, however.
+ */
+class QUOTIENT_API GetRelatingEventsWithRelTypeAndEventTypeJob
+ : public BaseJob {
+public:
+ /*! \brief Get the child events for a given parent event, with a given
+ * `relType` and `eventType`.
+ *
+ * \param roomId
+ * The ID of the room containing the parent event.
+ *
+ * \param eventId
+ * The ID of the parent event whose child events are to be returned.
+ *
+ * \param relType
+ * The [relationship type](/client-server-api/#relationship-types) to
+ * search for.
+ *
+ * \param eventType
+ * The event type of child events to search for.
+ *
+ * Note that in encrypted rooms this will typically always be
+ * `m.room.encrypted` regardless of the event type contained within the
+ * encrypted payload.
+ *
+ * \param from
+ * The pagination token to start returning results from. If not supplied,
+ * results start at the most recent topological event known to the server.
+ *
+ * Can be a `next_batch` or `prev_batch` token from a previous call, or a
+ * returned `start` token from
+ * [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages),
+ * or a `next_batch` token from
+ * [`/sync`](/client-server-api/#get_matrixclientv3sync).
+ *
+ * \param to
+ * The pagination token to stop returning results at. If not supplied,
+ * results continue up to `limit` or until there are no more events.
+ *
+ * Like `from`, this can be a previous token from a prior call to this
+ * endpoint or from `/messages` or `/sync`.
+ *
+ * \param limit
+ * The maximum number of results to return in a single `chunk`. The server
+ * can and should apply a maximum value to this parameter to avoid large
+ * responses.
+ *
+ * Similarly, the server should apply a default value when not supplied.
+ *
+ * \param dir
+ * Optional (default `b`) direction to return events from. If this is set
+ * to `f`, events will be returned in chronological order starting at
+ * `from`. If it is set to `b`, events will be returned in *reverse*
+ * chronological order, again starting at `from`.
+ */
+ explicit GetRelatingEventsWithRelTypeAndEventTypeJob(
+ const QString& roomId, const QString& eventId, const QString& relType,
+ const QString& eventType, const QString& from = {},
+ const QString& to = {}, Omittable<int> limit = none,
+ const QString& dir = {});
+
+ /*! \brief Construct a URL without creating a full-fledged job object
+ *
+ * This function can be used when a URL for
+ * GetRelatingEventsWithRelTypeAndEventTypeJob is necessary but the job
+ * itself isn't.
+ */
+ static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ const QString& eventId, const QString& relType,
+ const QString& eventType,
+ const QString& from = {}, const QString& to = {},
+ Omittable<int> limit = none,
+ const QString& dir = {});
+
+ // Result properties
+
+ /// The child events of the requested event, ordered topologically
+ /// most-recent first. The events returned will match the `relType` and
+ /// `eventType` supplied in the URL.
+ RoomEvents chunk() { return takeFromJson<RoomEvents>("chunk"_ls); }
+
+ /// An opaque string representing a pagination token. The absence of this
+ /// token means there are no more results to fetch and the client should
+ /// stop paginating.
+ QString nextBatch() const { return loadFromJson<QString>("next_batch"_ls); }
+
+ /// An opaque string representing a pagination token. The absence of this
+ /// token means this is the start of the result set, i.e. this is the first
+ /// batch/page.
+ QString prevBatch() const { return loadFromJson<QString>("prev_batch"_ls); }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/report_content.cpp b/lib/csapi/report_content.cpp
index 0a41625f..bc52208f 100644
--- a/lib/csapi/report_content.cpp
+++ b/lib/csapi/report_content.cpp
@@ -4,18 +4,16 @@
#include "report_content.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
ReportContentJob::ReportContentJob(const QString& roomId, const QString& eventId,
- int score, const QString& reason)
+ Omittable<int> score, const QString& reason)
: BaseJob(HttpVerb::Post, QStringLiteral("ReportContentJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/report/" % eventId)
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/report/",
+ eventId))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("score"), score);
- addParam<>(_data, QStringLiteral("reason"), reason);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("score"), score);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("reason"), reason);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/report_content.h b/lib/csapi/report_content.h
index 375e1829..8c533c19 100644
--- a/lib/csapi/report_content.h
+++ b/lib/csapi/report_content.h
@@ -13,7 +13,7 @@ namespace Quotient {
* Reports an event as inappropriate to the server, which may then notify
* the appropriate people.
*/
-class ReportContentJob : public BaseJob {
+class QUOTIENT_API ReportContentJob : public BaseJob {
public:
/*! \brief Reports an event as inappropriate.
*
@@ -31,7 +31,8 @@ public:
* The reason the content is being reported. May be blank.
*/
explicit ReportContentJob(const QString& roomId, const QString& eventId,
- int score, const QString& reason);
+ Omittable<int> score = none,
+ const QString& reason = {});
};
} // namespace Quotient
diff --git a/lib/csapi/room_send.cpp b/lib/csapi/room_send.cpp
index 63986c56..2319496f 100644
--- a/lib/csapi/room_send.cpp
+++ b/lib/csapi/room_send.cpp
@@ -4,16 +4,14 @@
#include "room_send.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SendMessageJob::SendMessageJob(const QString& roomId, const QString& eventType,
const QString& txnId, const QJsonObject& body)
: BaseJob(HttpVerb::Put, QStringLiteral("SendMessageJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/send/" % eventType % "/" % txnId)
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/send/",
+ eventType, "/", txnId))
{
- setRequestData(Data(toJson(body)));
+ setRequestData({ toJson(body) });
addExpectedKey("event_id");
}
diff --git a/lib/csapi/room_send.h b/lib/csapi/room_send.h
index 96f5beca..abe5f207 100644
--- a/lib/csapi/room_send.h
+++ b/lib/csapi/room_send.h
@@ -16,9 +16,10 @@ namespace Quotient {
*
* The body of the request should be the content object of the event; the
* fields in this object will vary depending on the type of event. See
- * [Room Events](/client-server-api/#room-events) for the m. event specification.
+ * [Room Events](/client-server-api/#room-events) for the m. event
+ * specification.
*/
-class SendMessageJob : public BaseJob {
+class QUOTIENT_API SendMessageJob : public BaseJob {
public:
/*! \brief Send a message event to the given room.
*
@@ -29,9 +30,10 @@ public:
* The type of event to send.
*
* \param txnId
- * The transaction ID for this event. Clients should generate an
- * ID unique across requests with the same access token; it will be
- * used by the server to ensure idempotency of requests.
+ * The [transaction ID](/client-server-api/#transaction-identifiers) for
+ * this event. Clients should generate an ID unique across requests with the
+ * same access token; it will be used by the server to ensure idempotency of
+ * requests.
*
* \param body
* This endpoint is used to send a message event to a room. Message events
diff --git a/lib/csapi/room_state.cpp b/lib/csapi/room_state.cpp
index e18108ac..b4adb739 100644
--- a/lib/csapi/room_state.cpp
+++ b/lib/csapi/room_state.cpp
@@ -4,8 +4,6 @@
#include "room_state.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SetRoomStateWithKeyJob::SetRoomStateWithKeyJob(const QString& roomId,
@@ -13,9 +11,9 @@ SetRoomStateWithKeyJob::SetRoomStateWithKeyJob(const QString& roomId,
const QString& stateKey,
const QJsonObject& body)
: BaseJob(HttpVerb::Put, QStringLiteral("SetRoomStateWithKeyJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/state/" % eventType % "/" % stateKey)
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/state/",
+ eventType, "/", stateKey))
{
- setRequestData(Data(toJson(body)));
+ setRequestData({ toJson(body) });
addExpectedKey("event_id");
}
diff --git a/lib/csapi/room_state.h b/lib/csapi/room_state.h
index f95af223..a00b0947 100644
--- a/lib/csapi/room_state.h
+++ b/lib/csapi/room_state.h
@@ -29,7 +29,7 @@ namespace Quotient {
* state event is to be sent. Servers do not validate aliases which are
* being removed or are already present in the state event.
*/
-class SetRoomStateWithKeyJob : public BaseJob {
+class QUOTIENT_API SetRoomStateWithKeyJob : public BaseJob {
public:
/*! \brief Send a state event to the given room.
*
diff --git a/lib/csapi/room_upgrades.cpp b/lib/csapi/room_upgrades.cpp
index e3791b08..b03fb6e8 100644
--- a/lib/csapi/room_upgrades.cpp
+++ b/lib/csapi/room_upgrades.cpp
@@ -4,17 +4,14 @@
#include "room_upgrades.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
UpgradeRoomJob::UpgradeRoomJob(const QString& roomId, const QString& newVersion)
: BaseJob(HttpVerb::Post, QStringLiteral("UpgradeRoomJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/upgrade")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/upgrade"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("new_version"), newVersion);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("new_version"), newVersion);
+ setRequestData({ _dataJson });
addExpectedKey("replacement_room");
}
diff --git a/lib/csapi/room_upgrades.h b/lib/csapi/room_upgrades.h
index 58327587..0432f667 100644
--- a/lib/csapi/room_upgrades.h
+++ b/lib/csapi/room_upgrades.h
@@ -12,7 +12,7 @@ namespace Quotient {
*
* Upgrades the given room to a particular room version.
*/
-class UpgradeRoomJob : public BaseJob {
+class QUOTIENT_API UpgradeRoomJob : public BaseJob {
public:
/*! \brief Upgrades a room to a new room version.
*
diff --git a/lib/csapi/rooms.cpp b/lib/csapi/rooms.cpp
index 724d941f..563f4fa5 100644
--- a/lib/csapi/rooms.cpp
+++ b/lib/csapi/rooms.cpp
@@ -4,24 +4,21 @@
#include "rooms.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetOneRoomEventJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
const QString& eventId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/rooms/" % roomId % "/event/"
- % eventId);
+ makePath("/_matrix/client/v3", "/rooms/",
+ roomId, "/event/", eventId));
}
GetOneRoomEventJob::GetOneRoomEventJob(const QString& roomId,
const QString& eventId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetOneRoomEventJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/event/" % eventId)
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/event/",
+ eventId))
{}
QUrl GetRoomStateWithKeyJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
@@ -29,36 +26,35 @@ QUrl GetRoomStateWithKeyJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
const QString& stateKey)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/rooms/" % roomId % "/state/"
- % eventType % "/" % stateKey);
+ makePath("/_matrix/client/v3", "/rooms/",
+ roomId, "/state/", eventType, "/",
+ stateKey));
}
GetRoomStateWithKeyJob::GetRoomStateWithKeyJob(const QString& roomId,
const QString& eventType,
const QString& stateKey)
: BaseJob(HttpVerb::Get, QStringLiteral("GetRoomStateWithKeyJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/state/" % eventType % "/" % stateKey)
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/state/",
+ eventType, "/", stateKey))
{}
QUrl GetRoomStateJob::makeRequestUrl(QUrl baseUrl, const QString& roomId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/rooms/" % roomId % "/state");
+ makePath("/_matrix/client/v3", "/rooms/",
+ roomId, "/state"));
}
GetRoomStateJob::GetRoomStateJob(const QString& roomId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetRoomStateJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/state")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/state"))
{}
auto queryToGetMembersByRoom(const QString& at, const QString& membership,
const QString& notMembership)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("at"), at);
addParam<IfNotEmpty>(_q, QStringLiteral("membership"), membership);
addParam<IfNotEmpty>(_q, QStringLiteral("not_membership"), notMembership);
@@ -72,7 +68,7 @@ QUrl GetMembersByRoomJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
{
return BaseJob::makeRequestUrl(
std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId % "/members",
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/members"),
queryToGetMembersByRoom(at, membership, notMembership));
}
@@ -81,8 +77,7 @@ GetMembersByRoomJob::GetMembersByRoomJob(const QString& roomId,
const QString& membership,
const QString& notMembership)
: BaseJob(HttpVerb::Get, QStringLiteral("GetMembersByRoomJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/members",
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/members"),
queryToGetMembersByRoom(at, membership, notMembership))
{}
@@ -90,12 +85,12 @@ QUrl GetJoinedMembersByRoomJob::makeRequestUrl(QUrl baseUrl,
const QString& roomId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/rooms/" % roomId % "/joined_members");
+ makePath("/_matrix/client/v3", "/rooms/",
+ roomId, "/joined_members"));
}
GetJoinedMembersByRoomJob::GetJoinedMembersByRoomJob(const QString& roomId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetJoinedMembersByRoomJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/joined_members")
+ makePath("/_matrix/client/v3", "/rooms/", roomId,
+ "/joined_members"))
{}
diff --git a/lib/csapi/rooms.h b/lib/csapi/rooms.h
index 51af2c65..7823a1b0 100644
--- a/lib/csapi/rooms.h
+++ b/lib/csapi/rooms.h
@@ -4,8 +4,8 @@
#pragma once
-#include "events/eventloader.h"
-#include "events/roommemberevent.h"
+#include "events/roomevent.h"
+#include "events/stateevent.h"
#include "jobs/basejob.h"
namespace Quotient {
@@ -15,7 +15,7 @@ namespace Quotient {
* Get a single event based on `roomId/eventId`. You must have permission to
* retrieve this event e.g. by being a member in the room for this event.
*/
-class GetOneRoomEventJob : public BaseJob {
+class QUOTIENT_API GetOneRoomEventJob : public BaseJob {
public:
/*! \brief Get a single event by event ID.
*
@@ -38,7 +38,7 @@ public:
// Result properties
/// The full event.
- EventPtr event() { return fromJson<EventPtr>(jsonData()); }
+ RoomEventPtr event() { return fromJson<RoomEventPtr>(jsonData()); }
};
/*! \brief Get the state identified by the type and key.
@@ -48,7 +48,7 @@ public:
* state of the room. If the user has left the room then the state is
* taken from the state of the room when they left.
*/
-class GetRoomStateWithKeyJob : public BaseJob {
+class QUOTIENT_API GetRoomStateWithKeyJob : public BaseJob {
public:
/*! \brief Get the state identified by the type and key.
*
@@ -80,7 +80,7 @@ public:
*
* Get the state events for the current state of a room.
*/
-class GetRoomStateJob : public BaseJob {
+class QUOTIENT_API GetRoomStateJob : public BaseJob {
public:
/*! \brief Get all state events in the current state of a room.
*
@@ -106,7 +106,7 @@ public:
*
* Get the list of members for this room.
*/
-class GetMembersByRoomJob : public BaseJob {
+class QUOTIENT_API GetMembersByRoomJob : public BaseJob {
public:
/*! \brief Get the m.room.member events for the room.
*
@@ -146,10 +146,7 @@ public:
// Result properties
/// Get the list of members for this room.
- EventsArray<RoomMemberEvent> chunk()
- {
- return takeFromJson<EventsArray<RoomMemberEvent>>("chunk"_ls);
- }
+ StateEvents chunk() { return takeFromJson<StateEvents>("chunk"_ls); }
};
/*! \brief Gets the list of currently joined users and their profile data.
@@ -157,11 +154,10 @@ public:
* This API returns a map of MXIDs to member info objects for members of the
* room. The current user must be in the room for it to work, unless it is an
* Application Service in which case any of the AS's users must be in the room.
- * This API is primarily for Application Services and should be faster to
- * respond than `/members` as it can be implemented more efficiently on the
- * server.
+ * This API is primarily for Application Services and should be faster to respond
+ * than `/members` as it can be implemented more efficiently on the server.
*/
-class GetJoinedMembersByRoomJob : public BaseJob {
+class QUOTIENT_API GetJoinedMembersByRoomJob : public BaseJob {
public:
// Inner data structures
@@ -175,7 +171,7 @@ public:
/// The display name of the user this object is representing.
QString displayName;
/// The mxc avatar url of the user this object is representing.
- QString avatarUrl;
+ QUrl avatarUrl;
};
// Construction/destruction
diff --git a/lib/csapi/search.cpp b/lib/csapi/search.cpp
new file mode 100644
index 00000000..4e2c9e92
--- /dev/null
+++ b/lib/csapi/search.cpp
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#include "search.h"
+
+using namespace Quotient;
+
+auto queryToSearch(const QString& nextBatch)
+{
+ QUrlQuery _q;
+ addParam<IfNotEmpty>(_q, QStringLiteral("next_batch"), nextBatch);
+ return _q;
+}
+
+SearchJob::SearchJob(const Categories& searchCategories,
+ const QString& nextBatch)
+ : BaseJob(HttpVerb::Post, QStringLiteral("SearchJob"),
+ makePath("/_matrix/client/v3", "/search"),
+ queryToSearch(nextBatch))
+{
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("search_categories"), searchCategories);
+ setRequestData({ _dataJson });
+ addExpectedKey("search_categories");
+}
diff --git a/lib/csapi/search.h b/lib/csapi/search.h
new file mode 100644
index 00000000..30095f32
--- /dev/null
+++ b/lib/csapi/search.h
@@ -0,0 +1,307 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "csapi/definitions/room_event_filter.h"
+
+#include "events/roomevent.h"
+#include "events/stateevent.h"
+#include "jobs/basejob.h"
+
+namespace Quotient {
+
+/*! \brief Perform a server-side search.
+ *
+ * Performs a full text search across different categories.
+ */
+class QUOTIENT_API SearchJob : public BaseJob {
+public:
+ // Inner data structures
+
+ /// Configures whether any context for the events
+ /// returned are included in the response.
+ struct IncludeEventContext {
+ /// How many events before the result are
+ /// returned. By default, this is `5`.
+ Omittable<int> beforeLimit;
+ /// How many events after the result are
+ /// returned. By default, this is `5`.
+ Omittable<int> afterLimit;
+ /// Requests that the server returns the
+ /// historic profile information for the users
+ /// that sent the events that were returned.
+ /// By default, this is `false`.
+ Omittable<bool> includeProfile;
+ };
+
+ /// Configuration for group.
+ struct Group {
+ /// Key that defines the group.
+ QString key;
+ };
+
+ /// Requests that the server partitions the result set
+ /// based on the provided list of keys.
+ struct Groupings {
+ /// List of groups to request.
+ QVector<Group> groupBy;
+ };
+
+ /// Mapping of category name to search criteria.
+ struct RoomEventsCriteria {
+ /// The string to search events for
+ QString searchTerm;
+ /// The keys to search. Defaults to all.
+ QStringList keys;
+ /// This takes a [filter](/client-server-api/#filtering).
+ RoomEventFilter filter;
+ /// The order in which to search for results.
+ /// By default, this is `"rank"`.
+ QString orderBy;
+ /// Configures whether any context for the events
+ /// returned are included in the response.
+ Omittable<IncludeEventContext> eventContext;
+ /// Requests the server return the current state for
+ /// each room returned.
+ Omittable<bool> includeState;
+ /// Requests that the server partitions the result set
+ /// based on the provided list of keys.
+ Omittable<Groupings> groupings;
+ };
+
+ /// Describes which categories to search in and their criteria.
+ struct Categories {
+ /// Mapping of category name to search criteria.
+ Omittable<RoomEventsCriteria> roomEvents;
+ };
+
+ /// Performs a full text search across different categories.
+ struct UserProfile {
+ /// Performs a full text search across different categories.
+ QString displayname;
+ /// Performs a full text search across different categories.
+ QUrl avatarUrl;
+ };
+
+ /// Context for result, if requested.
+ struct EventContext {
+ /// Pagination token for the start of the chunk
+ QString begin;
+ /// Pagination token for the end of the chunk
+ QString end;
+ /// The historic profile information of the
+ /// users that sent the events returned.
+ ///
+ /// The `string` key is the user ID for which
+ /// the profile belongs to.
+ QHash<QString, UserProfile> profileInfo;
+ /// Events just before the result.
+ RoomEvents eventsBefore;
+ /// Events just after the result.
+ RoomEvents eventsAfter;
+ };
+
+ /// The result object.
+ struct Result {
+ /// A number that describes how closely this result matches the search.
+ /// Higher is closer.
+ Omittable<double> rank;
+ /// The event that matched.
+ RoomEventPtr result;
+ /// Context for result, if requested.
+ Omittable<EventContext> context;
+ };
+
+ /// The results for a particular group value.
+ struct GroupValue {
+ /// Token that can be used to get the next batch
+ /// of results in the group, by passing as the
+ /// `next_batch` parameter to the next call. If
+ /// this field is absent, there are no more
+ /// results in this group.
+ QString nextBatch;
+ /// Key that can be used to order different
+ /// groups.
+ Omittable<int> order;
+ /// Which results are in this group.
+ QStringList results;
+ };
+
+ /// Mapping of category name to search criteria.
+ struct ResultRoomEvents {
+ /// An approximate count of the total number of results found.
+ Omittable<int> count;
+ /// List of words which should be highlighted, useful for stemming which
+ /// may change the query terms.
+ QStringList highlights;
+ /// List of results in the requested order.
+ std::vector<Result> results;
+ /// The current state for every room in the results.
+ /// This is included if the request had the
+ /// `include_state` key set with a value of `true`.
+ ///
+ /// The `string` key is the room ID for which the `State
+ /// Event` array belongs to.
+ UnorderedMap<QString, StateEvents> state;
+ /// Any groups that were requested.
+ ///
+ /// The outer `string` key is the group key requested (eg: `room_id`
+ /// or `sender`). The inner `string` key is the grouped value (eg:
+ /// a room's ID or a user's ID).
+ QHash<QString, QHash<QString, GroupValue>> groups;
+ /// Token that can be used to get the next batch of
+ /// results, by passing as the `next_batch` parameter to
+ /// the next call. If this field is absent, there are no
+ /// more results.
+ QString nextBatch;
+ };
+
+ /// Describes which categories to search in and their criteria.
+ struct ResultCategories {
+ /// Mapping of category name to search criteria.
+ Omittable<ResultRoomEvents> roomEvents;
+ };
+
+ // Construction/destruction
+
+ /*! \brief Perform a server-side search.
+ *
+ * \param searchCategories
+ * Describes which categories to search in and their criteria.
+ *
+ * \param nextBatch
+ * The point to return events from. If given, this should be a
+ * `next_batch` result from a previous call to this endpoint.
+ */
+ explicit SearchJob(const Categories& searchCategories,
+ const QString& nextBatch = {});
+
+ // Result properties
+
+ /// Describes which categories to search in and their criteria.
+ ResultCategories searchCategories() const
+ {
+ return loadFromJson<ResultCategories>("search_categories"_ls);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::IncludeEventContext> {
+ static void dumpTo(QJsonObject& jo,
+ const SearchJob::IncludeEventContext& pod)
+ {
+ addParam<IfNotEmpty>(jo, QStringLiteral("before_limit"),
+ pod.beforeLimit);
+ addParam<IfNotEmpty>(jo, QStringLiteral("after_limit"), pod.afterLimit);
+ addParam<IfNotEmpty>(jo, QStringLiteral("include_profile"),
+ pod.includeProfile);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::Group> {
+ static void dumpTo(QJsonObject& jo, const SearchJob::Group& pod)
+ {
+ addParam<IfNotEmpty>(jo, QStringLiteral("key"), pod.key);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::Groupings> {
+ static void dumpTo(QJsonObject& jo, const SearchJob::Groupings& pod)
+ {
+ addParam<IfNotEmpty>(jo, QStringLiteral("group_by"), pod.groupBy);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::RoomEventsCriteria> {
+ static void dumpTo(QJsonObject& jo, const SearchJob::RoomEventsCriteria& pod)
+ {
+ addParam<>(jo, QStringLiteral("search_term"), pod.searchTerm);
+ addParam<IfNotEmpty>(jo, QStringLiteral("keys"), pod.keys);
+ addParam<IfNotEmpty>(jo, QStringLiteral("filter"), pod.filter);
+ addParam<IfNotEmpty>(jo, QStringLiteral("order_by"), pod.orderBy);
+ addParam<IfNotEmpty>(jo, QStringLiteral("event_context"),
+ pod.eventContext);
+ addParam<IfNotEmpty>(jo, QStringLiteral("include_state"),
+ pod.includeState);
+ addParam<IfNotEmpty>(jo, QStringLiteral("groupings"), pod.groupings);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::Categories> {
+ static void dumpTo(QJsonObject& jo, const SearchJob::Categories& pod)
+ {
+ addParam<IfNotEmpty>(jo, QStringLiteral("room_events"), pod.roomEvents);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::UserProfile> {
+ static void fillFrom(const QJsonObject& jo, SearchJob::UserProfile& result)
+ {
+ fromJson(jo.value("displayname"_ls), result.displayname);
+ fromJson(jo.value("avatar_url"_ls), result.avatarUrl);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::EventContext> {
+ static void fillFrom(const QJsonObject& jo, SearchJob::EventContext& result)
+ {
+ fromJson(jo.value("start"_ls), result.begin);
+ fromJson(jo.value("end"_ls), result.end);
+ fromJson(jo.value("profile_info"_ls), result.profileInfo);
+ fromJson(jo.value("events_before"_ls), result.eventsBefore);
+ fromJson(jo.value("events_after"_ls), result.eventsAfter);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::Result> {
+ static void fillFrom(const QJsonObject& jo, SearchJob::Result& result)
+ {
+ fromJson(jo.value("rank"_ls), result.rank);
+ fromJson(jo.value("result"_ls), result.result);
+ fromJson(jo.value("context"_ls), result.context);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::GroupValue> {
+ static void fillFrom(const QJsonObject& jo, SearchJob::GroupValue& result)
+ {
+ fromJson(jo.value("next_batch"_ls), result.nextBatch);
+ fromJson(jo.value("order"_ls), result.order);
+ fromJson(jo.value("results"_ls), result.results);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::ResultRoomEvents> {
+ static void fillFrom(const QJsonObject& jo,
+ SearchJob::ResultRoomEvents& result)
+ {
+ fromJson(jo.value("count"_ls), result.count);
+ fromJson(jo.value("highlights"_ls), result.highlights);
+ fromJson(jo.value("results"_ls), result.results);
+ fromJson(jo.value("state"_ls), result.state);
+ fromJson(jo.value("groups"_ls), result.groups);
+ fromJson(jo.value("next_batch"_ls), result.nextBatch);
+ }
+};
+
+template <>
+struct JsonObjectConverter<SearchJob::ResultCategories> {
+ static void fillFrom(const QJsonObject& jo,
+ SearchJob::ResultCategories& result)
+ {
+ fromJson(jo.value("room_events"_ls), result.roomEvents);
+ }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/space_hierarchy.cpp b/lib/csapi/space_hierarchy.cpp
new file mode 100644
index 00000000..7b5c7eac
--- /dev/null
+++ b/lib/csapi/space_hierarchy.cpp
@@ -0,0 +1,43 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#include "space_hierarchy.h"
+
+using namespace Quotient;
+
+auto queryToGetSpaceHierarchy(Omittable<bool> suggestedOnly,
+ Omittable<int> limit, Omittable<int> maxDepth,
+ const QString& from)
+{
+ QUrlQuery _q;
+ addParam<IfNotEmpty>(_q, QStringLiteral("suggested_only"), suggestedOnly);
+ addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("max_depth"), maxDepth);
+ addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
+ return _q;
+}
+
+QUrl GetSpaceHierarchyJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ Omittable<bool> suggestedOnly,
+ Omittable<int> limit,
+ Omittable<int> maxDepth,
+ const QString& from)
+{
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl),
+ makePath("/_matrix/client/v1", "/rooms/", roomId, "/hierarchy"),
+ queryToGetSpaceHierarchy(suggestedOnly, limit, maxDepth, from));
+}
+
+GetSpaceHierarchyJob::GetSpaceHierarchyJob(const QString& roomId,
+ Omittable<bool> suggestedOnly,
+ Omittable<int> limit,
+ Omittable<int> maxDepth,
+ const QString& from)
+ : BaseJob(HttpVerb::Get, QStringLiteral("GetSpaceHierarchyJob"),
+ makePath("/_matrix/client/v1", "/rooms/", roomId, "/hierarchy"),
+ queryToGetSpaceHierarchy(suggestedOnly, limit, maxDepth, from))
+{
+ addExpectedKey("rooms");
+}
diff --git a/lib/csapi/space_hierarchy.h b/lib/csapi/space_hierarchy.h
new file mode 100644
index 00000000..e5da6df2
--- /dev/null
+++ b/lib/csapi/space_hierarchy.h
@@ -0,0 +1,152 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "events/stateevent.h"
+#include "jobs/basejob.h"
+
+namespace Quotient {
+
+/*! \brief Retrieve a portion of a space tree.
+ *
+ * Paginates over the space tree in a depth-first manner to locate child rooms
+ * of a given space.
+ *
+ * Where a child room is unknown to the local server, federation is used to fill
+ * in the details. The servers listed in the `via` array should be contacted to
+ * attempt to fill in missing rooms.
+ *
+ * Only [`m.space.child`](#mspacechild) state events of the room are considered.
+ * Invalid child rooms and parent events are not covered by this endpoint.
+ */
+class QUOTIENT_API GetSpaceHierarchyJob : public BaseJob {
+public:
+ // Inner data structures
+
+ /// Paginates over the space tree in a depth-first manner to locate child
+ /// rooms of a given space.
+ ///
+ /// Where a child room is unknown to the local server, federation is used to
+ /// fill in the details. The servers listed in the `via` array should be
+ /// contacted to attempt to fill in missing rooms.
+ ///
+ /// Only [`m.space.child`](#mspacechild) state events of the room are
+ /// considered. Invalid child rooms and parent events are not covered by
+ /// this endpoint.
+ struct ChildRoomsChunk {
+ /// The canonical alias of the room, if any.
+ QString canonicalAlias;
+ /// The name of the room, if any.
+ QString name;
+ /// The number of members joined to the room.
+ int numJoinedMembers;
+ /// The ID of the room.
+ QString roomId;
+ /// The topic of the room, if any.
+ QString topic;
+ /// Whether the room may be viewed by guest users without joining.
+ bool worldReadable;
+ /// Whether guest users may join the room and participate in it.
+ /// If they can, they will be subject to ordinary power level
+ /// rules like any other user.
+ bool guestCanJoin;
+ /// The URL for the room's avatar, if one is set.
+ QUrl avatarUrl;
+ /// The room's join rule. When not present, the room is assumed to
+ /// be `public`.
+ QString joinRule;
+ /// The `type` of room (from
+ /// [`m.room.create`](/client-server-api/#mroomcreate)), if any.
+ QString roomType;
+ /// The [`m.space.child`](#mspacechild) events of the space-room,
+ /// represented as [Stripped State Events](#stripped-state) with an
+ /// added `origin_server_ts` key.
+ ///
+ /// If the room is not a space-room, this should be empty.
+ StateEvents childrenState;
+ };
+
+ // Construction/destruction
+
+ /*! \brief Retrieve a portion of a space tree.
+ *
+ * \param roomId
+ * The room ID of the space to get a hierarchy for.
+ *
+ * \param suggestedOnly
+ * Optional (default `false`) flag to indicate whether or not the server
+ * should only consider suggested rooms. Suggested rooms are annotated in
+ * their [`m.space.child`](#mspacechild) event contents.
+ *
+ * \param limit
+ * Optional limit for the maximum number of rooms to include per response.
+ * Must be an integer greater than zero.
+ *
+ * Servers should apply a default value, and impose a maximum value to
+ * avoid resource exhaustion.
+ *
+ * \param maxDepth
+ * Optional limit for how far to go into the space. Must be a non-negative
+ * integer.
+ *
+ * When reached, no further child rooms will be returned.
+ *
+ * Servers should apply a default value, and impose a maximum value to
+ * avoid resource exhaustion.
+ *
+ * \param from
+ * A pagination token from a previous result. If specified, `max_depth`
+ * and `suggested_only` cannot be changed from the first request.
+ */
+ explicit GetSpaceHierarchyJob(const QString& roomId,
+ Omittable<bool> suggestedOnly = none,
+ Omittable<int> limit = none,
+ Omittable<int> maxDepth = none,
+ const QString& from = {});
+
+ /*! \brief Construct a URL without creating a full-fledged job object
+ *
+ * This function can be used when a URL for GetSpaceHierarchyJob
+ * is necessary but the job itself isn't.
+ */
+ static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ Omittable<bool> suggestedOnly = none,
+ Omittable<int> limit = none,
+ Omittable<int> maxDepth = none,
+ const QString& from = {});
+
+ // Result properties
+
+ /// The rooms for the current page, with the current filters.
+ std::vector<ChildRoomsChunk> rooms()
+ {
+ return takeFromJson<std::vector<ChildRoomsChunk>>("rooms"_ls);
+ }
+
+ /// A token to supply to `from` to keep paginating the responses. Not
+ /// present when there are no further results.
+ QString nextBatch() const { return loadFromJson<QString>("next_batch"_ls); }
+};
+
+template <>
+struct JsonObjectConverter<GetSpaceHierarchyJob::ChildRoomsChunk> {
+ static void fillFrom(const QJsonObject& jo,
+ GetSpaceHierarchyJob::ChildRoomsChunk& result)
+ {
+ fromJson(jo.value("canonical_alias"_ls), result.canonicalAlias);
+ fromJson(jo.value("name"_ls), result.name);
+ fromJson(jo.value("num_joined_members"_ls), result.numJoinedMembers);
+ fromJson(jo.value("room_id"_ls), result.roomId);
+ fromJson(jo.value("topic"_ls), result.topic);
+ fromJson(jo.value("world_readable"_ls), result.worldReadable);
+ fromJson(jo.value("guest_can_join"_ls), result.guestCanJoin);
+ fromJson(jo.value("avatar_url"_ls), result.avatarUrl);
+ fromJson(jo.value("join_rule"_ls), result.joinRule);
+ fromJson(jo.value("room_type"_ls), result.roomType);
+ fromJson(jo.value("children_state"_ls), result.childrenState);
+ }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/sso_login_redirect.cpp b/lib/csapi/sso_login_redirect.cpp
index 85a18560..71f8147c 100644
--- a/lib/csapi/sso_login_redirect.cpp
+++ b/lib/csapi/sso_login_redirect.cpp
@@ -4,13 +4,11 @@
#include "sso_login_redirect.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
auto queryToRedirectToSSO(const QString& redirectUrl)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<>(_q, QStringLiteral("redirectUrl"), redirectUrl);
return _q;
}
@@ -18,13 +16,36 @@ auto queryToRedirectToSSO(const QString& redirectUrl)
QUrl RedirectToSSOJob::makeRequestUrl(QUrl baseUrl, const QString& redirectUrl)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/login/sso/redirect",
+ makePath("/_matrix/client/v3",
+ "/login/sso/redirect"),
queryToRedirectToSSO(redirectUrl));
}
RedirectToSSOJob::RedirectToSSOJob(const QString& redirectUrl)
: BaseJob(HttpVerb::Get, QStringLiteral("RedirectToSSOJob"),
- QStringLiteral("/_matrix/client/r0") % "/login/sso/redirect",
+ makePath("/_matrix/client/v3", "/login/sso/redirect"),
queryToRedirectToSSO(redirectUrl), {}, false)
{}
+
+auto queryToRedirectToIdP(const QString& redirectUrl)
+{
+ QUrlQuery _q;
+ addParam<>(_q, QStringLiteral("redirectUrl"), redirectUrl);
+ return _q;
+}
+
+QUrl RedirectToIdPJob::makeRequestUrl(QUrl baseUrl, const QString& idpId,
+ const QString& redirectUrl)
+{
+ return BaseJob::makeRequestUrl(std::move(baseUrl),
+ makePath("/_matrix/client/v3",
+ "/login/sso/redirect/", idpId),
+ queryToRedirectToIdP(redirectUrl));
+}
+
+RedirectToIdPJob::RedirectToIdPJob(const QString& idpId,
+ const QString& redirectUrl)
+ : BaseJob(HttpVerb::Get, QStringLiteral("RedirectToIdPJob"),
+ makePath("/_matrix/client/v3", "/login/sso/redirect/", idpId),
+ queryToRedirectToIdP(redirectUrl), {}, false)
+{}
diff --git a/lib/csapi/sso_login_redirect.h b/lib/csapi/sso_login_redirect.h
index 6205ca59..f4f81c1e 100644
--- a/lib/csapi/sso_login_redirect.h
+++ b/lib/csapi/sso_login_redirect.h
@@ -17,7 +17,7 @@ namespace Quotient {
* or present a page which lets the user select an IdP to continue
* with in the event multiple are supported by the server.
*/
-class RedirectToSSOJob : public BaseJob {
+class QUOTIENT_API RedirectToSSOJob : public BaseJob {
public:
/*! \brief Redirect the user's browser to the SSO interface.
*
@@ -35,4 +35,36 @@ public:
static QUrl makeRequestUrl(QUrl baseUrl, const QString& redirectUrl);
};
+/*! \brief Redirect the user's browser to the SSO interface for an IdP.
+ *
+ * This endpoint is the same as `/login/sso/redirect`, though with an
+ * IdP ID from the original `identity_providers` array to inform the
+ * server of which IdP the client/user would like to continue with.
+ *
+ * The server MUST respond with an HTTP redirect to the SSO interface
+ * for that IdP.
+ */
+class QUOTIENT_API RedirectToIdPJob : public BaseJob {
+public:
+ /*! \brief Redirect the user's browser to the SSO interface for an IdP.
+ *
+ * \param idpId
+ * The `id` of the IdP from the `m.login.sso` `identity_providers`
+ * array denoting the user's selection.
+ *
+ * \param redirectUrl
+ * URI to which the user will be redirected after the homeserver has
+ * authenticated the user with SSO.
+ */
+ explicit RedirectToIdPJob(const QString& idpId, const QString& redirectUrl);
+
+ /*! \brief Construct a URL without creating a full-fledged job object
+ *
+ * This function can be used when a URL for RedirectToIdPJob
+ * is necessary but the job itself isn't.
+ */
+ static QUrl makeRequestUrl(QUrl baseUrl, const QString& idpId,
+ const QString& redirectUrl);
+};
+
} // namespace Quotient
diff --git a/lib/csapi/tags.cpp b/lib/csapi/tags.cpp
index dc22dc18..2c85842d 100644
--- a/lib/csapi/tags.cpp
+++ b/lib/csapi/tags.cpp
@@ -4,49 +4,47 @@
#include "tags.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetRoomTagsJob::makeRequestUrl(QUrl baseUrl, const QString& userId,
const QString& roomId)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0") % "/user/"
- % userId % "/rooms/" % roomId % "/tags");
+ makePath("/_matrix/client/v3", "/user/",
+ userId, "/rooms/", roomId, "/tags"));
}
GetRoomTagsJob::GetRoomTagsJob(const QString& userId, const QString& roomId)
: BaseJob(HttpVerb::Get, QStringLiteral("GetRoomTagsJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/rooms/" % roomId % "/tags")
+ makePath("/_matrix/client/v3", "/user/", userId, "/rooms/",
+ roomId, "/tags"))
{}
SetRoomTagJob::SetRoomTagJob(const QString& userId, const QString& roomId,
const QString& tag, Omittable<float> order,
const QVariantHash& additionalProperties)
: BaseJob(HttpVerb::Put, QStringLiteral("SetRoomTagJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/rooms/" % roomId % "/tags/" % tag)
+ makePath("/_matrix/client/v3", "/user/", userId, "/rooms/",
+ roomId, "/tags/", tag))
{
- QJsonObject _data;
- fillJson(_data, additionalProperties);
- addParam<IfNotEmpty>(_data, QStringLiteral("order"), order);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ fillJson(_dataJson, additionalProperties);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("order"), order);
+ setRequestData({ _dataJson });
}
QUrl DeleteRoomTagJob::makeRequestUrl(QUrl baseUrl, const QString& userId,
const QString& roomId, const QString& tag)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/user/" % userId % "/rooms/" % roomId
- % "/tags/" % tag);
+ makePath("/_matrix/client/v3", "/user/",
+ userId, "/rooms/", roomId, "/tags/",
+ tag));
}
DeleteRoomTagJob::DeleteRoomTagJob(const QString& userId, const QString& roomId,
const QString& tag)
: BaseJob(HttpVerb::Delete, QStringLiteral("DeleteRoomTagJob"),
- QStringLiteral("/_matrix/client/r0") % "/user/" % userId
- % "/rooms/" % roomId % "/tags/" % tag)
+ makePath("/_matrix/client/v3", "/user/", userId, "/rooms/",
+ roomId, "/tags/", tag))
{}
diff --git a/lib/csapi/tags.h b/lib/csapi/tags.h
index a854531a..f4250674 100644
--- a/lib/csapi/tags.h
+++ b/lib/csapi/tags.h
@@ -12,7 +12,7 @@ namespace Quotient {
*
* List the tags set by a user on a room.
*/
-class GetRoomTagsJob : public BaseJob {
+class QUOTIENT_API GetRoomTagsJob : public BaseJob {
public:
// Inner data structures
@@ -68,7 +68,7 @@ struct JsonObjectConverter<GetRoomTagsJob::Tag> {
*
* Add a tag to the room.
*/
-class SetRoomTagJob : public BaseJob {
+class QUOTIENT_API SetRoomTagJob : public BaseJob {
public:
/*! \brief Add a tag to a room.
*
@@ -98,7 +98,7 @@ public:
*
* Remove a tag from the room.
*/
-class DeleteRoomTagJob : public BaseJob {
+class QUOTIENT_API DeleteRoomTagJob : public BaseJob {
public:
/*! \brief Remove a tag from the room.
*
diff --git a/lib/csapi/third_party_lookup.cpp b/lib/csapi/third_party_lookup.cpp
index baf1fab5..1e5870ce 100644
--- a/lib/csapi/third_party_lookup.cpp
+++ b/lib/csapi/third_party_lookup.cpp
@@ -4,39 +4,36 @@
#include "third_party_lookup.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetProtocolsJob::makeRequestUrl(QUrl baseUrl)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/thirdparty/protocols");
+ makePath("/_matrix/client/v3",
+ "/thirdparty/protocols"));
}
GetProtocolsJob::GetProtocolsJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetProtocolsJob"),
- QStringLiteral("/_matrix/client/r0") % "/thirdparty/protocols")
+ makePath("/_matrix/client/v3", "/thirdparty/protocols"))
{}
QUrl GetProtocolMetadataJob::makeRequestUrl(QUrl baseUrl,
const QString& protocol)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/thirdparty/protocol/" % protocol);
+ makePath("/_matrix/client/v3",
+ "/thirdparty/protocol/", protocol));
}
GetProtocolMetadataJob::GetProtocolMetadataJob(const QString& protocol)
: BaseJob(HttpVerb::Get, QStringLiteral("GetProtocolMetadataJob"),
- QStringLiteral("/_matrix/client/r0") % "/thirdparty/protocol/"
- % protocol)
+ makePath("/_matrix/client/v3", "/thirdparty/protocol/", protocol))
{}
auto queryToQueryLocationByProtocol(const QString& searchFields)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("searchFields"), searchFields);
return _q;
}
@@ -46,22 +43,21 @@ QUrl QueryLocationByProtocolJob::makeRequestUrl(QUrl baseUrl,
const QString& searchFields)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/thirdparty/location/" % protocol,
+ makePath("/_matrix/client/v3",
+ "/thirdparty/location/", protocol),
queryToQueryLocationByProtocol(searchFields));
}
QueryLocationByProtocolJob::QueryLocationByProtocolJob(
const QString& protocol, const QString& searchFields)
: BaseJob(HttpVerb::Get, QStringLiteral("QueryLocationByProtocolJob"),
- QStringLiteral("/_matrix/client/r0") % "/thirdparty/location/"
- % protocol,
+ makePath("/_matrix/client/v3", "/thirdparty/location/", protocol),
queryToQueryLocationByProtocol(searchFields))
{}
auto queryToQueryUserByProtocol(const QString& fields)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<IfNotEmpty>(_q, QStringLiteral("fields..."), fields);
return _q;
}
@@ -71,22 +67,21 @@ QUrl QueryUserByProtocolJob::makeRequestUrl(QUrl baseUrl,
const QString& fields)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/thirdparty/user/" % protocol,
+ makePath("/_matrix/client/v3",
+ "/thirdparty/user/", protocol),
queryToQueryUserByProtocol(fields));
}
QueryUserByProtocolJob::QueryUserByProtocolJob(const QString& protocol,
const QString& fields)
: BaseJob(HttpVerb::Get, QStringLiteral("QueryUserByProtocolJob"),
- QStringLiteral("/_matrix/client/r0") % "/thirdparty/user/"
- % protocol,
+ makePath("/_matrix/client/v3", "/thirdparty/user/", protocol),
queryToQueryUserByProtocol(fields))
{}
auto queryToQueryLocationByAlias(const QString& alias)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<>(_q, QStringLiteral("alias"), alias);
return _q;
}
@@ -94,20 +89,20 @@ auto queryToQueryLocationByAlias(const QString& alias)
QUrl QueryLocationByAliasJob::makeRequestUrl(QUrl baseUrl, const QString& alias)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/thirdparty/location",
+ makePath("/_matrix/client/v3",
+ "/thirdparty/location"),
queryToQueryLocationByAlias(alias));
}
QueryLocationByAliasJob::QueryLocationByAliasJob(const QString& alias)
: BaseJob(HttpVerb::Get, QStringLiteral("QueryLocationByAliasJob"),
- QStringLiteral("/_matrix/client/r0") % "/thirdparty/location",
+ makePath("/_matrix/client/v3", "/thirdparty/location"),
queryToQueryLocationByAlias(alias))
{}
auto queryToQueryUserByID(const QString& userid)
{
- BaseJob::Query _q;
+ QUrlQuery _q;
addParam<>(_q, QStringLiteral("userid"), userid);
return _q;
}
@@ -115,13 +110,13 @@ auto queryToQueryUserByID(const QString& userid)
QUrl QueryUserByIDJob::makeRequestUrl(QUrl baseUrl, const QString& userid)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/thirdparty/user",
+ makePath("/_matrix/client/v3",
+ "/thirdparty/user"),
queryToQueryUserByID(userid));
}
QueryUserByIDJob::QueryUserByIDJob(const QString& userid)
: BaseJob(HttpVerb::Get, QStringLiteral("QueryUserByIDJob"),
- QStringLiteral("/_matrix/client/r0") % "/thirdparty/user",
+ makePath("/_matrix/client/v3", "/thirdparty/user"),
queryToQueryUserByID(userid))
{}
diff --git a/lib/csapi/third_party_lookup.h b/lib/csapi/third_party_lookup.h
index 969e767c..30c5346e 100644
--- a/lib/csapi/third_party_lookup.h
+++ b/lib/csapi/third_party_lookup.h
@@ -18,7 +18,7 @@ namespace Quotient {
* homeserver. Includes both the available protocols and all fields
* required for queries against each protocol.
*/
-class GetProtocolsJob : public BaseJob {
+class QUOTIENT_API GetProtocolsJob : public BaseJob {
public:
/// Retrieve metadata about all protocols that a homeserver supports.
explicit GetProtocolsJob();
@@ -45,7 +45,7 @@ public:
* Fetches the metadata from the homeserver about a particular third party
* protocol.
*/
-class GetProtocolMetadataJob : public BaseJob {
+class QUOTIENT_API GetProtocolMetadataJob : public BaseJob {
public:
/*! \brief Retrieve metadata about a specific protocol that the homeserver
* supports.
@@ -82,7 +82,7 @@ public:
* identifier. It should attempt to canonicalise the identifier as much
* as reasonably possible given the network type.
*/
-class QueryLocationByProtocolJob : public BaseJob {
+class QUOTIENT_API QueryLocationByProtocolJob : public BaseJob {
public:
/*! \brief Retrieve Matrix-side portals rooms leading to a third party
* location.
@@ -119,7 +119,7 @@ public:
* Retrieve a Matrix User ID linked to a user on the third party service, given
* a set of user parameters.
*/
-class QueryUserByProtocolJob : public BaseJob {
+class QUOTIENT_API QueryUserByProtocolJob : public BaseJob {
public:
/*! \brief Retrieve the Matrix User ID of a corresponding third party user.
*
@@ -155,7 +155,7 @@ public:
* Retrieve an array of third party network locations from a Matrix room
* alias.
*/
-class QueryLocationByAliasJob : public BaseJob {
+class QUOTIENT_API QueryLocationByAliasJob : public BaseJob {
public:
/*! \brief Reverse-lookup third party locations given a Matrix room alias.
*
@@ -184,7 +184,7 @@ public:
*
* Retrieve an array of third party users from a Matrix User ID.
*/
-class QueryUserByIDJob : public BaseJob {
+class QUOTIENT_API QueryUserByIDJob : public BaseJob {
public:
/*! \brief Reverse-lookup third party users given a Matrix User ID.
*
diff --git a/lib/csapi/third_party_membership.cpp b/lib/csapi/third_party_membership.cpp
index fda772d2..3ca986c7 100644
--- a/lib/csapi/third_party_membership.cpp
+++ b/lib/csapi/third_party_membership.cpp
@@ -4,21 +4,18 @@
#include "third_party_membership.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
InviteBy3PIDJob::InviteBy3PIDJob(const QString& roomId, const QString& idServer,
const QString& idAccessToken,
const QString& medium, const QString& address)
: BaseJob(HttpVerb::Post, QStringLiteral("InviteBy3PIDJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/invite")
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/invite"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("id_server"), idServer);
- addParam<>(_data, QStringLiteral("id_access_token"), idAccessToken);
- addParam<>(_data, QStringLiteral("medium"), medium);
- addParam<>(_data, QStringLiteral("address"), address);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("id_server"), idServer);
+ addParam<>(_dataJson, QStringLiteral("id_access_token"), idAccessToken);
+ addParam<>(_dataJson, QStringLiteral("medium"), medium);
+ addParam<>(_dataJson, QStringLiteral("address"), address);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/third_party_membership.h b/lib/csapi/third_party_membership.h
index a424678f..1129a9a8 100644
--- a/lib/csapi/third_party_membership.h
+++ b/lib/csapi/third_party_membership.h
@@ -16,7 +16,7 @@ namespace Quotient {
* The homeserver uses an identity server to perform the mapping from
* third party identifier to a Matrix identifier. The other is documented in
* the* [joining rooms
- * section](/client-server-api/#post_matrixclientr0roomsroomidinvite).
+ * section](/client-server-api/#post_matrixclientv3roomsroomidinvite).
*
* This API invites a user to participate in a particular room.
* They do not start participating in the room until they actually join the
@@ -52,7 +52,7 @@ namespace Quotient {
* If a token is requested from the identity server, the homeserver will
* append a `m.room.third_party_invite` event to the room.
*/
-class InviteBy3PIDJob : public BaseJob {
+class QUOTIENT_API InviteBy3PIDJob : public BaseJob {
public:
/*! \brief Invite a user to participate in a particular room.
*
diff --git a/lib/csapi/threads_list.cpp b/lib/csapi/threads_list.cpp
new file mode 100644
index 00000000..26924f24
--- /dev/null
+++ b/lib/csapi/threads_list.cpp
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#include "threads_list.h"
+
+using namespace Quotient;
+
+auto queryToGetThreadRoots(const QString& include, Omittable<int> limit,
+ const QString& from)
+{
+ QUrlQuery _q;
+ addParam<IfNotEmpty>(_q, QStringLiteral("include"), include);
+ addParam<IfNotEmpty>(_q, QStringLiteral("limit"), limit);
+ addParam<IfNotEmpty>(_q, QStringLiteral("from"), from);
+ return _q;
+}
+
+QUrl GetThreadRootsJob::makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ const QString& include,
+ Omittable<int> limit, const QString& from)
+{
+ return BaseJob::makeRequestUrl(std::move(baseUrl),
+ makePath("/_matrix/client/v1", "/rooms/",
+ roomId, "/threads"),
+ queryToGetThreadRoots(include, limit, from));
+}
+
+GetThreadRootsJob::GetThreadRootsJob(const QString& roomId,
+ const QString& include,
+ Omittable<int> limit, const QString& from)
+ : BaseJob(HttpVerb::Get, QStringLiteral("GetThreadRootsJob"),
+ makePath("/_matrix/client/v1", "/rooms/", roomId, "/threads"),
+ queryToGetThreadRoots(include, limit, from))
+{
+ addExpectedKey("chunk");
+}
diff --git a/lib/csapi/threads_list.h b/lib/csapi/threads_list.h
new file mode 100644
index 00000000..7041583a
--- /dev/null
+++ b/lib/csapi/threads_list.h
@@ -0,0 +1,76 @@
+/******************************************************************************
+ * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
+ */
+
+#pragma once
+
+#include "events/roomevent.h"
+#include "jobs/basejob.h"
+
+namespace Quotient {
+
+/*! \brief Retrieve a list of threads in a room, with optional filters.
+ *
+ * Paginates over the thread roots in a room, ordered by the `latest_event` of
+ * each thread root in its bundle.
+ */
+class QUOTIENT_API GetThreadRootsJob : public BaseJob {
+public:
+ /*! \brief Retrieve a list of threads in a room, with optional filters.
+ *
+ * \param roomId
+ * The room ID where the thread roots are located.
+ *
+ * \param include
+ * Optional (default `all`) flag to denote which thread roots are of
+ * interest to the caller. When `all`, all thread roots found in the room
+ * are returned. When `participated`, only thread roots for threads the user
+ * has [participated
+ * in](/client-server-api/#server-side-aggreagtion-of-mthread-relationships)
+ * will be returned.
+ *
+ * \param limit
+ * Optional limit for the maximum number of thread roots to include per
+ * response. Must be an integer greater than zero.
+ *
+ * Servers should apply a default value, and impose a maximum value to
+ * avoid resource exhaustion.
+ *
+ * \param from
+ * A pagination token from a previous result. When not provided, the
+ * server starts paginating from the most recent event visible to the user
+ * (as per history visibility rules; topologically).
+ */
+ explicit GetThreadRootsJob(const QString& roomId,
+ const QString& include = {},
+ Omittable<int> limit = none,
+ const QString& from = {});
+
+ /*! \brief Construct a URL without creating a full-fledged job object
+ *
+ * This function can be used when a URL for GetThreadRootsJob
+ * is necessary but the job itself isn't.
+ */
+ static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId,
+ const QString& include = {},
+ Omittable<int> limit = none,
+ const QString& from = {});
+
+ // Result properties
+
+ /// The thread roots, ordered by the `latest_event` in each event's
+ /// aggregation bundle. All events returned include bundled
+ /// [aggregations](/client-server-api/#aggregations).
+ ///
+ /// If the thread root event was sent by an [ignored
+ /// user](/client-server-api/#ignoring-users), the event is returned
+ /// redacted to the caller. This is to simulate the same behaviour of a
+ /// client doing aggregation locally on the thread.
+ RoomEvents chunk() { return takeFromJson<RoomEvents>("chunk"_ls); }
+
+ /// A token to supply to `from` to keep paginating the responses. Not
+ /// present when there are no further results.
+ QString nextBatch() const { return loadFromJson<QString>("next_batch"_ls); }
+};
+
+} // namespace Quotient
diff --git a/lib/csapi/to_device.cpp b/lib/csapi/to_device.cpp
index 28c4115a..e10fac69 100644
--- a/lib/csapi/to_device.cpp
+++ b/lib/csapi/to_device.cpp
@@ -4,18 +4,16 @@
#include "to_device.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SendToDeviceJob::SendToDeviceJob(
const QString& eventType, const QString& txnId,
const QHash<QString, QHash<QString, QJsonObject>>& messages)
: BaseJob(HttpVerb::Put, QStringLiteral("SendToDeviceJob"),
- QStringLiteral("/_matrix/client/r0") % "/sendToDevice/"
- % eventType % "/" % txnId)
+ makePath("/_matrix/client/v3", "/sendToDevice/", eventType, "/",
+ txnId))
{
- QJsonObject _data;
- addParam<IfNotEmpty>(_data, QStringLiteral("messages"), messages);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("messages"), messages);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/to_device.h b/lib/csapi/to_device.h
index f5d69d65..54828337 100644
--- a/lib/csapi/to_device.h
+++ b/lib/csapi/to_device.h
@@ -13,7 +13,7 @@ namespace Quotient {
* This endpoint is used to send send-to-device events to a set of
* client devices.
*/
-class SendToDeviceJob : public BaseJob {
+class QUOTIENT_API SendToDeviceJob : public BaseJob {
public:
/*! \brief Send an event to a given set of devices.
*
@@ -21,9 +21,10 @@ public:
* The type of event to send.
*
* \param txnId
- * The transaction ID for this event. Clients should generate an
- * ID unique across requests with the same access token; it will be
- * used by the server to ensure idempotency of requests.
+ * The [transaction ID](/client-server-api/#transaction-identifiers) for
+ * this event. Clients should generate an ID unique across requests with the
+ * same access token; it will be used by the server to ensure idempotency of
+ * requests.
*
* \param messages
* The messages to send. A map from user ID, to a map from
@@ -32,7 +33,7 @@ public:
*/
explicit SendToDeviceJob(
const QString& eventType, const QString& txnId,
- const QHash<QString, QHash<QString, QJsonObject>>& messages = {});
+ const QHash<QString, QHash<QString, QJsonObject>>& messages);
};
} // namespace Quotient
diff --git a/lib/csapi/typing.cpp b/lib/csapi/typing.cpp
index 8e214053..21bd45ae 100644
--- a/lib/csapi/typing.cpp
+++ b/lib/csapi/typing.cpp
@@ -4,18 +4,16 @@
#include "typing.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SetTypingJob::SetTypingJob(const QString& userId, const QString& roomId,
bool typing, Omittable<int> timeout)
: BaseJob(HttpVerb::Put, QStringLiteral("SetTypingJob"),
- QStringLiteral("/_matrix/client/r0") % "/rooms/" % roomId
- % "/typing/" % userId)
+ makePath("/_matrix/client/v3", "/rooms/", roomId, "/typing/",
+ userId))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("typing"), typing);
- addParam<IfNotEmpty>(_data, QStringLiteral("timeout"), timeout);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("typing"), typing);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("timeout"), timeout);
+ setRequestData({ _dataJson });
}
diff --git a/lib/csapi/typing.h b/lib/csapi/typing.h
index 64a310d0..234e91b0 100644
--- a/lib/csapi/typing.h
+++ b/lib/csapi/typing.h
@@ -15,7 +15,7 @@ namespace Quotient {
* Alternatively, if `typing` is `false`, it tells the server that the
* user has stopped typing.
*/
-class SetTypingJob : public BaseJob {
+class QUOTIENT_API SetTypingJob : public BaseJob {
public:
/*! \brief Informs the server that the user has started or stopped typing.
*
diff --git a/lib/csapi/users.cpp b/lib/csapi/users.cpp
index a0279d7e..c65280ee 100644
--- a/lib/csapi/users.cpp
+++ b/lib/csapi/users.cpp
@@ -4,19 +4,17 @@
#include "users.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
SearchUserDirectoryJob::SearchUserDirectoryJob(const QString& searchTerm,
Omittable<int> limit)
: BaseJob(HttpVerb::Post, QStringLiteral("SearchUserDirectoryJob"),
- QStringLiteral("/_matrix/client/r0") % "/user_directory/search")
+ makePath("/_matrix/client/v3", "/user_directory/search"))
{
- QJsonObject _data;
- addParam<>(_data, QStringLiteral("search_term"), searchTerm);
- addParam<IfNotEmpty>(_data, QStringLiteral("limit"), limit);
- setRequestData(std::move(_data));
+ QJsonObject _dataJson;
+ addParam<>(_dataJson, QStringLiteral("search_term"), searchTerm);
+ addParam<IfNotEmpty>(_dataJson, QStringLiteral("limit"), limit);
+ setRequestData({ _dataJson });
addExpectedKey("results");
addExpectedKey("limited");
}
diff --git a/lib/csapi/users.h b/lib/csapi/users.h
index eab18f6c..3c99758b 100644
--- a/lib/csapi/users.h
+++ b/lib/csapi/users.h
@@ -21,7 +21,7 @@ namespace Quotient {
* names preferably using a collation determined based upon the
* `Accept-Language` header provided in the request, if present.
*/
-class SearchUserDirectoryJob : public BaseJob {
+class QUOTIENT_API SearchUserDirectoryJob : public BaseJob {
public:
// Inner data structures
@@ -41,7 +41,7 @@ public:
/// The display name of the user, if one exists.
QString displayName;
/// The avatar url, as an MXC, if one exists.
- QString avatarUrl;
+ QUrl avatarUrl;
};
// Construction/destruction
diff --git a/lib/csapi/versions.cpp b/lib/csapi/versions.cpp
index 9003e27f..a1efc33e 100644
--- a/lib/csapi/versions.cpp
+++ b/lib/csapi/versions.cpp
@@ -4,20 +4,17 @@
#include "versions.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetVersionsJob::makeRequestUrl(QUrl baseUrl)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client")
- % "/versions");
+ makePath("/_matrix/client", "/versions"));
}
GetVersionsJob::GetVersionsJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetVersionsJob"),
- QStringLiteral("/_matrix/client") % "/versions", false)
+ makePath("/_matrix/client", "/versions"), false)
{
addExpectedKey("versions");
}
diff --git a/lib/csapi/versions.h b/lib/csapi/versions.h
index 896e2ea9..9f799cb0 100644
--- a/lib/csapi/versions.h
+++ b/lib/csapi/versions.h
@@ -12,11 +12,9 @@ namespace Quotient {
*
* Gets the versions of the specification supported by the server.
*
- * Values will take the form `rX.Y.Z`.
- *
- * Only the latest `Z` value will be reported for each supported `X.Y` value.
- * i.e. if the server implements `r0.0.0`, `r0.0.1`, and `r1.2.0`, it will
- * report `r0.0.1` and `r1.2.0`.
+ * Values will take the form `vX.Y` or `rX.Y.Z` in historical cases. See
+ * [the Specification Versioning](../#specification-versions) for more
+ * information.
*
* The server may additionally advertise experimental features it supports
* through `unstable_features`. These features should be namespaced and
@@ -31,7 +29,7 @@ namespace Quotient {
* upgrade appropriately. Additionally, clients should avoid using unstable
* features in their stable releases.
*/
-class GetVersionsJob : public BaseJob {
+class QUOTIENT_API GetVersionsJob : public BaseJob {
public:
/// Gets the versions of the specification supported by the server.
explicit GetVersionsJob();
diff --git a/lib/csapi/voip.cpp b/lib/csapi/voip.cpp
index 43170057..1e1f2441 100644
--- a/lib/csapi/voip.cpp
+++ b/lib/csapi/voip.cpp
@@ -4,18 +4,15 @@
#include "voip.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetTurnServerJob::makeRequestUrl(QUrl baseUrl)
{
- return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/voip/turnServer");
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl), makePath("/_matrix/client/v3", "/voip/turnServer"));
}
GetTurnServerJob::GetTurnServerJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetTurnServerJob"),
- QStringLiteral("/_matrix/client/r0") % "/voip/turnServer")
+ makePath("/_matrix/client/v3", "/voip/turnServer"))
{}
diff --git a/lib/csapi/voip.h b/lib/csapi/voip.h
index 087ebbbd..38904f60 100644
--- a/lib/csapi/voip.h
+++ b/lib/csapi/voip.h
@@ -13,7 +13,7 @@ namespace Quotient {
* This API provides credentials for the client to use when initiating
* calls.
*/
-class GetTurnServerJob : public BaseJob {
+class QUOTIENT_API GetTurnServerJob : public BaseJob {
public:
/// Obtain TURN server credentials.
explicit GetTurnServerJob();
diff --git a/lib/csapi/wellknown.cpp b/lib/csapi/wellknown.cpp
index 1aa0a90b..0b441279 100644
--- a/lib/csapi/wellknown.cpp
+++ b/lib/csapi/wellknown.cpp
@@ -4,18 +4,15 @@
#include "wellknown.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetWellknownJob::makeRequestUrl(QUrl baseUrl)
{
return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/.well-known")
- % "/matrix/client");
+ makePath("/.well-known", "/matrix/client"));
}
GetWellknownJob::GetWellknownJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetWellknownJob"),
- QStringLiteral("/.well-known") % "/matrix/client", false)
+ makePath("/.well-known", "/matrix/client"), false)
{}
diff --git a/lib/csapi/wellknown.h b/lib/csapi/wellknown.h
index c707d232..8615191c 100644
--- a/lib/csapi/wellknown.h
+++ b/lib/csapi/wellknown.h
@@ -21,7 +21,7 @@ namespace Quotient {
* Note that this endpoint is not necessarily handled by the homeserver,
* but by another webserver, to be used for discovering the homeserver URL.
*/
-class GetWellknownJob : public BaseJob {
+class QUOTIENT_API GetWellknownJob : public BaseJob {
public:
/// Gets Matrix server discovery information about the domain.
explicit GetWellknownJob();
diff --git a/lib/csapi/whoami.cpp b/lib/csapi/whoami.cpp
index 73f0298e..af0c5d31 100644
--- a/lib/csapi/whoami.cpp
+++ b/lib/csapi/whoami.cpp
@@ -4,20 +4,17 @@
#include "whoami.h"
-#include <QtCore/QStringBuilder>
-
using namespace Quotient;
QUrl GetTokenOwnerJob::makeRequestUrl(QUrl baseUrl)
{
- return BaseJob::makeRequestUrl(std::move(baseUrl),
- QStringLiteral("/_matrix/client/r0")
- % "/account/whoami");
+ return BaseJob::makeRequestUrl(
+ std::move(baseUrl), makePath("/_matrix/client/v3", "/account/whoami"));
}
GetTokenOwnerJob::GetTokenOwnerJob()
: BaseJob(HttpVerb::Get, QStringLiteral("GetTokenOwnerJob"),
- QStringLiteral("/_matrix/client/r0") % "/account/whoami")
+ makePath("/_matrix/client/v3", "/account/whoami"))
{
addExpectedKey("user_id");
}
diff --git a/lib/csapi/whoami.h b/lib/csapi/whoami.h
index 184459ea..3451dbc3 100644
--- a/lib/csapi/whoami.h
+++ b/lib/csapi/whoami.h
@@ -19,7 +19,7 @@ namespace Quotient {
* is registered by the appservice, and return it in the response
* body.
*/
-class GetTokenOwnerJob : public BaseJob {
+class QUOTIENT_API GetTokenOwnerJob : public BaseJob {
public:
/// Gets information about the owner of an access token.
explicit GetTokenOwnerJob();
@@ -35,6 +35,20 @@ public:
/// The user ID that owns the access token.
QString userId() const { return loadFromJson<QString>("user_id"_ls); }
+
+ /// Device ID associated with the access token. If no device
+ /// is associated with the access token (such as in the case
+ /// of application services) then this field can be omitted.
+ /// Otherwise this is required.
+ QString deviceId() const { return loadFromJson<QString>("device_id"_ls); }
+
+ /// When `true`, the user is a [Guest User](#guest-access). When
+ /// not present or `false`, the user is presumed to be a non-guest
+ /// user.
+ Omittable<bool> isGuest() const
+ {
+ return loadFromJson<Omittable<bool>>("is_guest"_ls);
+ }
};
} // namespace Quotient