diff --git a/src/api.c b/src/api.c index 933599a..19c3507 100644 --- a/src/api.c +++ b/src/api.c @@ -499,10 +499,10 @@ int generate_monitoring_event_for_type(const char* d_tag_value, cJSON* (*query_f // Use the library function to create and sign the event cJSON* signed_event = nostr_create_and_sign_event( 24567, // kind (ephemeral) - cJSON_GetStringValue(cJSON_GetObjectItem(monitoring_event, "content")), // content + cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(monitoring_event, "content")), // content tags, // tags relay_privkey, // private key - (time_t)cJSON_GetNumberValue(cJSON_GetObjectItem(monitoring_event, "created_at")) // timestamp + (time_t)cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(monitoring_event, "created_at")) // timestamp ); if (!signed_event) { @@ -922,10 +922,10 @@ int send_admin_response(const char* sender_pubkey, const char* response_content, // Use the library function to create and sign the event cJSON* signed_event = nostr_create_and_sign_event( 23457, // kind - cJSON_GetStringValue(cJSON_GetObjectItem(response_event, "content")), // content + cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(response_event, "content")), // content tags, // tags relay_privkey, // private key - (time_t)cJSON_GetNumberValue(cJSON_GetObjectItem(response_event, "created_at")) // timestamp + (time_t)cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(response_event, "created_at")) // timestamp ); if (!signed_event) { @@ -1169,7 +1169,7 @@ int handle_sql_query_unified(cJSON* event, const char* query, char* error_messag } // Get request event ID for response correlation - cJSON* request_id_obj = cJSON_GetObjectItem(event, "id"); + cJSON* request_id_obj = cJSON_GetObjectItemCaseSensitive(event, "id"); if (!request_id_obj || !cJSON_IsString(request_id_obj)) { snprintf(error_message, error_size, "Missing request event ID"); return -1; @@ -1188,7 +1188,7 @@ int handle_sql_query_unified(cJSON* event, const char* query, char* error_messag } // Get sender pubkey for response - cJSON* sender_pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* sender_pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (!sender_pubkey_obj || !cJSON_IsString(sender_pubkey_obj)) { free(result_json); snprintf(error_message, error_size, "Missing sender pubkey"); @@ -1491,7 +1491,7 @@ int send_nip17_response(const char* sender_pubkey, const char* response_content, } // Fix the p tag in the gift wrap - library function may use wrong pubkey - cJSON* gift_wrap_tags = cJSON_GetObjectItem(gift_wraps[0], "tags"); + cJSON* gift_wrap_tags = cJSON_GetObjectItemCaseSensitive(gift_wraps[0], "tags"); if (gift_wrap_tags && cJSON_IsArray(gift_wrap_tags)) { // Find and replace the p tag with the correct user pubkey cJSON* tag = NULL; @@ -1627,13 +1627,13 @@ char* generate_stats_text(void) { if (stats_obj) { // Extract basic metrics - cJSON* total_events = cJSON_GetObjectItem(stats_obj, "total_events"); - cJSON* db_size = cJSON_GetObjectItem(stats_obj, "database_size_bytes"); - cJSON* oldest_event = cJSON_GetObjectItem(stats_obj, "database_created_at"); - cJSON* newest_event = cJSON_GetObjectItem(stats_obj, "latest_event_at"); - cJSON* time_stats = cJSON_GetObjectItem(stats_obj, "time_stats"); - cJSON* event_kinds = cJSON_GetObjectItem(stats_obj, "event_kinds"); - // cJSON* top_pubkeys = cJSON_GetObjectItem(stats_obj, "top_pubkeys"); + cJSON* total_events = cJSON_GetObjectItemCaseSensitive(stats_obj, "total_events"); + cJSON* db_size = cJSON_GetObjectItemCaseSensitive(stats_obj, "database_size_bytes"); + cJSON* oldest_event = cJSON_GetObjectItemCaseSensitive(stats_obj, "database_created_at"); + cJSON* newest_event = cJSON_GetObjectItemCaseSensitive(stats_obj, "latest_event_at"); + cJSON* time_stats = cJSON_GetObjectItemCaseSensitive(stats_obj, "time_stats"); + cJSON* event_kinds = cJSON_GetObjectItemCaseSensitive(stats_obj, "event_kinds"); + // cJSON* top_pubkeys = cJSON_GetObjectItemCaseSensitive(stats_obj, "top_pubkeys"); long long total = total_events ? (long long)cJSON_GetNumberValue(total_events) : 0; long long db_bytes = db_size ? (long long)cJSON_GetNumberValue(db_size) : 0; @@ -1661,9 +1661,9 @@ char* generate_stats_text(void) { // Extract time-based stats long long last_24h = 0, last_7d = 0, last_30d = 0; if (time_stats) { - cJSON* h24 = cJSON_GetObjectItem(time_stats, "last_24h"); - cJSON* d7 = cJSON_GetObjectItem(time_stats, "last_7d"); - cJSON* d30 = cJSON_GetObjectItem(time_stats, "last_30d"); + cJSON* h24 = cJSON_GetObjectItemCaseSensitive(time_stats, "last_24h"); + cJSON* d7 = cJSON_GetObjectItemCaseSensitive(time_stats, "last_7d"); + cJSON* d30 = cJSON_GetObjectItemCaseSensitive(time_stats, "last_30d"); last_24h = h24 ? (long long)cJSON_GetNumberValue(h24) : 0; last_7d = d7 ? (long long)cJSON_GetNumberValue(d7) : 0; last_30d = d30 ? (long long)cJSON_GetNumberValue(d30) : 0; @@ -1695,9 +1695,9 @@ char* generate_stats_text(void) { if (event_kinds && cJSON_IsArray(event_kinds)) { cJSON* kind_item = NULL; cJSON_ArrayForEach(kind_item, event_kinds) { - cJSON* kind = cJSON_GetObjectItem(kind_item, "kind"); - cJSON* count = cJSON_GetObjectItem(kind_item, "count"); - cJSON* percentage = cJSON_GetObjectItem(kind_item, "percentage"); + cJSON* kind = cJSON_GetObjectItemCaseSensitive(kind_item, "kind"); + cJSON* count = cJSON_GetObjectItemCaseSensitive(kind_item, "count"); + cJSON* percentage = cJSON_GetObjectItemCaseSensitive(kind_item, "percentage"); if (kind && count && percentage) { // Format event kind (right-justified, minimum 5 chars wide with underscores) @@ -1767,9 +1767,9 @@ char* generate_stats_text(void) { // int rank = 1; // cJSON* pubkey_item = NULL; // cJSON_ArrayForEach(pubkey_item, top_pubkeys) { - // cJSON* pubkey = cJSON_GetObjectItem(pubkey_item, "pubkey"); - // cJSON* event_count = cJSON_GetObjectItem(pubkey_item, "event_count"); - // cJSON* percentage = cJSON_GetObjectItem(pubkey_item, "percentage"); + // cJSON* pubkey = cJSON_GetObjectItemCaseSensitive(pubkey_item, "pubkey"); + // cJSON* event_count = cJSON_GetObjectItemCaseSensitive(pubkey_item, "event_count"); + // cJSON* percentage = cJSON_GetObjectItemCaseSensitive(pubkey_item, "percentage"); // if (pubkey && event_count && percentage) { // const char* pubkey_str = cJSON_GetStringValue(pubkey); @@ -2457,7 +2457,7 @@ int handle_create_relay_event_command(cJSON* event, int kind, cJSON* event_data, } // Get request event ID for response correlation - cJSON* request_id_obj = cJSON_GetObjectItem(event, "id"); + cJSON* request_id_obj = cJSON_GetObjectItemCaseSensitive(event, "id"); if (!request_id_obj || !cJSON_IsString(request_id_obj)) { snprintf(error_message, error_size, "Missing request event ID"); return -1; @@ -2465,7 +2465,7 @@ int handle_create_relay_event_command(cJSON* event, int kind, cJSON* event_data, const char* request_id = cJSON_GetStringValue(request_id_obj); // Get sender pubkey for response - cJSON* sender_pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* sender_pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (!sender_pubkey_obj || !cJSON_IsString(sender_pubkey_obj)) { snprintf(error_message, error_size, "Missing sender pubkey"); return -1; @@ -2614,7 +2614,7 @@ cJSON* create_relay_dm_list_event(cJSON* dm_relays) { } // Extract relays array - cJSON* relays_array = cJSON_GetObjectItem(dm_relays, "relays"); + cJSON* relays_array = cJSON_GetObjectItemCaseSensitive(dm_relays, "relays"); if (relays_array && cJSON_IsArray(relays_array)) { cJSON* relay_item = NULL; cJSON_ArrayForEach(relay_item, relays_array) { @@ -2686,14 +2686,14 @@ cJSON* create_relay_list_event(cJSON* relays) { } // Extract relays array - cJSON* relays_array = cJSON_GetObjectItem(relays, "relays"); + cJSON* relays_array = cJSON_GetObjectItemCaseSensitive(relays, "relays"); if (relays_array && cJSON_IsArray(relays_array)) { cJSON* relay_item = NULL; cJSON_ArrayForEach(relay_item, relays_array) { if (cJSON_IsObject(relay_item)) { - cJSON* url = cJSON_GetObjectItem(relay_item, "url"); - cJSON* read = cJSON_GetObjectItem(relay_item, "read"); - cJSON* write = cJSON_GetObjectItem(relay_item, "write"); + cJSON* url = cJSON_GetObjectItemCaseSensitive(relay_item, "url"); + cJSON* read = cJSON_GetObjectItemCaseSensitive(relay_item, "read"); + cJSON* write = cJSON_GetObjectItemCaseSensitive(relay_item, "write"); if (url && cJSON_IsString(url)) { const char* relay_url = cJSON_GetStringValue(url); @@ -2752,7 +2752,7 @@ int handle_monitoring_command(cJSON* event, const char* command, char* error_mes } // Get request event ID for response correlation - cJSON* request_id_obj = cJSON_GetObjectItem(event, "id"); + cJSON* request_id_obj = cJSON_GetObjectItemCaseSensitive(event, "id"); if (!request_id_obj || !cJSON_IsString(request_id_obj)) { snprintf(error_message, error_size, "Missing request event ID"); return -1; @@ -2760,7 +2760,7 @@ int handle_monitoring_command(cJSON* event, const char* command, char* error_mes const char* request_id = cJSON_GetStringValue(request_id_obj); // Get sender pubkey for response - cJSON* sender_pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* sender_pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (!sender_pubkey_obj || !cJSON_IsString(sender_pubkey_obj)) { snprintf(error_message, error_size, "Missing sender pubkey"); return -1; diff --git a/src/config.c b/src/config.c index 1d18122..f62dedb 100644 --- a/src/config.c +++ b/src/config.c @@ -227,13 +227,13 @@ int store_config_event_in_database(const cJSON* event) { } // Get event fields - cJSON* id_obj = cJSON_GetObjectItem(event, "id"); - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); - cJSON* created_at_obj = cJSON_GetObjectItem(event, "created_at"); - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); - cJSON* content_obj = cJSON_GetObjectItem(event, "content"); - cJSON* sig_obj = cJSON_GetObjectItem(event, "sig"); - cJSON* tags_obj = cJSON_GetObjectItem(event, "tags"); + cJSON* id_obj = cJSON_GetObjectItemCaseSensitive(event, "id"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); + cJSON* created_at_obj = cJSON_GetObjectItemCaseSensitive(event, "created_at"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); + cJSON* content_obj = cJSON_GetObjectItemCaseSensitive(event, "content"); + cJSON* sig_obj = cJSON_GetObjectItemCaseSensitive(event, "sig"); + cJSON* tags_obj = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!id_obj || !pubkey_obj || !created_at_obj || !kind_obj || !content_obj || !sig_obj || !tags_obj) { return -1; @@ -665,8 +665,8 @@ cJSON* create_default_config_event(const unsigned char* admin_privkey_bytes, } // Log success information - cJSON* id_obj = cJSON_GetObjectItem(event, "id"); - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* id_obj = cJSON_GetObjectItemCaseSensitive(event, "id"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (id_obj && pubkey_obj) { // printf(" Event ID: %s\n", cJSON_GetStringValue(id_obj)); @@ -1273,7 +1273,7 @@ static int validate_configuration_event_fields(const cJSON* event, char* error_m } - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags || !cJSON_IsArray(tags)) { snprintf(error_msg, error_size, "missing or invalid tags array"); return -1; @@ -1337,8 +1337,8 @@ int process_configuration_event(const cJSON* event) { } // Validate event structure - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (!kind_obj || cJSON_GetNumberValue(kind_obj) != 33334) { DEBUG_ERROR("Invalid event kind for configuration"); @@ -1412,7 +1412,7 @@ extern void init_relay_info(void); static const char* get_config_value_from_event(const cJSON* event, const char* key) { if (!event || !key) return NULL; - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags || !cJSON_IsArray(tags)) return NULL; cJSON* tag = NULL; @@ -1957,7 +1957,7 @@ extern int is_authorized_admin_event(cJSON* event); // Process admin events (updated for Kind 23456) int process_admin_event_in_config(cJSON* event, char* error_message, size_t error_size, struct lws* wsi) { - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); if (!kind_obj || !cJSON_IsNumber(kind_obj)) { DEBUG_ERROR("Missing or invalid kind in admin event"); snprintf(error_message, error_size, "invalid: missing or invalid kind"); @@ -1982,7 +1982,7 @@ int process_admin_event_in_config(cJSON* event, char* error_message, size_t erro int process_admin_config_event(cJSON* event, char* error_message, size_t error_size) { // Parse tags to find query commands according to API specification - cJSON* tags_obj = cJSON_GetObjectItem(event, "tags"); + cJSON* tags_obj = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (tags_obj && cJSON_IsArray(tags_obj)) { cJSON* tag = NULL; cJSON_ArrayForEach(tag, tags_obj) { @@ -2072,7 +2072,7 @@ int process_admin_config_event(cJSON* event, char* error_message, size_t error_s // Handle Kind 23456 auth rules management int process_admin_auth_event(cJSON* event, char* error_message, size_t error_size, struct lws* wsi) { - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); int kind = kind_obj ? (int)cJSON_GetNumberValue(kind_obj) : 0; // Extract and log additional event details for debugging @@ -2447,7 +2447,7 @@ int wot_sync_from_admin_kind3(void) { const char* get_first_tag_name(cJSON* event) { if (!event) return NULL; - cJSON* tags_obj = cJSON_GetObjectItem(event, "tags"); + cJSON* tags_obj = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags_obj || !cJSON_IsArray(tags_obj)) return NULL; cJSON* first_tag = cJSON_GetArrayItem(tags_obj, 0); @@ -2465,7 +2465,7 @@ const char* get_first_tag_name(cJSON* event) { const char* get_tag_value(cJSON* event, const char* tag_name, int value_index) { if (!event || !tag_name) return NULL; - cJSON* tags_obj = cJSON_GetObjectItem(event, "tags"); + cJSON* tags_obj = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags_obj || !cJSON_IsArray(tags_obj)) return NULL; cJSON* tag = NULL; @@ -2575,8 +2575,8 @@ cJSON* create_admin_response_event(const char* encrypted_content, const char* re } // Log success information - cJSON* id_obj = cJSON_GetObjectItem(response_event, "id"); - cJSON* pubkey_obj = cJSON_GetObjectItem(response_event, "pubkey"); + cJSON* id_obj = cJSON_GetObjectItemCaseSensitive(response_event, "id"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(response_event, "pubkey"); if (id_obj && pubkey_obj) { // printf(" Event ID: %s\n", cJSON_GetStringValue(id_obj)); @@ -2689,7 +2689,7 @@ int send_admin_response_event(const cJSON* response_data, const char* recipient_ return -1; } - cJSON* id_obj = cJSON_GetObjectItem(response_event, "id"); + cJSON* id_obj = cJSON_GetObjectItemCaseSensitive(response_event, "id"); if (id_obj) { // printf(" Event ID: %s\n", cJSON_GetStringValue(id_obj)); } @@ -2783,7 +2783,7 @@ int handle_kind_23456_unified(cJSON* event, char* error_message, size_t error_si } // Verify the event sender is the authorized admin - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (!pubkey_obj || !cJSON_IsString(pubkey_obj)) { DEBUG_ERROR("invalid: missing sender pubkey in event"); snprintf(error_message, error_size, "invalid: missing sender pubkey in event"); @@ -2808,7 +2808,7 @@ int handle_kind_23456_unified(cJSON* event, char* error_message, size_t error_si } // Check if content is encrypted (NIP-44) - cJSON* content_obj = cJSON_GetObjectItem(event, "content"); + cJSON* content_obj = cJSON_GetObjectItemCaseSensitive(event, "content"); if (!content_obj || !cJSON_IsString(content_obj)) { DEBUG_ERROR("invalid: missing or invalid content"); snprintf(error_message, error_size, "invalid: missing or invalid content"); @@ -2830,7 +2830,7 @@ int handle_kind_23456_unified(cJSON* event, char* error_message, size_t error_si } // Get sender's pubkey from the event for NIP-44 decryption - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (!pubkey_obj || !cJSON_IsString(pubkey_obj)) { DEBUG_ERROR("invalid: missing sender pubkey in event"); free(relay_privkey); @@ -2961,7 +2961,7 @@ int handle_kind_23456_unified(cJSON* event, char* error_message, size_t error_si } // Add existing tags - cJSON* existing_tags = cJSON_GetObjectItem(event, "tags"); + cJSON* existing_tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (existing_tags && cJSON_IsArray(existing_tags)) { cJSON* tag = NULL; cJSON_ArrayForEach(tag, existing_tags) { @@ -3149,7 +3149,7 @@ int handle_auth_query_unified(cJSON* event, const char* query_type, char* error_ cJSON* response = build_query_response(mapped_query_type, results_array, rule_count); if (response) { // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3264,7 +3264,7 @@ int handle_config_query_unified(cJSON* event, const char* query_type, char* erro cJSON* response = build_query_response(mapped_query_type, results_array, config_count); if (response) { // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3360,7 +3360,7 @@ int handle_config_set_unified(cJSON* event, const char* config_key, const char* // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3424,7 +3424,7 @@ int handle_system_command_unified(cJSON* event, const char* command, char* error // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3501,7 +3501,7 @@ int handle_system_command_unified(cJSON* event, const char* command, char* error // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3562,7 +3562,7 @@ int handle_system_command_unified(cJSON* event, const char* command, char* error printf("Cache status: Not used (direct database queries)\n"); // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3594,7 +3594,7 @@ int handle_system_command_unified(cJSON* event, const char* command, char* error printf("Sending acknowledgment and initiating shutdown...\n"); // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3618,7 +3618,7 @@ int handle_system_command_unified(cJSON* event, const char* command, char* error } else if (strcmp(command, "wot_status") == 0) { // Get admin pubkey from event - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3676,7 +3676,7 @@ int handle_system_command_unified(cJSON* event, const char* command, char* error } else if (strcmp(command, "wot_sync") == 0) { // Get admin pubkey from event - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3738,7 +3738,7 @@ int handle_system_command_unified(cJSON* event, const char* command, char* error int handle_auth_rule_modification_unified(cJSON* event, char* error_message, size_t error_size, struct lws* wsi) { // Suppress unused parameter warning (void)wsi; - cJSON* tags_obj = cJSON_GetObjectItem(event, "tags"); + cJSON* tags_obj = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags_obj || !cJSON_IsArray(tags_obj)) { snprintf(error_message, error_size, "invalid: auth rule event must have tags"); return -1; @@ -3821,7 +3821,7 @@ int handle_auth_rule_modification_unified(cJSON* event, char* error_message, siz printf("Processed %d auth rule modifications\n", rules_processed); // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -3951,7 +3951,7 @@ int handle_stats_query_unified(cJSON* event, char* error_message, size_t error_s // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -4019,7 +4019,7 @@ int handle_config_update_unified(cJSON* event, char* error_message, size_t error // Extract config objects array from synthetic tags created by NIP-44 decryption // The decryption process creates synthetic tags like: ["config_update", [config_objects]] - cJSON* tags_obj = cJSON_GetObjectItem(event, "tags"); + cJSON* tags_obj = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags_obj || !cJSON_IsArray(tags_obj)) { snprintf(error_message, error_size, "invalid: config update event must have tags"); return -1; @@ -4100,10 +4100,10 @@ int handle_config_update_unified(cJSON* event, char* error_message, size_t error } // Extract required fields from config object - cJSON* key_obj = cJSON_GetObjectItem(config_obj, "key"); - cJSON* value_obj = cJSON_GetObjectItem(config_obj, "value"); - cJSON* data_type_obj = cJSON_GetObjectItem(config_obj, "data_type"); - cJSON* category_obj = cJSON_GetObjectItem(config_obj, "category"); + cJSON* key_obj = cJSON_GetObjectItemCaseSensitive(config_obj, "key"); + cJSON* value_obj = cJSON_GetObjectItemCaseSensitive(config_obj, "value"); + cJSON* data_type_obj = cJSON_GetObjectItemCaseSensitive(config_obj, "data_type"); + cJSON* category_obj = cJSON_GetObjectItemCaseSensitive(config_obj, "category"); if (!key_obj || !cJSON_IsString(key_obj) || !value_obj || !cJSON_IsString(value_obj)) { @@ -4300,7 +4300,7 @@ int handle_config_update_unified(cJSON* event, char* error_message, size_t error cJSON_AddItemToObject(error_response, "data", processed_configs); // Get admin pubkey from event for error response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (admin_pubkey) { @@ -4328,7 +4328,7 @@ int handle_config_update_unified(cJSON* event, char* error_message, size_t error cJSON_AddItemToObject(error_response, "data", processed_configs); // Get admin pubkey from event for error response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (admin_pubkey) { @@ -4357,7 +4357,7 @@ int handle_config_update_unified(cJSON* event, char* error_message, size_t error // Get admin pubkey from event for response - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* admin_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!admin_pubkey) { @@ -4763,7 +4763,7 @@ int populate_config_table_from_event(const cJSON* event) { DEBUG_INFO("Populating config table from configuration event..."); - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags || !cJSON_IsArray(tags)) { DEBUG_ERROR("Configuration event missing tags array"); return -1; @@ -4912,13 +4912,13 @@ int process_startup_config_event(const cJSON* event) { // Validate event structure first - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); if (!kind_obj || cJSON_GetNumberValue(kind_obj) != 33334) { DEBUG_ERROR("Invalid event kind for startup configuration"); return -1; } - cJSON* tags_obj = cJSON_GetObjectItem(event, "tags"); + cJSON* tags_obj = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags_obj || !cJSON_IsArray(tags_obj)) { DEBUG_ERROR("Startup configuration event missing tags"); return -1; @@ -5114,7 +5114,7 @@ int req_filter_requests_config_events(const cJSON* filter) { return 0; } - cJSON* kinds = cJSON_GetObjectItem(filter, "kinds"); + cJSON* kinds = cJSON_GetObjectItemCaseSensitive(filter, "kinds"); if (!kinds || !cJSON_IsArray(kinds)) { return 0; } diff --git a/src/dm_admin.c b/src/dm_admin.c index 34fa1c9..6fa8f37 100644 --- a/src/dm_admin.c +++ b/src/dm_admin.c @@ -141,7 +141,7 @@ int process_dm_admin_command(cJSON* command_array, cJSON* event, char* error_mes cJSON_AddItemToArray(synthetic_tags, command_tag); // Add existing event tags - cJSON* existing_tags = cJSON_GetObjectItem(event, "tags"); + cJSON* existing_tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (existing_tags && cJSON_IsArray(existing_tags)) { cJSON* tag = NULL; cJSON_ArrayForEach(tag, existing_tags) { @@ -304,7 +304,7 @@ cJSON* process_nip17_admin_message(cJSON* gift_wrap_event, char* error_message, // Only create a generic response for other command types that don't handle their own responses if (result == 0) { // Extract content to check if it's a plain text command - cJSON* content_obj = cJSON_GetObjectItem(inner_dm, "content"); + cJSON* content_obj = cJSON_GetObjectItemCaseSensitive(inner_dm, "content"); if (content_obj && cJSON_IsString(content_obj)) { const char* dm_content = cJSON_GetStringValue(content_obj); @@ -347,7 +347,7 @@ cJSON* process_nip17_admin_message(cJSON* gift_wrap_event, char* error_message, return NULL; // Get sender pubkey for response from the decrypted DM event - cJSON* sender_pubkey_obj = cJSON_GetObjectItem(inner_dm, "pubkey"); + cJSON* sender_pubkey_obj = cJSON_GetObjectItemCaseSensitive(inner_dm, "pubkey"); if (sender_pubkey_obj && cJSON_IsString(sender_pubkey_obj)) { const char* sender_pubkey = cJSON_GetStringValue(sender_pubkey_obj); @@ -439,13 +439,13 @@ int is_nip17_gift_wrap_for_relay(cJSON* event) { } // Check kind - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); if (!kind_obj || !cJSON_IsNumber(kind_obj) || (int)cJSON_GetNumberValue(kind_obj) != 1059) { return 0; } // Check tags for "p" tag with relay pubkey - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags || !cJSON_IsArray(tags)) { return 0; } @@ -484,7 +484,7 @@ int process_nip17_admin_command(cJSON* dm_event, char* error_message, size_t err DEBUG_INFO("DM_ADMIN: Processing NIP-17 admin command from decrypted DM"); // Extract content from DM - cJSON* content_obj = cJSON_GetObjectItem(dm_event, "content"); + cJSON* content_obj = cJSON_GetObjectItemCaseSensitive(dm_event, "content"); if (!content_obj || !cJSON_IsString(content_obj)) { DEBUG_INFO("DM_ADMIN: DM missing content field"); strncpy(error_message, "NIP-17: DM missing content", error_size - 1); @@ -495,7 +495,7 @@ int process_nip17_admin_command(cJSON* dm_event, char* error_message, size_t err DEBUG_INFO("DM_ADMIN: Extracted DM content: %.100s%s", dm_content, strlen(dm_content) > 100 ? "..." : ""); // Check if sender is admin before processing any commands - cJSON* sender_pubkey_obj = cJSON_GetObjectItem(dm_event, "pubkey"); + cJSON* sender_pubkey_obj = cJSON_GetObjectItemCaseSensitive(dm_event, "pubkey"); if (!sender_pubkey_obj || !cJSON_IsString(sender_pubkey_obj)) { DEBUG_INFO("DM_ADMIN: DM missing sender pubkey - treating as user DM"); return 0; // Not an error, just treat as user DM @@ -804,7 +804,7 @@ int process_nip17_admin_command(cJSON* dm_event, char* error_message, size_t err if (cJSON_IsString(first_item) && strcmp(cJSON_GetStringValue(first_item), "stats") == 0) { DEBUG_INFO("DM_ADMIN: Processing JSON stats command"); // Get sender pubkey for response - cJSON* sender_pubkey_obj = cJSON_GetObjectItem(dm_event, "pubkey"); + cJSON* sender_pubkey_obj = cJSON_GetObjectItemCaseSensitive(dm_event, "pubkey"); if (!sender_pubkey_obj || !cJSON_IsString(sender_pubkey_obj)) { cJSON_Delete(command_array); DEBUG_INFO("DM_ADMIN: DM missing sender pubkey for stats command"); @@ -846,13 +846,13 @@ int process_nip17_admin_command(cJSON* dm_event, char* error_message, size_t err cJSON_AddStringToObject(synthetic_event, "content", dm_content); // Copy pubkey from DM - cJSON* pubkey_obj = cJSON_GetObjectItem(dm_event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(dm_event, "pubkey"); if (pubkey_obj && cJSON_IsString(pubkey_obj)) { cJSON_AddStringToObject(synthetic_event, "pubkey", cJSON_GetStringValue(pubkey_obj)); } // Copy tags from DM - cJSON* tags = cJSON_GetObjectItem(dm_event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(dm_event, "tags"); if (tags) { cJSON_AddItemToObject(synthetic_event, "tags", cJSON_Duplicate(tags, 1)); } diff --git a/src/main.c b/src/main.c index b952599..8eb6b14 100644 --- a/src/main.c +++ b/src/main.c @@ -739,13 +739,13 @@ int store_event(cJSON* event) { } // Extract event fields - cJSON* id = cJSON_GetObjectItem(event, "id"); - cJSON* pubkey = cJSON_GetObjectItem(event, "pubkey"); - cJSON* created_at = cJSON_GetObjectItem(event, "created_at"); - cJSON* kind = cJSON_GetObjectItem(event, "kind"); - cJSON* content = cJSON_GetObjectItem(event, "content"); - cJSON* sig = cJSON_GetObjectItem(event, "sig"); - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* id = cJSON_GetObjectItemCaseSensitive(event, "id"); + cJSON* pubkey = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); + cJSON* created_at = cJSON_GetObjectItemCaseSensitive(event, "created_at"); + cJSON* kind = cJSON_GetObjectItemCaseSensitive(event, "kind"); + cJSON* content = cJSON_GetObjectItemCaseSensitive(event, "content"); + cJSON* sig = cJSON_GetObjectItemCaseSensitive(event, "sig"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!id || !pubkey || !created_at || !kind || !content || !sig) { DEBUG_ERROR("Invalid event - missing required fields"); @@ -863,8 +863,8 @@ int store_event(cJSON* event) { store_event_tags(cJSON_GetStringValue(id), tags); // Check if this is a kind 3 event from the admin — trigger WoT sync - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (kind_obj && pubkey_obj && cJSON_GetNumberValue(kind_obj) == 3) { int wot_level = get_config_int("wot_enabled", 0); if (wot_level > 0) { @@ -1005,7 +1005,7 @@ static int is_only_kind_99999_request(cJSON* filters) { return 0; } - cJSON* kinds = cJSON_GetObjectItem(filter, "kinds"); + cJSON* kinds = cJSON_GetObjectItemCaseSensitive(filter, "kinds"); if (!kinds || !cJSON_IsArray(kinds)) { // Filter has no kinds or kinds is not an array - not a pure 99999 request return 0; @@ -1256,7 +1256,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru // after retrieving events to ensure compatibility with all SQLite versions // Handle kinds filter - cJSON* kinds = cJSON_GetObjectItem(filter, "kinds"); + cJSON* kinds = cJSON_GetObjectItemCaseSensitive(filter, "kinds"); if (kinds && cJSON_IsArray(kinds)) { int kind_count = cJSON_GetArraySize(kinds); if (kind_count > 0) { @@ -1284,7 +1284,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru } // Handle authors filter - cJSON* authors = cJSON_GetObjectItem(filter, "authors"); + cJSON* authors = cJSON_GetObjectItemCaseSensitive(filter, "authors"); if (authors && cJSON_IsArray(authors)) { int author_count = 0; // Count valid authors @@ -1324,7 +1324,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru } // Handle ids filter - cJSON* ids = cJSON_GetObjectItem(filter, "ids"); + cJSON* ids = cJSON_GetObjectItemCaseSensitive(filter, "ids"); if (ids && cJSON_IsArray(ids)) { int id_count = 0; // Count valid ids @@ -1414,7 +1414,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru } // Handle search filter (NIP-50) - cJSON* search = cJSON_GetObjectItem(filter, "search"); + cJSON* search = cJSON_GetObjectItemCaseSensitive(filter, "search"); if (search && cJSON_IsString(search)) { const char* search_term = cJSON_GetStringValue(search); if (search_term && strlen(search_term) > 0) { @@ -1442,7 +1442,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru } // Handle since filter - cJSON* since = cJSON_GetObjectItem(filter, "since"); + cJSON* since = cJSON_GetObjectItemCaseSensitive(filter, "since"); if (since && cJSON_IsNumber(since)) { snprintf(sql_ptr, remaining, " AND created_at >= %ld", (long)cJSON_GetNumberValue(since)); sql_ptr += strlen(sql_ptr); @@ -1450,7 +1450,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru } // Handle until filter - cJSON* until = cJSON_GetObjectItem(filter, "until"); + cJSON* until = cJSON_GetObjectItemCaseSensitive(filter, "until"); if (until && cJSON_IsNumber(until)) { snprintf(sql_ptr, remaining, " AND created_at <= %ld", (long)cJSON_GetNumberValue(until)); sql_ptr += strlen(sql_ptr); @@ -1463,7 +1463,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru remaining = sizeof(sql) - strlen(sql); // Handle limit filter - cJSON* limit = cJSON_GetObjectItem(filter, "limit"); + cJSON* limit = cJSON_GetObjectItemCaseSensitive(filter, "limit"); if (limit && cJSON_IsNumber(limit)) { int limit_val = (int)cJSON_GetNumberValue(limit); if (limit_val > 0 && limit_val <= 5000) { @@ -1606,7 +1606,7 @@ int is_authorized_admin_event(cJSON* event, char* error_buffer, size_t error_buf // Step 1: Verify event kind is admin type - cJSON *kind_json = cJSON_GetObjectItem(event, "kind"); + cJSON *kind_json = cJSON_GetObjectItemCaseSensitive(event, "kind"); if (!kind_json || !cJSON_IsNumber(kind_json)) { snprintf(error_buffer, error_buffer_size, "Missing or invalid event kind"); return -1; @@ -1619,7 +1619,7 @@ int is_authorized_admin_event(cJSON* event, char* error_buffer, size_t error_buf } // Step 2: Check if event targets this relay (look for 'p' tag with our relay pubkey) - cJSON *tags = cJSON_GetObjectItem(event, "tags"); + cJSON *tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags || !cJSON_IsArray(tags)) { // No tags array - treat as regular event for different relay snprintf(error_buffer, error_buffer_size, "Admin event not targeting this relay (no tags)"); @@ -1654,7 +1654,7 @@ int is_authorized_admin_event(cJSON* event, char* error_buffer, size_t error_buf } // Step 3: Verify admin signature authorization - cJSON *pubkey_json = cJSON_GetObjectItem(event, "pubkey"); + cJSON *pubkey_json = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (!pubkey_json || !cJSON_IsString(pubkey_json)) { DEBUG_WARN("Unauthorized admin event attempt: missing or invalid pubkey"); snprintf(error_buffer, error_buffer_size, "Unauthorized admin event attempt: missing pubkey"); diff --git a/src/main.h b/src/main.h index 4355b3b..ccd6358 100644 --- a/src/main.h +++ b/src/main.h @@ -13,8 +13,8 @@ // Using CRELAY_ prefix to avoid conflicts with nostr_core_lib VERSION macros #define CRELAY_VERSION_MAJOR 1 #define CRELAY_VERSION_MINOR 2 -#define CRELAY_VERSION_PATCH 8 -#define CRELAY_VERSION "v1.2.8" +#define CRELAY_VERSION_PATCH 9 +#define CRELAY_VERSION "v1.2.9" // Relay metadata (authoritative source for NIP-11 information) #define RELAY_NAME "C-Relay" diff --git a/src/nip009.c b/src/nip009.c index 3520dba..020ff96 100644 --- a/src/nip009.c +++ b/src/nip009.c @@ -33,12 +33,12 @@ int handle_deletion_request(cJSON* event, char* error_message, size_t error_size } // Extract event details - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); - cJSON* created_at_obj = cJSON_GetObjectItem(event, "created_at"); - cJSON* tags_obj = cJSON_GetObjectItem(event, "tags"); - cJSON* content_obj = cJSON_GetObjectItem(event, "content"); - cJSON* event_id_obj = cJSON_GetObjectItem(event, "id"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); + cJSON* created_at_obj = cJSON_GetObjectItemCaseSensitive(event, "created_at"); + cJSON* tags_obj = cJSON_GetObjectItemCaseSensitive(event, "tags"); + cJSON* content_obj = cJSON_GetObjectItemCaseSensitive(event, "content"); + cJSON* event_id_obj = cJSON_GetObjectItemCaseSensitive(event, "id"); if (!kind_obj || !pubkey_obj || !created_at_obj || !tags_obj || !event_id_obj) { snprintf(error_message, error_size, "invalid: incomplete deletion request"); diff --git a/src/nip013.c b/src/nip013.c index e121d1b..bcb9cc2 100644 --- a/src/nip013.c +++ b/src/nip013.c @@ -55,7 +55,7 @@ int validate_event_pow(cJSON* event, char* error_message, size_t error_size) { // If min_pow_difficulty is 0, only validate events that have nonce tags // This allows events without PoW when difficulty requirement is 0 if (min_pow_difficulty == 0) { - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); int has_nonce_tag = 0; if (tags && cJSON_IsArray(tags)) { diff --git a/src/nip040.c b/src/nip040.c index 5962c1c..d592724 100644 --- a/src/nip040.c +++ b/src/nip040.c @@ -114,7 +114,7 @@ int is_event_expired(cJSON* event, time_t current_time) { return 0; // Invalid event, not expired } - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); long expiration_ts = extract_expiration_timestamp(tags); if (expiration_ts == 0) { @@ -140,7 +140,7 @@ int validate_event_expiration(cJSON* event, char* error_message, size_t error_si time_t current_time = time(NULL); if (is_event_expired(event, current_time)) { if (g_expiration_config.strict_mode) { - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); long expiration_ts = extract_expiration_timestamp(tags); snprintf(error_message, error_size, diff --git a/src/nip042.c b/src/nip042.c index ae1830d..35436a6 100644 --- a/src/nip042.c +++ b/src/nip042.c @@ -99,7 +99,7 @@ void handle_nip42_auth_signed_event(struct lws* wsi, struct per_session_data* ps char authenticated_pubkey[65] = {0}; if (result == 0) { // Extract pubkey from the auth event - cJSON* pubkey_json = cJSON_GetObjectItem(auth_event, "pubkey"); + cJSON* pubkey_json = cJSON_GetObjectItemCaseSensitive(auth_event, "pubkey"); if (pubkey_json && cJSON_IsString(pubkey_json)) { const char* pubkey_str = cJSON_GetStringValue(pubkey_json); if (pubkey_str && strlen(pubkey_str) == 64) { diff --git a/src/request_validator.c b/src/request_validator.c index 64cbde5..8862758 100644 --- a/src/request_validator.c +++ b/src/request_validator.c @@ -252,13 +252,13 @@ int nostr_validate_unified_request(const char* json_string, size_t json_length) } // 4. Validate basic event structure - cJSON *id = cJSON_GetObjectItem(event, "id"); - cJSON *pubkey = cJSON_GetObjectItem(event, "pubkey"); - cJSON *created_at = cJSON_GetObjectItem(event, "created_at"); - cJSON *kind = cJSON_GetObjectItem(event, "kind"); - cJSON *tags = cJSON_GetObjectItem(event, "tags"); - cJSON *content = cJSON_GetObjectItem(event, "content"); - cJSON *sig = cJSON_GetObjectItem(event, "sig"); + cJSON *id = cJSON_GetObjectItemCaseSensitive(event, "id"); + cJSON *pubkey = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); + cJSON *created_at = cJSON_GetObjectItemCaseSensitive(event, "created_at"); + cJSON *kind = cJSON_GetObjectItemCaseSensitive(event, "kind"); + cJSON *tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); + cJSON *content = cJSON_GetObjectItemCaseSensitive(event, "content"); + cJSON *sig = cJSON_GetObjectItemCaseSensitive(event, "sig"); if (!id || !cJSON_IsString(id) || !pubkey || !cJSON_IsString(pubkey) || @@ -380,7 +380,7 @@ int nostr_validate_unified_request(const char* json_string, size_t json_length) // Always check expiration tags if present (following NIP-40 specification) cJSON *expiration_tag = NULL; - cJSON *tags_array = cJSON_GetObjectItem(event, "tags"); + cJSON *tags_array = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (tags_array && cJSON_IsArray(tags_array)) { cJSON *tag = NULL; @@ -818,7 +818,7 @@ int nostr_nip42_verify_auth_event(cJSON *event, const char *challenge_id, } // Check if event has the required tags for NIP-42 - cJSON *tags = cJSON_GetObjectItem(event, "tags"); + cJSON *tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!tags || !cJSON_IsArray(tags)) { return NOSTR_ERROR_NIP42_AUTH_EVENT_INVALID; } @@ -896,7 +896,7 @@ int nostr_nip42_verify_auth_event(cJSON *event, const char *challenge_id, } // Check created_at timestamp for reasonable bounds - cJSON *created_at_json = cJSON_GetObjectItem(event, "created_at"); + cJSON *created_at_json = cJSON_GetObjectItemCaseSensitive(event, "created_at"); if (created_at_json && cJSON_IsNumber(created_at_json)) { time_t created_at = (time_t)cJSON_GetNumberValue(created_at_json); if (abs((int)(now - created_at)) > time_tolerance_seconds) { diff --git a/src/subscriptions.c b/src/subscriptions.c index 3b37d9a..d83bb37 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -192,32 +192,32 @@ subscription_filter_t* create_subscription_filter(cJSON* filter_json) { } // Copy filter criteria - cJSON* kinds = cJSON_GetObjectItem(filter_json, "kinds"); + cJSON* kinds = cJSON_GetObjectItemCaseSensitive(filter_json, "kinds"); if (kinds && cJSON_IsArray(kinds)) { filter->kinds = cJSON_Duplicate(kinds, 1); } - cJSON* authors = cJSON_GetObjectItem(filter_json, "authors"); + cJSON* authors = cJSON_GetObjectItemCaseSensitive(filter_json, "authors"); if (authors && cJSON_IsArray(authors)) { filter->authors = cJSON_Duplicate(authors, 1); } - cJSON* ids = cJSON_GetObjectItem(filter_json, "ids"); + cJSON* ids = cJSON_GetObjectItemCaseSensitive(filter_json, "ids"); if (ids && cJSON_IsArray(ids)) { filter->ids = cJSON_Duplicate(ids, 1); } - cJSON* since = cJSON_GetObjectItem(filter_json, "since"); + cJSON* since = cJSON_GetObjectItemCaseSensitive(filter_json, "since"); if (since && cJSON_IsNumber(since)) { filter->since = (long)cJSON_GetNumberValue(since); } - cJSON* until = cJSON_GetObjectItem(filter_json, "until"); + cJSON* until = cJSON_GetObjectItemCaseSensitive(filter_json, "until"); if (until && cJSON_IsNumber(until)) { filter->until = (long)cJSON_GetNumberValue(until); } - cJSON* limit = cJSON_GetObjectItem(filter_json, "limit"); + cJSON* limit = cJSON_GetObjectItemCaseSensitive(filter_json, "limit"); if (limit && cJSON_IsNumber(limit)) { filter->limit = (int)cJSON_GetNumberValue(limit); } @@ -532,9 +532,9 @@ int event_matches_filter(cJSON* event, subscription_filter_t* filter) { } // Debug: Log event details being tested - cJSON* event_kind_obj = cJSON_GetObjectItem(event, "kind"); - cJSON* event_id_obj = cJSON_GetObjectItem(event, "id"); - cJSON* event_created_at_obj = cJSON_GetObjectItem(event, "created_at"); + cJSON* event_kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); + cJSON* event_id_obj = cJSON_GetObjectItemCaseSensitive(event, "id"); + cJSON* event_created_at_obj = cJSON_GetObjectItemCaseSensitive(event, "created_at"); DEBUG_TRACE("FILTER_MATCH: Testing event kind=%d id=%.8s created_at=%ld", event_kind_obj ? (int)cJSON_GetNumberValue(event_kind_obj) : -1, @@ -545,7 +545,7 @@ int event_matches_filter(cJSON* event, subscription_filter_t* filter) { if (filter->kinds && cJSON_IsArray(filter->kinds)) { DEBUG_TRACE("FILTER_MATCH: Checking kinds filter with %d kinds", cJSON_GetArraySize(filter->kinds)); - cJSON* event_kind = cJSON_GetObjectItem(event, "kind"); + cJSON* event_kind = cJSON_GetObjectItemCaseSensitive(event, "kind"); if (!event_kind || !cJSON_IsNumber(event_kind)) { DEBUG_WARN("FILTER_MATCH: Event has no valid kind field"); return 0; @@ -577,7 +577,7 @@ int event_matches_filter(cJSON* event, subscription_filter_t* filter) { // Check authors filter if (filter->authors && cJSON_IsArray(filter->authors)) { - cJSON* event_pubkey = cJSON_GetObjectItem(event, "pubkey"); + cJSON* event_pubkey = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); if (!event_pubkey || !cJSON_IsString(event_pubkey)) { return 0; } @@ -604,7 +604,7 @@ int event_matches_filter(cJSON* event, subscription_filter_t* filter) { // Check IDs filter if (filter->ids && cJSON_IsArray(filter->ids)) { - cJSON* event_id = cJSON_GetObjectItem(event, "id"); + cJSON* event_id = cJSON_GetObjectItemCaseSensitive(event, "id"); if (!event_id || !cJSON_IsString(event_id)) { return 0; } @@ -631,7 +631,7 @@ int event_matches_filter(cJSON* event, subscription_filter_t* filter) { // Check since filter if (filter->since > 0) { - cJSON* event_created_at = cJSON_GetObjectItem(event, "created_at"); + cJSON* event_created_at = cJSON_GetObjectItemCaseSensitive(event, "created_at"); if (!event_created_at || !cJSON_IsNumber(event_created_at)) { DEBUG_WARN("FILTER_MATCH: Event has no valid created_at field"); return 0; @@ -650,7 +650,7 @@ int event_matches_filter(cJSON* event, subscription_filter_t* filter) { // Check until filter if (filter->until > 0) { - cJSON* event_created_at = cJSON_GetObjectItem(event, "created_at"); + cJSON* event_created_at = cJSON_GetObjectItemCaseSensitive(event, "created_at"); if (!event_created_at || !cJSON_IsNumber(event_created_at)) { return 0; } @@ -663,7 +663,7 @@ int event_matches_filter(cJSON* event, subscription_filter_t* filter) { // Check tag filters (e.g., #e, #p tags) if (filter->tag_filters && cJSON_IsObject(filter->tag_filters)) { - cJSON* event_tags = cJSON_GetObjectItem(event, "tags"); + cJSON* event_tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (!event_tags || !cJSON_IsArray(event_tags)) { return 0; // Event has no tags but filter requires tags } @@ -777,9 +777,9 @@ int broadcast_event_to_subscriptions(cJSON* event) { int broadcasts = 0; // Log event details - cJSON* event_kind = cJSON_GetObjectItem(event, "kind"); - cJSON* event_id = cJSON_GetObjectItem(event, "id"); - cJSON* event_created_at = cJSON_GetObjectItem(event, "created_at"); + cJSON* event_kind = cJSON_GetObjectItemCaseSensitive(event, "kind"); + cJSON* event_id = cJSON_GetObjectItemCaseSensitive(event, "id"); + cJSON* event_created_at = cJSON_GetObjectItemCaseSensitive(event, "created_at"); DEBUG_TRACE("BROADCAST: Event kind=%d id=%.8s created_at=%ld", event_kind ? (int)cJSON_GetNumberValue(event_kind) : -1, @@ -876,12 +876,12 @@ int broadcast_event_to_subscriptions(cJSON* event) { // Serialize event once per subscription using pre-serialized event_json if available, // otherwise fall back to cJSON serialization. // Format: ["EVENT","",] - cJSON* event_id_obj = cJSON_GetObjectItem(event, "id"); + cJSON* event_id_obj = cJSON_GetObjectItemCaseSensitive(event, "id"); const char* event_json_str = NULL; char* event_json_allocated = NULL; // Try to get pre-serialized event_json field first (fast path) - cJSON* event_json_field = cJSON_GetObjectItem(event, "event_json"); + cJSON* event_json_field = cJSON_GetObjectItemCaseSensitive(event, "event_json"); if (event_json_field && cJSON_IsString(event_json_field)) { event_json_str = cJSON_GetStringValue(event_json_field); } else { @@ -1473,7 +1473,7 @@ int validate_filter_values(cJSON* filter_json, char* error_message, size_t error int has_kind_99999 = 0; // Track if we encounter kind 99999 (NDK ping) // Validate kinds array - cJSON* kinds = cJSON_GetObjectItem(filter_json, "kinds"); + cJSON* kinds = cJSON_GetObjectItemCaseSensitive(filter_json, "kinds"); if (kinds) { if (!cJSON_IsArray(kinds)) { snprintf(error_message, error_size, "kinds must be an array"); @@ -1516,7 +1516,7 @@ int validate_filter_values(cJSON* filter_json, char* error_message, size_t error } // Validate authors array - cJSON* authors = cJSON_GetObjectItem(filter_json, "authors"); + cJSON* authors = cJSON_GetObjectItemCaseSensitive(filter_json, "authors"); if (authors) { if (!cJSON_IsArray(authors)) { snprintf(error_message, error_size, "authors must be an array"); @@ -1556,7 +1556,7 @@ int validate_filter_values(cJSON* filter_json, char* error_message, size_t error } // Validate ids array - cJSON* ids = cJSON_GetObjectItem(filter_json, "ids"); + cJSON* ids = cJSON_GetObjectItemCaseSensitive(filter_json, "ids"); if (ids) { if (!cJSON_IsArray(ids)) { snprintf(error_message, error_size, "ids must be an array"); @@ -1598,7 +1598,7 @@ int validate_filter_values(cJSON* filter_json, char* error_message, size_t error // Validate since/until timestamps long since_val = 0, until_val = 0; - cJSON* since = cJSON_GetObjectItem(filter_json, "since"); + cJSON* since = cJSON_GetObjectItemCaseSensitive(filter_json, "since"); if (since) { if (!cJSON_IsNumber(since)) { snprintf(error_message, error_size, "since must be a number"); @@ -1607,7 +1607,7 @@ int validate_filter_values(cJSON* filter_json, char* error_message, size_t error since_val = (long)cJSON_GetNumberValue(since); } - cJSON* until = cJSON_GetObjectItem(filter_json, "until"); + cJSON* until = cJSON_GetObjectItemCaseSensitive(filter_json, "until"); if (until) { if (!cJSON_IsNumber(until)) { snprintf(error_message, error_size, "until must be a number"); @@ -1621,7 +1621,7 @@ int validate_filter_values(cJSON* filter_json, char* error_message, size_t error } // Validate limit - cJSON* limit = cJSON_GetObjectItem(filter_json, "limit"); + cJSON* limit = cJSON_GetObjectItemCaseSensitive(filter_json, "limit"); if (limit) { if (!cJSON_IsNumber(limit)) { snprintf(error_message, error_size, "limit must be a number"); @@ -1635,7 +1635,7 @@ int validate_filter_values(cJSON* filter_json, char* error_message, size_t error } // Validate search term - cJSON* search = cJSON_GetObjectItem(filter_json, "search"); + cJSON* search = cJSON_GetObjectItemCaseSensitive(filter_json, "search"); if (search) { if (!cJSON_IsString(search)) { snprintf(error_message, error_size, "search must be a string"); diff --git a/src/websockets.c b/src/websockets.c index 587757e..f8abd15 100644 --- a/src/websockets.c +++ b/src/websockets.c @@ -654,7 +654,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso if (result == 0) { // Check if event has protected tag ["-"] int is_protected_event = 0; - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (tags && cJSON_IsArray(tags)) { cJSON* tag = NULL; cJSON_ArrayForEach(tag, tags) { @@ -681,7 +681,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso DEBUG_WARN("Protected event rejected: protected events not enabled"); } else { // Protected events enabled - check authentication - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* event_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!pss || !pss->authenticated || @@ -698,7 +698,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso // Check for admin events (kind 23456) and intercept them if (result == 0) { - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); if (kind_obj && cJSON_IsNumber(kind_obj)) { int event_kind = (int)cJSON_GetNumberValue(kind_obj); @@ -890,7 +890,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso } // Send OK response - cJSON* event_id = cJSON_GetObjectItem(event, "id"); + cJSON* event_id = cJSON_GetObjectItemCaseSensitive(event, "id"); if (event_id && cJSON_IsString(event_id)) { cJSON* response = cJSON_CreateArray(); cJSON_AddItemToArray(response, cJSON_CreateString("OK")); @@ -1251,11 +1251,11 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso cJSON* event_obj = cJSON_GetArrayItem(json, 1); if (event_obj && cJSON_IsObject(event_obj)) { // Extract event kind for kind-specific NIP-42 authentication check - cJSON* kind_obj = cJSON_GetObjectItem(event_obj, "kind"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event_obj, "kind"); int event_kind = kind_obj && cJSON_IsNumber(kind_obj) ? (int)cJSON_GetNumberValue(kind_obj) : -1; // Extract pubkey for debugging - cJSON* pubkey_obj = cJSON_GetObjectItem(event_obj, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event_obj, "pubkey"); const char* event_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : "unknown"; // Check if NIP-42 authentication is required for this event kind or globally @@ -1264,7 +1264,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso // Special case: allow kind 14 DMs addressed to relay to bypass auth (admin commands) int bypass_auth = 0; if (event_kind == 14 && event_obj && cJSON_IsObject(event_obj)) { - cJSON* tags = cJSON_GetObjectItem(event_obj, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event_obj, "tags"); if (tags && cJSON_IsArray(tags)) { const char* relay_pubkey = get_config_value("relay_pubkey"); if (relay_pubkey) { @@ -1390,7 +1390,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso if (result == 0) { // Check if event has protected tag ["-"] int is_protected_event = 0; - cJSON* tags = cJSON_GetObjectItem(event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags"); if (tags && cJSON_IsArray(tags)) { cJSON* tag = NULL; cJSON_ArrayForEach(tag, tags) { @@ -1417,7 +1417,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso DEBUG_WARN("Protected event rejected: protected events not enabled"); } else { // Protected events enabled - check authentication - cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey"); const char* event_pubkey = pubkey_obj ? cJSON_GetStringValue(pubkey_obj) : NULL; if (!pss || !pss->authenticated || @@ -1434,7 +1434,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso // Check for admin events (kind 23456) and intercept them if (result == 0) { - cJSON* kind_obj = cJSON_GetObjectItem(event, "kind"); + cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind"); if (kind_obj && cJSON_IsNumber(kind_obj)) { int event_kind = (int)cJSON_GetNumberValue(kind_obj); @@ -1626,7 +1626,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso } // Send OK response - cJSON* event_id = cJSON_GetObjectItem(event, "id"); + cJSON* event_id = cJSON_GetObjectItemCaseSensitive(event, "id"); if (event_id && cJSON_IsString(event_id)) { cJSON* response = cJSON_CreateArray(); cJSON_AddItemToArray(response, cJSON_CreateString("OK")); @@ -2344,7 +2344,7 @@ int process_dm_stats_command(cJSON* dm_event, char* error_message, size_t error_ } // Check if DM is addressed to relay - cJSON* tags = cJSON_GetObjectItem(dm_event, "tags"); + cJSON* tags = cJSON_GetObjectItemCaseSensitive(dm_event, "tags"); if (!tags || !cJSON_IsArray(tags)) { strncpy(error_message, "DM missing or invalid tags", error_size - 1); return -1; @@ -2380,7 +2380,7 @@ int process_dm_stats_command(cJSON* dm_event, char* error_message, size_t error_ } // Get sender pubkey - cJSON* pubkey_obj = cJSON_GetObjectItem(dm_event, "pubkey"); + cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(dm_event, "pubkey"); if (!pubkey_obj || !cJSON_IsString(pubkey_obj)) { strncpy(error_message, "DM missing sender pubkey", error_size - 1); return -1; @@ -2419,7 +2419,7 @@ int process_dm_stats_command(cJSON* dm_event, char* error_message, size_t error_ } // Get encrypted content - cJSON* content_obj = cJSON_GetObjectItem(dm_event, "content"); + cJSON* content_obj = cJSON_GetObjectItemCaseSensitive(dm_event, "content"); if (!content_obj || !cJSON_IsString(content_obj)) { strncpy(error_message, "DM missing content", error_size - 1); return -1; @@ -2545,7 +2545,7 @@ int handle_count_message(const char* sub_id, cJSON* filters, struct lws *wsi, st // after retrieving events to ensure compatibility with all SQLite versions // Handle kinds filter - cJSON* kinds = cJSON_GetObjectItem(filter, "kinds"); + cJSON* kinds = cJSON_GetObjectItemCaseSensitive(filter, "kinds"); if (kinds && cJSON_IsArray(kinds)) { int kind_count = cJSON_GetArraySize(kinds); if (kind_count > 0) { @@ -2573,7 +2573,7 @@ int handle_count_message(const char* sub_id, cJSON* filters, struct lws *wsi, st } // Handle authors filter - cJSON* authors = cJSON_GetObjectItem(filter, "authors"); + cJSON* authors = cJSON_GetObjectItemCaseSensitive(filter, "authors"); if (authors && cJSON_IsArray(authors)) { int author_count = 0; // Count valid authors @@ -2617,7 +2617,7 @@ int handle_count_message(const char* sub_id, cJSON* filters, struct lws *wsi, st } // Handle ids filter - cJSON* ids = cJSON_GetObjectItem(filter, "ids"); + cJSON* ids = cJSON_GetObjectItemCaseSensitive(filter, "ids"); if (ids && cJSON_IsArray(ids)) { int id_count = 0; // Count valid ids @@ -2719,7 +2719,7 @@ int handle_count_message(const char* sub_id, cJSON* filters, struct lws *wsi, st } // Handle search filter (NIP-50) - cJSON* search = cJSON_GetObjectItem(filter, "search"); + cJSON* search = cJSON_GetObjectItemCaseSensitive(filter, "search"); if (search && cJSON_IsString(search)) { const char* search_term = cJSON_GetStringValue(search); if (search_term && strlen(search_term) > 0) { @@ -2747,7 +2747,7 @@ int handle_count_message(const char* sub_id, cJSON* filters, struct lws *wsi, st } // Handle since filter - cJSON* since = cJSON_GetObjectItem(filter, "since"); + cJSON* since = cJSON_GetObjectItemCaseSensitive(filter, "since"); if (since && cJSON_IsNumber(since)) { snprintf(sql_ptr, remaining, " AND created_at >= %ld", (long)cJSON_GetNumberValue(since)); sql_ptr += strlen(sql_ptr); @@ -2755,7 +2755,7 @@ int handle_count_message(const char* sub_id, cJSON* filters, struct lws *wsi, st } // Handle until filter - cJSON* until = cJSON_GetObjectItem(filter, "until"); + cJSON* until = cJSON_GetObjectItemCaseSensitive(filter, "until"); if (until && cJSON_IsNumber(until)) { snprintf(sql_ptr, remaining, " AND created_at <= %ld", (long)cJSON_GetNumberValue(until)); sql_ptr += strlen(sql_ptr);