This commit is contained in:
Your Name
2025-09-07 10:59:43 -04:00
parent f5bf1cd6ee
commit 67154164f1
60 changed files with 45716 additions and 58 deletions

342
scripts/setup.sh Executable file
View File

@@ -0,0 +1,342 @@
#!/bin/bash
# Ginxsom Interactive Setup Wizard
# Creates signed configuration events for first-run server setup
set -e
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
CONFIG_PATH="${1:-}"
# 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"; }
# 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"
}
# Validate private key format
validate_private_key() {
local key="$1"
if [[ ! "$key" =~ ^[a-fA-F0-9]{64}$ ]]; then
return 1
fi
return 0
}
# Setup key pairs with user choice
setup_keys() {
log_info "Setting up cryptographic key pairs..."
echo ""
echo "=== Admin Key Setup ==="
echo "Choose an option for your admin private key:"
echo "1. Generate a new random admin key"
echo "2. Use an existing admin private key"
echo ""
while true; do
echo -n "Choice (1/2): "
read -r ADMIN_KEY_CHOICE
case "$ADMIN_KEY_CHOICE" in
1)
log_info "Generating new admin key pair..."
ADMIN_PRIVKEY=$(nak key generate)
ADMIN_PUBKEY=$(echo "$ADMIN_PRIVKEY" | nak key public)
log_success "New admin key pair generated"
break
;;
2)
echo -n "Enter your admin private key (64 hex characters): "
read -r ADMIN_PRIVKEY
if validate_private_key "$ADMIN_PRIVKEY"; then
ADMIN_PUBKEY=$(echo "$ADMIN_PRIVKEY" | nak key public)
if [ $? -eq 0 ]; then
log_success "Admin private key validated"
break
else
log_error "Invalid private key format or nak error"
fi
else
log_error "Invalid private key format (must be 64 hex characters)"
fi
;;
*)
log_error "Please choose 1 or 2"
;;
esac
done
echo ""
echo "=== Server Key Setup ==="
echo "Choose an option for your Ginxsom server private key:"
echo "1. Generate a new random server key"
echo "2. Use an existing server private key"
echo ""
while true; do
echo -n "Choice (1/2): "
read -r SERVER_KEY_CHOICE
case "$SERVER_KEY_CHOICE" in
1)
log_info "Generating new server key pair..."
SERVER_PRIVKEY=$(nak key generate)
SERVER_PUBKEY=$(echo "$SERVER_PRIVKEY" | nak key public)
log_success "New server key pair generated"
break
;;
2)
echo -n "Enter your server private key (64 hex characters): "
read -r SERVER_PRIVKEY
if validate_private_key "$SERVER_PRIVKEY"; then
SERVER_PUBKEY=$(echo "$SERVER_PRIVKEY" | nak key public)
if [ $? -eq 0 ]; then
log_success "Server private key validated"
break
else
log_error "Invalid private key format or nak error"
fi
else
log_error "Invalid private key format (must be 64 hex characters)"
fi
;;
*)
log_error "Please choose 1 or 2"
;;
esac
done
echo ""
log_success "Key pairs configured:"
echo " Admin Public Key: $ADMIN_PUBKEY"
echo " Server Public Key: $SERVER_PUBKEY"
# Save keys securely
echo "ADMIN_PRIVKEY='$ADMIN_PRIVKEY'" > "$PROJECT_ROOT/.admin_keys"
echo "ADMIN_PUBKEY='$ADMIN_PUBKEY'" >> "$PROJECT_ROOT/.admin_keys"
echo "SERVER_PRIVKEY='$SERVER_PRIVKEY'" >> "$PROJECT_ROOT/.admin_keys"
echo "SERVER_PUBKEY='$SERVER_PUBKEY'" >> "$PROJECT_ROOT/.admin_keys"
chmod 600 "$PROJECT_ROOT/.admin_keys"
log_warning "Keys saved to $PROJECT_ROOT/.admin_keys (keep this file secure!)"
}
# Collect server configuration
collect_configuration() {
log_info "Collecting server configuration..."
echo ""
echo "=== Server Configuration Setup ==="
# CDN Origin
echo -n "CDN Origin URL (default: http://localhost:9001): "
read -r CDN_ORIGIN
CDN_ORIGIN="${CDN_ORIGIN:-http://localhost:9001}"
# Max file size
echo -n "Maximum file size in MB (default: 100): "
read -r MAX_SIZE_MB
MAX_SIZE_MB="${MAX_SIZE_MB:-100}"
MAX_FILE_SIZE=$((MAX_SIZE_MB * 1024 * 1024))
# NIP-94 support
echo -n "Enable NIP-94 metadata (y/n, default: y): "
read -r ENABLE_NIP94
case "$ENABLE_NIP94" in
[Nn]*) NIP94_ENABLED="false" ;;
*) NIP94_ENABLED="true" ;;
esac
# Authentication rules
echo -n "Enable authentication rules system (y/n, default: n): "
read -r ENABLE_AUTH_RULES
case "$ENABLE_AUTH_RULES" in
[Yy]*) AUTH_RULES_ENABLED="true" ;;
*) AUTH_RULES_ENABLED="false" ;;
esac
# Cache TTL
echo -n "Authentication cache TTL in seconds (default: 300): "
read -r CACHE_TTL
CACHE_TTL="${CACHE_TTL:-300}"
echo ""
log_success "Configuration collected:"
echo " CDN Origin: $CDN_ORIGIN"
echo " Max File Size: ${MAX_SIZE_MB}MB"
echo " NIP-94 Enabled: $NIP94_ENABLED"
echo " Auth Rules Enabled: $AUTH_RULES_ENABLED"
echo " Cache TTL: ${CACHE_TTL}s"
}
# Create configuration event
create_config_event() {
log_info "Creating signed configuration event..."
local expiration=$(($(date +%s) + 31536000)) # 1 year from now
# Create configuration event with all settings
CONFIG_EVENT=$(nak event -k 33333 -c "Ginxsom server configuration" \
--tag server_privkey="$SERVER_PRIVKEY" \
--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="$CACHE_TTL" \
--tag expiration="$expiration" \
--sec "$ADMIN_PRIVKEY")
if [ $? -ne 0 ]; then
log_error "Failed to create configuration event"
exit 1
fi
log_success "Configuration event created and signed"
}
# Save configuration file
save_config_file() {
local config_file="$1"
log_info "Saving configuration to $config_file"
# Create directory if it doesn't exist
local config_dir=$(dirname "$config_file")
mkdir -p "$config_dir"
# Save configuration event to file
echo "$CONFIG_EVENT" | jq . > "$config_file"
if [ $? -ne 0 ]; then
log_error "Failed to save configuration file"
exit 1
fi
chmod 600 "$config_file"
log_success "Configuration saved to $config_file"
}
# Setup database
setup_database() {
log_info "Setting up database configuration..."
local db_path="$PROJECT_ROOT/db/ginxsom.db"
if [ ! -f "$db_path" ]; then
log_warning "Database not found at $db_path"
log_warning "Please ensure the database is initialized before starting the server"
return
fi
# Insert admin configuration into database
sqlite3 "$db_path" << EOF
INSERT OR REPLACE INTO server_config (key, value, description) VALUES
('admin_pubkey', '$ADMIN_PUBKEY', 'Admin public key from setup wizard'),
('admin_enabled', 'true', 'Enable admin interface');
EOF
if [ $? -eq 0 ]; then
log_success "Database configuration updated"
else
log_warning "Failed to update database (this is OK if database doesn't exist yet)"
fi
}
# Display setup summary
show_setup_summary() {
echo ""
echo "================================================================="
echo " GINXSOM SETUP COMPLETE"
echo "================================================================="
echo ""
log_success "Configuration file created: $CONFIG_PATH"
log_success "Admin keys saved: $PROJECT_ROOT/.admin_keys"
echo ""
echo "Next steps:"
echo "1. Start the Ginxsom server:"
echo " cd $PROJECT_ROOT"
echo " make run"
echo ""
echo "2. Test admin API access:"
echo " source .admin_keys"
echo " ./scripts/test_admin.sh"
echo ""
echo "3. Access web admin (when implemented):"
echo " http://localhost:9001/admin"
echo ""
log_warning "Keep the .admin_keys file secure - it contains your admin private key!"
echo ""
}
# Main setup workflow
main() {
echo "=== Ginxsom Interactive Setup Wizard ==="
echo ""
# Validate config path
if [ -z "$CONFIG_PATH" ]; then
# Determine default config path
if [ -n "$XDG_CONFIG_HOME" ]; then
CONFIG_PATH="$XDG_CONFIG_HOME/ginxsom/ginxsom_config_event.json"
else
CONFIG_PATH="$HOME/.config/ginxsom/ginxsom_config_event.json"
fi
fi
log_info "Configuration will be saved to: $CONFIG_PATH"
# Check if config already exists
if [ -f "$CONFIG_PATH" ]; then
log_warning "Configuration file already exists at $CONFIG_PATH"
echo -n "Overwrite existing configuration? (y/n): "
read -r OVERWRITE
case "$OVERWRITE" in
[Yy]*) ;;
*) log_info "Setup cancelled"; exit 0 ;;
esac
fi
# Run setup steps
check_dependencies
setup_keys
collect_configuration
create_config_event
save_config_file "$CONFIG_PATH"
setup_database
show_setup_summary
}
# Allow sourcing for testing individual functions
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi