v0.4.10 - api

This commit is contained in:
Your Name
2025-10-05 14:35:09 -04:00
parent c63fd04c92
commit d5350d7c30
811 changed files with 119248 additions and 6432 deletions

135
tests/config_query_test.js Normal file
View File

@@ -0,0 +1,135 @@
#!/usr/bin/env node
// Spec-compliant test to send config_query command with proper NIP-44 encryption
// Uses nostr-tools for encryption and event creation
import { nip44, finalizeEvent, getPublicKey } from 'nostr-tools';
import WebSocket from 'ws';
// Test keys from make_and_restart_relay.sh -t
const ADMIN_PRIVATE_KEY = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const ADMIN_PUBLIC_KEY = "6a04ab98d9e4774ad806e302dddeb63bea16b5cb5f223ee77478e861bb583eb3";
const RELAY_PUBLIC_KEY = "4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa";
const RELAY_URL = "ws://localhost:8888";
async function main() {
console.log("=== Testing Admin API Config Query (Spec Compliant) ===");
console.log("Sending config_query command using nostr-tools...");
// Command array as per README.md spec
const commandArray = ["config_query", "all"];
const commandJson = JSON.stringify(commandArray);
console.log(`Command: ${commandJson}`);
return new Promise((resolve, reject) => {
const ws = new WebSocket(RELAY_URL);
let queryResponseReceived = false;
ws.on('open', () => {
console.log("WebSocket connected");
try {
const adminPubkey = getPublicKey(Buffer.from(ADMIN_PRIVATE_KEY, 'hex'));
console.log(`Admin pubkey: ${adminPubkey}`);
// Send subscription for response events
const subId = "admin_response";
const subMessage = JSON.stringify(["REQ", subId, { kinds: [23457], "#p": [ADMIN_PUBLIC_KEY] }]);
ws.send(subMessage);
console.log(`Subscription sent: ${subMessage}`);
// Send the first command
sendCommand(ws, commandArray);
} catch (error) {
console.error("Failed to prepare/send command:", error.message);
ws.close();
reject(error);
}
});
ws.on('message', (data) => {
const message = data.toString();
console.log(`Relay response: ${message}`);
try {
const parsed = JSON.parse(message);
if (parsed[0] === "EVENT" && parsed[1] === "admin_response") {
const event = parsed[2];
if (event.kind === 23457) {
// Decrypt the response content
const conversationKey = nip44.getConversationKey(Buffer.from(ADMIN_PRIVATE_KEY, 'hex'), RELAY_PUBLIC_KEY);
const decrypted = nip44.decrypt(event.content, conversationKey);
console.log(`Decrypted response: ${decrypted}`);
if (!queryResponseReceived) {
queryResponseReceived = true;
console.log("\n=== Testing Admin API Config Update ===");
console.log("Sending config_update command to change relay_description...");
// Send the second command
const updateCommandArray = ["config_update", [{"key": "relay_description", "value": "Bozo the clown", "data_type": "string", "category": "relay"}]];
sendCommand(ws, updateCommandArray);
}
}
}
} catch (error) {
// Ignore parsing errors
}
});
ws.on('error', (error) => {
console.error("WebSocket error:", error.message);
reject(error);
});
ws.on('close', () => {
console.log("WebSocket closed");
resolve();
});
// Timeout after 20 seconds
setTimeout(() => {
ws.close();
}, 20000);
});
}
function sendCommand(ws, commandArray) {
try {
const commandJson = JSON.stringify(commandArray);
console.log(`Command: ${commandJson}`);
// Derive conversation key for NIP-44 encryption
const conversationKey = nip44.getConversationKey(Buffer.from(ADMIN_PRIVATE_KEY, 'hex'), RELAY_PUBLIC_KEY);
// Encrypt the command JSON with NIP-44
const encryptedContent = nip44.encrypt(commandJson, conversationKey);
console.log(`Encrypted content: ${encryptedContent.substring(0, 50)}...`);
// Create the event template
const eventTemplate = {
kind: 23456,
created_at: Math.floor(Date.now() / 1000),
tags: [['p', RELAY_PUBLIC_KEY]],
content: encryptedContent
};
// Sign the event
const event = finalizeEvent(eventTemplate, Buffer.from(ADMIN_PRIVATE_KEY, 'hex'));
console.log(`Event sent: ${JSON.stringify(event, null, 2)}`);
// Send the event
const eventMessage = JSON.stringify(["EVENT", event]);
ws.send(eventMessage);
console.log("Command sent successfully!");
console.log("Listening for responses...");
} catch (error) {
console.error("Failed to send command:", error.message);
ws.close();
}
}
main().catch(console.error);

View File

