Working on API

This commit is contained in:
Your Name
2025-09-25 16:35:16 -04:00
parent 036b0823b9
commit bc6a7b3f20
9 changed files with 1530 additions and 894 deletions

View File

@@ -228,7 +228,10 @@ int nostr_validate_unified_request(const char* json_string, size_t json_length);
int handle_configuration_event(cJSON* event, char* error_message, size_t error_size);
// Forward declaration for admin event processing (kinds 33334 and 33335)
int process_admin_event_in_config(cJSON* event, char* error_message, size_t error_size);
int process_admin_event_in_config(cJSON* event, char* error_message, size_t error_size, struct lws* wsi);
// Forward declaration for enhanced admin event authorization
int is_authorized_admin_event(cJSON* event, char* error_message, size_t error_size);
// Forward declaration for NOTICE message support
void send_notice_message(struct lws* wsi, const char* message);
@@ -3009,6 +3012,109 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
return events_sent;
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// ADMIN EVENT AUTHORIZATION
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// Enhanced admin event authorization function
int is_authorized_admin_event(cJSON* event, char* error_buffer, size_t error_buffer_size) {
if (!event || !error_buffer) {
if (error_buffer && error_buffer_size > 0) {
snprintf(error_buffer, error_buffer_size, "Invalid parameters for admin authorization");
}
return -1;
}
// Step 1: Verify event kind is admin type
cJSON *kind_json = cJSON_GetObjectItem(event, "kind");
if (!kind_json || !cJSON_IsNumber(kind_json)) {
snprintf(error_buffer, error_buffer_size, "Missing or invalid event kind");
return -1;
}
int event_kind = kind_json->valueint;
if (event_kind != 33334 && event_kind != 33335 && event_kind != 23455 && event_kind != 23456) {
snprintf(error_buffer, error_buffer_size, "Event kind %d is not an admin event type", event_kind);
return -1;
}
// Step 2: Check if event targets this relay (look for 'p' tag with our relay pubkey)
cJSON *tags = cJSON_GetObjectItem(event, "tags");
if (!tags || !cJSON_IsArray(tags)) {
// No tags array - treat as regular event for different relay
log_info("Admin event has no tags array - treating as event for different relay");
snprintf(error_buffer, error_buffer_size, "Admin event not targeting this relay (no tags)");
return -1;
}
int targets_this_relay = 0;
cJSON *tag;
cJSON_ArrayForEach(tag, tags) {
if (cJSON_IsArray(tag)) {
cJSON *tag_name = cJSON_GetArrayItem(tag, 0);
cJSON *tag_value = cJSON_GetArrayItem(tag, 1);
if (tag_name && cJSON_IsString(tag_name) &&
tag_value && cJSON_IsString(tag_value) &&
strcmp(tag_name->valuestring, "p") == 0) {
// Compare with our relay pubkey
const char* relay_pubkey = get_config_value("relay_pubkey");
if (relay_pubkey && strcmp(tag_value->valuestring, relay_pubkey) == 0) {
targets_this_relay = 1;
break;
}
}
}
}
if (!targets_this_relay) {
// Admin event for different relay - not an error, just not for us
log_info("Admin event targets different relay - treating as regular event");
snprintf(error_buffer, error_buffer_size, "Admin event not targeting this relay");
return -1;
}
// Step 3: Verify admin signature authorization
cJSON *pubkey_json = cJSON_GetObjectItem(event, "pubkey");
if (!pubkey_json || !cJSON_IsString(pubkey_json)) {
log_warning("Unauthorized admin event attempt: missing or invalid pubkey");
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: missing pubkey");
return -1;
}
// Get admin pubkey from configuration
const char* admin_pubkey = get_config_value("admin_pubkey");
if (!admin_pubkey || strlen(admin_pubkey) == 0) {
log_warning("Unauthorized admin event attempt: no admin pubkey configured");
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: no admin configured");
return -1;
}
// Compare pubkeys
if (strcmp(pubkey_json->valuestring, admin_pubkey) != 0) {
log_warning("Unauthorized admin event attempt: pubkey mismatch");
char warning_msg[256];
snprintf(warning_msg, sizeof(warning_msg),
"Unauthorized admin event attempt from pubkey: %.32s...", pubkey_json->valuestring);
log_warning(warning_msg);
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: invalid admin pubkey");
return -1;
}
// Step 4: Verify event signature
if (nostr_verify_event_signature(event) != 0) {
log_warning("Unauthorized admin event attempt: invalid signature");
snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: signature verification failed");
return -1;
}
// All checks passed - authorized admin event
log_info("Admin event authorization successful");
return 0;
}
@@ -3266,47 +3372,68 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
}
if (event_kind == 33334 || event_kind == 33335 || event_kind == 23455 || event_kind == 23456) {
// This is an admin event - process it through the admin API instead of normal storage
log_info("DEBUG ADMIN: Admin event detected, processing through admin API");
// Enhanced admin event security - check authorization first
log_info("DEBUG ADMIN: Admin event detected, checking authorization");
char admin_error[512] = {0};
int admin_result = process_admin_event_in_config(event, admin_error, sizeof(admin_error));
char auth_error[512] = {0};
int auth_result = is_authorized_admin_event(event, auth_error, sizeof(auth_error));
char debug_admin_msg[256];
snprintf(debug_admin_msg, sizeof(debug_admin_msg),
"DEBUG ADMIN: process_admin_event_in_config returned %d", admin_result);
log_info(debug_admin_msg);
// Log results for Kind 23455 and 23456 events
if (event_kind == 23455 || event_kind == 23456) {
if (admin_result == 0) {
char success_result_msg[256];
snprintf(success_result_msg, sizeof(success_result_msg),
"SUCCESS: Kind %d event processed successfully", event_kind);
log_success(success_result_msg);
} else {
char error_result_msg[512];
snprintf(error_result_msg, sizeof(error_result_msg),
"ERROR: Kind %d event processing failed: %s", event_kind, admin_error);
log_error(error_result_msg);
}
}
if (admin_result != 0) {
log_error("DEBUG ADMIN: Failed to process admin event through admin API");
if (auth_result != 0) {
// Authorization failed - log and reject
log_warning("DEBUG ADMIN: Admin event authorization failed");
result = -1;
size_t error_len = strlen(admin_error);
size_t error_len = strlen(auth_error);
size_t copy_len = (error_len < sizeof(error_message) - 1) ? error_len : sizeof(error_message) - 1;
memcpy(error_message, admin_error, copy_len);
memcpy(error_message, auth_error, copy_len);
error_message[copy_len] = '\0';
char debug_admin_error_msg[600];
snprintf(debug_admin_error_msg, sizeof(debug_admin_error_msg),
"DEBUG ADMIN ERROR: %.400s", admin_error);
log_error(debug_admin_error_msg);
char debug_auth_error_msg[600];
snprintf(debug_auth_error_msg, sizeof(debug_auth_error_msg),
"DEBUG ADMIN AUTH ERROR: %.400s", auth_error);
log_warning(debug_auth_error_msg);
} else {
log_success("DEBUG ADMIN: Admin event processed successfully through admin API");
// Admin events are processed by the admin API, not broadcast to subscriptions
// Authorization successful - process through admin API
log_info("DEBUG ADMIN: Admin event authorized, processing through admin API");
char admin_error[512] = {0};
int admin_result = process_admin_event_in_config(event, admin_error, sizeof(admin_error), wsi);
char debug_admin_msg[256];
snprintf(debug_admin_msg, sizeof(debug_admin_msg),
"DEBUG ADMIN: process_admin_event_in_config returned %d", admin_result);
log_info(debug_admin_msg);
// Log results for Kind 23455 and 23456 events
if (event_kind == 23455 || event_kind == 23456) {
if (admin_result == 0) {
char success_result_msg[256];
snprintf(success_result_msg, sizeof(success_result_msg),
"SUCCESS: Kind %d event processed successfully", event_kind);
log_success(success_result_msg);
} else {
char error_result_msg[512];
snprintf(error_result_msg, sizeof(error_result_msg),
"ERROR: Kind %d event processing failed: %s", event_kind, admin_error);
log_error(error_result_msg);
}
}
if (admin_result != 0) {
log_error("DEBUG ADMIN: Failed to process admin event through admin API");
result = -1;
size_t error_len = strlen(admin_error);
size_t copy_len = (error_len < sizeof(error_message) - 1) ? error_len : sizeof(error_message) - 1;
memcpy(error_message, admin_error, copy_len);
error_message[copy_len] = '\0';
char debug_admin_error_msg[600];
snprintf(debug_admin_error_msg, sizeof(debug_admin_error_msg),
"DEBUG ADMIN ERROR: %.400s", admin_error);
log_error(debug_admin_error_msg);
} else {
log_success("DEBUG ADMIN: Admin event processed successfully through admin API");
// Admin events are processed by the admin API, not broadcast to subscriptions
}
}
} else {
// Regular event - store in database and broadcast