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