2021-08-22 15:34:28 -04:00
|
|
|
#pragma once
|
|
|
|
|
2024-02-20 21:41:37 -05:00
|
|
|
/**
|
|
|
|
** \defgroup ssb_db SSB Database
|
|
|
|
** This is the main interface to SSB persistence. Everything about getting and
|
|
|
|
** storing messages and blobs goes through here.
|
|
|
|
** @{
|
|
|
|
*/
|
|
|
|
|
2023-01-17 19:37:45 -05:00
|
|
|
#include "ssb.h"
|
|
|
|
|
2023-05-21 17:36:51 -04:00
|
|
|
#include "quickjs.h"
|
|
|
|
|
2021-08-22 15:34:28 -04:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
2024-03-06 12:46:27 -05:00
|
|
|
/** An SSB instance. */
|
2021-08-22 15:34:28 -04:00
|
|
|
typedef struct _tf_ssb_t tf_ssb_t;
|
|
|
|
|
2024-03-06 12:46:27 -05:00
|
|
|
/**
|
|
|
|
** Initialize the database writer for an SSB instance.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
*/
|
2021-08-22 15:34:28 -04:00
|
|
|
void tf_ssb_db_init(tf_ssb_t* ssb);
|
2024-03-06 12:46:27 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Configure an opened SQLite database for reading.
|
|
|
|
*/
|
2023-02-17 17:43:19 -05:00
|
|
|
void tf_ssb_db_init_reader(sqlite3* db);
|
2024-03-06 12:46:27 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Get message content by ID.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param id The message identifier.
|
|
|
|
** @param[out] out_blob Populated with the message content.
|
|
|
|
** @param[out] out_size POpulated with the size of the message content.
|
|
|
|
** @return true If the message content was found and retrieved.
|
|
|
|
*/
|
2021-08-22 15:41:27 -04:00
|
|
|
bool tf_ssb_db_message_content_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_t* out_size);
|
2024-03-06 12:46:27 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Determine whether a blob is in the database by ID.
|
|
|
|
** @param ssb The SSB instasnce.
|
|
|
|
** @param id The blob identifier.
|
|
|
|
** @return true If the blob is in the database.
|
|
|
|
*/
|
2022-11-16 20:49:34 -05:00
|
|
|
bool tf_ssb_db_blob_has(tf_ssb_t* ssb, const char* id);
|
2024-03-06 12:46:27 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Retrieve a blob from the database.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param id The blob identifier.
|
|
|
|
** @param[out] out_blob Populated with the blob data.
|
|
|
|
** @param[out] out_size The size of the blob data.
|
|
|
|
** @return true If the blob was found and retrieved.
|
|
|
|
*/
|
2021-08-22 15:41:27 -04:00
|
|
|
bool tf_ssb_db_blob_get(tf_ssb_t* ssb, const char* id, uint8_t** out_blob, size_t* out_size);
|
2023-07-18 19:46:15 -04:00
|
|
|
|
2024-03-06 12:46:27 -05:00
|
|
|
/**
|
|
|
|
** A function called when a message is stored in the database.
|
|
|
|
** @param id The message identifier.
|
|
|
|
** @param stored True if the message wasn't already in the database.
|
|
|
|
** @param user_data The user data.
|
|
|
|
*/
|
2024-02-15 18:35:01 -05:00
|
|
|
typedef void(tf_ssb_db_store_message_callback_t)(const char* id, bool stored, void* user_data);
|
2024-03-06 12:46:27 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Store a message in the database.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param context The JS context.
|
|
|
|
** @param id The message identifier.
|
|
|
|
** @param val The message object.
|
|
|
|
** @param signature The signature of the message.
|
2024-03-13 19:40:09 -04:00
|
|
|
** @param flags tf_ssb_message_flags_t describing the message.
|
2024-03-06 12:46:27 -05:00
|
|
|
** @param callback A callback to call upon completion.
|
|
|
|
** @param user_data User data for the callback.
|
|
|
|
*/
|
2024-03-13 19:40:09 -04:00
|
|
|
void tf_ssb_db_store_message(
|
|
|
|
tf_ssb_t* ssb, JSContext* context, const char* id, JSValue val, const char* signature, int flags, tf_ssb_db_store_message_callback_t* callback, void* user_data);
|
2023-07-19 21:02:50 -04:00
|
|
|
|
2024-03-06 12:46:27 -05:00
|
|
|
/**
|
|
|
|
** A function called when a block is stored in the database.
|
|
|
|
** @param id The blob identifier.
|
|
|
|
** @param is_new True if the blob wasn't already in the database.
|
|
|
|
** @param user_data The user data.
|
|
|
|
*/
|
2024-02-15 18:35:01 -05:00
|
|
|
typedef void(tf_ssb_db_blob_store_callback_t)(const char* id, bool is_new, void* user_data);
|
2024-03-06 12:46:27 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Store a blob in the database asynchronously.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param blob The blob data.
|
|
|
|
** @param size The size of the blob data.
|
|
|
|
** @param callback A callback to call upon completion.
|
|
|
|
** @param user_data User data for the callback.
|
|
|
|
*/
|
2023-07-18 19:46:15 -04:00
|
|
|
void tf_ssb_db_blob_store_async(tf_ssb_t* ssb, const uint8_t* blob, size_t size, tf_ssb_db_blob_store_callback_t* callback, void* user_data);
|
2024-03-06 12:46:27 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Store a blob in the database and wait for the operation to complete.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param blob The blob data.
|
|
|
|
** @param size The size of the blob.
|
|
|
|
** @param[out] out_id Populated with the blob identifier.
|
|
|
|
** @param out_id_size The size of the out_id buffer.
|
|
|
|
** @param[out] out_new True if the blob wasn't already in the datbase.
|
|
|
|
*/
|
2022-10-12 08:27:32 -04:00
|
|
|
bool tf_ssb_db_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char* out_id, size_t out_id_size, bool* out_new);
|
2021-08-22 15:34:28 -04:00
|
|
|
|
2024-03-06 12:46:27 -05:00
|
|
|
/**
|
|
|
|
** Get a message by its identifier.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param id The message identifier.
|
|
|
|
** @param is_keys Whether to produce {"key": id, "value": message, "timestamp": ts} or just the message.
|
|
|
|
** @return The message.
|
|
|
|
*/
|
2024-02-15 18:35:01 -05:00
|
|
|
JSValue tf_ssb_db_get_message_by_id(tf_ssb_t* ssb, const char* id, bool is_keys);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Get a message by its author and sequence number.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param author The author's identity.
|
|
|
|
** @param sequence The message sequence number.
|
|
|
|
** @param[out] out_message_id Populated with the message identifier.
|
|
|
|
** @param out_message_id_size The size of the out_message_id buffer.
|
|
|
|
** @param[out] out_timestamp Populated with the timestamp.
|
|
|
|
** @param[out] out_content Populated with the message content. Free with tf_free().
|
|
|
|
** @return True if the message was found and retrieved.
|
|
|
|
*/
|
2024-02-15 18:35:01 -05:00
|
|
|
bool tf_ssb_db_get_message_by_author_and_sequence(
|
2024-02-17 14:22:02 -05:00
|
|
|
tf_ssb_t* ssb, const char* author, int64_t sequence, char* out_message_id, size_t out_message_id_size, double* out_timestamp, char** out_content);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Get information about the last message from an author.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param author The author's identity.
|
|
|
|
** @param[out] out_sequence Populated with the message sequence number.
|
|
|
|
** @param[out] out_message_id Populated with the message identifier.
|
|
|
|
** @param out_message_id_size The size of the out_message_id buffer.
|
|
|
|
** @return True if the message was found and information was retrieved.
|
|
|
|
*/
|
2021-08-22 15:41:27 -04:00
|
|
|
bool tf_ssb_db_get_latest_message_by_author(tf_ssb_t* ssb, const char* author, int64_t* out_sequence, char* out_message_id, size_t out_message_id_size);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Call a function for each result row of an SQL query.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param query The SQL query.
|
|
|
|
** @param binds An array of values to bind to SQL parameters.
|
|
|
|
** @param callback A callback to call for each result row.
|
|
|
|
** @param user_data User data to pass to the callback.
|
|
|
|
** @return A promise resolved when the query completes or rejected if it fails.
|
|
|
|
*/
|
2022-04-17 20:24:00 -04:00
|
|
|
JSValue tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds, void (*callback)(JSValue row, void* user_data), void* user_data);
|
2022-02-09 22:58:33 -05:00
|
|
|
|
2024-03-06 20:57:38 -05:00
|
|
|
/**
|
|
|
|
** Sanity check the feed for the given author.
|
|
|
|
** @param db The SQLite database instance to use.
|
|
|
|
** @param author The identity of the author to check.
|
|
|
|
** @return True if the author's feed is fully valid.
|
|
|
|
*/
|
2022-02-10 21:44:27 -05:00
|
|
|
bool tf_ssb_db_check(sqlite3* db, const char* author);
|
2022-07-13 21:01:14 -04:00
|
|
|
|
2024-03-06 20:57:38 -05:00
|
|
|
/**
|
|
|
|
** Get the number of SSB identities a Tilde Friends user has.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param user The user's username.
|
|
|
|
** @return The number of identities found.
|
|
|
|
*/
|
2022-07-13 21:01:14 -04:00
|
|
|
int tf_ssb_db_identity_get_count_for_user(tf_ssb_t* ssb, const char* user);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Create a new identity for a user.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param user The user's username.
|
|
|
|
** @param[out] out_public_key A buffer populated with the new public key.
|
2024-03-31 16:15:50 -04:00
|
|
|
** @param[out] out_private_key A buffer populated with the new private key.
|
2024-03-06 20:57:38 -05:00
|
|
|
** @return True if the identity was created.
|
|
|
|
*/
|
2022-10-14 08:27:34 -04:00
|
|
|
bool tf_ssb_db_identity_create(tf_ssb_t* ssb, const char* user, uint8_t* out_public_key, uint8_t* out_private_key);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Delete an identity for a user from the database. This is an unrecoverable operation.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param user The user's username.
|
|
|
|
** @param public_key The identity to delete.
|
|
|
|
** @return True if the identity was deleted.
|
|
|
|
*/
|
2024-01-06 14:22:49 -05:00
|
|
|
bool tf_ssb_db_identity_delete(tf_ssb_t* ssb, const char* user, const char* public_key);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Add an identity for a user to the database.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param user The user's username.
|
|
|
|
** @param public_key The public key of the identity.
|
|
|
|
** @param private_key The private key of the identity.
|
|
|
|
*/
|
2022-07-13 21:01:14 -04:00
|
|
|
bool tf_ssb_db_identity_add(tf_ssb_t* ssb, const char* user, const char* public_key, const char* private_key);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Call a function for each identity owned by a user.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param user The user's username.
|
|
|
|
** @param callback The function to call for each identity.
|
|
|
|
** @param user_data User data to pass to the callback.
|
|
|
|
*/
|
2022-07-13 21:01:14 -04:00
|
|
|
void tf_ssb_db_identity_visit(tf_ssb_t* ssb, const char* user, void (*callback)(const char* identity, void* user_data), void* user_data);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Call a function for all identities in the database.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param callback The callback to call for each identity.
|
|
|
|
** @param user_data User data to pass to the callback.
|
|
|
|
*/
|
2022-07-31 15:01:08 -04:00
|
|
|
void tf_ssb_db_identity_visit_all(tf_ssb_t* ssb, void (*callback)(const char* identity, void* user_data), void* user_data);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Get the private key for an identity in the database.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param user The owning user's username.
|
|
|
|
** @param public_key The public key of the identity.
|
|
|
|
** @param[out] out_private_key A buffer to receive the private key of the identity.
|
|
|
|
** @param private_key_size The size of the out_private_key buffer.
|
|
|
|
** @return True if the private key was found and retrieved.
|
|
|
|
*/
|
2022-07-13 21:01:14 -04:00
|
|
|
bool tf_ssb_db_identity_get_private_key(tf_ssb_t* ssb, const char* user, const char* public_key, uint8_t* out_private_key, size_t private_key_size);
|
2022-08-14 22:23:45 -04:00
|
|
|
|
2024-03-06 20:57:38 -05:00
|
|
|
/**
|
|
|
|
** Format a message in the standard format for SSB signing.
|
|
|
|
** @param context A JS context.
|
|
|
|
** @param previous The previous message identifier.
|
|
|
|
** @param author The author's public key.
|
|
|
|
** @param sequence The message sequence number.
|
|
|
|
** @param timestamp The message timestamp.
|
|
|
|
** @param hash The hash type (probably "sha256").
|
|
|
|
** @param content The message content.
|
|
|
|
** @param signature The signature of the message.
|
2024-03-13 19:40:09 -04:00
|
|
|
** @param flags tf_ssb_message_flags_t describing the message.
|
2024-03-06 20:57:38 -05:00
|
|
|
*/
|
2024-03-13 19:40:09 -04:00
|
|
|
JSValue tf_ssb_format_message(
|
|
|
|
JSContext* context, const char* previous, const char* author, int64_t sequence, double timestamp, const char* hash, const char* content, const char* signature, int flags);
|
2023-11-02 20:45:30 -04:00
|
|
|
|
2024-03-06 20:57:38 -05:00
|
|
|
/** Information about a single followed account. */
|
2023-11-02 20:45:30 -04:00
|
|
|
typedef struct _tf_ssb_following_t
|
|
|
|
{
|
2024-03-06 20:57:38 -05:00
|
|
|
/** The number of known users the account is following. */
|
2023-11-02 20:45:30 -04:00
|
|
|
int following_count;
|
2024-03-06 20:57:38 -05:00
|
|
|
/** The number of known users the account is blocking. */
|
2023-11-02 20:45:30 -04:00
|
|
|
int blocking_count;
|
2024-03-06 20:57:38 -05:00
|
|
|
/** The number of known users following the account. */
|
2023-11-02 20:45:30 -04:00
|
|
|
int followed_by_count;
|
2024-03-06 20:57:38 -05:00
|
|
|
/** The number of known users blocking the account. */
|
2023-11-02 20:45:30 -04:00
|
|
|
int blocked_by_count;
|
2024-03-06 20:57:38 -05:00
|
|
|
/** The account's identity. */
|
2024-01-10 20:38:30 -05:00
|
|
|
char id[k_id_base64_len];
|
2023-11-02 20:45:30 -04:00
|
|
|
} tf_ssb_following_t;
|
|
|
|
|
2024-03-06 20:57:38 -05:00
|
|
|
/**
|
|
|
|
** Get all the identities visible from a set of identities given known follows and blocks.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param ids An array of identities.
|
|
|
|
** @param count The number of identities.
|
|
|
|
** @param depth The following depth to use (prefer 2).
|
|
|
|
** @return An array of identities. Free with tf_free().
|
|
|
|
*/
|
2023-11-02 20:45:30 -04:00
|
|
|
const char** tf_ssb_db_following_deep_ids(tf_ssb_t* ssb, const char** ids, int count, int depth);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Return information about identities visible from a set of identities given known follows and blocks.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param ids An array of identities.
|
|
|
|
** @param count The number of identities.
|
|
|
|
** @param depth The following depth to use (prefer 2).
|
|
|
|
** @return An array of information about visible accounts. Fere with tf_free().
|
|
|
|
*/
|
2023-11-02 20:45:30 -04:00
|
|
|
tf_ssb_following_t* tf_ssb_db_following_deep(tf_ssb_t* ssb, const char** ids, int count, int depth);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Get all visible identities from all local accounts.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param depth The following depth to consider (prefer 2).
|
|
|
|
** @return The visible identities. Free with tf_free().
|
|
|
|
*/
|
2023-01-08 15:01:35 -05:00
|
|
|
const char** tf_ssb_db_get_all_visible_identities(tf_ssb_t* ssb, int depth);
|
2022-12-31 16:44:48 -05:00
|
|
|
|
2024-03-06 20:57:38 -05:00
|
|
|
/**
|
|
|
|
** Information about a stored SHS connection.
|
|
|
|
*/
|
2023-01-17 19:37:45 -05:00
|
|
|
typedef struct _tf_ssb_db_stored_connection_t
|
|
|
|
{
|
2024-03-06 20:57:38 -05:00
|
|
|
/** The connection's address. */
|
2023-01-17 19:37:45 -05:00
|
|
|
char address[256];
|
2024-03-06 20:57:38 -05:00
|
|
|
/** The network port number of the connection. */
|
2023-01-17 19:37:45 -05:00
|
|
|
int port;
|
2024-03-06 20:57:38 -05:00
|
|
|
/** The identity. */
|
2023-01-17 19:37:45 -05:00
|
|
|
char pubkey[k_id_base64_len];
|
|
|
|
} tf_ssb_db_stored_connection_t;
|
|
|
|
|
2024-03-06 20:57:38 -05:00
|
|
|
/**
|
|
|
|
** Get the list of stored connections from the SSB connection tracker.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param[out] out_count Populated with the number of returned connections.
|
|
|
|
** @return Information about all the stored connections.
|
|
|
|
*/
|
2023-01-17 19:37:45 -05:00
|
|
|
tf_ssb_db_stored_connection_t* tf_ssb_db_get_stored_connections(tf_ssb_t* ssb, int* out_count);
|
2024-03-06 20:57:38 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
** Remove a stored connection.
|
|
|
|
** @param ssb The SSB instance.
|
|
|
|
** @param address The connection address.
|
|
|
|
** @param port The connection network port number.
|
|
|
|
** @param pubkey The identity of the connection.
|
|
|
|
*/
|
2023-01-17 19:37:45 -05:00
|
|
|
void tf_ssb_db_forget_stored_connection(tf_ssb_t* ssb, const char* address, int port, const char* pubkey);
|
2023-08-16 18:43:08 -04:00
|
|
|
|
2024-03-06 20:57:38 -05:00
|
|
|
/**
|
|
|
|
** An SQLite authorizer callback. See https://www.sqlite.org/c3ref/set_authorizer.html for use.
|
|
|
|
** @param user_data User data registered with the authorizer.
|
|
|
|
** @param action_code The type of action.
|
|
|
|
** @param arg0 Depends on the action.
|
|
|
|
** @param arg1 Depends on the action.
|
|
|
|
** @param arg2 Depends on the action.
|
|
|
|
** @param arg3 Depends on the action.
|
|
|
|
** @return A value indicating whether the operation is allowed.
|
|
|
|
*/
|
2023-08-16 18:43:08 -04:00
|
|
|
int tf_ssb_sqlite_authorizer(void* user_data, int action_code, const char* arg0, const char* arg1, const char* arg2, const char* arg3);
|
2024-02-20 21:41:37 -05:00
|
|
|
|
|
|
|
/** @} */
|