1 | #pragma once |
2 | |
3 | /// @file |
4 | /// @brief Structs for for requests to the Matrix API. |
5 | |
6 | #include <string> |
7 | #include <variant> |
8 | |
9 | #include <mtx/common.hpp> |
10 | #include <mtx/events/collections.hpp> |
11 | #if __has_include(<nlohmann/json_fwd.hpp>) |
12 | #include <nlohmann/json_fwd.hpp> |
13 | #else |
14 | #include <nlohmann/json.hpp> |
15 | #endif |
16 | |
17 | namespace mtx { |
18 | //! Namespace for request structs |
19 | namespace requests { |
20 | //! Convenience parameter for setting various default state events based on a preset. |
21 | enum class Preset |
22 | { |
23 | //! `join_rules` is set to `invite`. `history_visibility` is set to `shared`. |
24 | PrivateChat, |
25 | //! `join_rules` is set to `public`. `history_visibility` is set to `shared`. |
26 | PublicChat, |
27 | //! `join_rules` is set to `invite`. `history_visibility` is set to `shared`. |
28 | //! All invitees are given the same power level as the room creator. |
29 | TrustedPrivateChat, |
30 | }; |
31 | |
32 | //! Request payload for the `POST /_matrix/client/r0/createRoom` endpoint. |
33 | struct CreateRoom |
34 | { |
35 | //! If this is included, an `m.room.name` event will |
36 | //! be sent into the room to indicate the name of the room. |
37 | std::string name; |
38 | //! If this is included, an `m.room.topic` event will be sent |
39 | //! into the room to indicate the topic for the room. |
40 | std::string topic; |
41 | //! The desired room alias local part. e.g `#foo:example.com`. |
42 | std::string room_alias_name; |
43 | //! A list of user IDs to invite to the room. |
44 | std::vector<std::string> invite; |
45 | //! This flag makes the server set the is_direct flag on the |
46 | //! `m.room.member` events sent to the users in @p invite and @p invite_3pid. |
47 | bool is_direct = false; |
48 | //! Convenience parameter for setting various default state events. |
49 | Preset preset = Preset::PrivateChat; |
50 | //! Whether or not the room will be visible by non members. |
51 | common::RoomVisibility visibility = common::RoomVisibility::Private; |
52 | |
53 | //! A list of state events to set in the new room. This allows the user to override the default |
54 | //! state events set in the new room. The expected format of the state events are an object with |
55 | //! type, state_key and content keys set. |
56 | std::vector<events::collections::StrippedEvents> initial_state; |
57 | |
58 | //! The room version to set for the room. If not provided, the homeserver is to use its |
59 | //! configured default. If provided, the homeserver will return a 400 error with the errcode |
60 | //! M_UNSUPPORTED_ROOM_VERSION if it does not support the room version. |
61 | std::string room_version; |
62 | |
63 | //! Extra keys, such as m.federate, to be added to the content of the m.room.create event. The |
64 | //! server will overwrite the following keys: creator, room_version. Future versions of the |
65 | //! specification may allow the server to overwrite other keys. |
66 | std::optional<events::state::Create> creation_content; |
67 | |
68 | friend void to_json(nlohmann::json &obj, const CreateRoom &request); |
69 | }; |
70 | |
71 | namespace login_identifier { |
72 | //! The user is identified by their Matrix ID. |
73 | struct User |
74 | { |
75 | //! A client can identify a user using their Matrix ID. This can either be the fully |
76 | //! qualified Matrix user ID, or just the localpart of the user ID. |
77 | std::string user; |
78 | }; |
79 | //! The user is identified by a third-party identifier in canonicalised form. |
80 | struct Thirdparty |
81 | { |
82 | //! The medium of the third party identifier |
83 | std::string medium; |
84 | //! The canonicalised third party address of the user |
85 | std::string address; |
86 | }; |
87 | //! The user is identified by a phone number. |
88 | struct PhoneNumber |
89 | { |
90 | //! The country is the two-letter uppercase ISO-3166-1 alpha-2 country code that the number |
91 | //! in phone should be parsed as if it were dialled from. |
92 | std::string country; |
93 | //! The phone number. If the client wishes to canonicalise the phone number, then it can use |
94 | //! the m.id.thirdparty identifier type with a medium of msisdn instead. |
95 | std::string phone; |
96 | }; |
97 | } |
98 | |
99 | //! Request payload for the `POST /_matrix/client/r0/login` endpoint. |
100 | struct Login |
101 | { |
102 | //! The login type being used. One of ["m.login.password", "m.login.token"] |
103 | std::string type = "m.login.password" ; |
104 | //! Identification information for the user. Usually you use `login_identifier::User` with |
105 | //! an mxid. Required. |
106 | std:: |
107 | variant<login_identifier::User, login_identifier::Thirdparty, login_identifier::PhoneNumber> |
108 | identifier; |
109 | //! Required when type is m.login.token. The login token. |
110 | std::string token; |
111 | //! Required when type is m.login.password. The user's password. |
112 | std::string password; |
113 | //! ID of the client device. If this does not correspond to a known client device, |
114 | //! a new device will be created. |
115 | //! The server will auto-generate a device_id if this is not specified. |
116 | std::string device_id; |
117 | //! A display name to assign to the newly-created device. |
118 | //! Ignored if device_id corresponds to a known device. |
119 | std::string initial_device_display_name; |
120 | |
121 | friend void to_json(nlohmann::json &obj, const Login &request); |
122 | }; |
123 | |
124 | /// @brief Request payload for |
125 | /// `POST /_matrix/client/r0/{register,account/password}/email/requestToken` |
126 | /// |
127 | /// The homeserver should validate the email itself, either by sending a validation email itself or |
128 | /// by using a service it has control over. |
129 | struct RequestEmailToken |
130 | { |
131 | //! Required. A unique string generated by the client, and used to identify the validation |
132 | //! attempt. It must be a string consisting of the characters [0-9a-zA-Z.=_-]. Its length must |
133 | //! not exceed 255 characters and it must not be empty. |
134 | std::string client_secret; |
135 | //! Required. The email address to validate. |
136 | std::string email; |
137 | |
138 | //! Required. The server will only send an email if the send_attempt is a number greater than |
139 | //! the most recent one which it has seen, scoped to that email + client_secret pair. This is to |
140 | //! avoid repeatedly sending the same email in the case of request retries between the POSTing |
141 | //! user and the identity server. The client should increment this value if they desire a new |
142 | //! email (e.g. a reminder) to be sent. If they do not, the server should respond with success |
143 | //! but not resend the email. |
144 | int send_attempt = 0; |
145 | |
146 | friend void to_json(nlohmann::json &obj, const RequestEmailToken &request); |
147 | }; |
148 | |
149 | /// @brief Request payload for |
150 | /// `POST /_matrix/client/r0/{register,account/password}/msisdn/requestToken` |
151 | /// |
152 | /// The homeserver should validate the email itself, either by sending a validation email itself or |
153 | /// by using a service it has control over. |
154 | struct RequestMSISDNToken |
155 | { |
156 | //! Required. A unique string generated by the client, and used to identify the validation |
157 | //! attempt. It must be a string consisting of the characters [0-9a-zA-Z.=_-]. Its length must |
158 | //! not exceed 255 characters and it must not be empty. |
159 | std::string client_secret; |
160 | //! Required. The two-letter uppercase ISO-3166-1 alpha-2 country code that the number in |
161 | //! phone_number should be parsed as if it were dialled from. |
162 | std::string country; |
163 | //! Required. The phone number to validate. |
164 | std::string phone_number; |
165 | |
166 | //! Required. The server will only send an SMS if the send_attempt is a number greater than the |
167 | //! most recent one which it has seen, scoped to that country + phone_number + client_secret |
168 | //! triple. This is to avoid repeatedly sending the same SMS in the case of request retries |
169 | //! between the POSTing user and the identity server. The client should increment this value if |
170 | //! they desire a new SMS (e.g. a reminder) to be sent. |
171 | int send_attempt = 0; |
172 | }; |
173 | |
174 | void |
175 | to_json(nlohmann::json &obj, const RequestMSISDNToken &request); |
176 | |
177 | //! Validate ownership of an email address/phone number. |
178 | struct IdentitySubmitToken |
179 | { |
180 | //! Required. The session ID, generated by the requestToken call. |
181 | std::string sid; |
182 | //! Required. The client secret that was supplied to the requestToken call. |
183 | std::string client_secret; |
184 | //! Required. The token generated by the requestToken call and emailed to the user. |
185 | std::string token; |
186 | |
187 | friend void to_json(nlohmann::json &obj, const IdentitySubmitToken &request); |
188 | }; |
189 | |
190 | //! Request payload for the `PUT /_matrix/client/r0/sendToDevice/{eventType}/{transcationID}` |
191 | template<typename EventContent> |
192 | using ToDeviceMessages = std::map<mtx::identifiers::User, std::map<std::string, EventContent>>; |
193 | |
194 | //! Request payload for the `POST /_matrix/client/r0/profile/{userId}/avatar_url` endpoint. |
195 | struct AvatarUrl |
196 | { |
197 | std::string avatar_url; |
198 | |
199 | friend void to_json(nlohmann::json &obj, const AvatarUrl &request); |
200 | }; |
201 | |
202 | //! Request payload for the `PUT /_matrix/client/r0/profile/{userId}/displayname` endpoint. |
203 | struct DisplayName |
204 | { |
205 | //! The new display name for this device. If not given, the display name is unchanged. |
206 | std::string displayname; |
207 | |
208 | friend void to_json(nlohmann::json &obj, const DisplayName &request); |
209 | }; |
210 | |
211 | //! Request payload for the `POST /_matrix/client/r0/rooms/{roomId}/invite` endpoint as well as ban, |
212 | //! unban and kick. |
213 | struct RoomMembershipChange |
214 | { |
215 | std::string user_id; |
216 | |
217 | //! optional kick, invite or ban reason |
218 | std::string reason; |
219 | |
220 | friend void to_json(nlohmann::json &obj, const RoomMembershipChange &request); |
221 | }; |
222 | |
223 | //! Request payload for the `PUT /_matrix/client/r0/rooms/{roomId}/typing/{userId}` endpoint. |
224 | struct TypingNotification |
225 | { |
226 | //! Whether the user is typing or not. |
227 | bool typing = false; |
228 | //! The length of time in milliseconds to mark this user as typing. |
229 | uint64_t timeout = 0; |
230 | |
231 | friend void to_json(nlohmann::json &obj, const TypingNotification &request); |
232 | }; |
233 | |
234 | //! Request payload for the `PUT /_matrix/client/r0/devices/{deviceId}` endpoint. |
235 | struct DeviceUpdate |
236 | { |
237 | std::string display_name; |
238 | |
239 | friend void to_json(nlohmann::json &obj, const DeviceUpdate &request); |
240 | }; |
241 | |
242 | //! Request payload for the `PUT /_matrix/client/r0/directory/list/room/{roomId}` endpoint |
243 | struct PublicRoomVisibility |
244 | { |
245 | //! The new visibility setting for the room. Defaults to 'public'. One of: ["private", |
246 | //! "public"] |
247 | common::RoomVisibility visibility; |
248 | |
249 | friend void to_json(nlohmann::json &obj, const PublicRoomVisibility &request); |
250 | }; |
251 | |
252 | struct PublicRoomsFilter |
253 | { |
254 | //! A string to search for in the room metadata, |
255 | //! e.g. name, topic, canonical alias etc. (Optional). |
256 | std::string generic_search_term; |
257 | |
258 | friend void to_json(nlohmann::json &obj, const PublicRoomsFilter &req); |
259 | }; |
260 | |
261 | //! Request payload for the `POST /_matrix/client/r0/publicRooms` endpoint. |
262 | struct PublicRooms |
263 | { |
264 | //! Limit the number of results returned. |
265 | int limit; |
266 | //! A pagination token from a previous request, allowing clients |
267 | //! to get the next (or previous) batch of rooms. The direction of |
268 | //! pagination is specified solely by which token is supplied, |
269 | //! rather than via an explicit flag. |
270 | std::string since; |
271 | //! Filter to apply to the results. |
272 | PublicRoomsFilter filter; |
273 | //! Whether or not to include all known networks/protocols from |
274 | //! application services on the homeserver. Defaults to false. |
275 | bool include_all_networks = false; |
276 | //! The specific third party network/protocol to request from |
277 | //! the homeserver. Can only be used if include_all_networks is false. |
278 | std::string third_party_instance_id; |
279 | |
280 | friend void to_json(nlohmann::json &obj, const PublicRooms &request); |
281 | }; |
282 | |
283 | //! An empty response. |
284 | /// |
285 | /// Some endpoints return this on success. |
286 | struct Empty |
287 | { |
288 | friend inline void to_json(nlohmann::json &, const Empty &) {} |
289 | }; |
290 | |
291 | //! A successfull logout. |
292 | using Logout = Empty; |
293 | |
294 | //! A signed onetime key. Usually curve25519. |
295 | struct SignedOneTimeKey |
296 | { |
297 | //! Required. The unpadded Base64-encoded 32-byte Curve25519 public key. |
298 | std::string key; |
299 | //! When uploading a signed key, an additional fallback: true key should be included to denote |
300 | //! that the key is a fallback key. |
301 | bool fallback = false; |
302 | //! Required. Signatures of the key object. |
303 | //! The signature is calculated using the process described at Signing JSON. |
304 | std::map<std::string, std::map<std::string, std::string>> signatures; |
305 | |
306 | friend void to_json(nlohmann::json &obj, const SignedOneTimeKey &); |
307 | }; |
308 | |
309 | //! Upload a mix of device, one time and fallback keys. |
310 | struct UploadKeys |
311 | { |
312 | //! Identity keys for the device. |
313 | //! May be absent if no new identity keys are required. |
314 | mtx::crypto::DeviceKeys device_keys; |
315 | //! One-time public keys for "pre-key" messages. |
316 | //! The names of the properties should be in the format `<algorithm>:<key_id>`. |
317 | //! The format of the key is determined by the key algorithm. |
318 | std::map<std::string, std::variant<std::string, SignedOneTimeKey>> one_time_keys; |
319 | |
320 | //! The public key which should be used if the device’s one-time keys are exhausted. The |
321 | //! fallback key is not deleted once used, but should be replaced when additional one-time keys |
322 | //! are being uploaded. The server will notify the client of the fallback key being used through |
323 | //! /sync. |
324 | //! |
325 | //! There can only be at most one key per algorithm uploaded, and the server will only persist |
326 | //! one key per algorithm. |
327 | //! |
328 | //! When uploading a signed key, an additional fallback: true key should be included to denote |
329 | //! that the key is a fallback key. |
330 | //! |
331 | //! May be absent if a new fallback key is not required. |
332 | std::map<std::string, std::variant<std::string, SignedOneTimeKey>> fallback_keys; |
333 | |
334 | friend void to_json(nlohmann::json &obj, const UploadKeys &); |
335 | }; |
336 | |
337 | //! The default timeout for a download. |
338 | inline constexpr uint64_t DEFAULT_DOWNLOAD_TIMEOUT = 10UL * 1000; // 10 seconds |
339 | |
340 | //! Query the keys of devices of specific users. |
341 | struct QueryKeys |
342 | { |
343 | //! The time (in milliseconds) to wait when downloading keys from remote servers. |
344 | uint64_t timeout = DEFAULT_DOWNLOAD_TIMEOUT; |
345 | //! The keys to be downloaded. |
346 | //! A map from user ID, to a list of device IDs, or to an empty |
347 | //! list to indicate all devices for the corresponding user. |
348 | std::map<std::string, std::vector<std::string>> device_keys; |
349 | //! If the client is fetching keys as a result of a device update |
350 | //! received in a sync request, this should be the 'since' token of |
351 | //! that sync request, or any later sync token. |
352 | //! This allows the server to ensure its response contains the keys |
353 | //! advertised by the notification in that sync. |
354 | std::string token; |
355 | |
356 | friend void to_json(nlohmann::json &obj, const QueryKeys &); |
357 | }; |
358 | |
359 | //! Claim onetime keys of devices of specific users. |
360 | struct ClaimKeys |
361 | { |
362 | //! The time (in milliseconds) to wait when downloading keys from remote servers. |
363 | uint64_t timeout = DEFAULT_DOWNLOAD_TIMEOUT; |
364 | //! The keys to be claimed. A map from user ID, to a map from device ID to algorithm name. |
365 | std::map<std::string, std::map<std::string, std::string>> one_time_keys; |
366 | |
367 | friend void to_json(nlohmann::json &obj, const ClaimKeys &request); |
368 | }; |
369 | |
370 | //! Upload new signatures for a device or cross-signing key. |
371 | struct KeySignaturesUpload |
372 | { |
373 | //! map from user_id to either a map of device id to DeviceKey with new signatures or the |
374 | //! key id to CrossSigningKeys with new signatures |
375 | std::map< |
376 | std::string, |
377 | std::map<std::string, std::variant<mtx::crypto::DeviceKeys, mtx::crypto::CrossSigningKeys>>> |
378 | signatures; |
379 | |
380 | friend void to_json(nlohmann::json &obj, const KeySignaturesUpload &req); |
381 | }; |
382 | |
383 | //! Upload cross signing keys |
384 | struct DeviceSigningUpload |
385 | { |
386 | //! Optional. The user's master key. |
387 | std::optional<mtx::crypto::CrossSigningKeys> master_key; |
388 | //! Optional. The user's self-signing key. Must be signed by the accompanying master key, or by |
389 | //! the user's most recently uploaded master key if no master key is included in the request. |
390 | std::optional<mtx::crypto::CrossSigningKeys> self_signing_key; |
391 | //! Optional. The user's user-signing key. Must be signed by the accompanying master key, or by |
392 | //! the user's most recently uploaded master key if no master key is included in the request. |
393 | std::optional<mtx::crypto::CrossSigningKeys> user_signing_key; |
394 | |
395 | friend void to_json(nlohmann::json &obj, const DeviceSigningUpload &req); |
396 | }; |
397 | |
398 | //! Information about a pusher. |
399 | struct PusherData |
400 | { |
401 | //! Required if `kind` is http. The URL to use to send notifications to. |
402 | //! MUST be an HTTPS URL with a path of /_matrix/push/v1/notify. |
403 | std::string url; |
404 | //! The format to send notifications in to Push Gateways if the kind is http. |
405 | //! The details about what fields the homeserver should send to the push gateway are |
406 | //! defined in the Push Gateway Specification. Currently the only format available is |
407 | //! 'event_id_only'. |
408 | std::string format; |
409 | |
410 | friend void to_json(nlohmann::json &obj, const PusherData &data); |
411 | }; |
412 | |
413 | //! Request payload for the `POST /_matrix/client/r0/pushers/set` endpoint. |
414 | struct SetPusher |
415 | { |
416 | //! Required. Unique identifier for this pusher. |
417 | std::string pushkey; |
418 | //! Required. The kind of pusher to configure. "http" makes a pusher that sends HTTP pokes. |
419 | //! "email" makes a pusher that emails the user with unread notifications. |
420 | //! null deletes the pusher. |
421 | std::string kind; |
422 | //! Required. This is a reverse-DNS style identifier for the application. |
423 | //! If the `kind` is "email", this is "m.email". |
424 | std::string app_id; |
425 | //! Required. A string that will allow the user to identify what application owns this |
426 | //! pusher. |
427 | std::string app_display_name; |
428 | //! Required. A string that will allow the user to identify what device owns this pusher. |
429 | std::string device_display_name; |
430 | //! Determines which set of device specific rules this pusher executes. |
431 | std::string profile_tag; |
432 | //! Required. The preferred language for receiving notifications. |
433 | std::string lang; |
434 | //! Required. Data for the pusher implementation (for example, if `kind` is `http`, includes |
435 | //! the URL to push to). |
436 | PusherData data; |
437 | //! If true, add another pusher instead of updating an existing one. |
438 | bool append = false; |
439 | |
440 | friend void to_json(nlohmann::json &obj, const SetPusher &req); |
441 | }; |
442 | } // namespace requests |
443 | } // namespace mtx |
444 | |