Groups
Info::Info
Constructs a group info config object from existing data (stored from dump()
).
To construct a blank info object (i.e. with no pre-existing dumped data to load) pass
std::nullopt
as the third argument.
Encryption keys must be loaded before the Info object can be modified or parse other Info
messages, and are typically loaded by providing the Info
object to the Keys
class.
Declaration
Info(ustring_view ed25519_pubkey,
std::optional<ustring_view> ed25519_secretkey,
std::optional<ustring_view> dumped);
Parameters
ed25519_pubkey
is the public key of this group, used to validate config messages. Config messages not signed with this key will be rejected.ed25519_secretkey
is the secret key of the group, used to sign pushed config messages. This is only possessed by the group admin(s), and must be provided in order to make and push config changes.dumped
— eitherstd::nullopt
to construct a new, empty object; or binary state data that was previously dumped from an instance of this class by callingdump()
.
Returns
Info::destroy_group
Sets the group as permanently deleted, and set this status in the group's config. Receiving clients are supposed to remove the conversation from their conversation list when this happens.
This change is permanent; the flag cannot be unset once set!
Declaration
Parameters
None: this call is destructive and permanent. Be careful!
Returns
Info::encryption_domain
Returns the encryption domain used when encrypting messages of this type.
Declaration
Parameters
This endpoint takes no inputs.
Returns
const char*
- Will return "groups::Info"
Info::get_created
Returns the creation timestamp, if set/known.
Declaration
Parameters
This endpoint takes no inputs.
Returns
std::optional<int64_t>
— the unix timestamp when the group was created, or nullopt if the creation timestamp is not set.
Info::get_delete_attach_before
Returns the delete-attachments-before unix timestamp (seconds) for the group; clients should delete all messages from the closed group with timestamps earlier than this value, if set.
Returns std::nullopt if no delete-attachments-before timestamp is set.
Declaration
Parameters
This endpoint takes no inputs.
Returns
int64_t
— the unix timestamp for which all older message attachments shall be deleted
Info::get_delete_before
Returns the delete-before unix timestamp (seconds) for the group; clients should delete all messages from the closed group with timestamps earlier than this value, if set.
Returns std::nullopt if no delete-before timestamp is set.
Declaration
Parameters
This endpoint takes no inputs.
Returns
int64_t
— the unix timestamp for which all older messages shall be delete
Info::get_description
Returns the group description, or std::nullopt if there is no group description set.
If given a description longer than Info::DESCRIPTION_MAX_LENGTH
(2000) bytes it will be
truncated.
Declaration
Parameters
This endpoint takes no inputs.
Returns
std::optional<std::string_view>
- Returns the group description if it is set
Info::get_expiry_timer
Returns the group's current message expiry timer, or std::nullopt
if no expiry timer is
set. If not nullopt then the expiry will always be >= 1s.
Note that groups only support expire-after-send expiry timers and so there is no separate expiry type setting.
Declaration
Parameters
This endpoint takes no inputs.
Returns
std::chrono::seconds
— the expiry timer duration
Info::get_name
Returns the group name, or std::nullopt if there is no group name set.
Declaration
Parameters
This endpoint takes no inputs.
Returns
std::optional<std::string_view>
- Returns the group name if it is set
Info::get_profile_pic
Gets the group's current profile pic URL and decryption key. The returned object will evaluate as false if the URL and/or key are not set.
Declaration
Parameters
This endpoint takes no inputs.
Returns
profile_pic
- Returns the group's profile pic
Info::id
Contains the (read-only) id of this group, that is, 03 followed by the pubkey in hex. (This is equivalent to a 05-prefixed session_id, but is the group-specific identifier).
Declaration
Parameters
This endpoint takes no inputs.
Returns
std::string
containing the hex group id/pubkey
Info::is_destroyed
Returns true if this group has been marked destroyed; the receiving client is expected to delete it.
Declaration
Parameters
This endpoint takes no inputs.
Returns
true
if the group has been destroyed,false
otherwise.
Info::set_created
Sets the created timestamp. It's recommended (but not required) that you only set this if not already set.
Declaration
Parameters
session_id
— hex string of the session idtimestamp
— standard unix timestamp when the group was created
Returns
Info::set_delete_attach_before
Sets a "delete attachments before" unix timestamp: this instructs clients to drop the
attachments (though not necessarily the messages themselves; see get_delete_before
for
that) from any messages older than the given timestamp. Returns nullopt if no
delete-attachments-before timestamp is set.
The given value is checked for sanity (e.g. if you pass milliseconds it will be interpreted as such)
Declaration
Parameters
timestamp
— the new unix timestamp before which clients should delete attachments. Pass 0 (or negative) to disable the delete-attachment-before timestamp.
Returns
Info::set_delete_before
Sets a "delete before" unix timestamp: this instructs clients to delete all messages from the closed group history with a timestamp earlier than this value. Returns nullopt if no delete-before timestamp is set.
The given value is checked for sanity (e.g. if you pass milliseconds it will be interpreted as such)
Declaration
Parameters
timestamp
— the new unix timestamp before which clients should delete messages. Pass 0 (or negative) to disable the delete-before timestamp.
Returns
Info::set_description
Sets the optional group description; if given an empty string then an existing description is removed.
Declaration
Parameters
new_desc
— The new description to be put into the group Info
Returns
Info::set_description_truncated
Sets the optional group description; if given an empty string then an existing description
is removed. The same as set_description
but if the name is too long it'll be truncated.
Declaration
Parameters
new_desc
— The new description to be put into the group Info
Returns
Info::set_expiry_timer
Sets (or clears) the group's message expiry timer. If > 0s the setting becomes the delete-after-send value; if omitted or given a 0 or negative duration then the expiring message timer is disabled for the group.
Declaration
Parameters
expiration_timer
— how long the expiration timer should be, defaults to zero (disabling message expiration) if the argument is omitted.
Returns
Info::set_name
Sets the group name; if given an empty string then the name is removed.
If given a name longer than Info::NAME_MAX_LENGTH
(100) bytes an error will be thrown.
Declaration
Parameters
new_name
— The name to be put into the group Info
Returns
Info::set_name_truncated
Sets the group name; if given an empty string then the name is removed.
If given a name longer than Info::NAME_MAX_LENGTH
(100) bytes it will be truncated.
Declaration
Parameters
new_name
— The name to be put into the group Info
Returns
Info::set_profile_pic
Sets the group's current profile pic to a new URL and decryption key. Clears both if either one is empty.
Declaration
void set_profile_pic(std::string_view url, ustring_view key);
void set_profile_pic(profile_pic pic);
Parameters
- First function:
url
— URL pointing to the profile pickey
— Decryption key- Second function:
pic
— Profile pic object
Returns
Info::storage_namespace
Returns the Info namespace. Is constant, will always return Namespace::GroupInfo
Declaration
Parameters
This endpoint takes no inputs.
Returns
Namespace
- Will return Namespace::GroupInfo
Keys::Keys
Constructs a group members config object from existing data (stored from dump()
) and a
list of encryption keys for encrypting new and decrypting existing messages.
To construct a blank info object (i.e. with no pre-existing dumped data to load) pass
std::nullopt
as the last argument.
When no dump is provided the initial Keys object will be created with no keys loaded at all, these will be loaded later into this and the info/members objects when loading keys via received config messages. If this is a brand new group then rekey() MUST be called, otherwise the group will be in an invalid state.
Declaration
Keys(ustring_view user_ed25519_secretkey,
ustring_view group_ed25519_pubkey,
std::optional<ustring_view> group_ed25519_secretkey,
std::optional<ustring_view> dumped,
Info& info,
Members& members);
Parameters
user_ed25519_secretkey
is the ed25519 secret key backing the current user's session ID, and is used to decrypt incoming keys. It is required.group_ed25519_pubkey
is the public key of the group, used to verify message signatures on key updates. Required. Should not include the03
prefix.group_ed25519_secretkey
is the secret key of the group, used to encrypt, decrypt, and sign config messages. This is only possessed by the group admin(s), and must be provided in order to make and push config changes.dumped
— eitherstd::nullopt
to construct a new, empty object; or binary state data that was previously dumped from an instance of this class by callingdump()
.info
andmembers
— will be loaded with the group keys, if present in the dump.
Returns
Keys::current_hashes
Returns a set of message hashes of messages that contain currently active decryption keys. These are the messages that should be periodically renewed by clients with write access to keep them alive for other accounts (or devices) who might need them in the future.
Declaration
Parameters
This endpoint takes no inputs.
Returns
- vector of message hashes
Keys::decrypt_message
Decrypts group message content that was presumably encrypted with encrypt_message
,
verifies the sender signature, decompresses the message (if necessary) and then returns the
author pubkey and the plaintext data.
To prevent against memory exhaustion attacks, this method will fail if the value is a compressed value that would decompress to a value larger than 1MB.
Declaration
Parameters
ciphertext
— an encrypted, encoded, signed, (possibly) compressed message as produced byencrypt_message()
.
Returns
std::pair<std::string, ustring>
— the session ID (in hex) and the plaintext binary data that was encrypted.
On failure this throws a std::exception-derived exception with a .what()
string containing
some diagnostic info on what part failed. Typically a production session client would catch
(and possibly log) but otherwise ignore such exceptions and just not process the message if
it throws.
Keys::dump
Returns a dump of the current state of this keys config that allows the Keys object to be reinstantiated from scratch. Updates the internal needs_dump flag to false.
Although this can be called at any time, it is recommended to only do so when
needs_dump()
returns true.
Declaration
Parameters
This endpoint takes no inputs.
Returns
- opaque binary data containing the group keys and other Keys config data that can be passed
to the
Keys
constructor to reinitialize a Keys object with the current state.
Keys::encrypt_message
Compresses, signs, and encrypts group message content.
This method is passed a binary value containing a group message (typically a serialized protobuf, but this method doesn't care about the specific data). That data will be, in order: - compressed (but only if this actually reduces the data size) - signed by the user's underlying session Ed25519 pubkey - tagged with the user's underlying session Ed25519 pubkey (from which the session id can be computed). - all of the above encoded into a bt-encoded dict - suffix-padded with null bytes so that the final output value will be a multiple of 256 bytes - encrypted with the most-current group encryption key
Since compression and padding is applied as part of this method, it is not required that the given message include its own padding (and in fact, such padding will typically be compressed down to nothing (if non-random)).
This final encrypted value is then returned to be pushed to the swarm as-is (i.e. not
further wrapped). For users downloading the message, all of the above is processed in
reverse by passing the returned message into decrypt_message()
.
The current implementation uses XChaCha20-Poly1305 for encryption and zstd for compression; the bt-encoded value is a dict consisting of keys: - "": the version of this encoding, currently set to 1. This MUST be bumped if this is changed in such a way that older clients will not be able to properly decrypt such a message. - "a": the Ed25519 pubkey (32 bytes) of the author of the message. (This will be converted to a x25519 pubkey to extract the sender's session id when decrypting). - "s": signature by "a" of whichever of "d" or "z" are included in the data. Exacly one of: - "d": the uncompressed data (which must be non-empty if present) - "z": the zstd-compressed data (which must be non-empty if present)
When compression is enabled (by omitting the compress
argument or specifying it as true)
then ZSTD compression will be attempted on the plaintext message and will be used if the
compressed data is smaller than the uncompressed data. If disabled, or if compression does
not reduce the size, then the message will not be compressed.
This method will throw on failure, which can happen in two cases:
- if there no encryption keys are available at all (which should not occur in normal use).
- if given a plaintext buffer larger than 1MB (even if the compressed version would be much
smaller). It is recommended that clients impose their own limits much smaller than this
on data passed into encrypt_message; this limitation is in this function to match the
decrypt_message
limit which is merely intended to guard against decompression memory
exhaustion attacks.
Declaration
Parameters
plaintext
— the binary message to encrypt.compress
— can be specified asfalse
to forcibly disable compression. Normally omitted, to use compression if and only if it reduces the size.padding
— the padding multiple: padding will be added as needed to attain a multiple of this value for the final result. 0 or 1 disables padding entirely. Normally omitted to use the default of next-multiple-of-256.
Returns
ciphertext
— the encrypted, etc. value to send to the swarm
Keys::encryption_domain
Returns the encryption domain used when encrypting messages of this type.
Declaration
Parameters
This endpoint takes no inputs.
Returns
const char*
- Will return "groups::Keys"
Keys::encryption_key
Accesses the current encryption key: that is, the most current group decryption key. Throws
if there are no encryption keys at all. (This is essentially the same as group_keys()[0]
,
except for the throwing and avoiding needing to constructor a vector).
You normally don't need to call this; the key is used automatically by methods such as encrypt_message() that need it.
Declaration
Parameters
This endpoint takes no inputs.
Returns
ustring_view
of the most current group encryption key.
Keys::group_keys
Returns all the unexpired decryption keys that we know about. Keys are returned ordered from most-recent to least-recent (and so the first one is meant to be used as the encryption key), including a pending key if this object is in the process of pushing a new keys message.
This isn't typically directly needed: this object manages the key lists in the info
and
members
objects itself.
Declaration
Parameters
This endpoint takes no inputs.
Returns
std::vector<ustring_view>
- vector of encryption keys.
Keys::is_admin
True if we have admin permissions (i.e. we know the group's master secret key).
Declaration
Parameters
This endpoint takes no inputs.
Returns
true
if this object knows the group's master key
Keys::key_supplement
Generates a supplemental key message for one or more session IDs. This is used to distribute existing active keys to a new member so that that member can access existing keys, configs, and messages. Only admins can call this.
The recommended order of operations for adding such a member is: - add the member to Members - generate the key supplement - push new members & key supplement (ideally in a batch) - send invite details, auth signature, etc. to the new user
To add a member without giving them access you would use rekey() instead of this method.
Declaration
Parameters
sid
orsids
— session ID(s) of the members to generate a supplemental key for (there are two versions of this function, one taking a single ID and one taking a vector). Session IDs are specified in hex.
Returns
ustring
containing the message that should be pushed to the swarm containing encrypted keys for the given user(s).
Keys::load_admin_key
Loads the group secret key into the Keys object (as well as passing it along to the Info and Members objects).
The primary use of this is when accepting a promotion-to-admin: the Keys object would be constructed as a regular member (without the admin key) then this method "upgrades" the object with the group signing key.
This will do nothing if the secret key is already known; it will throw if the given secret key does not yield the group's public key. The given key can be either the 32 byte seed, or the libsodium 64 byte "secret key" (which is just the seed and cached public key stuck together).
Declaration
Parameters
secret
— the group's 64-byte secret key or 32-byte seedinfo
andmembers
— will be loaded with the group keys if the key is loaded successfully.
Outputs: nothing. After a successful call, admin()
will return true. Throws if the given
secret key does not match the group's pubkey.
Returns
Keys::load_key
Loads a key pulled down from the swarm into this Keys object.
A Session client must process messages from the keys namespace before other group config messages as new key messages may contain encryption keys needed to decrypt the other group config message types.
It is safe to load the same config multiple times, and to load expired configs; such cases would typically not change the keys, but are allowed anyway.
This method should always be wrapped in a try/catch
: if the given configuration data is
malformed or is not properly signed an exception will be raised (but the Keys object remains
usable).
Declaration
bool load_key_message(
std::string_view hash,
ustring_view data,
int64_t timestamp_ms,
Info& info,
Members& members);
Parameters
hash
- the message hash from the swarmdata
- the full stored config message valuetimestamp_ms
- the timestamp (from the swarm) when this message was stored (used to track when other keys expire).info
- the given group::Info object's en/decryption key list will be updated to match this object's key list.members
- the given group::Members object's en/decryption key list will be updated to match this object's key list.
Returns
- throws
std::runtime_error
(typically a subclass thereof) on failure to parse. - returns true if we found a key for us in the message, false if we did not. Note that this is mainly informative and does not signal an error: false could mean, for instance, be a supplemental message that wasn't for us. Note also that true doesn't mean keys changed: it could mean we decrypted one for us, but already had it.
Keys::make_dump
Returns a dump of the current state; unlike dump()
this does not update the internal
needs_dump flag; it is mostly used internally (by dump()
), but can also be called
externally for debugging purposes.
Declaration
Parameters
This endpoint takes no inputs.
Returns
ustring
— Returns binary data of the state dump
Keys::needs_dump
Returns true if this Keys config has changes, either made directly or from incoming configs,
that need to be dumped to the database (made since the last call to dump()
), false if no
changes have been made.
Declaration
Parameters
This endpoint takes no inputs.
Returns
true
if state needs to be dumped,false
if state hasn't changed since the last call todump()
.
Keys::needs_rekey
Returns true if the key list requires a new key to be generated and pushed to the server (by
calling rekey()
). This will only be true for admin accounts (as only admin accounts can
call rekey()). Note that this value will also remain true until the pushed data is fetched
and loaded via load_key_message
.
Note that this not only tracks when an automatic rekey()
is needed because of a key
collision (such as two admins removing different members at the same time); there are other
situations in which rekey() should also be called (such as when kicking a member) that are
not reflected by this flag.
The recommended use of this method is to call it immediately after fetching messages from the group config namespace of the swarm, whether or not new configs were retrieved, but after processing incoming new config messages that were pulled down.
Unlike regular config messages, there is no need to confirm the push: confirmation (and adoption of the new keys) happens when the new keys arrived back down from the swarm in the next fetch.
Declaration
Parameters
This endpoint takes no inputs.
Returns
true
if a rekey is needed,false
otherwise.
Keys::pending_config
If a rekey has been performed but not yet confirmed then this will contain the config message to be pushed to the swarm. If there is no push current pending then this returns nullopt. The value should be used immediately (i.e. the ustring_view may not remain valid if other calls to the config object are made).
Declaration
Parameters
This endpoint takes no inputs.
Returns
std::optional<ustring_view>
— returns a populated config message that should be pushed, if not yet confirmed, otherwise when no pending update is present this returns nullopt.
Keys::pending_key
After calling rekey() this contains the new group encryption key before it is confirmed pushed into the swarm. This is primarily intended for internal use as this key is generally already propagated to the member/info lists when rekeying occurs.
The pending key is dropped when an incoming keys message is successfully loaded with either the pending key itself, or a keys message with a higher generation.
Declaration
Parameters
This endpoint takes no inputs.
Returns
std::optional<ustring_view>
the encryption key generated by the lastrekey()
call. This is set to a new key whenrekey()
is called, and is cleared when any config message is successfully loaded byload_key
.
Keys::rekey
Generate a new encryption key for the group and returns an encrypted key message to be pushed to the swarm containing the key, encrypted for the members of the given config::groups::Members object. This can only be done by an admin account (i.e. we must have the group's private key).
This method is intended to be called in these situations:
- potentially after loading new keys config messages (see needs_rekey()
)
- when removing a member to switch to a new encryption key for the group that excludes that
member.
- when adding a member and switching to a new encryption key (without making the old key
available to the member) so that the new member cannot decipher pre-existing configs and
messages.
This method is closely coupled to the group's Info and Members configs: it updates their encryption keys and sets them as dirty, requiring a re-push to re-encrypt each of them. Typically a rekey is performed as follows:
rekey()
is called, returning the new keys config.info.push()
is called to get the new info config (re-encrypted with the new key)members.push()
is called to get the new members config (using the new key)- all three new configs are pushed (ideally all at once, in a single batch request).
Declaration
Parameters
Info
- the group's Info; it will be dirtied after the rekey and will require a push.Members
- the current Members config for the group. When removing one or more members this should be the list of members with the specific members already removed. The members config will be dirtied after the rekey and will require a push.
Returns
ustring_view
containing the data that needs to be pushed to the config keys namespace for the group. (This can be re-obtained frompending_config()
if needed until it has been confirmed or superceded). This data must be consumed or copied from the returned string_view immediately: it will not be valid past other calls on the Keys config object.
Keys::size
Returns the number of distinct decryption keys that we know about. Mainly for debugging/information purposes.
Declaration
Parameters
This endpoint takes no inputs.
Returns
size_t
of the number of keys we know about
Keys::storage_namespace
Returns the Keys namespace. Is constant, will always return Namespace::GroupKeys
Declaration
Parameters
This endpoint takes no inputs.
Returns
Namespace
- Will return Namespace::GroupKeys
Keys::swarm_auth
This struct containing the storage server authentication values for subaccount
authentication. The three strings in this struct may be either raw bytes, or base64
encoded, depending on the binary
parameter passed to swarm_subaccount_sign
.
.subaccount
is the value to be passed as the "subaccount" authentication parameter. (It
consists of permission flags followed by a blinded public key.)
.subaccount_sig
is the value to be passed as the "subaccount_sig" authentication
parameter. (It consists of an admin-produced signature of the subaccount, providing
permission for that token to be used for authentication).
.signature
is the value to be passed as the "signature" authentication parameter. (It is
an Ed25519 signature that validates using the blinded public key inside subaccount
).
Declaration
Parameters
This endpoint takes no inputs.
Returns
Keys::swarm_make_subaccount
Constructs a swarm subaccount signing value that a member can use to access messages in the swarm. Requires group admins keys.
Declaration
ustring swarm_make_subaccount(
std::string_view session_id, bool write = true, bool del = false) const;
Parameters
session_id
— the session ID of the member (in hex)write
— if true (which is the default if omitted) then the member shall be allowed to submit messages into the group account of the swarm and extend (but not shorten) the expiry of messages in the group account. If false then the user can only retrieve messages.del
— if true (default is false) then the user shall be allowed to delete messages from the swarm. This permission can be used to appoint a sort of "moderator" who can delete messages without having the full admin group keys.
Returns
ustring
— contains a subaccount swarm signing value; this can be passed (by the user) intoswarm_subaccount_sign
to sign a value suitable for swarm authentication. (Internally this packs the flags, blinding factor, and group admin signature together and will be 4 + 32 + 64 = 100 bytes long).
This value must be provided to the user so that they can authentication. The user should
call swarm_verify_subaccount
to verify that the signing value was indeed signed by a
group admin before using/storing it.
The signing value produced will be the same (for a given session_id
/write
/del
values) when constructed by any admin of the group.
Keys::swarm_subaccount_sign
This helper function generates the required signature for swarm subaccount authentication,
given the user's keys and swarm auth keys (as provided by an admin, produced via
swarm_make_subaccount
).
Storage server subaccount authentication requires passing the three values in the returned struct in the storage server request. (See Keys::swarm_auth for details).
Declaration
swarm_auth swarm_subaccount_sign(
ustring_view msg, ustring_view signing_value, bool binary = false) const;
Parameters
msg
— the data that needs to be signed (which depends on the storage server request being made; for example, "retrieve9991234567890123" for a retrieve request to namespace 999 made at unix time 1234567890.123; see storage server RPC documentation for details).signing_value
— the 100-byte subaccount signing value, as produced by an admin'sswarm_make_subaccount
and provided to this member.binary
— if set to true then the returned values will be binary. If omitted (or explicitly false), the returned struct values will be base64-encoded suitable for direct passing as JSON values to the storage server without further encoding/modification.
Returns
- struct containing three binary values enabling swarm authentication (see description above).
Keys::swarm_subaccount_token
Constructs the subaccount token for a session id. The main use of this is to submit a swarm
token revocation; for issuing subaccount tokens you want to use swarm_make_subaccount
instead. This will produce the same subaccount token that swarm_make_subaccount
implicitly creates that can be passed to a swarm to add a revocation for that subaccount.
This is recommended to be used when removing a non-admin member to prevent their access. (Note, however, that there are circumstances where this can fail to prevent access, and so should be combined with proper member removal and key rotation so that even if the member gains access to messages, they cannot read them).
Declaration
ustring swarm_subaccount_token(
std::string_view session_id, bool write = true, bool del = false) const;
Parameters
session_id
— the session ID of the member (in hex)write
,del
— optional; seeswarm_make_subaccount
. The same arguments should be provided (or omitted) as were used inswarm_make_subaccount
.
Returns
- 36 byte token that can be used for swarm token revocation.
Keys::swarm_verify_subaccount
Verifies that a received subaccount signing value (allegedly produced by swarm_make_subaccount) is a valid subaccount signing value for the given group pubkey, including a proper signature by an admin of the group. The signing value must have read permission, but parameters can be given to also require write or delete permissions. A subaccount signing value should always be checked for validity using this before creating a group that would depend on it.
There are two versions of this function: a static one callable without having a Keys instance that takes the group id and user's session Ed25519 secret key as arguments; and a member function that omits these first two arguments (using the ones from the Keys instance).
Declaration
static bool swarm_verify_subaccount(
std::string group_id,
ustring_view session_ed25519_secretkey,
ustring_view signing_value,
bool write = false,
bool del = false);
Parameters
groupid
— the group id/pubkey, in hex, beginning with "03".session_ed25519_secretkey
— the user's Session ID secret key.signing_value
— the subaccount signing value to validatewrite
— if true, require that the signing_value has write permission (i.e. that the user will be allowed to post messages).del
— if true, required that the signing_value has delete permissions (i.e. that the user will be allowed to remove storage messages from the group's swarm). Note that this permission is about forcible swarm message deletion, and has no effect on an ability to submit a deletion meta-message to the group (which only requires writing a message).
Returns
true
ifsigning_value
is a valid subaccount signing value forgroupid
with read (and possible write and/or del permissions, if requested).false
if the signing value does not validate or does not meet the requirements.
Members::Members
Constructs a group members config object from existing data (stored from dump()
) and a
list of encryption keys for encrypting new and decrypting existing messages.
To construct a blank info object (i.e. with no pre-existing dumped data to load) pass
std::nullopt
as the third argument.
Encryption keys must be loaded before the Info object can be modified or parse other Info
messages, and are typically loaded by providing the Info
object to the Keys
class.
Declaration
Members(ustring_view ed25519_pubkey,
std::optional<ustring_view> ed25519_secretkey,
std::optional<ustring_view> dumped);
Parameters
ed25519_pubkey
is the public key of this group, used to validate config messages. Config messages not signed with this key will be rejected.ed25519_secretkey
is the secret key of the group, used to sign pushed config messages. This is only possessed by the group admin(s), and must be provided in order to make and push config changes.dumped
— eitherstd::nullopt
to construct a new, empty object; or binary state data that was previously dumped from an instance of this class by callingdump()
.
Returns
Members::begin
Iterators for iterating through all members. Typically you access this implicit via a for
loop over the Members
object:
This iterates in sorted order through the session_ids.
It is NOT permitted to add/modify/remove records while iterating; instead such modifications require two passes: an iterator loop to collect the required modifications, then a second pass to apply the modifications.
Declaration
Parameters
This endpoint takes no inputs.
Returns
iterator
- Returns an iterator for the beginning of the members
Members::encryption_domain
Returns the encryption domain used when encrypting messages of this type.
Declaration
Parameters
This endpoint takes no inputs.
Returns
const char*
- Will return "groups::Members"
Members::end
Iterator for passing the end of the members
Declaration
Parameters
This endpoint takes no inputs.
Returns
iterator
- Returns an iterator for the end of the members
Members::erase
Removes a session ID from the member list, if present.
Typically this call should be coupled with a re-key of the group's encryption key so that the removed member cannot read the group. For example:
bool removed = members.erase("050123456789abcdef...");
// You can remove more than one at a time, if needed:
removed |= members.erase("050000111122223333...");
if (removed) {
auto new_keys_conf = keys.rekey(members);
members.add_key(*keys.pending_key(), true);
auto [seqno, new_memb_conf, obs] = members.push();
// Send the two new configs to the swarm (via a seqence of two `store`s):
// - new_keys_conf goes into the keys namespace
// - new_memb_conf goes into the members namespace
}
Declaration
Parameters
session_id
the hex session ID of the member to remove
Returns
- true if the member was found (and removed); false if the member was not in the list.
Members::get
Looks up and returns a member by hex session ID. Returns nullopt if the session ID was
not found, otherwise returns a filled out member
.
Declaration
Parameters
pubkey_hex
— hex string of the session id
Returns
std::optional<member>
- Returns nullopt if session ID was not found, otherwise a filled outmember
struct.
Members::get_or_construct
Similar to get(), but if the session ID does not exist this returns a filled-out member
containing the session_id (all other fields will be empty/defaulted). This is intended to
be combined with set
to set-or-create a record.
NB: calling this does not add the session id to the member list when called: that requires
also calling set
with this value.
Declaration
Parameters
pubkey_hex
— hex string of the session id
Returns
member
- Returns a filled out member struct
Members::get_status
This function goes through the various status values and returns a single consolidated status for the member.
Declaration
Parameters
member
— member value to to retrieve the status for
Returns
status
- an enum indicating the consolidated status of this member in the group.
Members::has_pending_send
This function can be used to check if a member is pending send locally.
Declaration
Parameters
pubkey_hex
— hex string of the session id
Returns
bool
- true if that sessionid is marked as pending send locally
Members::set
Sets or updates the various values associated with a member with the given info. The usual use is to access the current info, change anything desired, then pass it back into set, e.g.:
Declaration
Parameters
member
— member value to set
Returns
Members::set_pending_send
This function can be used to set the pending send state of a member. If that effectively made a change, it will set _needs_dump to true.
Declaration
Parameters
pubkey_hex
— hex string of the session idpending
— pending send state to set for that member
Returns
Members::size
Returns the number of members in the group.
Declaration
Parameters
This endpoint takes no inputs.
Returns
size_t
- number of members
Members::storage_namespace
Returns the Members namespace. Is constant, will always return Namespace::GroupMembers
Declaration
Parameters
This endpoint takes no inputs.
Returns
Namespace
- Will return Namespace::GroupMembers
current_generation
Returns the current generation number for the latest keys message.
Declaration
Parameters
This endpoint takes no inputs.
Returns
int
— latest keys generation number.
member::admin
Flag that is set to indicate to the group that this member is an admin or has been promoted to admin.
Note that this is only informative but isn't a permission gate: someone could still possess the admin keys without this (e.g. if they cleared the flag to appear invisible), or could have lost (or never had) the keys even if this is set.
Declaration
member::into
Converts the member info into a C struct.
Declaration
Parameters
m
— Reference to C struct to fill with group member info.
Returns
member::name
The member's human-readable name. Optional. This is used by other members of the group to display a member's details before having seen a message from that member.
Declaration
member::profile_picture
The member's profile picture (URL & decryption key). Optional. This is used by other members of the group to display a member's details before having seen a message from that member.
Declaration
member::session_id
The member's session ID, in hex.
Declaration
member::set_invite_failed
This marks the user to indicate that their invitation message failed to send (this is intended as a signal to other clients that the invitation should be reissued).
Declaration
Parameters
This endpoint takes no inputs.
Returns
member::set_invite_not_sent
This resets the invite status of a user to STATUS_NOT_SENT
.
Declaration
Parameters
This endpoint takes no inputs.
Returns
member::set_invite_sent
This marks the user as having had an invitation message sent to them.
Declaration
Parameters
This endpoint takes no inputs.
Returns
member::set_name
Sets a name; this is exactly the same as assigning to .name directly, except that we throw an exception if the given name is longer than MAX_NAME_LENGTH.
Note that you can set a longer name directly into the .name
member, but it will be
truncated when serializing the record.
Declaration
Parameters
name
— Name to assign to the contact
Returns
member::set_name_truncated
Sets a name; this is exactly the same as assigning to .name directly, except that we truncate if the given name is longer than MAX_NAME_LENGTH.
Note that you can set a longer name directly into the .name
member, but it will be
truncated when serializing the record.
Declaration
Parameters
name
— Name to assign to the contact
Returns
member::set_promoted
This marks the user as having a pending promotion-to-admin in the group, waiting for the promotion message to be sent to them.
Declaration
Parameters
This endpoint takes no inputs.
Returns
member::set_promotion_accepted
This marks the user as having accepted a promotion to admin in the group.
Declaration
Parameters
This endpoint takes no inputs.
Returns
member::set_promotion_failed
This marks the user as being promoted to an admin, but that their promotion message failed to send (this is intended as a signal to other clients that the promotion should be reissued).
Declaration
Parameters
This endpoint takes no inputs.
Returns
member::set_promotion_sent
This marks the user as having a pending promotion-to-admin in the group, and that a promotion message has been sent to them.
Declaration
Parameters
This endpoint takes no inputs.
Returns
member::set_removed
Sets the "removed" flag for this user. This marks the user as pending removal from the
group. The optional messages
parameter can be specified as true if we want to remove
any messages sent by the member upon a successful removal.
Declaration
Parameters
messages
: can be specified as true to indicate any messages sent by the member should also be removed upon a successful member removal.
Returns
member::supplement
Flag that is set to indicate to the group that this member was added with a supplemental key rotation so that other admins can trigger the same key rotation method if they send a new invitation to the same member.
Note that this should be cleared when a member accepts an invitation.
Declaration
members::set_invite_accepted
This clears the "invited" and "supplement" flags for this user, thus indicating that the user has accepted an invitation and is now a regular member of the group.
Declaration
Parameters
This endpoint takes no inputs.