@@ -1,400 +0,0 @@
#!/bin/bash
# Comprehensive Error Handling and Recovery Testing for Event-Based Configuration System
# Tests various failure scenarios and recovery mechanisms
set -e
# Configuration
RELAY_BINARY="./build/c_relay_x86"
TEST_DB_PREFIX="test_relay"
LOG_FILE="test_results.log"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test results tracking
TESTS_PASSED=0
TESTS_FAILED=0
TESTS_TOTAL=0
# Function to print colored output
print_test_header() {
echo -e "${BLUE}[TEST]${NC} $1"
((TESTS_TOTAL++))
}
print_success() {
echo -e "${GREEN}[PASS]${NC} $1"
((TESTS_PASSED++))
}
print_failure() {
echo -e "${RED}[FAIL]${NC} $1"
((TESTS_FAILED++))
}
print_info() {
echo -e "${YELLOW}[INFO]${NC} $1"
}
# Clean up function
cleanup_test_files() {
print_info "Cleaning up test files..."
pkill -f "c_relay_" 2>/dev/null || true
rm -f ${TEST_DB_PREFIX}*.nrdb* 2>/dev/null || true
rm -f test_*.log 2>/dev/null || true
sleep 1
}
# Function to start relay and capture output
start_relay_test() {
local test_name="$1"
local timeout="${2:-10}"
print_info "Starting relay for test: $test_name"
timeout $timeout $RELAY_BINARY > "test_${test_name}.log" 2>&1 &
local relay_pid=$!
sleep 2
if kill -0 $relay_pid 2>/dev/null; then
echo $relay_pid
else
echo "0"
fi
}
# Function to stop relay
stop_relay_test() {
local relay_pid="$1"
if [ "$relay_pid" != "0" ]; then
kill $relay_pid 2>/dev/null || true
wait $relay_pid 2>/dev/null || true
fi
}
# Function to check if relay started successfully
check_relay_startup() {
local log_file="$1"
if grep -q "First-time startup sequence completed\|Existing relay startup" "$log_file" 2>/dev/null; then
return 0
else
return 1
fi
}
# Function to check if relay has admin keys
check_admin_keys() {
local log_file="$1"
if grep -q "Admin Private Key:" "$log_file" 2>/dev/null; then
return 0
else
return 1
fi
}
# Function to check database file creation
check_database_creation() {
if ls *.nrdb 2>/dev/null | head -1; then
return 0
else
return 1
fi
}
# Function to check configuration event in database
check_config_event_stored() {
local db_file="$1"
if [ -f "$db_file" ]; then
local count=$(sqlite3 "$db_file" "SELECT COUNT(*) FROM events WHERE kind = 33334;" 2>/dev/null || echo "0")
if [ "$count" -gt 0 ]; then
return 0
fi
fi
return 1
}
echo "========================================"
echo "Event-Based Configuration System Tests"
echo "========================================"
echo
# Ensure binary exists
if [ ! -f "$RELAY_BINARY" ]; then
print_failure "Relay binary not found. Please build first: make"
exit 1
fi
print_info "Starting comprehensive error handling and recovery tests..."
echo
# TEST 1: Normal First-Time Startup
print_test_header "Test 1: Normal First-Time Startup"
cleanup_test_files
relay_pid=$(start_relay_test "first_startup" 15)
sleep 5
stop_relay_test $relay_pid
if check_relay_startup "test_first_startup.log"; then
if check_admin_keys "test_first_startup.log"; then
if db_file=$(check_database_creation); then
if check_config_event_stored "$db_file"; then
print_success "First-time startup completed successfully"
else
print_failure "Configuration event not stored in database"
fi
else
print_failure "Database file not created"
fi
else
print_failure "Admin keys not generated"
fi
else
print_failure "Relay failed to complete startup"
fi
# TEST 2: Existing Relay Startup
print_test_header "Test 2: Existing Relay Startup (using existing database)"
relay_pid=$(start_relay_test "existing_startup" 10)
sleep 3
stop_relay_test $relay_pid
if check_relay_startup "test_existing_startup.log"; then
if ! check_admin_keys "test_existing_startup.log"; then
print_success "Existing relay startup (no new keys generated)"
else
print_failure "New admin keys generated for existing relay"
fi
else
print_failure "Existing relay failed to start"
fi
# TEST 3: Corrupted Database Recovery
print_test_header "Test 3: Corrupted Database Recovery"
if db_file=$(check_database_creation); then
# Corrupt the database by truncating it
truncate -s 100 "$db_file"
print_info "Database corrupted for recovery test"
relay_pid=$(start_relay_test "corrupted_db" 10)
sleep 3
stop_relay_test $relay_pid
if grep -q "ERROR.*database\|Failed.*database\|disk I/O error" "test_corrupted_db.log"; then
print_success "Corrupted database properly detected and handled"
else
print_failure "Corrupted database not properly handled"
fi
fi
# TEST 4: Missing Database File Recovery
print_test_header "Test 4: Missing Database File Recovery"
cleanup_test_files
# Create a database then remove it to simulate loss
relay_pid=$(start_relay_test "create_db" 10)
sleep 3
stop_relay_test $relay_pid
if db_file=$(check_database_creation); then
rm -f "$db_file"*
print_info "Database files removed to test recovery"
relay_pid=$(start_relay_test "missing_db" 15)
sleep 5
stop_relay_test $relay_pid
if check_relay_startup "test_missing_db.log"; then
if check_admin_keys "test_missing_db.log"; then
print_success "Missing database recovery successful (new keys generated)"
else
print_failure "New admin keys not generated after database loss"
fi
else
print_failure "Failed to recover from missing database"
fi
fi
# TEST 5: Invalid Configuration Event Handling
print_test_header "Test 5: Configuration Event Structure Validation"
# This test would require injecting an invalid configuration event
# For now, we check that the validation functions are properly integrated
if grep -q "nostr_validate_event_structure\|nostr_verify_event_signature" src/config.c; then
print_success "Configuration event validation functions integrated"
else
print_failure "Configuration event validation functions not found"
fi
# TEST 6: Database Schema Version Check
print_test_header "Test 6: Database Schema Consistency"
if db_file=$(check_database_creation); then
# Check that the database has the correct schema version
schema_version=$(sqlite3 "$db_file" "SELECT value FROM schema_info WHERE key = 'version';" 2>/dev/null || echo "")
if [ "$schema_version" = "4" ]; then
print_success "Database schema version is correct (v4)"
else
print_failure "Database schema version incorrect: $schema_version (expected: 4)"
fi
# Check that legacy tables don't exist
if ! sqlite3 "$db_file" ".tables" 2>/dev/null | grep -q "config_file_cache\|active_config"; then
print_success "Legacy configuration tables properly removed"
else
print_failure "Legacy configuration tables still present"
fi
fi
# TEST 7: Memory and Resource Management
print_test_header "Test 7: Resource Cleanup and Memory Management"
relay_pid=$(start_relay_test "resource_test" 15)
sleep 5
# Check for memory leaks or resource issues (basic check)
if kill -0 $relay_pid 2>/dev/null; then
# Send termination signal and check cleanup
kill -TERM $relay_pid 2>/dev/null || true
sleep 2
if ! kill -0 $relay_pid 2>/dev/null; then
if grep -q "Configuration system cleaned up" "test_resource_test.log"; then
print_success "Resource cleanup completed successfully"
else
print_failure "Resource cleanup not logged properly"
fi
else
kill -KILL $relay_pid 2>/dev/null || true
print_failure "Relay did not shut down cleanly"
fi
else
print_failure "Relay process not running for resource test"
fi
# TEST 8: Configuration Cache Consistency
print_test_header "Test 8: Configuration Cache Consistency"
if db_file=$(check_database_creation); then
# Check that configuration is properly cached and accessible
config_count=$(sqlite3 "$db_file" "SELECT COUNT(*) FROM events WHERE kind = 33334;" 2>/dev/null || echo "0")
if [ "$config_count" -eq 1 ]; then
print_success "Single configuration event stored (replaceable event working)"
else
print_failure "Multiple or no configuration events found: $config_count"
fi
fi
# TEST 9: Network Port Binding
print_test_header "Test 9: Network Port Availability and Binding"
relay_pid=$(start_relay_test "network_test" 10)
sleep 3
if kill -0 $relay_pid 2>/dev/null; then
# Check if port 8888 is being used
if netstat -tln 2>/dev/null | grep -q ":8888"; then
print_success "Relay successfully bound to network port 8888"
else
print_failure "Relay not bound to expected port 8888"
fi
stop_relay_test $relay_pid
else
print_failure "Relay failed to start for network test"
fi
# TEST 10: Port Override with Admin/Relay Key Overrides
print_test_header "Test 10: Port Override with -a/-r Flags"
cleanup_test_files
# Generate test keys (64 hex chars each)
TEST_ADMIN_PUBKEY="1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
TEST_RELAY_PRIVKEY="abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
print_info "Testing port override with -p 9999 -a $TEST_ADMIN_PUBKEY -r $TEST_RELAY_PRIVKEY"
# Start relay with port override and key overrides
timeout 15 $RELAY_BINARY -p 9999 -a $TEST_ADMIN_PUBKEY -r $TEST_RELAY_PRIVKEY > "test_port_override.log" 2>&1 &
relay_pid=$!
sleep 5
if kill -0 $relay_pid 2>/dev/null; then
# Check if relay bound to port 9999 (not default 8888)
if netstat -tln 2>/dev/null | grep -q ":9999"; then
print_success "Relay successfully bound to overridden port 9999"
else
print_failure "Relay not bound to overridden port 9999"
fi
# Check that relay started successfully
if check_relay_startup "test_port_override.log"; then
print_success "Relay startup completed with overrides"
else
print_failure "Relay failed to complete startup with overrides"
fi
# Check that admin keys were NOT generated (since -a was provided)
if ! check_admin_keys "test_port_override.log"; then
print_success "Admin keys not generated (correctly using provided -a key)"
else
print_failure "Admin keys generated despite -a override"
fi
stop_relay_test $relay_pid
else
print_failure "Relay failed to start with port/key overrides"
fi
# TEST 11: Multiple Startup Attempts (Port Conflict)
print_test_header "Test 11: Port Conflict Handling"
relay_pid1=$(start_relay_test "port_conflict_1" 10)
sleep 2
if kill -0 $relay_pid1 2>/dev/null; then
# Try to start a second relay (should fail due to port conflict)
relay_pid2=$(start_relay_test "port_conflict_2" 5)
sleep 1
if [ "$relay_pid2" = "0" ] || ! kill -0 $relay_pid2 2>/dev/null; then
print_success "Port conflict properly handled (second instance failed to start)"
else
print_failure "Multiple relay instances started (port conflict not handled)"
stop_relay_test $relay_pid2
fi
stop_relay_test $relay_pid1
else
print_failure "First relay instance failed to start"
fi
# Final cleanup
cleanup_test_files
# Test Results Summary
echo
echo "========================================"
echo "Test Results Summary"
echo "========================================"
echo "Tests Passed: $TESTS_PASSED"
echo "Tests Failed: $TESTS_FAILED"
echo "Total Tests: $TESTS_TOTAL"
echo
if [ $TESTS_FAILED -eq 0 ]; then
print_success "ALL TESTS PASSED! Event-based configuration system is robust."
exit 0
else
print_failure "$TESTS_FAILED tests failed. Review the results above."
echo
print_info "Check individual test log files (test_*.log) for detailed error information."
exit 1
fi

