#!/bin/bash # Ginxsom Manual Configuration Generator # Creates signed configuration events for server setup set -e # Default values ADMIN_KEY="" SERVER_KEY="" CDN_ORIGIN="http://localhost:9001" MAX_FILE_SIZE="104857600" # 100MB NIP94_ENABLED="true" AUTH_RULES_ENABLED="false" AUTH_CACHE_TTL="300" OUTPUT_FILE="" EXPIRATION_HOURS="8760" # 1 year # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Helper functions log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } # Display usage usage() { cat << EOF Usage: $0 [OPTIONS] Generate a signed Ginxsom configuration event. OPTIONS: --admin-key KEY Admin private key (hex, 64 chars) --server-key KEY Server private key (hex, 64 chars) --cdn-origin URL CDN origin URL (default: http://localhost:9001) --max-size BYTES Maximum file size in bytes (default: 104857600) --enable-nip94 Enable NIP-94 metadata (default: true) --disable-nip94 Disable NIP-94 metadata --enable-auth-rules Enable authentication rules system --disable-auth-rules Disable authentication rules system (default) --cache-ttl SECONDS Auth cache TTL in seconds (default: 300) --expiration HOURS Config expiration in hours (default: 8760) --output FILE Output file path --generate-keys Generate new admin and server keys --help Show this help EXAMPLES: # Generate keys and create config interactively $0 --generate-keys --output config.json # Create config with existing keys $0 --admin-key abc123... --server-key def456... --output config.json # Create config for production server $0 --admin-key abc123... --server-key def456... \\ --cdn-origin https://cdn.example.com \\ --max-size 209715200 \\ --enable-auth-rules \\ --output /etc/ginxsom/config.json EOF } # Parse command line arguments parse_args() { while [[ $# -gt 0 ]]; do case $1 in --admin-key) ADMIN_KEY="$2" shift 2 ;; --server-key) SERVER_KEY="$2" shift 2 ;; --cdn-origin) CDN_ORIGIN="$2" shift 2 ;; --max-size) MAX_FILE_SIZE="$2" shift 2 ;; --enable-nip94) NIP94_ENABLED="true" shift ;; --disable-nip94) NIP94_ENABLED="false" shift ;; --enable-auth-rules) AUTH_RULES_ENABLED="true" shift ;; --disable-auth-rules) AUTH_RULES_ENABLED="false" shift ;; --cache-ttl) AUTH_CACHE_TTL="$2" shift 2 ;; --expiration) EXPIRATION_HOURS="$2" shift 2 ;; --output) OUTPUT_FILE="$2" shift 2 ;; --generate-keys) GENERATE_KEYS="true" shift ;; --help) usage exit 0 ;; *) log_error "Unknown option: $1" usage exit 1 ;; esac done } # Check dependencies check_dependencies() { log_info "Checking dependencies..." local missing_deps=() for cmd in nak jq; do if ! command -v $cmd &> /dev/null; then missing_deps+=("$cmd") fi done if [ ${#missing_deps[@]} -ne 0 ]; then log_error "Missing dependencies: ${missing_deps[*]}" echo "" echo "Please install the missing dependencies:" echo "- nak: https://github.com/fiatjaf/nak" echo "- jq: sudo apt install jq (or equivalent for your system)" exit 1 fi log_success "All dependencies found" } # Generate new key pairs generate_keys() { log_info "Generating new key pairs..." ADMIN_KEY=$(nak key generate) SERVER_KEY=$(nak key generate) local admin_pubkey=$(echo "$ADMIN_KEY" | nak key public) local server_pubkey=$(echo "$SERVER_KEY" | nak key public) log_success "New keys generated:" echo " Admin Private Key: $ADMIN_KEY" echo " Admin Public Key: $admin_pubkey" echo " Server Private Key: $SERVER_KEY" echo " Server Public Key: $server_pubkey" echo "" log_warning "Save these keys securely!" } # Validate keys validate_keys() { log_info "Validating keys..." if [ -z "$ADMIN_KEY" ]; then log_error "Admin key is required (use --admin-key or --generate-keys)" exit 1 fi if [ -z "$SERVER_KEY" ]; then log_error "Server key is required (use --server-key or --generate-keys)" exit 1 fi # Validate key format (64 hex characters) if [[ ! "$ADMIN_KEY" =~ ^[a-fA-F0-9]{64}$ ]]; then log_error "Invalid admin key format (must be 64 hex characters)" exit 1 fi if [[ ! "$SERVER_KEY" =~ ^[a-fA-F0-9]{64}$ ]]; then log_error "Invalid server key format (must be 64 hex characters)" exit 1 fi # Test key validity with nak local admin_pubkey=$(echo "$ADMIN_KEY" | nak key public 2>/dev/null) local server_pubkey=$(echo "$SERVER_KEY" | nak key public 2>/dev/null) if [ -z "$admin_pubkey" ]; then log_error "Invalid admin private key" exit 1 fi if [ -z "$server_pubkey" ]; then log_error "Invalid server private key" exit 1 fi log_success "Keys validated" } # Validate configuration values validate_config() { log_info "Validating configuration..." # Validate URL format if [[ ! "$CDN_ORIGIN" =~ ^https?:// ]]; then log_error "CDN origin must be a valid HTTP/HTTPS URL" exit 1 fi # Validate max file size if [[ ! "$MAX_FILE_SIZE" =~ ^[0-9]+$ ]]; then log_error "Max file size must be a number" exit 1 fi if [ "$MAX_FILE_SIZE" -lt 1024 ]; then log_error "Max file size must be at least 1024 bytes" exit 1 fi # Validate boolean values if [[ ! "$NIP94_ENABLED" =~ ^(true|false)$ ]]; then log_error "NIP94 enabled must be 'true' or 'false'" exit 1 fi if [[ ! "$AUTH_RULES_ENABLED" =~ ^(true|false)$ ]]; then log_error "Auth rules enabled must be 'true' or 'false'" exit 1 fi # Validate cache TTL if [[ ! "$AUTH_CACHE_TTL" =~ ^[0-9]+$ ]]; then log_error "Cache TTL must be a number" exit 1 fi if [ "$AUTH_CACHE_TTL" -lt 60 ]; then log_error "Cache TTL must be at least 60 seconds" exit 1 fi log_success "Configuration validated" } # Create configuration event create_config_event() { log_info "Creating signed configuration event..." local expiration=$(($(date +%s) + (EXPIRATION_HOURS * 3600))) # Create configuration event with all settings CONFIG_EVENT=$(nak event -k 33333 -c "Ginxsom server configuration" \ --tag server_privkey="$SERVER_KEY" \ --tag cdn_origin="$CDN_ORIGIN" \ --tag max_file_size="$MAX_FILE_SIZE" \ --tag nip94_enabled="$NIP94_ENABLED" \ --tag auth_rules_enabled="$AUTH_RULES_ENABLED" \ --tag auth_cache_ttl="$AUTH_CACHE_TTL" \ --tag expiration="$expiration" \ --sec "$ADMIN_KEY") if [ $? -ne 0 ]; then log_error "Failed to create configuration event" exit 1 fi log_success "Configuration event created and signed" } # Save configuration save_config() { if [ -z "$OUTPUT_FILE" ]; then # Default output location if [ -n "$XDG_CONFIG_HOME" ]; then OUTPUT_FILE="$XDG_CONFIG_HOME/ginxsom/ginxsom_config_event.json" else OUTPUT_FILE="$HOME/.config/ginxsom/ginxsom_config_event.json" fi fi log_info "Saving configuration to $OUTPUT_FILE" # Create directory if needed local output_dir=$(dirname "$OUTPUT_FILE") mkdir -p "$output_dir" # Save formatted JSON echo "$CONFIG_EVENT" | jq . > "$OUTPUT_FILE" if [ $? -ne 0 ]; then log_error "Failed to save configuration file" exit 1 fi chmod 600 "$OUTPUT_FILE" log_success "Configuration saved to $OUTPUT_FILE" } # Display summary show_summary() { local admin_pubkey=$(echo "$ADMIN_KEY" | nak key public) local server_pubkey=$(echo "$SERVER_KEY" | nak key public) echo "" echo "=================================================================" echo " GINXSOM CONFIGURATION GENERATED" echo "=================================================================" echo "" log_success "Configuration file: $OUTPUT_FILE" echo "" echo "Configuration summary:" echo " Admin Public Key: $admin_pubkey" echo " Server Public Key: $server_pubkey" echo " CDN Origin: $CDN_ORIGIN" echo " Max File Size: $(( MAX_FILE_SIZE / 1024 / 1024 ))MB" echo " NIP-94 Enabled: $NIP94_ENABLED" echo " Auth Rules Enabled: $AUTH_RULES_ENABLED" echo " Cache TTL: ${AUTH_CACHE_TTL}s" echo " Expires: $(date -d @$(($(date +%s) + (EXPIRATION_HOURS * 3600))))" echo "" echo "Next steps:" echo "1. Place config file in server's config directory" echo "2. Set admin_pubkey in server database:" echo " sqlite3 db/ginxsom.db << EOF" echo " INSERT OR REPLACE INTO server_config (key, value) VALUES" echo " ('admin_pubkey', '$admin_pubkey')," echo " ('admin_enabled', 'true');" echo " EOF" echo "3. Start ginxsom server" echo "" } # Main execution main() { parse_args "$@" if [ "$GENERATE_KEYS" = "true" ]; then check_dependencies generate_keys fi validate_keys validate_config create_config_event save_config show_summary } # Run main function if script is executed directly if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi