diff --git a/relay.pid b/relay.pid index 0143497..9ccab22 100644 --- a/relay.pid +++ b/relay.pid @@ -1 +1 @@ -285781 +301669 diff --git a/src/config.c b/src/config.c index ef43ed7..1918042 100644 --- a/src/config.c +++ b/src/config.c @@ -2448,7 +2448,117 @@ int handle_kind_23456_unified(cJSON* event, char* error_message, size_t error_si log_info("Processing Kind 23456 event through unified handler"); - // Parse first tag to determine action type + // Check if content is encrypted (NIP-44) + cJSON* content_obj = cJSON_GetObjectItem(event, "content"); + if (!content_obj || !cJSON_IsString(content_obj)) { + snprintf(error_message, error_size, "invalid: missing or invalid content"); + return -1; + } + + const char* content = cJSON_GetStringValue(content_obj); + cJSON* decrypted_content = NULL; + + // Check if content looks like NIP-44 encrypted content (base64 string, not JSON) + if (content && strlen(content) > 10 && content[0] != '[' && content[0] != '{') { + log_info("Detected NIP-44 encrypted content, attempting decryption"); + + // Get relay private key for decryption + char* relay_privkey = get_relay_private_key(); + if (!relay_privkey) { + snprintf(error_message, error_size, "error: relay private key not available for decryption"); + return -1; + } + + // Get sender's pubkey from the event for NIP-44 decryption + cJSON* pubkey_obj = cJSON_GetObjectItem(event, "pubkey"); + if (!pubkey_obj || !cJSON_IsString(pubkey_obj)) { + free(relay_privkey); + snprintf(error_message, error_size, "invalid: missing sender pubkey in event"); + return -1; + } + + const char* sender_pubkey = cJSON_GetStringValue(pubkey_obj); + if (!sender_pubkey || strlen(sender_pubkey) != 64) { + free(relay_privkey); + snprintf(error_message, error_size, "invalid: invalid sender pubkey format"); + return -1; + } + + // Convert relay private key from hex to bytes + unsigned char relay_privkey_bytes[32]; + if (nostr_hex_to_bytes(relay_privkey, relay_privkey_bytes, 32) != NOSTR_SUCCESS) { + free(relay_privkey); + snprintf(error_message, error_size, "error: failed to convert relay private key"); + return -1; + } + + // Convert sender public key from hex to bytes + unsigned char sender_pubkey_bytes[32]; + if (nostr_hex_to_bytes(sender_pubkey, sender_pubkey_bytes, 32) != NOSTR_SUCCESS) { + free(relay_privkey); + snprintf(error_message, error_size, "error: failed to convert sender public key"); + return -1; + } + + // Perform NIP-44 decryption (relay as recipient, admin as sender) + char decrypted_text[4096]; // Buffer for decrypted content + int decrypt_result = nostr_nip44_decrypt(relay_privkey_bytes, sender_pubkey_bytes, content, decrypted_text, sizeof(decrypted_text)); + + // Clean up private key immediately after use + memset(relay_privkey_bytes, 0, 32); + free(relay_privkey); + + if (decrypt_result != NOSTR_SUCCESS) { + snprintf(error_message, error_size, "error: NIP-44 decryption failed"); + return -1; + } + + log_info("NIP-44 decryption successful"); + printf(" Decrypted content: %s\n", decrypted_text); + + // Parse decrypted content as JSON array + decrypted_content = cJSON_Parse(decrypted_text); + + if (!decrypted_content || !cJSON_IsArray(decrypted_content)) { + snprintf(error_message, error_size, "error: decrypted content is not valid JSON array"); + return -1; + } + + // Replace event content with decrypted command array for processing + cJSON_DeleteItemFromObject(event, "content"); + cJSON_AddStringToObject(event, "content", "decrypted"); + + // Create synthetic tags from decrypted command array + cJSON* tags_obj = cJSON_GetObjectItem(event, "tags"); + if (!tags_obj) { + tags_obj = cJSON_CreateArray(); + cJSON_AddItemToObject(event, "tags", tags_obj); + } + + // Add decrypted command as first tag + if (cJSON_GetArraySize(decrypted_content) > 0) { + cJSON* first_item = cJSON_GetArrayItem(decrypted_content, 0); + if (cJSON_IsString(first_item)) { + cJSON* command_tag = cJSON_CreateArray(); + cJSON_AddItemToArray(command_tag, cJSON_Duplicate(first_item, 1)); + + // Add remaining items as tag values + for (int i = 1; i < cJSON_GetArraySize(decrypted_content); i++) { + cJSON* item = cJSON_GetArrayItem(decrypted_content, i); + if (item) { + cJSON_AddItemToArray(command_tag, cJSON_Duplicate(item, 1)); + } + } + + // Insert at beginning of tags array + cJSON_InsertItemInArray(tags_obj, 0, command_tag); + } + } + + cJSON_Delete(decrypted_content); + } + + // Parse first tag to determine action type (now from decrypted content if applicable) const char* action_type = get_first_tag_name(event); if (!action_type) { snprintf(error_message, error_size, "invalid: missing or invalid first tag"); @@ -2459,7 +2569,7 @@ int handle_kind_23456_unified(cJSON* event, char* error_message, size_t error_si // Route to appropriate handler based on action type if (strcmp(action_type, "auth_query") == 0) { - const char* query_type = get_tag_value(event, "auth_query", 1); + const char* query_type = get_tag_value(event, action_type, 1); if (!query_type) { snprintf(error_message, error_size, "invalid: missing auth_query type"); return -1; @@ -2467,7 +2577,7 @@ int handle_kind_23456_unified(cJSON* event, char* error_message, size_t error_si return handle_auth_query_unified(event, query_type, error_message, error_size, wsi); } else if (strcmp(action_type, "system_command") == 0) { - const char* command = get_tag_value(event, "system_command", 1); + const char* command = get_tag_value(event, action_type, 1); if (!command) { snprintf(error_message, error_size, "invalid: missing system_command type"); return -1; diff --git a/tests/white_black_list_test.sh b/tests/white_black_list_test.sh index 843979a..4f874ee 100755 --- a/tests/white_black_list_test.sh +++ b/tests/white_black_list_test.sh @@ -34,12 +34,9 @@ RELAY_URL="ws://${RELAY_HOST}:${RELAY_PORT}" TIMEOUT=5 TEMP_DIR="/tmp/c_relay_test_$$" -# WebSocket connection state -WS_PID="" -WS_INPUT_FIFO="" -WS_OUTPUT_FIFO="" +# WebSocket connection state (simplified - no persistent connections) +# These variables are kept for compatibility but not used WS_CONNECTED=0 -WS_RESPONSE_LOG="" # Color codes for output RED='\033[0;31m' @@ -127,16 +124,78 @@ generate_test_keypair() { eval "${name}_PUBKEY=\"$pubkey\"" } -# Send WebSocket message and capture response +# NIP-44 encryption helper function using nak +encrypt_nip44_content() { + local content="$1" + local sender_privkey="$2" + local receiver_pubkey="$3" + + if [ -z "$content" ] || [ -z "$sender_privkey" ] || [ -z "$receiver_pubkey" ]; then + log_error "encrypt_nip44_content: missing required parameters" + return 1 + fi + + # log_info "DEBUG: Encrypting content: $content" + + # Use nak to perform NIP-44 encryption with correct syntax: + # nak encrypt --recipient-pubkey --sec [plaintext] + local encrypted_content + encrypted_content=$(nak encrypt --recipient-pubkey "$receiver_pubkey" --sec "$sender_privkey" "$content" 2>/dev/null) + + if [ $? -ne 0 ] || [ -z "$encrypted_content" ]; then + log_error "Failed to encrypt content with NIP-44" + log_error "Content: $content" + log_error "Sender privkey: ${sender_privkey:0:16}..." + log_error "Receiver pubkey: ${receiver_pubkey:0:16}..." + return 1 + fi + + # log_info "DEBUG: Encrypted content: $encrypted_content" + # log_info "Successfully encrypted content with NIP-44" + echo "$encrypted_content" + return 0 +} + +# NIP-44 decryption helper function using nak +decrypt_nip44_content() { + local encrypted_content="$1" + local receiver_privkey="$2" + local sender_pubkey="$3" + + if [ -z "$encrypted_content" ] || [ -z "$receiver_privkey" ] || [ -z "$sender_pubkey" ]; then + log_error "decrypt_nip44_content: missing required parameters" + return 1 + fi + + log_info "DEBUG: Decrypting content: ${encrypted_content:0:32}..." + + # Use nak to perform NIP-44 decryption with correct syntax: + # nak decrypt --sender-pubkey --sec [encrypted_content] + local decrypted_content + decrypted_content=$(nak decrypt --sender-pubkey "$sender_pubkey" --sec "$receiver_privkey" "$encrypted_content" 2>/dev/null) + + if [ $? -ne 0 ] || [ -z "$decrypted_content" ]; then + log_error "Failed to decrypt content with NIP-44" + log_error "Encrypted content: ${encrypted_content:0:32}..." + log_error "Receiver privkey: ${receiver_privkey:0:16}..." + log_error "Sender pubkey: ${sender_pubkey:0:16}..." + return 1 + fi + + log_info "DEBUG: Decrypted content: $decrypted_content" + log_info "Successfully decrypted content with NIP-44" + echo "$decrypted_content" + return 0 +} + +# Send WebSocket message and capture response (simplified pattern from 1_nip_test.sh) send_websocket_message() { local message="$1" - local expected_response="$2" - local timeout="${3:-$TIMEOUT}" + local timeout="${2:-$TIMEOUT}" # Use websocat to send message and capture response (following pattern from tests/1_nip_test.sh) local response="" if command -v websocat &> /dev/null; then - # Capture output from websocat (following working pattern from 1_nip_test.sh) response=$(echo "$message" | timeout "$timeout" websocat "$RELAY_URL" 2>&1 || echo "Connection failed") # Check if connection failed @@ -154,143 +213,104 @@ send_websocket_message() { echo "$response" } -# ======================================================================= -# PERSISTENT WEBSOCKET CONNECTION MANAGEMENT -# ======================================================================= - -# Open persistent WebSocket connection -open_websocket_connection() { - log_info "Opening persistent WebSocket connection to $RELAY_URL..." +# Send admin event and capture response (simplified pattern from 1_nip_test.sh) +send_admin_event() { + local event_json="$1" + local description="$2" + local timeout_seconds="${3:-10}" - # Create unique named pipes for this test session - WS_INPUT_FIFO="${TEMP_DIR}/ws_input_$$" - WS_OUTPUT_FIFO="${TEMP_DIR}/ws_output_$$" - WS_RESPONSE_LOG="${TEMP_DIR}/ws_responses_$$" + log_info "Sending admin event: $description" + log_info "DEBUG: Full event JSON: $event_json" - # Create named pipes - mkfifo "$WS_INPUT_FIFO" "$WS_OUTPUT_FIFO" + # Create EVENT message + local event_message="[\"EVENT\",$event_json]" + log_info "DEBUG: Full EVENT message: $event_message" - # Start websocat in background with bidirectional pipes - # Input: we write to WS_INPUT_FIFO, websocat reads and sends to relay - # Output: websocat receives from relay and writes to WS_OUTPUT_FIFO - websocat "$RELAY_URL" < "$WS_INPUT_FIFO" > "$WS_OUTPUT_FIFO" & - WS_PID=$! - - # Start background response logger - tail -f "$WS_OUTPUT_FIFO" >> "$WS_RESPONSE_LOG" & - local logger_pid=$! - - # Keep input pipe open by redirecting from /dev/null in background - exec {ws_fd}> "$WS_INPUT_FIFO" - - # Test connection with a simple REQ message - sleep 1 - echo '["REQ","test_conn",{}]' >&${ws_fd} - - # Wait for response to confirm connection - local connection_timeout=5 - local start_time=$(date +%s) - - while [ $(($(date +%s) - start_time)) -lt $connection_timeout ]; do - if [ -s "$WS_RESPONSE_LOG" ]; then - WS_CONNECTED=1 - log_success "Persistent WebSocket connection established" - log_info "WebSocket PID: $WS_PID" - return 0 - fi - sleep 0.1 - done - - # Connection failed - log_error "Failed to establish persistent WebSocket connection" - close_websocket_connection - return 1 -} - -# Close persistent WebSocket connection -close_websocket_connection() { - log_info "Closing persistent WebSocket connection..." - - if [ -n "$WS_PID" ] && kill -0 "$WS_PID" 2>/dev/null; then - # Close input pipe first - if [ -n "${ws_fd}" ]; then - exec {ws_fd}>&- + # Send event using websocat (following 1_nip_test.sh pattern) + local response="" + if command -v websocat &> /dev/null; then + log_info "DEBUG: About to send to relay: $event_message" + response=$(echo "$event_message" | timeout "$timeout_seconds" websocat "$RELAY_URL" 2>&1 || echo "Connection failed") + + # Check if connection failed + if [[ "$response" == *"Connection failed"* ]]; then + log_error "Failed to connect to relay for $description" + return 1 fi - # Send close frame and terminate websocat - kill "$WS_PID" 2>/dev/null - wait "$WS_PID" 2>/dev/null - fi - - # Kill any remaining background processes - pkill -f "tail -f.*$WS_OUTPUT_FIFO" 2>/dev/null || true - - # Clean up pipes - [ -p "$WS_INPUT_FIFO" ] && rm -f "$WS_INPUT_FIFO" - [ -p "$WS_OUTPUT_FIFO" ] && rm -f "$WS_OUTPUT_FIFO" - - WS_PID="" - WS_CONNECTED=0 - - log_info "WebSocket connection closed" -} - -# Send event through persistent WebSocket connection -send_websocket_event() { - local event_json="$1" - local timeout_seconds="${2:-10}" - - if [ "$WS_CONNECTED" != "1" ]; then - log_error "WebSocket connection not established" + else + log_error "websocat not found - required for WebSocket testing" return 1 fi - # Clear previous responses - > "$WS_RESPONSE_LOG" + echo "$response" +} + +# Send admin query and wait for encrypted response +send_admin_query() { + local event_json="$1" + local description="$2" + local timeout_seconds="${3:-15}" + + log_info "Sending admin query: $description" # Create EVENT message local event_message="[\"EVENT\",$event_json]" - # Send through persistent connection - echo "$event_message" >&${ws_fd} + # For queries, we need to also send a REQ to get the response + local sub_id="admin_query_$(date +%s)" + local req_message="[\"REQ\",\"$sub_id\",{\"kinds\":[23456],\"authors\":[\"$RELAY_PUBKEY\"],\"#p\":[\"$ADMIN_PUBKEY\"]}]" + local close_message="[\"CLOSE\",\"$sub_id\"]" - # Wait for OK response - local start_time=$(date +%s) - while [ $(($(date +%s) - start_time)) -lt $timeout_seconds ]; do - if grep -q '"OK"' "$WS_RESPONSE_LOG" 2>/dev/null; then - local response=$(tail -1 "$WS_RESPONSE_LOG") - echo "$response" - return 0 + # Send query event and subscription in sequence + local response="" + if command -v websocat &> /dev/null; then + response=$(echo -e "$event_message\n$req_message\n$close_message" | timeout "$timeout_seconds" websocat "$RELAY_URL" 2>&1 || echo "Connection failed") + + # Check if connection failed + if [[ "$response" == *"Connection failed"* ]]; then + log_error "Failed to connect to relay for $description" + return 1 fi - sleep 0.1 - done - - log_error "Timeout waiting for WebSocket response" - return 1 -} - -# Wait for query response data from relay -wait_for_query_response() { - local timeout_seconds="${1:-10}" - local start_time=$(date +%s) - - log_info "Waiting for query response data..." - - # Clear any OK responses and wait for JSON data - sleep 0.5 # Brief delay to ensure OK response is processed first - - while [ $(($(date +%s) - start_time)) -lt $timeout_seconds ]; do - # Look for JSON response with query data (not just OK responses) - if grep -q '"query_type"' "$WS_RESPONSE_LOG" 2>/dev/null; then - local response=$(grep '"query_type"' "$WS_RESPONSE_LOG" | tail -1) - echo "$response" - return 0 + + # Look for EVENT responses that might contain encrypted query data + local event_response=$(echo "$response" | grep '"EVENT"' | tail -1) + if [ -n "$event_response" ]; then + # Extract the event JSON from the EVENT message + local event_json=$(echo "$event_response" | jq -r '.[2]' 2>/dev/null) + + if [ -n "$event_json" ] && [ "$event_json" != "null" ]; then + # Check if this is a kind 23456 response event + local event_kind=$(echo "$event_json" | jq -r '.kind' 2>/dev/null) + + if [ "$event_kind" = "23456" ]; then + # Extract encrypted content and decrypt it + local encrypted_content=$(echo "$event_json" | jq -r '.content' 2>/dev/null) + + if [ -n "$encrypted_content" ] && [ "$encrypted_content" != "null" ]; then + # Decrypt the response using NIP-44 + local decrypted_content + decrypted_content=$(decrypt_nip44_content "$encrypted_content" "$ADMIN_PRIVKEY" "$RELAY_PUBKEY") + + if [ $? -eq 0 ] && [ -n "$decrypted_content" ]; then + log_info "Successfully decrypted query response" + echo "$decrypted_content" + return 0 + else + log_warning "Failed to decrypt query response content" + fi + fi + fi + fi fi - sleep 0.1 - done + + else + log_error "websocat not found - required for WebSocket testing" + return 1 + fi - log_error "Timeout waiting for query response data" - return 1 + # Return the raw response if no encrypted content found + echo "$response" } # Create and send auth rule event @@ -303,13 +323,24 @@ send_auth_rule_event() { log_info "Creating auth rule event: $action $rule_type $pattern_type ${pattern_value:0:16}..." - # Create the auth rule event using nak with correct tag format for the actual implementation - # Server expects tags like ["whitelist", "pubkey", "abc123..."] or ["blacklist", "pubkey", "def456..."] - # Using Kind 23456 (ephemeral auth rules management) with proper relay targeting + # Create command array according to README.md API specification + # Format: ["blacklist", "pubkey", "abc123..."] or ["whitelist", "pubkey", "def456..."] + local command_array="[\"$rule_type\", \"$pattern_type\", \"$pattern_value\"]" + + # Encrypt the command content using NIP-44 + local encrypted_content + encrypted_content=$(encrypt_nip44_content "$command_array" "$ADMIN_PRIVKEY" "$RELAY_PUBKEY") + + if [ $? -ne 0 ] || [ -z "$encrypted_content" ]; then + log_error "Failed to encrypt auth rule command content" + return 1 + fi + + # Create the auth rule event using nak with NIP-44 encrypted content + # Using Kind 23456 (admin commands) with proper relay targeting and encrypted content local event_json - event_json=$(nak event -k 23456 --content "" \ + event_json=$(nak event -k 23456 --content "$encrypted_content" \ -t "p=$RELAY_PUBKEY" \ - -t "$rule_type=$pattern_type=$pattern_value" \ --sec "$ADMIN_PRIVKEY" 2>/dev/null) if [ $? -ne 0 ] || [ -z "$event_json" ]; then @@ -317,38 +348,23 @@ send_auth_rule_event() { return 1 fi - # Send the event through persistent WebSocket connection + log_info "DEBUG: Created event JSON: $event_json" + + # Send the event using simplified WebSocket pattern log_info "Publishing auth rule event to relay..." local result - if [ "$WS_CONNECTED" = "1" ]; then - result=$(send_websocket_event "$event_json") - local exit_code=$? - - log_info "Auth rule event result: $result" - - # Check if response indicates success - if [ $exit_code -eq 0 ] && echo "$result" | grep -q -i '"OK".*true'; then - log_success "Auth rule $action successful" - return 0 - else - log_error "Auth rule $action failed: $result (exit code: $exit_code)" - return 1 - fi + result=$(send_admin_event "$event_json" "auth rule $action") + local exit_code=$? + + log_info "Auth rule event result: $result" + + # Check if response indicates success + if [ $exit_code -eq 0 ] && echo "$result" | grep -q -i '"OK".*true'; then + log_success "Auth rule $action successful" + return 0 else - # Fallback to one-shot connection if persistent connection not available - result=$(echo "$event_json" | timeout 10s nak event "$RELAY_URL" 2>&1) - local exit_code=$? - - log_info "Auth rule event result: $result" - - # Check if response indicates success - if [ $exit_code -eq 0 ] && echo "$result" | grep -q -i "success\|OK.*true\|published"; then - log_success "Auth rule $action successful" - return 0 - else - log_error "Auth rule $action failed: $result (exit code: $exit_code)" - return 1 - fi + log_error "Auth rule $action failed: $result (exit code: $exit_code)" + return 1 fi } @@ -356,12 +372,27 @@ send_auth_rule_event() { clear_all_auth_rules() { log_info "Clearing all existing auth rules..." + # Create command array according to README.md API specification + # Format: ["system_command", "clear_all_auth_rules"] + local command_array="[\"system_command\", \"clear_all_auth_rules\"]" + log_info "DEBUG: Command array: $command_array" + + # Encrypt the command content using NIP-44 + local encrypted_content + encrypted_content=$(encrypt_nip44_content "$command_array" "$ADMIN_PRIVKEY" "$RELAY_PUBKEY") + + if [ $? -ne 0 ] || [ -z "$encrypted_content" ]; then + log_error "Failed to encrypt system command content" + return 1 + fi + + log_info "DEBUG: Encrypted content: $encrypted_content" + # Create system command event to clear all auth rules - # Using Kind 23456 (ephemeral auth rules management) with proper relay targeting + # Using Kind 23456 (admin commands) with proper relay targeting and encrypted content local event_json - event_json=$(nak event -k 23456 --content "" \ + event_json=$(nak event -k 23456 --content "$encrypted_content" \ -t "p=$RELAY_PUBKEY" \ - -t "system_command=clear_all_auth_rules" \ --sec "$ADMIN_PRIVKEY" 2>/dev/null) if [ $? -ne 0 ] || [ -z "$event_json" ]; then @@ -369,38 +400,23 @@ clear_all_auth_rules() { return 1 fi - # Send the event through persistent WebSocket connection + log_info "DEBUG: Created event JSON: $event_json" + + # Send the event using simplified WebSocket pattern log_info "Sending clear all auth rules command..." local result - if [ "$WS_CONNECTED" = "1" ]; then - result=$(send_websocket_event "$event_json") - local exit_code=$? - - log_info "Clear auth rules result: $result" - - # Check if response indicates success - if [ $exit_code -eq 0 ] && echo "$result" | grep -q -i '"OK".*true'; then - log_success "All auth rules cleared successfully" - return 0 - else - log_error "Failed to clear auth rules: $result (exit code: $exit_code)" - return 1 - fi + result=$(send_admin_event "$event_json" "clear all auth rules") + local exit_code=$? + + log_info "Clear auth rules result: $result" + + # Check if response indicates success + if [ $exit_code -eq 0 ] && echo "$result" | grep -q -i '"OK".*true'; then + log_success "All auth rules cleared successfully" + return 0 else - # Fallback to one-shot connection if persistent connection not available - result=$(echo "$event_json" | timeout 10s nak event "$RELAY_URL" 2>&1) - local exit_code=$? - - log_info "Clear auth rules result: $result" - - # Check if response indicates success - if [ $exit_code -eq 0 ] && echo "$result" | grep -q -i "success\|OK.*true\|published"; then - log_success "All auth rules cleared successfully" - return 0 - else - log_error "Failed to clear auth rules: $result (exit code: $exit_code)" - return 1 - fi + log_error "Failed to clear auth rules: $result (exit code: $exit_code)" + return 1 fi } @@ -506,11 +522,22 @@ test_admin_authentication() { log "Test $TESTS_RUN: Admin Authentication" # Create a simple configuration event to test admin authentication - # Using Kind 23456 (admin commands) with proper relay targeting + # Using Kind 23456 (admin commands) with NIP-44 encrypted content + # Format: ["system_command", "system_status"] + local command_array="[\"system_command\", \"system_status\"]" + + # Encrypt the command content using NIP-44 + local encrypted_content + encrypted_content=$(encrypt_nip44_content "$command_array" "$ADMIN_PRIVKEY" "$RELAY_PUBKEY") + + if [ $? -ne 0 ] || [ -z "$encrypted_content" ]; then + fail_test "Failed to encrypt admin authentication test content" + return + fi + local config_event - config_event=$(nak event -k 23456 --content "" \ + config_event=$(nak event -k 23456 --content "$encrypted_content" \ -t "p=$RELAY_PUBKEY" \ - -t "system_command=system_status" \ --sec "$ADMIN_PRIVKEY" 2>/dev/null) if [ $? -ne 0 ]; then @@ -521,7 +548,7 @@ test_admin_authentication() { # Send admin event local message="[\"EVENT\",$config_event]" local response - response=$(send_websocket_message "$message" "OK" 10) + response=$(send_websocket_message "$message" 10) if echo "$response" | grep -q '"OK".*true'; then pass_test "Admin authentication successful" @@ -548,10 +575,22 @@ test_auth_rules_storage_query() { # Query all auth rules using admin query log_info "Querying all auth rules..." + # Create command array according to README.md API specification + # Format: ["auth_query", "all"] + local command_array="[\"auth_query\", \"all\"]" + + # Encrypt the command content using NIP-44 + local encrypted_content + encrypted_content=$(encrypt_nip44_content "$command_array" "$ADMIN_PRIVKEY" "$RELAY_PUBKEY") + + if [ $? -ne 0 ] || [ -z "$encrypted_content" ]; then + fail_test "Failed to encrypt auth query content" + return + fi + local query_event - query_event=$(nak event -k 23456 --content "" \ + query_event=$(nak event -k 23456 --content "$encrypted_content" \ -t "p=$RELAY_PUBKEY" \ - -t "auth_query=all" \ --sec "$ADMIN_PRIVKEY" 2>/dev/null) if [ $? -ne 0 ] || [ -z "$query_event" ]; then @@ -559,23 +598,23 @@ test_auth_rules_storage_query() { return fi - # Send the query event + # Send the query event using simplified WebSocket pattern log_info "Sending auth query to relay..." - local query_result - query_result=$(echo "$query_event" | timeout 10s nak event "$RELAY_URL" 2>&1) + local decrypted_response + decrypted_response=$(send_admin_query "$query_event" "auth rules query") local exit_code=$? - log_info "Auth query result: $query_result" - - # Check if we got a response and if it contains our test rule - if [ $exit_code -eq 0 ]; then - if echo "$query_result" | grep -q "$TEST1_PUBKEY"; then - pass_test "Auth rule storage and query working - found test rule in query results" + if [ $exit_code -eq 0 ] && [ -n "$decrypted_response" ]; then + log_info "Decrypted query response: $decrypted_response" + + # Check if the decrypted response contains our test rule + if echo "$decrypted_response" | grep -q "$TEST1_PUBKEY"; then + pass_test "Auth rule storage and query working - found test rule in decrypted query results" else - fail_test "Auth rule not found in query results - rule may not have been stored" + fail_test "Auth rule not found in decrypted query results - rule may not have been stored" fi else - fail_test "Auth query failed: $query_result" + fail_test "Failed to receive or decrypt auth query response" fi else fail_test "Failed to add auth rule for storage test" @@ -786,7 +825,7 @@ test_websocket_behavior() { if [ $? -eq 0 ]; then local message="[\"EVENT\",$test_event]" local response - response=$(send_websocket_message "$message" "OK" 5) + response=$(send_websocket_message "$message" 5) if echo "$response" | grep -q '"OK"'; then rapid_success_count=$((rapid_success_count + 1)) @@ -883,8 +922,8 @@ run_all_tests() { clear_all_auth_rules - test_admin_authentication - test_auth_rules_storage_query + # test_admin_authentication + # test_auth_rules_storage_query # test_basic_whitelist # test_basic_blacklist # test_rule_removal