1/******************************************************************************
2 * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
3 */
4
5#pragma once
6
7#include <Quotient/csapi/definitions/cross_signing_key.h>
8#include <Quotient/csapi/definitions/device_keys.h>
9
10#include <Quotient/e2ee/e2ee_common.h>
11
12#include <Quotient/jobs/basejob.h>
13
14namespace Quotient {
15
16/*! \brief Upload end-to-end encryption keys.
17 *
18 * Publishes end-to-end encryption keys for the device.
19 */
20class QUOTIENT_API UploadKeysJob : public BaseJob {
21public:
22 /*! \brief Upload end-to-end encryption keys.
23 *
24 * \param deviceKeys
25 * Identity keys for the device. May be absent if no new
26 * identity keys are required.
27 *
28 * \param oneTimeKeys
29 * One-time public keys for "pre-key" messages. The names of
30 * the properties should be in the format
31 * `<algorithm>:<key_id>`. The format of the key is determined
32 * by the [key algorithm](/client-server-api/#key-algorithms).
33 *
34 * May be absent if no new one-time keys are required.
35 *
36 * \param fallbackKeys
37 * The public key which should be used if the device's one-time keys
38 * are exhausted. The fallback key is not deleted once used, but should
39 * be replaced when additional one-time keys are being uploaded. The
40 * server will notify the client of the fallback key being used through
41 * `/sync`.
42 *
43 * There can only be at most one key per algorithm uploaded, and the
44 * server will only persist one key per algorithm.
45 *
46 * When uploading a signed key, an additional `fallback: true` key should
47 * be included to denote that the key is a fallback key.
48 *
49 * May be absent if a new fallback key is not required.
50 */
51 explicit UploadKeysJob(const Omittable<DeviceKeys>& deviceKeys = none,
52 const OneTimeKeys& oneTimeKeys = {},
53 const OneTimeKeys& fallbackKeys = {});
54
55 // Result properties
56
57 /// For each key algorithm, the number of unclaimed one-time keys
58 /// of that type currently held on the server for this device.
59 /// If an algorithm is not listed, the count for that algorithm
60 /// is to be assumed zero.
61 QHash<QString, int> oneTimeKeyCounts() const
62 {
63 return loadFromJson<QHash<QString, int>>(keyName: "one_time_key_counts"_ls);
64 }
65};
66
67/*! \brief Download device identity keys.
68 *
69 * Returns the current devices and identity keys for the given users.
70 */
71class QUOTIENT_API QueryKeysJob : public BaseJob {
72public:
73 // Inner data structures
74
75 /// Additional data added to the device key information
76 /// by intermediate servers, and not covered by the
77 /// signatures.
78 struct UnsignedDeviceInfo {
79 /// The display name which the user set on the device.
80 QString deviceDisplayName{};
81 };
82
83 /// Returns the current devices and identity keys for the given users.
84 struct DeviceInformation : DeviceKeys {
85 /// Additional data added to the device key information
86 /// by intermediate servers, and not covered by the
87 /// signatures.
88 Omittable<UnsignedDeviceInfo> unsignedData{};
89 };
90
91 // Construction/destruction
92
93 /*! \brief Download device identity keys.
94 *
95 * \param deviceKeys
96 * The keys to be downloaded. A map from user ID, to a list of
97 * device IDs, or to an empty list to indicate all devices for the
98 * corresponding user.
99 *
100 * \param timeout
101 * The time (in milliseconds) to wait when downloading keys from
102 * remote servers. 10 seconds is the recommended default.
103 */
104 explicit QueryKeysJob(const QHash<QString, QStringList>& deviceKeys,
105 Omittable<int> timeout = none);
106
107 // Result properties
108
109 /// If any remote homeservers could not be reached, they are
110 /// recorded here. The names of the properties are the names of
111 /// the unreachable servers.
112 ///
113 /// If the homeserver could be reached, but the user or device
114 /// was unknown, no failure is recorded. Instead, the corresponding
115 /// user or device is missing from the `device_keys` result.
116 QHash<QString, QJsonObject> failures() const
117 {
118 return loadFromJson<QHash<QString, QJsonObject>>(keyName: "failures"_ls);
119 }
120
121 /// Information on the queried devices. A map from user ID, to a
122 /// map from device ID to device information. For each device,
123 /// the information returned will be the same as uploaded via
124 /// `/keys/upload`, with the addition of an `unsigned`
125 /// property.
126 QHash<QString, QHash<QString, DeviceInformation>> deviceKeys() const
127 {
128 return loadFromJson<QHash<QString, QHash<QString, DeviceInformation>>>(
129 keyName: "device_keys"_ls);
130 }
131
132 /// Information on the master cross-signing keys of the queried users.
133 /// A map from user ID, to master key information. For each key, the
134 /// information returned will be the same as uploaded via
135 /// `/keys/device_signing/upload`, along with the signatures
136 /// uploaded via `/keys/signatures/upload` that the requesting user
137 /// is allowed to see.
138 QHash<QString, CrossSigningKey> masterKeys() const
139 {
140 return loadFromJson<QHash<QString, CrossSigningKey>>(keyName: "master_keys"_ls);
141 }
142
143 /// Information on the self-signing keys of the queried users. A map
144 /// from user ID, to self-signing key information. For each key, the
145 /// information returned will be the same as uploaded via
146 /// `/keys/device_signing/upload`.
147 QHash<QString, CrossSigningKey> selfSigningKeys() const
148 {
149 return loadFromJson<QHash<QString, CrossSigningKey>>(
150 keyName: "self_signing_keys"_ls);
151 }
152
153 /// Information on the user-signing key of the user making the
154 /// request, if they queried their own device information. A map
155 /// from user ID, to user-signing key information. The
156 /// information returned will be the same as uploaded via
157 /// `/keys/device_signing/upload`.
158 QHash<QString, CrossSigningKey> userSigningKeys() const
159 {
160 return loadFromJson<QHash<QString, CrossSigningKey>>(
161 keyName: "user_signing_keys"_ls);
162 }
163};
164
165template <>
166struct JsonObjectConverter<QueryKeysJob::UnsignedDeviceInfo> {
167 static void fillFrom(const QJsonObject& jo,
168 QueryKeysJob::UnsignedDeviceInfo& result)
169 {
170 fillFromJson(jv: jo.value(key: "device_display_name"_ls),
171 pod&: result.deviceDisplayName);
172 }
173};
174
175template <>
176struct JsonObjectConverter<QueryKeysJob::DeviceInformation> {
177 static void fillFrom(const QJsonObject& jo,
178 QueryKeysJob::DeviceInformation& result)
179 {
180 fillFromJson<DeviceKeys>(jv: jo, pod&: result);
181 fillFromJson(jv: jo.value(key: "unsigned"_ls), pod&: result.unsignedData);
182 }
183};
184
185/*! \brief Claim one-time encryption keys.
186 *
187 * Claims one-time keys for use in pre-key messages.
188 */
189class QUOTIENT_API ClaimKeysJob : public BaseJob {
190public:
191 /*! \brief Claim one-time encryption keys.
192 *
193 * \param oneTimeKeys
194 * The keys to be claimed. A map from user ID, to a map from
195 * device ID to algorithm name.
196 *
197 * \param timeout
198 * The time (in milliseconds) to wait when downloading keys from
199 * remote servers. 10 seconds is the recommended default.
200 */
201 explicit ClaimKeysJob(
202 const QHash<QString, QHash<QString, QString>>& oneTimeKeys,
203 Omittable<int> timeout = none);
204
205 // Result properties
206
207 /// If any remote homeservers could not be reached, they are
208 /// recorded here. The names of the properties are the names of
209 /// the unreachable servers.
210 ///
211 /// If the homeserver could be reached, but the user or device
212 /// was unknown, no failure is recorded. Instead, the corresponding
213 /// user or device is missing from the `one_time_keys` result.
214 QHash<QString, QJsonObject> failures() const
215 {
216 return loadFromJson<QHash<QString, QJsonObject>>(keyName: "failures"_ls);
217 }
218
219 /// One-time keys for the queried devices. A map from user ID, to a
220 /// map from devices to a map from `<algorithm>:<key_id>` to the key object.
221 ///
222 /// See the [key algorithms](/client-server-api/#key-algorithms) section for
223 /// information on the Key Object format.
224 ///
225 /// If necessary, the claimed key might be a fallback key. Fallback
226 /// keys are re-used by the server until replaced by the device.
227 QHash<QString, QHash<QString, OneTimeKeys>> oneTimeKeys() const
228 {
229 return loadFromJson<QHash<QString, QHash<QString, OneTimeKeys>>>(
230 keyName: "one_time_keys"_ls);
231 }
232};
233
234/*! \brief Query users with recent device key updates.
235 *
236 * Gets a list of users who have updated their device identity keys since a
237 * previous sync token.
238 *
239 * The server should include in the results any users who:
240 *
241 * * currently share a room with the calling user (ie, both users have
242 * membership state `join`); *and*
243 * * added new device identity keys or removed an existing device with
244 * identity keys, between `from` and `to`.
245 */
246class QUOTIENT_API GetKeysChangesJob : public BaseJob {
247public:
248 /*! \brief Query users with recent device key updates.
249 *
250 * \param from
251 * The desired start point of the list. Should be the `next_batch` field
252 * from a response to an earlier call to
253 * [`/sync`](/client-server-api/#get_matrixclientv3sync). Users who have not
254 * uploaded new device identity keys since this point, nor deleted
255 * existing devices with identity keys since then, will be excluded
256 * from the results.
257 *
258 * \param to
259 * The desired end point of the list. Should be the `next_batch`
260 * field from a recent call to
261 * [`/sync`](/client-server-api/#get_matrixclientv3sync) - typically the
262 * most recent such call. This may be used by the server as a hint to check
263 * its caches are up to date.
264 */
265 explicit GetKeysChangesJob(const QString& from, const QString& to);
266
267 /*! \brief Construct a URL without creating a full-fledged job object
268 *
269 * This function can be used when a URL for GetKeysChangesJob
270 * is necessary but the job itself isn't.
271 */
272 static QUrl makeRequestUrl(QUrl baseUrl, const QString& from,
273 const QString& to);
274
275 // Result properties
276
277 /// The Matrix User IDs of all users who updated their device
278 /// identity keys.
279 QStringList changed() const
280 {
281 return loadFromJson<QStringList>(keyName: "changed"_ls);
282 }
283
284 /// The Matrix User IDs of all users who may have left all
285 /// the end-to-end encrypted rooms they previously shared
286 /// with the user.
287 QStringList left() const { return loadFromJson<QStringList>(keyName: "left"_ls); }
288};
289
290} // namespace Quotient
291