View File

@@ -1,116 +0,0 @@
#!/bin/bash
# Test malformed expiration tag handling
# This test verifies that malformed expiration tags are ignored instead of treated as expired
set -e
RELAY_URL="ws://127.0.0.1:8888"
TEST_NAME="Malformed Expiration Tag Test"
echo "=== $TEST_NAME ==="
# Function to generate a test event with custom expiration tag
generate_event_with_expiration() {
local expiration_value="$1"
local current_time=$(date +%s)
local event_id=$(openssl rand -hex 32)
local private_key=$(openssl rand -hex 32)
local public_key=$(echo "$private_key" | xxd -r -p | openssl dgst -sha256 -binary | xxd -p -c 32)
# Create event JSON with malformed expiration
cat << EOF
["EVENT",{
"id": "$event_id",
"pubkey": "$public_key",
"created_at": $current_time,
"kind": 1,
"tags": [["expiration", "$expiration_value"]],
"content": "Test event with expiration: $expiration_value",
"sig": "$(openssl rand -hex 64)"
}]
EOF
}
# Function to send event and check response
test_malformed_expiration() {
local expiration_value="$1"
local description="$2"
echo "Testing: $description (expiration='$expiration_value')"
# Generate event
local event_json=$(generate_event_with_expiration "$expiration_value")
# Send event to relay using websocat or curl
if command -v websocat &> /dev/null; then
# Use websocat if available
response=$(echo "$event_json" | timeout 5s websocat "$RELAY_URL" 2>/dev/null | head -1 || echo "timeout")
else
# Fall back to a simple test
echo "websocat not available, skipping network test"
response='["OK","test",true,""]' # Simulate success
fi
echo "Response: $response"
# Check if response indicates success (malformed expiration should be ignored)
if [[ "$response" == *'"OK"'* ]] && [[ "$response" == *'true'* ]]; then
echo "✅ SUCCESS: Event with malformed expiration '$expiration_value' was accepted (ignored)"
elif [[ "$response" == "timeout" ]]; then
echo "⚠️ TIMEOUT: Could not test with relay (may be network issue)"
elif [[ "$response" == *'"OK"'* ]] && [[ "$response" == *'false'* ]]; then
if [[ "$response" == *"expired"* ]]; then
echo "❌ FAILED: Event with malformed expiration '$expiration_value' was treated as expired instead of ignored"
return 1
else
echo "⚠️ Event rejected for other reason: $response"
fi
else
echo "⚠️ Unexpected response format: $response"
fi
echo ""
}
echo "Starting malformed expiration tag tests..."
echo ""
# Test Case 1: Empty string
test_malformed_expiration "" "Empty string"
# Test Case 2: Non-numeric string
test_malformed_expiration "not_a_number" "Non-numeric string"
# Test Case 3: Mixed alphanumeric
test_malformed_expiration "123abc" "Mixed alphanumeric"
# Test Case 4: Negative number (technically valid but unusual)
test_malformed_expiration "-123" "Negative number"
# Test Case 5: Decimal number
test_malformed_expiration "123.456" "Decimal number"
# Test Case 6: Very large number
test_malformed_expiration "999999999999999999999999999" "Very large number"
# Test Case 7: Leading/trailing spaces
test_malformed_expiration " 123 " "Number with spaces"
# Test Case 8: Just whitespace
test_malformed_expiration " " "Only whitespace"
# Test Case 9: Special characters
test_malformed_expiration "!@#$%" "Special characters"
# Test Case 10: Valid number (should work normally)
future_time=$(($(date +%s) + 3600)) # 1 hour in future
test_malformed_expiration "$future_time" "Valid future timestamp"
echo "=== Test Summary ==="
echo "All malformed expiration tests completed."
echo "✅ Events with malformed expiration tags should be accepted (tags ignored)"
echo "✅ Events with valid expiration tags should work normally"
echo ""
echo "Check relay.log for detailed validation debug messages:"
echo "grep -A5 -B5 'malformed\\|Malformed\\|expiration' relay.log | tail -20"

