Files

318 lines
12 KiB
C++

#pragma once
#include <chrono>
#include <memory>
#include <session/config.hpp>
#include "../base.hpp"
#include "../namespaces.hpp"
#include "../profile_pic.hpp"
namespace session::config::groups {
using namespace std::literals;
/// keys used in this config, either currently or in the past (so that we don't reuse):
///
/// ! - set to true if the group has been destroyed (and should be removed from receiving clients)
/// c - creation unix timestamp (seconds)
/// d - delete before timestamp: this instructs receiving clients that they should delete all
/// messages with a timestamp < the set value.
/// D - delete attachments before - same as above, but specific to attachments.
/// E - disappearing message timer (seconds) if the delete-after-send disappearing messages mode is
/// enabled for the group. Omitted if disappearing messages is disabled.
/// n - utf8 group name (human-readable); may not contain nulls, max length 100.
/// o - utf8 group description (human-readable); may not contain nulls, max length 2000.
/// p - group profile url
/// q - group profile decryption key (binary)
class Info : public ConfigBase {
public:
/// Limits for the name & description strings, in bytes. If longer, we truncate to these
/// lengths:
static constexpr size_t NAME_MAX_LENGTH = 100; // same as base_group_info::NAME_MAX_LENGTH
static constexpr size_t DESCRIPTION_MAX_LENGTH = 600;
// No default constructor
Info() = delete;
/// API: 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.
///
/// Inputs:
/// - `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` -- either `std::nullopt` to construct a new, empty object; or binary state data
/// that was previously dumped from an instance of this class by calling `dump()`.
Info(std::span<const unsigned char> ed25519_pubkey,
std::optional<std::span<const unsigned char>> ed25519_secretkey,
std::optional<std::span<const unsigned char>> dumped);
/// API: groups/Info::storage_namespace
///
/// Returns the Info namespace. Is constant, will always return Namespace::GroupInfo
///
/// Inputs: None
///
/// Outputs:
/// - `Namespace` - Will return Namespace::GroupInfo
Namespace storage_namespace() const override { return Namespace::GroupInfo; }
/// API: groups/Info::encryption_domain
///
/// Returns the encryption domain used when encrypting messages of this type.
///
/// Inputs: None
///
/// Outputs:
/// - `const char*` - Will return "groups::Info"
const char* encryption_domain() const override { return "groups::Info"; }
/// API: groups/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).
///
/// Inputs: None
///
/// Outputs:
/// - `std::string` containing the hex group id/pubkey
const std::string id;
/// API: groups/Info::get_name
///
/// Returns the group name, or std::nullopt if there is no group name set.
///
/// Inputs: None
///
/// Outputs:
/// - `std::optional<std::string_view>` - Returns the group name if it is set
std::optional<std::string_view> get_name() const;
/// API: groups/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.
///
/// Inputs:
/// - `new_name` -- The name to be put into the group Info
void set_name(std::string_view new_name);
/// API: groups/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.
///
/// Inputs:
/// - `new_name` -- The name to be put into the group Info
void set_name_truncated(std::string new_name);
/// API: groups/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` bytes it will be
/// truncated.
///
/// Inputs: None
///
/// Outputs:
/// - `std::optional<std::string_view>` - Returns the group description if it is set
std::optional<std::string_view> get_description() const;
/// API: groups/Info::set_description
///
/// Sets the optional group description; if given an empty string then an existing description
/// is removed.
///
/// Inputs:
/// - `new_desc` -- The new description to be put into the group Info
void set_description(std::string_view new_desc);
/// API: groups/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.
///
/// Inputs:
/// - `new_desc` -- The new description to be put into the group Info
void set_description_truncated(std::string new_desc);
/// API: groups/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:
/// ```cpp
/// profile_pic get_group_pic() const;
/// ```
///
/// Inputs: None
///
/// Outputs:
/// - `profile_pic` - Returns the group's profile pic
profile_pic get_profile_pic() const;
/// API: groups/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:
/// ```cpp
/// void set_profile_pic(std::string_view url, std::span<const unsigned char> key);
/// void set_profile_pic(profile_pic pic);
/// ```
///
/// Inputs:
/// - First function:
/// - `url` -- URL pointing to the profile pic
/// - `key` -- Decryption key
/// - Second function:
/// - `pic` -- Profile pic object
void set_profile_pic(std::string_view url, std::span<const unsigned char> key);
void set_profile_pic(profile_pic pic);
/// API: groups/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.
///
/// Inputs:
/// - `expiration_timer` -- how long the expiration timer should be, defaults to zero (disabling
/// message expiration) if the argument is omitted.
void set_expiry_timer(std::chrono::seconds expiration_timer = 0min);
/// API: groups/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.
///
/// Inputs: none
///
/// Outputs:
/// - `std::chrono::seconds` -- the expiry timer duration
std::optional<std::chrono::seconds> get_expiry_timer() const;
/// API: groups/Info::set_created
///
/// Sets the created timestamp. It's recommended (but not required) that you only set this if
/// not already set.
///
/// Inputs:
/// - `session_id` -- hex string of the session id
/// - `timestamp` -- standard unix timestamp when the group was created
void set_created(int64_t timestamp);
/// API: groups/Info::get_created
///
/// Returns the creation timestamp, if set/known.
///
/// Inputs: none.
///
/// Outputs:
/// - `std::optional<int64_t>` -- the unix timestamp when the group was created, or nullopt if
/// the creation timestamp is not set.
std::optional<int64_t> get_created() const;
/// API: groups/Info::set_delete_before
///
/// Sets a "delete before" unix timestamp: this instructs clients to delete all messages from
/// the 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)
///
/// Inputs:
/// - `timestamp` -- the new unix timestamp before which clients should delete messages. Pass 0
/// (or negative) to disable the delete-before timestamp.
void set_delete_before(int64_t timestamp);
/// API: groups/Info::get_delete_before
///
/// Returns the delete-before unix timestamp (seconds) for the group; clients should delete all
/// messages from the group with timestamps earlier than this value, if set.
///
/// Returns std::nullopt if no delete-before timestamp is set.
///
/// Inputs: none.
///
/// Outputs:
/// - `int64_t` -- the unix timestamp for which all older messages shall be delete
std::optional<int64_t> get_delete_before() const;
/// API: groups/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)
///
/// Inputs:
/// - `timestamp` -- the new unix timestamp before which clients should delete attachments. Pass
/// 0
/// (or negative) to disable the delete-attachment-before timestamp.
void set_delete_attach_before(int64_t timestamp);
/// API: groups/Info::get_delete_attach_before
///
/// Returns the delete-attachments-before unix timestamp (seconds) for the group; clients should
/// delete all messages from the group with timestamps earlier than this value, if set.
///
/// Returns std::nullopt if no delete-attachments-before timestamp is set.
///
/// Inputs: none.
///
/// Outputs:
/// - `int64_t` -- the unix timestamp for which all older message attachments shall be deleted
std::optional<int64_t> get_delete_attach_before() const;
/// API: groups/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!
///
/// Inputs:
///
/// None: this call is destructive and permanent. Be careful!
void destroy_group();
/// API: groups/Info::is_destroyed
///
/// Returns true if this group has been marked destroyed; the receiving client is expected to
/// delete it.
///
/// Inputs: none.
///
/// Outputs:
/// - `true` if the group has been destroyed, `false` otherwise.
bool is_destroyed() const;
};
} // namespace session::config::groups