Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fd3e531c3 | ||
|
|
c1c05991cf | ||
|
|
ab378e14d1 | ||
|
|
c0f9bf9ef5 |
@@ -27,7 +27,7 @@
|
||||
## Critical Integration Issues
|
||||
|
||||
### Event-Based Configuration System
|
||||
- **No traditional config files** - all configuration stored as kind 33334 Nostr events
|
||||
- **No traditional config files** - all configuration stored in config table
|
||||
- Admin private key shown **only once** on first startup
|
||||
- Configuration changes require cryptographically signed events
|
||||
- Database path determined by generated relay pubkey
|
||||
@@ -35,7 +35,7 @@
|
||||
### First-Time Startup Sequence
|
||||
1. Relay generates admin keypair and relay keypair
|
||||
2. Creates database file with relay pubkey as filename
|
||||
3. Stores default configuration as kind 33334 event
|
||||
3. Stores default configuration in config table
|
||||
4. **CRITICAL**: Admin private key displayed once and never stored on disk
|
||||
|
||||
### Port Management
|
||||
@@ -51,7 +51,7 @@
|
||||
### Configuration Event Structure
|
||||
```json
|
||||
{
|
||||
"kind": 33334,
|
||||
"kind": 23455,
|
||||
"content": "C Nostr Relay Configuration",
|
||||
"tags": [
|
||||
["d", "<relay_pubkey>"],
|
||||
|
||||
@@ -76,6 +76,7 @@ All commands are sent as nip44 encrypted content. The following table lists all
|
||||
| **Auth Rules Management** |
|
||||
| `auth_add_blacklist` | `["blacklist", "pubkey", "abc123..."]` | Add pubkey to blacklist |
|
||||
| `auth_add_whitelist` | `["whitelist", "pubkey", "def456..."]` | Add pubkey to whitelist |
|
||||
| `auth_delete_rule` | `["delete_auth_rule", "blacklist", "pubkey", "abc123..."]` | Delete specific auth rule |
|
||||
| `auth_query_all` | `["auth_query", "all"]` | Query all auth rules |
|
||||
| `auth_query_type` | `["auth_query", "whitelist"]` | Query specific rule type |
|
||||
| `auth_query_pattern` | `["auth_query", "pattern", "abc123..."]` | Query specific pattern |
|
||||
|
||||
1350
api/index.html
1350
api/index.html
File diff suppressed because it is too large
Load Diff
@@ -282,14 +282,14 @@ cd build
|
||||
# Start relay in background and capture its PID
|
||||
if [ "$USE_TEST_KEYS" = true ]; then
|
||||
echo "Using deterministic test keys for development..."
|
||||
./$(basename $BINARY_PATH) -a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -r 1111111111111111111111111111111111111111111111111111111111111111 > ../relay.log 2>&1 &
|
||||
./$(basename $BINARY_PATH) -a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -r 1111111111111111111111111111111111111111111111111111111111111111 --strict-port > ../relay.log 2>&1 &
|
||||
elif [ -n "$RELAY_ARGS" ]; then
|
||||
echo "Starting relay with custom configuration..."
|
||||
./$(basename $BINARY_PATH) $RELAY_ARGS > ../relay.log 2>&1 &
|
||||
./$(basename $BINARY_PATH) $RELAY_ARGS --strict-port > ../relay.log 2>&1 &
|
||||
else
|
||||
# No command line arguments needed for random key generation
|
||||
echo "Starting relay with random key generation..."
|
||||
./$(basename $BINARY_PATH) > ../relay.log 2>&1 &
|
||||
./$(basename $BINARY_PATH) --strict-port > ../relay.log 2>&1 &
|
||||
fi
|
||||
RELAY_PID=$!
|
||||
# Change back to original directory
|
||||
|
||||
783
src/config.c
783
src/config.c
File diff suppressed because it is too large
Load Diff
@@ -98,6 +98,7 @@ typedef struct {
|
||||
int port_override; // -1 = not set, >0 = port value
|
||||
char admin_privkey_override[65]; // Empty string = not set, 64-char hex = override
|
||||
char relay_privkey_override[65]; // Empty string = not set, 64-char hex = override
|
||||
int strict_port; // 0 = allow port increment, 1 = fail if exact port unavailable
|
||||
} cli_options_t;
|
||||
|
||||
// Global unified configuration cache
|
||||
@@ -172,10 +173,10 @@ int process_admin_auth_event(cJSON* event, char* error_message, size_t error_siz
|
||||
int handle_kind_23456_unified(cJSON* event, char* error_message, size_t error_size, struct lws* wsi);
|
||||
int handle_auth_query_unified(cJSON* event, const char* query_type, char* error_message, size_t error_size, struct lws* wsi);
|
||||
int handle_system_command_unified(cJSON* event, const char* command, char* error_message, size_t error_size, struct lws* wsi);
|
||||
int handle_auth_rule_modification_unified(cJSON* event, char* error_message, size_t error_size);
|
||||
int handle_auth_rule_modification_unified(cJSON* event, char* error_message, size_t error_size, struct lws* wsi);
|
||||
|
||||
// WebSocket response functions
|
||||
int send_websocket_response_data(cJSON* event, cJSON* response_data, struct lws* wsi);
|
||||
// Admin response functions
|
||||
int send_admin_response_event(const cJSON* response_data, const char* recipient_pubkey, struct lws* wsi);
|
||||
cJSON* build_query_response(const char* query_type, cJSON* results_array, int total_count);
|
||||
|
||||
// Auth rules management functions
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
* Default Configuration Event Template
|
||||
*
|
||||
* This header contains the default configuration values for the C Nostr Relay.
|
||||
* These values are used to create the initial kind 33334 configuration event
|
||||
* during first-time startup.
|
||||
* These values are used to populate the config table during first-time startup.
|
||||
*
|
||||
* IMPORTANT: These values should never be accessed directly by other parts
|
||||
* of the program. They are only used during initial configuration event creation.
|
||||
|
||||
64
src/main.c
64
src/main.c
@@ -224,10 +224,7 @@ int handle_event_message(cJSON* event, char* error_message, size_t error_size);
|
||||
// Forward declaration for unified validation
|
||||
int nostr_validate_unified_request(const char* json_string, size_t json_length);
|
||||
|
||||
// Forward declaration for configuration event handling (kind 33334)
|
||||
int handle_configuration_event(cJSON* event, char* error_message, size_t error_size);
|
||||
|
||||
// Forward declaration for admin event processing (kinds 33334 and 33335)
|
||||
// Forward declaration for admin event processing (kinds 23455 and 23456)
|
||||
int process_admin_event_in_config(cJSON* event, char* error_message, size_t error_size, struct lws* wsi);
|
||||
|
||||
// Forward declaration for enhanced admin event authorization
|
||||
@@ -3035,7 +3032,7 @@ int is_authorized_admin_event(cJSON* event, char* error_buffer, size_t error_buf
|
||||
}
|
||||
|
||||
int event_kind = kind_json->valueint;
|
||||
if (event_kind != 33334 && event_kind != 33335 && event_kind != 23455 && event_kind != 23456) {
|
||||
if (event_kind != 23455 && event_kind != 23456) {
|
||||
snprintf(error_buffer, error_buffer_size, "Event kind %d is not an admin event type", event_kind);
|
||||
return -1;
|
||||
}
|
||||
@@ -3203,11 +3200,18 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
|
||||
memcpy(message, in, len);
|
||||
message[len] = '\0';
|
||||
|
||||
log_info("Received WebSocket message");
|
||||
|
||||
// Parse JSON message
|
||||
// Parse JSON message (this is the normal program flow)
|
||||
cJSON* json = cJSON_Parse(message);
|
||||
if (json && cJSON_IsArray(json)) {
|
||||
// Log the complete parsed JSON message once
|
||||
char* complete_message = cJSON_Print(json);
|
||||
if (complete_message) {
|
||||
char debug_msg[2048];
|
||||
snprintf(debug_msg, sizeof(debug_msg),
|
||||
"Received complete WebSocket message: %s", complete_message);
|
||||
log_info(debug_msg);
|
||||
free(complete_message);
|
||||
}
|
||||
// Get message type
|
||||
cJSON* type = cJSON_GetArrayItem(json, 0);
|
||||
if (type && cJSON_IsString(type)) {
|
||||
@@ -3349,7 +3353,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
|
||||
// Cleanup event JSON string
|
||||
free(event_json_str);
|
||||
|
||||
// Check for admin events (kinds 33334, 33335, 23455, and 23456) and intercept them
|
||||
// Check for admin events (kinds 23455 and 23456) and intercept them
|
||||
if (result == 0) {
|
||||
cJSON* kind_obj = cJSON_GetObjectItem(event, "kind");
|
||||
if (kind_obj && cJSON_IsNumber(kind_obj)) {
|
||||
@@ -3371,7 +3375,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
|
||||
}
|
||||
}
|
||||
|
||||
if (event_kind == 33334 || event_kind == 33335 || event_kind == 23455 || event_kind == 23456) {
|
||||
if (event_kind == 23455 || event_kind == 23456) {
|
||||
// Enhanced admin event security - check authorization first
|
||||
log_info("DEBUG ADMIN: Admin event detected, checking authorization");
|
||||
|
||||
@@ -3690,7 +3694,7 @@ int check_port_available(int port) {
|
||||
}
|
||||
|
||||
// Start libwebsockets-based WebSocket Nostr relay server
|
||||
int start_websocket_relay(int port_override) {
|
||||
int start_websocket_relay(int port_override, int strict_port) {
|
||||
struct lws_context_creation_info info;
|
||||
|
||||
log_info("Starting libwebsockets-based Nostr relay server...");
|
||||
@@ -3700,7 +3704,7 @@ int start_websocket_relay(int port_override) {
|
||||
int configured_port = (port_override > 0) ? port_override : get_config_int("relay_port", DEFAULT_PORT);
|
||||
int actual_port = configured_port;
|
||||
int port_attempts = 0;
|
||||
const int max_port_attempts = 5;
|
||||
const int max_port_attempts = 10; // Increased from 5 to 10
|
||||
|
||||
// Minimal libwebsockets configuration
|
||||
info.protocols = protocols;
|
||||
@@ -3719,8 +3723,8 @@ int start_websocket_relay(int port_override) {
|
||||
// Max payload size for Nostr events
|
||||
info.max_http_header_data = 4096;
|
||||
|
||||
// Find an available port with pre-checking
|
||||
while (port_attempts < max_port_attempts) {
|
||||
// Find an available port with pre-checking (or fail immediately in strict mode)
|
||||
while (port_attempts < (strict_port ? 1 : max_port_attempts)) {
|
||||
char attempt_msg[256];
|
||||
snprintf(attempt_msg, sizeof(attempt_msg), "Checking port availability: %d", actual_port);
|
||||
log_info(attempt_msg);
|
||||
@@ -3728,7 +3732,13 @@ int start_websocket_relay(int port_override) {
|
||||
// Pre-check if port is available
|
||||
if (!check_port_available(actual_port)) {
|
||||
port_attempts++;
|
||||
if (port_attempts < max_port_attempts) {
|
||||
if (strict_port) {
|
||||
char error_msg[256];
|
||||
snprintf(error_msg, sizeof(error_msg),
|
||||
"Strict port mode: port %d is not available", actual_port);
|
||||
log_error(error_msg);
|
||||
return -1;
|
||||
} else if (port_attempts < max_port_attempts) {
|
||||
char retry_msg[256];
|
||||
snprintf(retry_msg, sizeof(retry_msg), "Port %d is in use, trying port %d (attempt %d/%d)",
|
||||
actual_port, actual_port + 1, port_attempts + 1, max_port_attempts);
|
||||
@@ -3767,7 +3777,13 @@ int start_websocket_relay(int port_override) {
|
||||
log_warning(lws_error_msg);
|
||||
|
||||
port_attempts++;
|
||||
if (port_attempts < max_port_attempts) {
|
||||
if (strict_port) {
|
||||
char error_msg[256];
|
||||
snprintf(error_msg, sizeof(error_msg),
|
||||
"Strict port mode: failed to bind to port %d", actual_port);
|
||||
log_error(error_msg);
|
||||
break;
|
||||
} else if (port_attempts < max_port_attempts) {
|
||||
actual_port++;
|
||||
continue;
|
||||
}
|
||||
@@ -3833,6 +3849,7 @@ void print_usage(const char* program_name) {
|
||||
printf(" -p, --port PORT Override relay port (first-time startup only)\n");
|
||||
printf(" -a, --admin-privkey HEX Override admin private key (64-char hex)\n");
|
||||
printf(" -r, --relay-privkey HEX Override relay private key (64-char hex)\n");
|
||||
printf(" --strict-port Fail if exact port is unavailable (no port increment)\n");
|
||||
printf("\n");
|
||||
printf("Configuration:\n");
|
||||
printf(" This relay uses event-based configuration stored in the database.\n");
|
||||
@@ -3841,10 +3858,16 @@ void print_usage(const char* program_name) {
|
||||
printf(" After initial setup, all configuration is managed via database events.\n");
|
||||
printf(" Database file: <relay_pubkey>.db (created automatically)\n");
|
||||
printf("\n");
|
||||
printf("Port Binding:\n");
|
||||
printf(" Default: Try up to 10 consecutive ports if requested port is busy\n");
|
||||
printf(" --strict-port: Fail immediately if exact requested port is unavailable\n");
|
||||
printf("\n");
|
||||
printf("Examples:\n");
|
||||
printf(" %s # Start relay (auto-configure on first run)\n", program_name);
|
||||
printf(" %s -p 8080 # First-time setup with port 8080\n", program_name);
|
||||
printf(" %s --port 9000 # First-time setup with port 9000\n", program_name);
|
||||
printf(" %s --strict-port # Fail if default port 8888 is unavailable\n", program_name);
|
||||
printf(" %s -p 8080 --strict-port # Fail if port 8080 is unavailable\n", program_name);
|
||||
printf(" %s --help # Show this help\n", program_name);
|
||||
printf(" %s --version # Show version info\n", program_name);
|
||||
printf("\n");
|
||||
@@ -3863,7 +3886,8 @@ int main(int argc, char* argv[]) {
|
||||
cli_options_t cli_options = {
|
||||
.port_override = -1, // -1 = not set
|
||||
.admin_privkey_override = {0}, // Empty string = not set
|
||||
.relay_privkey_override = {0} // Empty string = not set
|
||||
.relay_privkey_override = {0}, // Empty string = not set
|
||||
.strict_port = 0 // 0 = allow port increment (default)
|
||||
};
|
||||
|
||||
// Parse command line arguments
|
||||
@@ -3958,6 +3982,10 @@ int main(int argc, char* argv[]) {
|
||||
i++; // Skip the key argument
|
||||
|
||||
log_info("Relay private key override specified");
|
||||
} else if (strcmp(argv[i], "--strict-port") == 0) {
|
||||
// Strict port mode option
|
||||
cli_options.strict_port = 1;
|
||||
log_info("Strict port mode enabled - will fail if exact port is unavailable");
|
||||
} else {
|
||||
log_error("Unknown argument. Use --help for usage information.");
|
||||
print_usage(argv[0]);
|
||||
@@ -4179,7 +4207,7 @@ int main(int argc, char* argv[]) {
|
||||
log_info("Starting relay server...");
|
||||
|
||||
// Start WebSocket Nostr relay server (port from configuration)
|
||||
int result = start_websocket_relay(-1); // Let config system determine port
|
||||
int result = start_websocket_relay(-1, cli_options.strict_port); // Let config system determine port, pass strict_port flag
|
||||
|
||||
// Cleanup
|
||||
cleanup_relay_info();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
static const char* const EMBEDDED_SCHEMA_SQL =
|
||||
"-- C Nostr Relay Database Schema\n\
|
||||
-- SQLite schema for storing Nostr events with JSON tags support\n\
|
||||
-- Event-based configuration system using kind 33334 Nostr events\n\
|
||||
-- Configuration system using config table\n\
|
||||
\n\
|
||||
-- Schema version tracking\n\
|
||||
PRAGMA user_version = 7;\n\
|
||||
|
||||
@@ -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'
|
||||
@@ -120,24 +117,99 @@ generate_test_keypair() {
|
||||
|
||||
echo "$pubkey" > "$pubkey_file"
|
||||
|
||||
log_info "Generated keypair for $name: pubkey=${pubkey:0:16}..."
|
||||
log_info "Generated keypair for $name: pubkey=$pubkey"
|
||||
|
||||
# Export for use in calling functions
|
||||
eval "${name}_PRIVKEY=\"$privkey\""
|
||||
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: About to encrypt content: '$content'" >&2
|
||||
log_info "DEBUG: Sender privkey: $sender_privkey" >&2
|
||||
log_info "DEBUG: Receiver pubkey: $receiver_pubkey" >&2
|
||||
|
||||
# Use nak to perform NIP-44 encryption with correct syntax:
|
||||
# nak encrypt --recipient-pubkey <pubkey> --sec <private_key> [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"
|
||||
log_error "Receiver pubkey: $receiver_pubkey"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Validate that encrypted content is valid base64 and doesn't contain problematic characters
|
||||
if ! echo "$encrypted_content" | grep -q '^[A-Za-z0-9+/]*=*$'; then
|
||||
log_error "Encrypted content contains invalid characters for JSON: $encrypted_content"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if encrypted content is valid UTF-8/base64
|
||||
if ! echo "$encrypted_content" | base64 -d >/dev/null 2>&1; then
|
||||
log_warning "Encrypted content may not be valid base64: $encrypted_content"
|
||||
fi
|
||||
|
||||
log_info "DEBUG: Encrypted content: $encrypted_content" >&2
|
||||
log_info "Successfully encrypted content with NIP-44" >&2
|
||||
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"
|
||||
|
||||
# Use nak to perform NIP-44 decryption with correct syntax:
|
||||
# nak decrypt --sender-pubkey <pubkey> --sec <private_key> [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"
|
||||
log_error "Receiver privkey: $receiver_privkey"
|
||||
log_error "Sender pubkey: $sender_pubkey"
|
||||
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")
|
||||
response=$(printf '%s\n' "$message" | timeout "$timeout" websocat "$RELAY_URL" 2>&1 || echo "Connection failed")
|
||||
|
||||
# Check if connection failed
|
||||
if [[ "$response" == *"Connection failed"* ]]; then
|
||||
@@ -154,143 +226,137 @@ 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"
|
||||
|
||||
# Create named pipes
|
||||
mkfifo "$WS_INPUT_FIFO" "$WS_OUTPUT_FIFO"
|
||||
# Create EVENT message using jq to properly handle special characters
|
||||
local event_message
|
||||
event_message=$(jq -n --argjson event "$event_json" '["EVENT", $event]')
|
||||
|
||||
# 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=$!
|
||||
# Validate that the event message is valid UTF-8 (temporarily disabled for debugging)
|
||||
# if ! echo "$event_message" | iconv -f utf-8 -t utf-8 >/dev/null 2>&1; then
|
||||
# log_error "Event message contains invalid UTF-8 characters"
|
||||
# return 1
|
||||
# fi
|
||||
|
||||
# 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}>&-
|
||||
# Use websocat to send event and capture OK response
|
||||
local response=""
|
||||
if command -v websocat &> /dev/null; then
|
||||
log_info "Sending event using websocat..."
|
||||
|
||||
# Debug: Show what we're sending
|
||||
log_info "DEBUG: Event message being sent: $event_message"
|
||||
|
||||
# Write to temporary file to avoid shell interpretation issues
|
||||
local temp_file="${TEMP_DIR}/event_message_$$"
|
||||
printf '%s\n' "$event_message" > "$temp_file"
|
||||
|
||||
# Send via websocat using file input with delay to receive response
|
||||
response=$(timeout "$timeout_seconds" sh -c "cat '$temp_file'; sleep 0.5" | websocat "$RELAY_URL" 2>&1)
|
||||
local websocat_exit_code=$?
|
||||
|
||||
# Clean up temp file
|
||||
rm -f "$temp_file"
|
||||
|
||||
log_info "DEBUG: Websocat exit code: $websocat_exit_code"
|
||||
log_info "DEBUG: Websocat response: $response"
|
||||
|
||||
# Check for specific websocat errors
|
||||
if [[ "$response" == *"UTF-8 failure"* ]]; then
|
||||
log_error "UTF-8 encoding error in event data for $description"
|
||||
log_error "Event message: $event_message"
|
||||
return 1
|
||||
elif [[ "$response" == *"Connection failed"* ]] || [[ "$response" == *"Connection refused"* ]] || [[ "$response" == *"timeout"* ]]; then
|
||||
log_error "Failed to connect to relay for $description"
|
||||
return 1
|
||||
elif [[ "$response" == *"error running"* ]]; then
|
||||
log_error "Websocat error for $description: $response"
|
||||
return 1
|
||||
elif [ $websocat_exit_code -eq 0 ]; then
|
||||
log_info "Event sent successfully via websocat"
|
||||
else
|
||||
log_warning "Websocat returned exit code $websocat_exit_code"
|
||||
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"
|
||||
|
||||
# Create EVENT message
|
||||
local event_message="[\"EVENT\",$event_json]"
|
||||
|
||||
# Send through persistent connection
|
||||
echo "$event_message" >&${ws_fd}
|
||||
|
||||
# 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
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
log_error "Timeout waiting for WebSocket response"
|
||||
return 1
|
||||
echo "$response"
|
||||
}
|
||||
|
||||
# Wait for query response data from relay
|
||||
wait_for_query_response() {
|
||||
local timeout_seconds="${1:-10}"
|
||||
local start_time=$(date +%s)
|
||||
# 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 "Waiting for query response data..."
|
||||
log_info "Sending admin query: $description"
|
||||
|
||||
# Clear any OK responses and wait for JSON data
|
||||
sleep 0.5 # Brief delay to ensure OK response is processed first
|
||||
# Create EVENT message using jq to properly handle special characters
|
||||
local event_message
|
||||
event_message=$(jq -n --argjson event "$event_json" '["EVENT", $event]')
|
||||
|
||||
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
|
||||
# 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\"]"
|
||||
|
||||
# Send query event and subscription in sequence
|
||||
local response=""
|
||||
if command -v websocat &> /dev/null; then
|
||||
response=$(printf '%s\n%s\n%s\n' "$event_message" "$req_message" "$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
|
||||
|
||||
# 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
|
||||
|
||||
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
|
||||
@@ -301,15 +367,26 @@ send_auth_rule_event() {
|
||||
local pattern_value="$4" # actual pubkey or hash value
|
||||
local description="$5" # optional description
|
||||
|
||||
log_info "Creating auth rule event: $action $rule_type $pattern_type ${pattern_value:0:16}..."
|
||||
log_info "Creating auth rule event: $action $rule_type $pattern_type $pattern_value"
|
||||
|
||||
# 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 +394,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 +418,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 +446,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
|
||||
}
|
||||
|
||||
@@ -414,7 +476,7 @@ test_event_publishing() {
|
||||
log_info "Testing event publishing: $description"
|
||||
|
||||
# Create a simple test event (kind 1 - text note) using nak like NIP-42 test
|
||||
local test_content="Test message from ${test_pubkey:0:16}... at $(date)"
|
||||
local test_content="Test message from $test_pubkey at $(date)"
|
||||
local test_event
|
||||
test_event=$(nak event -k 1 --content "$test_content" --sec "$test_privkey" 2>/dev/null)
|
||||
|
||||
@@ -426,7 +488,7 @@ test_event_publishing() {
|
||||
# Send the event using nak directly (more reliable than websocat)
|
||||
log_info "Publishing test event to relay..."
|
||||
local result
|
||||
result=$(echo "$test_event" | timeout 10s nak event "$RELAY_URL" 2>&1)
|
||||
result=$(printf '%s\n' "$test_event" | timeout 10s nak event "$RELAY_URL" 2>&1)
|
||||
local exit_code=$?
|
||||
|
||||
log_info "Event publishing result: $result"
|
||||
@@ -506,11 +568,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
|
||||
@@ -518,15 +591,17 @@ test_admin_authentication() {
|
||||
return
|
||||
fi
|
||||
|
||||
# Send admin event
|
||||
local message="[\"EVENT\",$config_event]"
|
||||
# Send admin event using the proper admin event function
|
||||
local response
|
||||
response=$(send_websocket_message "$message" "OK" 10)
|
||||
response=$(send_admin_event "$config_event" "admin authentication test")
|
||||
local exit_code=$?
|
||||
|
||||
if echo "$response" | grep -q '"OK".*true'; then
|
||||
log_info "Admin authentication result: $response"
|
||||
|
||||
if [ $exit_code -eq 0 ] && echo "$response" | grep -q '"OK".*true'; then
|
||||
pass_test "Admin authentication successful"
|
||||
else
|
||||
fail_test "Admin authentication failed: $response"
|
||||
fail_test "Admin authentication failed: $response (exit code: $exit_code)"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -548,10 +623,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 +646,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"
|
||||
@@ -747,14 +834,14 @@ test_hash_blacklist() {
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Testing hash blacklist with event ID: ${event_id:0:16}..."
|
||||
log_info "Testing hash blacklist with event ID: $event_id"
|
||||
|
||||
# Add the event ID to hash blacklist
|
||||
if send_auth_rule_event "add" "blacklist" "hash" "$event_id" "Test hash blacklist"; then
|
||||
# Try to publish the same event using nak - should be blocked
|
||||
log_info "Attempting to publish blacklisted event..."
|
||||
local result
|
||||
result=$(echo "$test_event" | timeout 10s nak event "$RELAY_URL" 2>&1)
|
||||
result=$(printf '%s\n' "$test_event" | timeout 10s nak event "$RELAY_URL" 2>&1)
|
||||
local exit_code=$?
|
||||
|
||||
if [ $exit_code -ne 0 ] || echo "$result" | grep -q -i "blocked\|denied\|rejected\|blacklist"; then
|
||||
@@ -786,7 +873,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))
|
||||
@@ -884,7 +971,7 @@ run_all_tests() {
|
||||
clear_all_auth_rules
|
||||
|
||||
test_admin_authentication
|
||||
test_auth_rules_storage_query
|
||||
# test_auth_rules_storage_query
|
||||
# test_basic_whitelist
|
||||
# test_basic_blacklist
|
||||
# test_rule_removal
|
||||
@@ -941,7 +1028,7 @@ main() {
|
||||
echo ""
|
||||
|
||||
# Check if relay is running - using websocat like the working tests
|
||||
if ! echo '["REQ","connection_test",{}]' | timeout 5 websocat "$RELAY_URL" >/dev/null 2>&1; then
|
||||
if ! printf '%s\n' '["REQ","connection_test",{}]' | timeout 5 websocat "$RELAY_URL" >/dev/null 2>&1; then
|
||||
log_error "Cannot connect to relay at $RELAY_URL"
|
||||
log_error "Please ensure the C-Relay server is running in test mode"
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user