View File

@@ -1,88 +0,0 @@
=== NIP-42 Authentication Test Started ===
2025-09-30 11:15:28 - Starting NIP-42 authentication tests
[INFO] === Starting NIP-42 Authentication Tests ===
[INFO] Checking dependencies...
[SUCCESS] Dependencies check complete
[INFO] Test 1: Checking NIP-42 support in relay info
[SUCCESS] NIP-42 is advertised in supported NIPs
2025-09-30 11:15:28 - Supported NIPs: 1,9,11,13,15,20,40,42
[INFO] Test 2: Testing AUTH challenge generation
[INFO] Found admin private key, configuring NIP-42 authentication...
[WARNING] Failed to create configuration event - proceeding with manual test
[INFO] Test 3: Testing complete NIP-42 authentication flow
[INFO] Generated test keypair: test_pubkey
[INFO] Attempting to publish event without authentication...
[INFO] Publishing test event to relay...
2025-09-30 11:15:30 - Event publish result: connecting to ws://localhost:8888... ok.
{"kind":1,"id":"acfc4da1903ce1c065f2c472348b21837a322c79cb4b248c62de5cff9b5b6607","pubkey":"d3e8d83eabac2a28e21039136a897399f4866893dd43bfbf0bdc8391913a4013","created_at":1759245329,"tags":[],"content":"NIP-42 test event - should require auth","sig":"2051b3da705214d5b5e95fb5b4dd9f1c893666965f7c51ccd2a9ccd495b67dd76ed3ce9768f0f2a16a3f9a602368e8102758ca3cc1408280094abf7e92fcc75e"}
publishing to ws://localhost:8888... success.
[SUCCESS] Relay requested authentication as expected
[INFO] Test 4: Testing WebSocket AUTH message handling
[INFO] Testing WebSocket connection and AUTH message...
[INFO] Sending test message via WebSocket...
2025-09-30 11:15:30 - WebSocket response:
[INFO] No AUTH challenge in WebSocket response
[INFO] Test 5: Testing NIP-42 configuration options
[INFO] Retrieving current relay configuration...
[WARNING] Could not retrieve configuration events
[INFO] Test 6: Testing NIP-42 performance and stability
[INFO] Testing multiple authentication attempts...
2025-09-30 11:15:31 - Attempt 1: .297874340s - connecting to ws://localhost:8888... ok.
{"kind":1,"id":"0d742f093b7be0ce811068e7a6171573dd225418c9459f5c7e9580f57d88af7b","pubkey":"37d1a52ec83a837eb8c6ae46df5c892f338c65ae0c29eb4873e775082252a18a","created_at":1759245331,"tags":[],"content":"Performance test event 1","sig":"d4aec950c47fbd4c1da637b84fafbde570adf86e08795236fb6a3f7e12d2dbaa16cb38cbb68d3b9755d186b20800bdb84b0a050f8933d06b10991a9542fe9909"}
publishing to ws://localhost:8888... success.
2025-09-30 11:15:32 - Attempt 2: .270493759s - connecting to ws://localhost:8888... ok.
{"kind":1,"id":"b45ae1b0458e284ed89b6de453bab489d506352680f6d37c8a5f0aed9eebc7a5","pubkey":"37d1a52ec83a837eb8c6ae46df5c892f338c65ae0c29eb4873e775082252a18a","created_at":1759245331,"tags":[],"content":"Performance test event 2","sig":"f9702aa537ec1485d151a0115c38c7f6f1bc05a63929be784e33850b46be6a961996eb922b8b337d607312c8e4583590ee35f38330300e19ab921f94926719c5"}
publishing to ws://localhost:8888... success.
2025-09-30 11:15:32 - Attempt 3: .239220029s - connecting to ws://localhost:8888... ok.
{"kind":1,"id":"5f70f9cb2a30a12e7d088e62a9295ef2fbea4f40a1d8b07006db03f610c5abce","pubkey":"37d1a52ec83a837eb8c6ae46df5c892f338c65ae0c29eb4873e775082252a18a","created_at":1759245332,"tags":[],"content":"Performance test event 3","sig":"ea2e1611ce3ddea3aa73764f4542bad7d922fc0d2ed40e58dcc2a66cb6e046bfae22d6baef296eb51d965a22b2a07394fc5f8664e3a7777382ae523431c782cd"}
publishing to ws://localhost:8888... success.
2025-09-30 11:15:33 - Attempt 4: .221429674s - connecting to ws://localhost:8888... ok.
{"kind":1,"id":"eafcf5f7e0bd0be35267f13ff93eef339faec6a5af13fe451fee2b7443b9de6e","pubkey":"37d1a52ec83a837eb8c6ae46df5c892f338c65ae0c29eb4873e775082252a18a","created_at":1759245332,"tags":[],"content":"Performance test event 4","sig":"976017abe67582af29d46cd54159ce0465c94caf348be35f26b6522cb48c4c9ce5ba9835e92873cf96a906605a032071360fc85beea815a8e4133a4f45d2bf0a"}
publishing to ws://localhost:8888... success.
2025-09-30 11:15:33 - Attempt 5: .242410067s - connecting to ws://localhost:8888... ok.
{"kind":1,"id":"c7cf6776000a325b1180240c61ef20b849b84dee3f5d2efed4c1a9e9fbdbd7b1","pubkey":"37d1a52ec83a837eb8c6ae46df5c892f338c65ae0c29eb4873e775082252a18a","created_at":1759245333,"tags":[],"content":"Performance test event 5","sig":"18b4575bd644146451dcf86607d75f358828ce2907e8904bd08b903ff5d79ec5a69ff60168735975cc406dcee788fd22fc7bf7c97fb7ac6dff3580eda56cee2e"}
publishing to ws://localhost:8888... success.
[SUCCESS] Performance test completed: 5/5 successful responses
[INFO] Test 7: Testing kind-specific NIP-42 authentication requirements
[INFO] Generated test keypair for kind-specific tests: test_pubkey
[INFO] Testing kind 1 event (regular note) - should work without authentication...
2025-09-30 11:15:34 - Kind 1 event result: connecting to ws://localhost:8888... ok.
{"kind":1,"id":"012690335e48736fd29769669d2bda15a079183c1d0f27b8400366a54b5b9ddd","pubkey":"ad362b9bbf61b140c5f677a2d091d622fef6fa186c579e6600dd8b24a85a2260","created_at":1759245334,"tags":[],"content":"Regular note - should not require auth","sig":"a3a0ce218666d2a374983a343bc24da5a727ce251c23828171021f15a3ab441a0c86f56200321467914ce4bee9a987f1de301151467ae639d7f941bac7fbe68e"}
publishing to ws://localhost:8888... success.
[SUCCESS] Kind 1 event accepted without authentication (correct behavior)
[INFO] Testing kind 4 event (direct message) - should require authentication...
2025-09-30 11:15:44 - Kind 4 event result: connecting to ws://localhost:8888... ok.
{"kind":4,"id":"e629dd91320d48c1e3103ec16e40c707c2ee8143012c9ad8bb9d32f98610f447","pubkey":"ad362b9bbf61b140c5f677a2d091d622fef6fa186c579e6600dd8b24a85a2260","created_at":1759245334,"tags":[["p,test_pubkey"]],"content":"This is a direct message - should require auth","sig":"7677b3f2932fb4979bab3da6d241217b7ea2010411fc8bf5a51f6987f38696d5634f91a30b13e0f4861479ceabff995b3bb2eb2fc74af5f3d1175235d5448ce2"}
publishing to ws://localhost:8888...
[SUCCESS] Kind 4 event requested authentication (correct behavior for DMs)
[INFO] Testing kind 14 event (chat message) - should require authentication...
2025-09-30 11:15:55 - Kind 14 event result: connecting to ws://localhost:8888... ok.
{"kind":14,"id":"a5398c5851dd72a8980723c91d35345bd0088b800102180dd41af7056f1cad50","pubkey":"ad362b9bbf61b140c5f677a2d091d622fef6fa186c579e6600dd8b24a85a2260","created_at":1759245344,"tags":[["p,test_pubkey"]],"content":"Chat message - should require auth","sig":"62d43f3f81755d4ef81cbfc8aca9abc11f28b0c45640f19d3dd41a09bae746fe7a4e9d8e458c416dcd2cab02deb090ce1e29e8426d9be5445d130eaa00d339f2"}
publishing to ws://localhost:8888...
[SUCCESS] Kind 14 event requested authentication (correct behavior for DMs)
[INFO] Testing other event kinds - should work without authentication...
2025-09-30 11:15:55 - Kind 0 event result: connecting to ws://localhost:8888... ok.
{"kind":0,"id":"069ac4db07da3230681aa37ab9e6a2aa48e2c199245259681e45ffb2f1b21846","pubkey":"ad362b9bbf61b140c5f677a2d091d622fef6fa186c579e6600dd8b24a85a2260","created_at":1759245355,"tags":[],"content":"Test event kind 0 - should not require auth","sig":"3c99b97c0ea2d18bc88fc07b2e95e213b6a6af804512d62158f8fd63cc24a3937533b830f59d38ccacccf98ba2fb0ed7467b16271154d4dd37fbc075eba32e49"}
publishing to ws://localhost:8888... success.
[SUCCESS] Kind 0 event accepted without authentication (correct)
2025-09-30 11:15:56 - Kind 3 event result: connecting to ws://localhost:8888... ok.
{"kind":3,"id":"1dd1ccb13ebd0d50b2aa79dbb938b408a24f0a4dd9f872b717ed91ae6729051c","pubkey":"ad362b9bbf61b140c5f677a2d091d622fef6fa186c579e6600dd8b24a85a2260","created_at":1759245355,"tags":[],"content":"Test event kind 3 - should not require auth","sig":"c205cc76f687c3957cf8b35cd8346fd8c2e44d9ef82324b95a7eef7f57429fb6f2ab1d0263dd5d00204dd90e626d5918a8710341b0d68a5095b41455f49cf0dd"}
publishing to ws://localhost:8888... success.
[SUCCESS] Kind 3 event accepted without authentication (correct)
2025-09-30 11:15:56 - Kind 7 event result: connecting to ws://localhost:8888... ok.
{"kind":7,"id":"b6161b1da8a4d362e3c230df99c4f87b6311ef6e9f67e03a2476f8a6366352c1","pubkey":"ad362b9bbf61b140c5f677a2d091d622fef6fa186c579e6600dd8b24a85a2260","created_at":1759245356,"tags":[],"content":"Test event kind 7 - should not require auth","sig":"ab06c4b00a04d726109acd02d663e30188ff9ee854cf877e854fda90dd776a649ef3fab8ae5b530b4e6b5530490dd536a281a721e471bd3748a0dacc4eac9622"}
publishing to ws://localhost:8888... success.
[SUCCESS] Kind 7 event accepted without authentication (correct)
[INFO] Kind-specific authentication test completed
[INFO] === NIP-42 Test Results Summary ===
[SUCCESS] Dependencies: PASS
[SUCCESS] NIP-42 Support: PASS
[SUCCESS] Auth Challenge: PASS
[SUCCESS] Auth Flow: PASS
[SUCCESS] WebSocket AUTH: PASS
[SUCCESS] Configuration: PASS
[SUCCESS] Performance: PASS
[SUCCESS] Kind-Specific Auth: PASS
[SUCCESS] All NIP-42 tests completed successfully!
[SUCCESS] NIP-42 authentication implementation is working correctly
[INFO] === NIP-42 Authentication Tests Complete ===

