-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathcontacts.h
More file actions
464 lines (431 loc) · 15.5 KB
/
Copy pathcontacts.h
File metadata and controls
464 lines (431 loc) · 15.5 KB
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
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "base.h"
#include "expiring.h"
#include "notify.h"
#include "profile_pic.h"
#include "util.h"
// Maximum length of a contact name/nickname, in bytes (not including the null terminator).
LIBSESSION_EXPORT extern const size_t CONTACT_MAX_NAME_LENGTH;
typedef struct contacts_contact {
char session_id[67]; // in hex; 66 hex chars + null terminator.
// These two will be 0-length strings when unset:
char name[101];
char nickname[101];
user_profile_pic profile_pic;
int64_t profile_updated; // unix timestamp (seconds)
bool approved;
bool approved_me;
bool blocked;
int priority;
CONVO_NOTIFY_MODE notifications;
int64_t mute_until; // unix timestamp (seconds)
CONVO_EXPIRATION_MODE exp_mode;
int exp_seconds;
int64_t created; // unix timestamp (seconds)
} contacts_contact;
typedef struct contacts_blinded_contact {
char session_id[67]; // in hex; 66 hex chars + null terminator.
char base_url[268]; // null-terminated (max length 267), normalized (i.e. always lower-case,
// only has port if non-default, has trailing / removed)
unsigned char pubkey[32]; // 32 bytes (not terminated, can contain nulls)
char name[101]; // This will be a 0-length string when unset
user_profile_pic profile_pic;
bool legacy_blinding;
int64_t created; // unix timestamp (seconds)
} contacts_blinded_contact;
/// Struct containing a list of contacts_blinded_contact structs. Typically where this is returned
/// by this API it must be freed (via `free()`) when done with it.
///
/// When returned as a pointer by a libsession-util function this is allocated in such a way that
/// just the outer contacts_blinded_contact_list can be free()d to free both the list *and* the
/// inner `value` and pointed-at values.
typedef struct contacts_blinded_contact_list {
contacts_blinded_contact** value; // array of blinded contacts
size_t len; // length of `value`
} contacts_blinded_contact_list;
/// API: contacts/contacts_init
///
/// Constructs a contacts config object and sets a pointer to it in `conf`.
///
/// When done with the object the `config_object` must be destroyed by passing the pointer to
/// config_free() (in `session/config/base.h`).
///
/// Declaration:
/// ```cpp
/// INT contacts_init(
/// [out] config_object** conf,
/// [in] const unsigned char* ed25519_secretkey,
/// [in] const unsigned char* dump,
/// [in] size_t dumplen,
/// [out] char* error
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [out] Pointer to the config object
/// - `ed25519_secretkey` -- [in] must be the 32-byte secret key seed value. (You can also pass the
/// pointer to the beginning of the 64-byte value libsodium calls the "secret key" as the first 32
/// bytes of that are the seed). This field cannot be null.
/// - `dump` -- [in] if non-NULL this restores the state from the dumped byte string produced by a
/// past instantiation's call to `dump()`. To construct a new, empty object this should be NULL.
/// - `dumplen` -- [in] the length of `dump` when restoring from a dump, or 0 when `dump` is NULL.
/// - `error` -- [out] the pointer to a buffer in which we will write an error string if an error
/// occurs; error messages are discarded if this is given as NULL. If non-NULL this must be a
/// buffer of at least 256 bytes.
///
/// Outputs:
/// - `int` -- Returns 0 on success; returns a non-zero error code and write the exception message
/// as a C-string into `error` (if not NULL) on failure.
LIBSESSION_EXPORT int contacts_init(
config_object** conf,
const unsigned char* ed25519_secretkey,
const unsigned char* dump,
size_t dumplen,
char* error) LIBSESSION_WARN_UNUSED;
/// API: contacts/contacts_get
///
/// Fills `contact` with the contact info given a session ID (specified as a null-terminated hex
/// string), if the contact exists, and returns true. If the contact does not exist then `contact`
/// is left unchanged and false is returned.
///
/// Declaration:
/// ```cpp
/// BOOL contacts_get(
/// [in] config_object* conf,
/// [out] contacts_contact* contact,
/// [in] const char* session_id
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in] Pointer to the config object
/// - `contact` -- [out] the contact info data
/// - `session_id` -- [in] null terminated hex string
///
/// Output:
/// - `bool` -- Returns true if contact exsts
LIBSESSION_EXPORT bool contacts_get(
config_object* conf,
contacts_contact* contact,
const char* session_id) LIBSESSION_WARN_UNUSED;
/// API: contacts/contacts_get_or_construct
///
/// Same as the above `contacts_get()` except that when the contact does not exist, this sets all
/// the contact fields to defaults and loads it with the given session_id.
///
/// Returns true as long as it is given a valid session_id. A false return is considered an error,
/// and means the session_id was not a valid session_id.
///
/// This is the method that should usually be used to create or update a contact, followed by
/// setting fields in the contact, and then giving it to contacts_set().
///
/// Declaration:
/// ```cpp
/// BOOL contacts_get_or_construct(
/// [in] config_object* conf,
/// [out] contacts_contact* contact,
/// [in] const char* session_id
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in] Pointer to the config object
/// - `contact` -- [out] the contact info data
/// - `session_id` -- [in] null terminated hex string
///
/// Output:
/// - `bool` -- Returns true if contact exsts
LIBSESSION_EXPORT bool contacts_get_or_construct(
config_object* conf,
contacts_contact* contact,
const char* session_id) LIBSESSION_WARN_UNUSED;
/// API: contacts/contacts_set
///
/// Adds or updates a contact from the given contact info struct.
///
/// Declaration:
/// ```cpp
/// VOID contacts_set(
/// [in, out] config_object* conf,
/// [in] const contacts_contact* contact
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in, out] Pointer to the config object
/// - `contact` -- [in] Pointer containing the contact info data
///
/// Output:
/// - `bool` -- Returns true if the call succeeds, false if an error occurs.
LIBSESSION_EXPORT bool contacts_set(config_object* conf, const contacts_contact* contact);
// NB: wrappers for set_name, set_nickname, etc. C++ methods are deliberately omitted as they would
// save very little in actual calling code. The procedure for updating a single field without them
// is simple enough; for example to update `approved` and leave everything else unchanged:
//
// contacts_contact c;
// if (contacts_get_or_construct(conf, &c, some_session_id)) {
// const char* new_nickname = "Joe";
// c.approved = new_nickname;
// contacts_set_or_create(conf, &c);
// } else {
// // some_session_id was invalid!
// }
/// API: contacts/contacts_erase
///
/// Erases a contact from the contact list. session_id is in hex. Returns true if the contact was
/// found and removed, false if the contact was not present. You must not call this during
/// iteration; see details below.
///
/// Declaration:
/// ```cpp
/// BOOL contacts_erase(
/// [in, out] config_object* conf,
/// [in] const char* session_id
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in, out] Pointer to the config object
/// - `session_id` -- [in] Text containing null terminated hex string
///
/// Outputs:
/// - `bool` -- True if erasing was successful
LIBSESSION_EXPORT bool contacts_erase(config_object* conf, const char* session_id);
/// API: contacts/contacts_size
///
/// Returns the number of contacts.
///
/// Declaration:
/// ```cpp
/// SIZE_T contacts_size(
/// [in] const config_object* conf
/// );
/// ```
///
/// Inputs:
/// - `conf` -- input - Pointer to the config object
///
/// Outputs:
/// - `size_t` -- number of contacts
LIBSESSION_EXPORT size_t contacts_size(const config_object* conf);
/// API: contacts/contacts_blinded_contacts
///
/// Retrieves a list of blinded contact records.
///
/// Declaration:
/// ```cpp
/// contacts_blinded_contact_list* contacts_blinded_contacts(
/// [in] config_object* conf
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in, out] Pointer to config_object object
///
/// Outputs:
/// - `contacts_blinded_contact_list*` -- pointer to the list of blinded contact structs; the
/// pointer belongs to the caller and must be freed when done with it.
LIBSESSION_EXPORT contacts_blinded_contact_list* contacts_blinded(const config_object* conf);
/// API: contacts/contacts_get_blinded_contact
///
/// Fills `blinded_contact` with the blinded contact info given a blinded session ID (specified as a
/// null-terminated hex string), if the blinded contact exists, and returns true. If the contact
/// does not exist then `blinded_contact` is left unchanged and false is returned.
///
/// Declaration:
/// ```cpp
/// BOOL contacts_get_blinded_contact(
/// [in] config_object* conf,
/// [in] const char* blinded_id,
/// [in] bool legacy_blinding,
/// [out] contacts_blinded_contact* blinded_contact
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in] Pointer to the config object
/// - `blinded_id` -- [in] null terminated hex string
/// - `legacy_blinding` -- [in] null terminated hex string
/// - `blinded_contact` -- [out] the blinded contact info data
///
/// Output:
/// - `bool` -- Returns true if blinded contact exists
LIBSESSION_EXPORT bool contacts_get_blinded(
config_object* conf,
const char* blinded_id,
bool legacy_blinding,
contacts_blinded_contact* blinded_contact) LIBSESSION_WARN_UNUSED;
/// API: contacts/contacts_get_or_construct_blinded
///
/// Same as the above `contacts_get_blinded()` except that when the blinded contact does not exist,
/// this sets all the contact fields to defaults and loads it with the given blinded_id.
///
/// Returns true as long as it is given a valid blinded_id. A false return is considered an error,
/// and means the blinded_id was not a valid blinded_id.
///
/// This is the method that should usually be used to create or update a blinded contact, followed
/// by setting fields in the blinded contact, and then giving it to contacts_set_blinded().
///
/// Declaration:
/// ```cpp
/// BOOL contacts_get_or_construct_blinded(
/// [in] config_object* conf,
/// [in] const char* community_base_url,
/// [in] const char* community_pubkey_hex,
/// [in] const char* blinded_id,
/// [in] bool legacy_blinding,
/// [out] contacts_blinded_contact* blinded_contact
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in] Pointer to the config object
/// - `community_base_url` -- [in] null terminated string
/// - `community_pubkey_hex` -- [in] null terminated hex string
/// - `blinded_id` -- [in] null terminated hex string
/// - `legacy_blinding` -- [in] null terminated hex string
/// - `blinded_contact` -- [out] the blinded contact info data
///
/// Output:
/// - `bool` -- Returns true if contact exsts
LIBSESSION_EXPORT bool contacts_get_or_construct_blinded(
config_object* conf,
const char* community_base_url,
const char* community_pubkey_hex,
const char* blinded_id,
bool legacy_blinding,
contacts_blinded_contact* blinded_contact) LIBSESSION_WARN_UNUSED;
/// API: contacts/contacts_set_blinded
///
/// Adds or updates a blinded contact from the given contact info struct.
///
/// Declaration:
/// ```cpp
/// BOOL contacts_set_blinded_contact(
/// [in] config_object* conf,
/// [in] contacts_blinded_contact* bc
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in] Pointer to the config object
/// - `blinded_contact` -- [in] the blinded contact info data
///
/// Output:
/// - `bool` -- Returns true if the call succeeds, false if an error occurs.
LIBSESSION_EXPORT bool contacts_set_blinded(
config_object* conf, const contacts_blinded_contact* bc);
/// API: contacts/contacts_erase_blinded
///
/// Erases a blinded contact from the blinded contact list. blinded_id is in hex. Returns true if
/// the blinded contact was found and removed, false if the blinded contact was not present.
///
/// Declaration:
/// ```cpp
/// BOOL contacts_erase_blinded(
/// [in, out] config_object* conf,
/// [in] const char* community_base_url,
/// [in] const char* blinded_id,
/// [in] bool legacy_blinding
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in, out] Pointer to the config object
/// - `base_url` -- [in] Text containing null terminated base url for the community this blinded
/// contact originated from
/// - `blinded_id` -- [in] Text containing null terminated hex string
/// - `legacy_blinding` -- [in] Flag indicating whether this blinded contact used legacy blinding
///
/// Outputs:
/// - `bool` -- True if erasing was successful
LIBSESSION_EXPORT bool contacts_erase_blinded_contact(
config_object* conf,
const char* community_base_url,
const char* blinded_id,
bool legacy_blinding);
typedef struct contacts_iterator {
void* _internals;
} contacts_iterator;
/// API: contacts/contacts_iterator_new
///
/// Starts a new iterator.
///
/// Functions for iterating through the entire contact list, in sorted order. Intended use is:
///
/// contacts_contact c;
/// contacts_iterator *it = contacts_iterator_new(contacts);
/// for (; !contacts_iterator_done(it, &c); contacts_iterator_advance(it)) {
/// // c.session_id, c.nickname, etc. are loaded
/// }
/// contacts_iterator_free(it);
///
/// It is NOT permitted to add/remove/modify records while iterating.
///
/// Declaration:
/// ```cpp
/// CONTACTS_ITERATOR* contacts_iterator_new(
/// [in] const config_object* conf
/// );
/// ```
///
/// Inputs:
/// - `conf` -- [in] Pointer to the config object
///
/// Outputs:
/// - `contacts_iterator*` -- pointer to the iterator
LIBSESSION_EXPORT contacts_iterator* contacts_iterator_new(const config_object* conf);
/// API: contacts/contacts_iterator_free
///
/// Frees an iterator once no longer needed.
///
/// Declaration:
/// ```cpp
/// VOID contacts_iterator_free(
/// [in] contacts_iterator* it
/// );
/// ```
///
/// Inputs:
/// - `it` -- [in] Pointer to the contacts_iterator
LIBSESSION_EXPORT void contacts_iterator_free(contacts_iterator* it);
/// API: contacts/contacts_iterator_done
///
/// Returns true if iteration has reached the end. Otherwise `c` is populated and false is
/// returned.
///
/// Declaration:
/// ```cpp
/// BOOL contacts_iterator_done(
/// [in] contacts_iterator* it,
/// [out] contacts_contact* c
/// );
/// ```
///
/// Inputs:
/// - `it` -- [in] Pointer to the contacts_iterator
/// - `c` -- [out] Pointer to the contact, will be populated if false
///
/// Outputs:
/// - `bool` -- True if iteration has reached the end
LIBSESSION_EXPORT bool contacts_iterator_done(contacts_iterator* it, contacts_contact* c);
/// API: contacts/contacts_iterator_advance
///
/// Advances the iterator.
///
/// Declaration:
/// ```cpp
/// VOID contacts_iterator_advance(
/// [in] contacts_iterator* it
/// );
/// ```
///
/// Inputs:
/// - `it` -- [in] Pointer to the contacts_iterator
LIBSESSION_EXPORT void contacts_iterator_advance(contacts_iterator* it);
#ifdef __cplusplus
} // extern "C"
#endif