From 38d746b3106dab635351d60c378dd2ecfa854f9e Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Wed, 9 Apr 2025 19:32:38 -0400 Subject: [PATCH] ssb: Dust off the verify command. --- src/main.c | 33 +++++++++++++++++++++++++++++++-- src/ssb.db.c | 34 ++++++++++++++++++++++++++++++---- src/ssb.db.h | 3 ++- 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index e6b2a1fa..ee0d6154 100644 --- a/src/main.c +++ b/src/main.c @@ -1204,9 +1204,38 @@ static int _tf_command_verify(const char* file, int argc, char* argv[]) return EXIT_FAILURE; } - tf_printf("Verifying %s...\n", identity); + bool verified = false; tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL); - bool verified = tf_ssb_db_verify(ssb, identity); + if (identity) + { + tf_printf("Verifying %s...\n", identity); + verified = tf_ssb_db_verify(ssb, identity, true); + } + else + { + sqlite3* db = tf_ssb_acquire_db_reader(ssb); + sqlite3_stmt* statement = NULL; + if (sqlite3_prepare(db, "SELECT DISTINCT author FROM messages ORDER BY author", -1, &statement, NULL) == SQLITE_OK) + { + verified = true; + while (sqlite3_step(statement) == SQLITE_ROW) + { + const char* identity = (const char*)sqlite3_column_text(statement, 0); + tf_printf("Verifying %s...", identity); + if (tf_ssb_db_verify(ssb, identity, true)) + { + tf_printf("success.\n"); + } + else + { + tf_printf("fail.\n"); + verified = false; + } + } + sqlite3_finalize(statement); + } + tf_ssb_release_db_reader(ssb, db); + } tf_ssb_destroy(ssb); tf_free((void*)default_db_path); return verified ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/src/ssb.db.c b/src/ssb.db.c index 497ecce1..5b6d2226 100644 --- a/src/ssb.db.c +++ b/src/ssb.db.c @@ -182,8 +182,9 @@ void tf_ssb_db_init(tf_ssb_t* ssb) _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_timestamp_index ON messages (timestamp)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_type_timestamp_index ON messages (content ->> 'type', timestamp)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_size_by_author_index ON messages (author, length(content))"); - _tf_ssb_db_exec( - db, "CREATE INDEX IF NOT EXISTS messages_type_author_channel_root_timestamp_index ON messages (author, timestamp, content ->> 'type', content ->> 'channel', content ->> 'root')"); + _tf_ssb_db_exec(db, + "CREATE INDEX IF NOT EXISTS messages_type_author_channel_root_timestamp_index ON messages (author, timestamp, content ->> 'type', content ->> 'channel', content ->> " + "'root')"); _tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_type_author_channel_index"); _tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_author_id_index"); _tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_by_author_index"); @@ -2128,7 +2129,25 @@ void tf_ssb_db_resolve_index_async(tf_ssb_t* ssb, const char* host, void (*callb tf_ssb_run_work(ssb, _tf_ssb_db_resolve_index_work, _tf_ssb_db_resolve_index_after_work, request); } -bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id) +static void _tf_ssb_db_set_flags(tf_ssb_t* ssb, const char* message_id, int flags) +{ + sqlite3* db = tf_ssb_acquire_db_writer(ssb); + sqlite3_stmt* statement = NULL; + if (sqlite3_prepare(db, "UPDATE messages SET flags = ? WHERE id = ?", -1, &statement, NULL) == SQLITE_OK) + { + if (sqlite3_bind_int(statement, 1, flags) == SQLITE_OK && sqlite3_bind_text(statement, 2, message_id, -1, NULL) == SQLITE_OK) + { + if (sqlite3_step(statement) != SQLITE_DONE) + { + tf_printf("Setting flags of %s to %d failed: %s.\n", message_id, flags, sqlite3_errmsg(db)); + } + } + sqlite3_finalize(statement); + } + tf_ssb_release_db_writer(ssb, db); +} + +bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id, bool fix) { JSContext* context = tf_ssb_get_context(ssb); bool verified = true; @@ -2159,7 +2178,14 @@ bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id) if (calculated_flags != flags) { tf_printf("author=%s sequence=%" PRId64 " flag mismatch %d => %d.\n", id, i, flags, calculated_flags); - verified = false; + if (fix) + { + _tf_ssb_db_set_flags(ssb, message_id, calculated_flags); + } + else + { + verified = false; + } } if (strcmp(message_id, calculated_id)) { diff --git a/src/ssb.db.h b/src/ssb.db.h index 26546b32..419c9f9c 100644 --- a/src/ssb.db.h +++ b/src/ssb.db.h @@ -444,9 +444,10 @@ void tf_ssb_db_resolve_index_async(tf_ssb_t* ssb, const char* host, void (*callb ** Verify an author's feed. ** @param ssb The SSB instance. ** @param id The author'd identity. +** @param fix Fix invalid messages when possible. ** @return true If the feed verified successfully. */ -bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id); +bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id, bool fix); /** ** Check if a user has a specific permission.