v0.4.1 - Fixed startup bug
This commit is contained in:
84
src/config.c
84
src/config.c
@@ -917,10 +917,11 @@ cJSON* create_default_config_event(const unsigned char* admin_privkey_bytes,
|
||||
|
||||
int first_time_startup_sequence(const cli_options_t* cli_options) {
|
||||
log_info("Starting first-time startup sequence...");
|
||||
|
||||
|
||||
// 1. Generate or use provided admin keypair
|
||||
unsigned char admin_privkey_bytes[32];
|
||||
char admin_privkey[65], admin_pubkey[65];
|
||||
int generated_admin_key = 0; // Track if we generated a new admin key
|
||||
|
||||
if (cli_options && strlen(cli_options->admin_pubkey_override) == 64) {
|
||||
// Use provided admin public key directly - skip private key generation entirely
|
||||
@@ -943,6 +944,7 @@ int first_time_startup_sequence(const cli_options_t* cli_options) {
|
||||
// Set a dummy private key that will never be used (not displayed or stored)
|
||||
memset(admin_privkey_bytes, 0, 32); // Zero out for security
|
||||
memset(admin_privkey, 0, sizeof(admin_privkey)); // Zero out the hex string
|
||||
generated_admin_key = 0; // Did not generate a new key
|
||||
} else {
|
||||
// Generate random admin keypair using /dev/urandom + nostr_core_lib
|
||||
log_info("Generating random admin keypair");
|
||||
@@ -959,6 +961,7 @@ int first_time_startup_sequence(const cli_options_t* cli_options) {
|
||||
return -1;
|
||||
}
|
||||
nostr_bytes_to_hex(admin_pubkey_bytes, 32, admin_pubkey);
|
||||
generated_admin_key = 1; // Generated a new key
|
||||
}
|
||||
|
||||
// 2. Generate or use provided relay keypair
|
||||
@@ -1017,57 +1020,40 @@ int first_time_startup_sequence(const cli_options_t* cli_options) {
|
||||
g_temp_relay_privkey[sizeof(g_temp_relay_privkey) - 1] = '\0';
|
||||
log_info("Relay private key cached for secure storage after database initialization");
|
||||
|
||||
// 6. Handle configuration setup based on admin key availability
|
||||
if (cli_options && strlen(cli_options->admin_pubkey_override) == 64) {
|
||||
// Admin pubkey provided - will populate config table after database initialization
|
||||
log_info("Admin pubkey provided - config table will be populated after database initialization");
|
||||
// 6. Handle configuration setup - defaults will be populated after database initialization
|
||||
log_info("Configuration setup prepared - defaults will be populated after database initialization");
|
||||
|
||||
|
||||
// CLI overrides will be applied after database initialization in main.c
|
||||
// This prevents "g_db is NULL" errors during first-time startup
|
||||
|
||||
// 10. Print admin private key for user to save (only if we generated a new key)
|
||||
if (generated_admin_key) {
|
||||
printf("\n");
|
||||
printf("=================================================================\n");
|
||||
printf("IMPORTANT: SAVE THIS ADMIN PRIVATE KEY SECURELY!\n");
|
||||
printf("=================================================================\n");
|
||||
printf("Admin Private Key: %s\n", admin_privkey);
|
||||
printf("Admin Public Key: %s\n", admin_pubkey);
|
||||
printf("Relay Public Key: %s\n", relay_pubkey);
|
||||
printf("\nDatabase: %s\n", g_database_path);
|
||||
printf("\nThis admin private key is needed to update configuration!\n");
|
||||
printf("Store it safely - it will not be displayed again.\n");
|
||||
printf("=================================================================\n");
|
||||
printf("\n");
|
||||
} else {
|
||||
// Admin private key available - create signed configuration event
|
||||
log_info("Admin private key available - creating signed configuration event");
|
||||
|
||||
// Create initial configuration event using defaults
|
||||
cJSON* config_event = create_default_config_event(admin_privkey_bytes, relay_privkey, relay_pubkey, cli_options);
|
||||
if (!config_event) {
|
||||
log_error("Failed to create default configuration event");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Process configuration through admin API instead of storing in events table
|
||||
if (process_startup_config_event_with_fallback(config_event) == 0) {
|
||||
log_success("Initial configuration processed successfully through admin API");
|
||||
} else {
|
||||
log_warning("Failed to process initial configuration - will retry after database init");
|
||||
// Cache the event for later processing
|
||||
if (g_pending_config_event) {
|
||||
cJSON_Delete(g_pending_config_event);
|
||||
}
|
||||
g_pending_config_event = cJSON_Duplicate(config_event, 1);
|
||||
}
|
||||
|
||||
// Cache the current config
|
||||
if (g_current_config) {
|
||||
cJSON_Delete(g_current_config);
|
||||
}
|
||||
g_current_config = cJSON_Duplicate(config_event, 1);
|
||||
|
||||
// Clean up
|
||||
cJSON_Delete(config_event);
|
||||
printf("\n");
|
||||
printf("=================================================================\n");
|
||||
printf("RELAY STARTUP COMPLETE\n");
|
||||
printf("=================================================================\n");
|
||||
printf("Using provided admin public key for authentication\n");
|
||||
printf("Admin Public Key: %s\n", admin_pubkey);
|
||||
printf("Relay Public Key: %s\n", relay_pubkey);
|
||||
printf("\nDatabase: %s\n", g_database_path);
|
||||
printf("=================================================================\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// 10. Print admin private key for user to save
|
||||
printf("\n");
|
||||
printf("=================================================================\n");
|
||||
printf("IMPORTANT: SAVE THIS ADMIN PRIVATE KEY SECURELY!\n");
|
||||
printf("=================================================================\n");
|
||||
printf("Admin Private Key: %s\n", admin_privkey);
|
||||
printf("Admin Public Key: %s\n", admin_pubkey);
|
||||
printf("Relay Public Key: %s\n", relay_pubkey);
|
||||
printf("\nDatabase: %s\n", g_database_path);
|
||||
printf("\nThis admin private key is needed to update configuration!\n");
|
||||
printf("Store it safely - it will not be displayed again.\n");
|
||||
printf("=================================================================\n");
|
||||
printf("\n");
|
||||
|
||||
log_success("First-time startup sequence completed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
113
src/main.c
113
src/main.c
@@ -348,18 +348,18 @@ int init_database(const char* database_path_override) {
|
||||
}
|
||||
|
||||
if (!has_auth_rules) {
|
||||
// Add auth_rules table
|
||||
// Add auth_rules table matching sql_schema.h
|
||||
const char* create_auth_rules_sql =
|
||||
"CREATE TABLE IF NOT EXISTS auth_rules ("
|
||||
" id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||
" rule_type TEXT NOT NULL," // 'pubkey_whitelist', 'pubkey_blacklist', 'hash_blacklist'
|
||||
" operation TEXT NOT NULL," // 'event', 'event_kind_1', etc.
|
||||
" rule_target TEXT NOT NULL," // pubkey, hash, or other identifier
|
||||
" enabled INTEGER DEFAULT 1," // 0 = disabled, 1 = enabled
|
||||
" priority INTEGER DEFAULT 1000," // Lower numbers = higher priority
|
||||
" description TEXT," // Optional description
|
||||
" created_at INTEGER DEFAULT (strftime('%s', 'now')),"
|
||||
" UNIQUE(rule_type, operation, rule_target)"
|
||||
" rule_type TEXT NOT NULL CHECK (rule_type IN ('whitelist', 'blacklist', 'rate_limit', 'auth_required')),"
|
||||
" pattern_type TEXT NOT NULL CHECK (pattern_type IN ('pubkey', 'kind', 'ip', 'global')),"
|
||||
" pattern_value TEXT,"
|
||||
" action TEXT NOT NULL CHECK (action IN ('allow', 'deny', 'require_auth', 'rate_limit')),"
|
||||
" parameters TEXT,"
|
||||
" active INTEGER NOT NULL DEFAULT 1,"
|
||||
" created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),"
|
||||
" updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))"
|
||||
");";
|
||||
|
||||
char* error_msg = NULL;
|
||||
@@ -373,6 +373,24 @@ int init_database(const char* database_path_override) {
|
||||
return -1;
|
||||
}
|
||||
log_success("Created auth_rules table");
|
||||
|
||||
// Add indexes for auth_rules table
|
||||
const char* create_auth_rules_indexes_sql =
|
||||
"CREATE INDEX IF NOT EXISTS idx_auth_rules_pattern ON auth_rules(pattern_type, pattern_value);"
|
||||
"CREATE INDEX IF NOT EXISTS idx_auth_rules_type ON auth_rules(rule_type);"
|
||||
"CREATE INDEX IF NOT EXISTS idx_auth_rules_active ON auth_rules(active);";
|
||||
|
||||
char* index_error_msg = NULL;
|
||||
int index_rc = sqlite3_exec(g_db, create_auth_rules_indexes_sql, NULL, NULL, &index_error_msg);
|
||||
if (index_rc != SQLITE_OK) {
|
||||
char index_error_log[512];
|
||||
snprintf(index_error_log, sizeof(index_error_log), "Failed to create auth_rules indexes: %s",
|
||||
index_error_msg ? index_error_msg : "unknown error");
|
||||
log_error(index_error_log);
|
||||
if (index_error_msg) sqlite3_free(index_error_msg);
|
||||
return -1;
|
||||
}
|
||||
log_success("Created auth_rules indexes");
|
||||
} else {
|
||||
log_info("auth_rules table already exists, skipping creation");
|
||||
}
|
||||
@@ -1408,35 +1426,43 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
// Handle configuration setup after database is initialized
|
||||
if (cli_options.admin_pubkey_override && strlen(cli_options.admin_pubkey_override) == 64) {
|
||||
// Admin pubkey provided - populate config table directly
|
||||
log_info("Populating config table for admin pubkey override after database initialization");
|
||||
// Always populate defaults directly in config table (abandoning legacy event signing)
|
||||
log_info("Populating config table with defaults after database initialization");
|
||||
|
||||
// Populate default config values in table
|
||||
if (populate_default_config_values() != 0) {
|
||||
log_error("Failed to populate default config values");
|
||||
cleanup_configuration_system();
|
||||
nostr_cleanup();
|
||||
close_database();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Add pubkeys to config table
|
||||
if (add_pubkeys_to_config_table() != 0) {
|
||||
log_error("Failed to add pubkeys to config table");
|
||||
cleanup_configuration_system();
|
||||
nostr_cleanup();
|
||||
close_database();
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_success("Configuration populated directly in config table after database initialization");
|
||||
} else {
|
||||
// Admin private key available - retry storing initial config event
|
||||
if (retry_store_initial_config_event() != 0) {
|
||||
log_warning("Failed to store initial config event - will retry later");
|
||||
}
|
||||
// Populate default config values in table
|
||||
if (populate_default_config_values() != 0) {
|
||||
log_error("Failed to populate default config values");
|
||||
cleanup_configuration_system();
|
||||
nostr_cleanup();
|
||||
close_database();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Apply CLI overrides now that database is available
|
||||
if (cli_options.port_override > 0) {
|
||||
char port_str[16];
|
||||
snprintf(port_str, sizeof(port_str), "%d", cli_options.port_override);
|
||||
if (update_config_in_table("relay_port", port_str) != 0) {
|
||||
log_error("Failed to update relay port override in config table");
|
||||
cleanup_configuration_system();
|
||||
nostr_cleanup();
|
||||
close_database();
|
||||
return 1;
|
||||
}
|
||||
log_info("Applied port override from command line");
|
||||
printf(" Port: %d (overriding default)\n", cli_options.port_override);
|
||||
}
|
||||
|
||||
// Add pubkeys to config table
|
||||
if (add_pubkeys_to_config_table() != 0) {
|
||||
log_error("Failed to add pubkeys to config table");
|
||||
cleanup_configuration_system();
|
||||
nostr_cleanup();
|
||||
close_database();
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_success("Configuration populated directly in config table after database initialization");
|
||||
|
||||
// Now store the pubkeys in config table since database is available
|
||||
const char* admin_pubkey = get_admin_pubkey_cached();
|
||||
@@ -1539,6 +1565,21 @@ int main(int argc, char* argv[]) {
|
||||
log_warning("No configuration event found in existing database");
|
||||
}
|
||||
|
||||
// Apply CLI overrides for existing relay (port override should work even for existing relays)
|
||||
if (cli_options.port_override > 0) {
|
||||
char port_str[16];
|
||||
snprintf(port_str, sizeof(port_str), "%d", cli_options.port_override);
|
||||
if (update_config_in_table("relay_port", port_str) != 0) {
|
||||
log_error("Failed to update relay port override in config table for existing relay");
|
||||
cleanup_configuration_system();
|
||||
nostr_cleanup();
|
||||
close_database();
|
||||
return 1;
|
||||
}
|
||||
log_info("Applied port override from command line for existing relay");
|
||||
printf(" Port: %d (overriding configured port)\n", cli_options.port_override);
|
||||
}
|
||||
|
||||
// Free memory
|
||||
free(relay_pubkey);
|
||||
for (int i = 0; existing_files[i]; i++) {
|
||||
|
||||
Reference in New Issue
Block a user