View File

@@ -1,150 +0,0 @@
#!/bin/bash
# Quick Error Handling and Recovery Tests for Event-Based Configuration System
# Focused tests for key error scenarios
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test results tracking
TESTS_PASSED=0
TESTS_FAILED=0
print_test() {
echo -e "${BLUE}[TEST]${NC} $1"
}
print_pass() {
echo -e "${GREEN}[PASS]${NC} $1"
((TESTS_PASSED++))
}
print_fail() {
echo -e "${RED}[FAIL]${NC} $1"
((TESTS_FAILED++))
}
print_info() {
echo -e "${YELLOW}[INFO]${NC} $1"
}
echo "========================================"
echo "Quick Error Handling and Recovery Tests"
echo "========================================"
echo
# Clean up any existing processes and files
print_info "Cleaning up existing processes..."
pkill -f c_relay 2>/dev/null || true
rm -f *.nrdb* 2>/dev/null || true
sleep 1
# TEST 1: Signature Validation Integration
print_test "Signature Validation Integration Check"
if grep -q "nostr_validate_event_structure\|nostr_verify_event_signature" src/config.c; then
print_pass "Signature validation functions found in code"
else
print_fail "Signature validation functions missing"
fi
# TEST 2: Legacy Schema Cleanup
print_test "Legacy Schema Cleanup Verification"
if ! grep -q "config_file_cache\|active_config" src/sql_schema.h; then
print_pass "Legacy tables removed from schema"
else
print_fail "Legacy tables still present in schema"
fi
# TEST 3: Configuration Event Processing
print_test "Configuration Event Processing Functions"
if grep -q "process_configuration_event\|handle_configuration_event" src/config.c; then
print_pass "Configuration event processing functions present"
else
print_fail "Configuration event processing functions missing"
fi
# TEST 4: Runtime Configuration Handlers
print_test "Runtime Configuration Handlers"
if grep -q "apply_runtime_config_handlers" src/config.c; then
print_pass "Runtime configuration handlers implemented"
else
print_fail "Runtime configuration handlers missing"
fi
# TEST 5: Error Logging Integration
print_test "Error Logging and Validation"
if grep -q "log_error.*signature\|log_error.*validation" src/config.c; then
print_pass "Error logging for validation integrated"
else
print_fail "Error logging for validation missing"
fi
# TEST 6: First-Time vs Existing Relay Detection
print_test "Relay State Detection Logic"
if grep -q "is_first_time_startup\|find_existing_nrdb_files" src/config.c; then
print_pass "Relay state detection functions present"
else
print_fail "Relay state detection functions missing"
fi
# TEST 7: Database Schema Version
print_test "Database Schema Version Check"
if grep -q "('version', '4')\|\"version\", \"4\"" src/sql_schema.h; then
print_pass "Database schema version 4 detected"
else
print_fail "Database schema version not updated"
fi
# TEST 8: Configuration Value Access Functions
print_test "Configuration Value Access"
if grep -q "get_config_value\|get_config_int\|get_config_bool" src/config.c; then
print_pass "Configuration access functions present"
else
print_fail "Configuration access functions missing"
fi
# TEST 9: Resource Cleanup Functions
print_test "Resource Cleanup Implementation"
if grep -q "cleanup_configuration_system\|cJSON_Delete" src/config.c; then
print_pass "Resource cleanup functions present"
else
print_fail "Resource cleanup functions missing"
fi
# TEST 10: Build System Integration
print_test "Build System Validation"
if [ -f "build/c_relay_x86" ]; then
print_pass "Binary built successfully"
else
print_fail "Binary not found - build may have failed"
fi
echo
echo "========================================"
echo "Quick Test Results Summary"
echo "========================================"
echo "Tests Passed: $TESTS_PASSED"
echo "Tests Failed: $TESTS_FAILED"
echo "Total Tests: $((TESTS_PASSED + TESTS_FAILED))"
echo
if [ $TESTS_FAILED -eq 0 ]; then
print_pass "ALL QUICK TESTS PASSED! Core error handling integrated."
echo
print_info "The event-based configuration system has:"
echo " ✓ Comprehensive signature validation"
echo " ✓ Runtime configuration handlers"
echo " ✓ Proper error logging and recovery"
echo " ✓ Clean database schema (v4)"
echo " ✓ Resource management and cleanup"
echo " ✓ First-time vs existing relay detection"
echo
exit 0
else
print_fail "$TESTS_FAILED tests failed. System needs attention."
exit 1
fi

View File

@@ -1,129 +0,0 @@
#!/bin/bash
# Test script for database statistics query functionality
# Tests the new stats_query admin API command
set -e
# Configuration
RELAY_HOST="127.0.0.1"
RELAY_PORT="8888"
ADMIN_PRIVKEY="f2f2bee9e45bec8ce1921f4c6dd6f6633c86ff291f56e480ac2bc47362dc2771"
ADMIN_PUBKEY="7a7a78cc7bd4c9879d67e2edd980730bda0d2a5e9e99b712e9307780b6bdbc03"
RELAY_PUBKEY="790ce38fbbbc9fdfa1723abe8f1a171c4005c869ab45df3dea4e0a0f201ba340"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
print_info() {
echo -e "${YELLOW}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[PASS]${NC} $1"
}
print_failure() {
echo -e "${RED}[FAIL]${NC} $1"
}
print_test() {
echo -e "${BLUE}[TEST]${NC} $1"
}
# Check if relay is running
check_relay_running() {
if pgrep -f "c_relay_" > /dev/null; then
return 0
else
return 1
fi
}
# Create a stats_query event
create_stats_query_event() {
# Create the command array
COMMAND='["stats_query"]'
# Create the event JSON
EVENT=$(cat <<EOF
{
"id": "$(openssl rand -hex 32)",
"pubkey": "$ADMIN_PUBKEY",
"created_at": $(date +%s),
"kind": 23456,
"content": "encrypted_placeholder",
"tags": [
["p", "$RELAY_PUBKEY"]
],
"sig": "signature_placeholder"
}
EOF
)
echo "$EVENT"
}
print_test "Database Statistics Query Test"
if ! check_relay_running; then
print_failure "Relay is not running. Please start the relay first."
exit 1
fi
print_info "Relay is running, proceeding with stats_query test"
# Create the stats query event
EVENT_JSON=$(create_stats_query_event)
print_info "Created stats_query event"
# For now, we'll just test that the relay accepts connections
# A full end-to-end test would require implementing NIP-44 encryption/decryption
# and WebSocket communication, which is complex for a shell script
print_info "Testing basic WebSocket connectivity..."
# Test basic WebSocket connection with a simple ping
if command -v websocat >/dev/null 2>&1; then
print_info "Using websocat to test WebSocket connection"
# Send a basic Nostr REQ message to test connectivity
TEST_MESSAGE='["REQ", "test_sub", {"kinds": [1], "limit": 1}]'
# This is a basic connectivity test - full stats_query testing would require
# implementing NIP-44 encryption and proper event signing
if echo "$TEST_MESSAGE" | timeout 5 websocat "ws://$RELAY_HOST:$RELAY_PORT" >/dev/null 2>&1; then
print_success "WebSocket connection to relay successful"
else
print_failure "WebSocket connection to relay failed"
fi
elif command -v wscat >/dev/null 2>&1; then
print_info "Using wscat to test WebSocket connection"
# Basic connectivity test
if echo "$TEST_MESSAGE" | timeout 5 wscat -c "ws://$RELAY_HOST:$RELAY_PORT" >/dev/null 2>&1; then
print_success "WebSocket connection to relay successful"
else
print_failure "WebSocket connection to relay failed"
fi
else
print_info "No WebSocket client found (websocat or wscat). Testing HTTP endpoint instead..."
# Test HTTP endpoint (NIP-11)
if curl -s -H "Accept: application/nostr+json" "http://$RELAY_HOST:$RELAY_PORT" >/dev/null 2>&1; then
print_success "HTTP endpoint accessible"
else
print_failure "HTTP endpoint not accessible"
fi
fi
print_info "Basic connectivity test completed"
print_info "Note: Full stats_query testing requires NIP-44 encryption implementation"
print_info "The backend stats_query handler has been implemented and integrated"
print_info "Manual testing via the web interface (api/index.html) is recommended"
print_success "Stats query backend implementation test completed"