e8d9b1fd42
Add complete token system with Plex/Tautulli/Overseer integration: - Anchor program for SPL token mint/burn/transfer - Express backend with OAuth, webhooks, Solana integration - Next.js frontend with dashboard, admin panel, wallet management - Docker deployment for 172.20.1.0/24 infrastructure - Production configs with SSL, Nginx, health monitoring Tautulli webhooks auto-mint on watch events. Overseer integration burns for content requests.
358 lines
11 KiB
Bash
Executable File
358 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ==========================================
|
|
# CoopCredits Infrastructure Setup Script
|
|
# Configures integration with existing services
|
|
# Server Infrastructure: 172.20.1.0/24
|
|
# ==========================================
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
|
|
echo "🏗️ CoopCredits Infrastructure Setup"
|
|
echo "===================================="
|
|
echo ""
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# ==========================================
|
|
# Configuration
|
|
# ==========================================
|
|
PLEX_IP="172.20.1.220"
|
|
OVERSEER_IP="172.20.1.225"
|
|
TAUTULLI_IP="172.20.1.255"
|
|
|
|
PLEX_PORT="32400"
|
|
OVERSEER_PORT="5055"
|
|
TAUTULLI_PORT="8181"
|
|
|
|
echo "📋 Configuration:"
|
|
echo " Plex: http://${PLEX_IP}:${PLEX_PORT}"
|
|
echo " Overseer: http://${OVERSEER_IP}:${OVERSEER_PORT}"
|
|
echo " Tautulli: http://${TAUTULLI_IP}:${TAUTULLI_PORT}"
|
|
echo ""
|
|
|
|
# ==========================================
|
|
# Test Connectivity
|
|
# ==========================================
|
|
test_connectivity() {
|
|
echo "🔍 Testing connectivity to services..."
|
|
|
|
# Test Plex
|
|
if curl -sf "http://${PLEX_IP}:${PLEX_PORT}/identity" > /dev/null 2>&1; then
|
|
echo -e "${GREEN}✅${NC} Plex is reachable"
|
|
else
|
|
echo -e "${YELLOW}⚠️${NC} Plex not responding (may need auth or be offline)"
|
|
fi
|
|
|
|
# Test Tautulli
|
|
if curl -sf "http://${TAUTULLI_IP}:${TAUTULLI_PORT}/api/v2?apikey=test&cmd=get_server_info" > /dev/null 2>&1; then
|
|
echo -e "${GREEN}✅${NC} Tautulli is reachable"
|
|
else
|
|
echo -e "${YELLOW}⚠️${NC} Tautulli not responding (check API key)"
|
|
fi
|
|
|
|
# Test Overseer
|
|
if curl -sf "http://${OVERSEER_IP}:${OVERSEER_PORT}/api/v1/status" > /dev/null 2>&1; then
|
|
echo -e "${GREEN}✅${NC} Overseer is reachable"
|
|
else
|
|
echo -e "${YELLOW}⚠️${NC} Overseer not responding (may need API key)"
|
|
fi
|
|
|
|
echo ""
|
|
}
|
|
|
|
# ==========================================
|
|
# Generate Environment File
|
|
# ==========================================
|
|
generate_env() {
|
|
echo "📝 Generating environment configuration..."
|
|
|
|
ENV_FILE="${PROJECT_DIR}/.env"
|
|
|
|
if [ -f "$ENV_FILE" ]; then
|
|
echo -e "${YELLOW}⚠️${NC} .env file already exists. Creating backup..."
|
|
cp "$ENV_FILE" "${ENV_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
fi
|
|
|
|
# Generate secure keys
|
|
JWT_SECRET=$(openssl rand -hex 32)
|
|
ENCRYPTION_KEY=$(openssl rand -base64 32)
|
|
WEBHOOK_SECRET=$(openssl rand -hex 16)
|
|
POSTGRES_PASSWORD=$(openssl rand -base64 24 | tr -d '=+/')
|
|
REDIS_PASSWORD=$(openssl rand -base64 24 | tr -d '=+/')
|
|
|
|
cat > "$ENV_FILE" << EOF
|
|
# ==========================================
|
|
# CoopCredits Environment Configuration
|
|
# Generated: $(date)
|
|
# Network: 172.20.1.0/24
|
|
# ==========================================
|
|
|
|
# Database
|
|
DATABASE_URL="postgresql://coop:${POSTGRES_PASSWORD}@postgres:5432/coop_credits?schema=public"
|
|
POSTGRES_PASSWORD="${POSTGRES_PASSWORD}"
|
|
|
|
# Server
|
|
PORT=3001
|
|
NODE_ENV=production
|
|
API_URL=https://coop.hobokenchicken.com
|
|
FRONTEND_URL=https://coop.hobokenchicken.com
|
|
|
|
# JWT Secret
|
|
JWT_SECRET="${JWT_SECRET}"
|
|
|
|
# ==========================================
|
|
# Plex Server (172.20.1.220:32400)
|
|
# ==========================================
|
|
# Get from: https://plex.tv/claim
|
|
PLEX_CLIENT_ID=""
|
|
PLEX_CLIENT_SECRET=""
|
|
PLEX_REDIRECT_URI="https://coop.hobokenchicken.com/auth/callback"
|
|
|
|
# ==========================================
|
|
# Tautulli (172.20.1.255:8181)
|
|
# ==========================================
|
|
# Get from: Settings > Web Interface > API > API Key
|
|
TAUTULLI_URL="http://${TAUTULLI_IP}:${TAUTULLI_PORT}"
|
|
TAUTULLI_API_KEY=""
|
|
TAUTULLI_WEBHOOK_SECRET="${WEBHOOK_SECRET}"
|
|
|
|
# ==========================================
|
|
# Overseer (172.20.1.225:5055)
|
|
# ==========================================
|
|
# Get from: Settings > General > API Key
|
|
OVERSEER_URL="http://${OVERSEER_IP}:${OVERSEER_PORT}"
|
|
OVERSEER_API_KEY=""
|
|
|
|
# ==========================================
|
|
# Solana (Devnet)
|
|
# ==========================================
|
|
# Run: npm run setup:solana to generate
|
|
SOLANA_RPC_URL="https://api.devnet.solana.com"
|
|
SOLANA_PROGRAM_ID="CoopCredits111111111111111111111111111111111"
|
|
SOLANA_MINT_AUTHORITY_KEYPAIR=""
|
|
SOLANA_TOKEN_DECIMALS=6
|
|
|
|
# ==========================================
|
|
# Redis
|
|
# ==========================================
|
|
REDIS_URL="redis://:${REDIS_PASSWORD}@redis:6379"
|
|
REDIS_PASSWORD="${REDIS_PASSWORD}"
|
|
|
|
# ==========================================
|
|
# Encryption
|
|
# ==========================================
|
|
ENCRYPTION_KEY="${ENCRYPTION_KEY}"
|
|
|
|
# ==========================================
|
|
# Frontend
|
|
# ==========================================
|
|
NEXT_PUBLIC_API_URL="https://coop.hobokenchicken.com"
|
|
NEXT_PUBLIC_SOLANA_NETWORK="devnet"
|
|
NEXT_PUBLIC_SOLANA_RPC_URL="https://api.devnet.solana.com"
|
|
NEXT_PUBLIC_APP_NAME="CoopCredits"
|
|
NEXT_PUBLIC_APP_URL="https://coop.hobokenchicken.com"
|
|
EOF
|
|
|
|
echo -e "${GREEN}✅${NC} Environment file created: ${ENV_FILE}"
|
|
echo ""
|
|
echo -e "${YELLOW}⚠️${NC} IMPORTANT: Edit .env and add your API keys:"
|
|
echo " 1. PLEX_CLIENT_ID and PLEX_CLIENT_SECRET from plex.tv"
|
|
echo " 2. TAUTULLI_API_KEY from Tautulli settings"
|
|
echo " 3. OVERSEER_API_KEY from Overseer settings"
|
|
echo " 4. SOLANA_MINT_AUTHORITY_KEYPAIR from 'npm run setup:solana'"
|
|
echo ""
|
|
}
|
|
|
|
# ==========================================
|
|
# Configure Tautulli Webhook
|
|
# ==========================================
|
|
configure_tautulli() {
|
|
echo "📺 Tautulli Webhook Configuration"
|
|
echo "=================================="
|
|
echo ""
|
|
echo "To complete Tautulli integration:"
|
|
echo ""
|
|
echo "1. Open Tautulli: http://${TAUTULLI_IP}:${TAUTULLI_PORT}"
|
|
echo "2. Go to: Settings > Notification Agents"
|
|
echo "3. Click 'Add a new notification agent'"
|
|
echo "4. Select 'Webhook'"
|
|
echo ""
|
|
echo "Configure the webhook:"
|
|
echo " Webhook URL: https://coop.hobokenchicken.com/webhooks/tautulli"
|
|
echo " Webhook Method: POST"
|
|
echo " Content Type: application/json"
|
|
echo ""
|
|
echo "JSON Payload (copy this exactly):"
|
|
cat << 'JSONEOF'
|
|
{
|
|
"action": "watched",
|
|
"user_id": "{user_id}",
|
|
"username": "{username}",
|
|
"rating_key": "{rating_key}",
|
|
"session_key": "{session_key}",
|
|
"media_type": "{media_type}",
|
|
"title": "{title}",
|
|
"grandparent_title": "{grandparent_title}",
|
|
"started": "{started}",
|
|
"stopped": "{stopped}",
|
|
"percent_complete": "{percent_complete}",
|
|
"is_new": "{is_new}"
|
|
}
|
|
JSONEOF
|
|
echo ""
|
|
echo "Triggers: Enable 'Watched'"
|
|
echo "Conditions: None (or customize as needed)"
|
|
echo ""
|
|
}
|
|
|
|
# ==========================================
|
|
# Configure Overseer Webhook
|
|
# ==========================================
|
|
configure_overseer() {
|
|
echo "🎬 Overseer Webhook Configuration"
|
|
echo "=================================="
|
|
echo ""
|
|
echo "To complete Overseer integration:"
|
|
echo ""
|
|
echo "1. Open Overseer: http://${OVERSEER_IP}:${OVERSEER_PORT}"
|
|
echo "2. Go to: Settings > Notifications"
|
|
echo "3. Click 'Webhook'"
|
|
echo ""
|
|
echo "Configure the webhook:"
|
|
echo " Webhook URL: https://coop.hobokenchicken.com/webhooks/overseer"
|
|
echo " Authorization Header: Bearer <your-webhook-secret-from-env>"
|
|
echo ""
|
|
echo "JSON Payload:"
|
|
cat << 'JSONEOF'
|
|
{
|
|
"request_id": "{{request.id}}",
|
|
"status": "{{request.status}}",
|
|
"media_type": "{{media.media_type}}",
|
|
"title": "{{media.title}}"
|
|
}
|
|
JSONEOF
|
|
echo ""
|
|
echo "Events: Enable 'Request Approved' and 'Request Declined'"
|
|
echo ""
|
|
}
|
|
|
|
# ==========================================
|
|
# Configure Plex OAuth
|
|
# ==========================================
|
|
configure_plex() {
|
|
echo "🎭 Plex OAuth Configuration"
|
|
echo "==========================="
|
|
echo ""
|
|
echo "To enable Plex authentication:"
|
|
echo ""
|
|
echo "1. Go to: https://plex.tv/claim"
|
|
echo " Or: https://www.plex.tv/link/"
|
|
echo ""
|
|
echo "2. For OAuth app registration, you may need to contact Plex"
|
|
echo " or use a third-party OAuth provider that supports Plex"
|
|
echo ""
|
|
echo "3. Alternative: Use custom authentication with Plex credentials"
|
|
echo " stored securely and linked to wallets"
|
|
echo ""
|
|
}
|
|
|
|
# ==========================================
|
|
# Firewall Rules
|
|
# ==========================================
|
|
configure_firewall() {
|
|
echo "🔥 Firewall Configuration"
|
|
echo "========================="
|
|
echo ""
|
|
echo "Recommended firewall rules for CoopCredits server:"
|
|
echo ""
|
|
echo "# Allow web traffic"
|
|
echo "sudo ufw allow 80/tcp"
|
|
echo "sudo ufw allow 443/tcp"
|
|
echo ""
|
|
echo "# Allow internal network access to services"
|
|
echo "sudo ufw allow from 172.20.1.0/24 to any port 3001"
|
|
echo ""
|
|
echo "# Allow PostgreSQL only from localhost"
|
|
echo "sudo ufw allow from 127.0.0.1 to any port 5432"
|
|
echo ""
|
|
echo "# Allow Redis only from localhost"
|
|
echo "sudo ufw allow from 127.0.0.1 to any port 6379"
|
|
echo ""
|
|
echo "Current UFW status:"
|
|
sudo ufw status verbose 2>/dev/null || echo "UFW not installed or not active"
|
|
echo ""
|
|
}
|
|
|
|
# ==========================================
|
|
# SSL Certificate Setup
|
|
# ==========================================
|
|
setup_ssl() {
|
|
echo "🔒 SSL Certificate Setup"
|
|
echo "======================="
|
|
echo ""
|
|
|
|
SSL_DIR="${PROJECT_DIR}/docker/nginx/ssl"
|
|
mkdir -p "$SSL_DIR"
|
|
|
|
if [ -f "${SSL_DIR}/cert.pem" ] && [ -f "${SSL_DIR}/key.pem" ]; then
|
|
echo -e "${GREEN}✅${NC} SSL certificates already exist"
|
|
else
|
|
echo "SSL certificates not found at ${SSL_DIR}/"
|
|
echo ""
|
|
echo "Options:"
|
|
echo ""
|
|
echo "1. Let's Encrypt (recommended for production):"
|
|
echo " docker-compose -f docker-compose.prod.yml run --rm certbot certonly"
|
|
echo " --webroot -w /var/www/certbot"
|
|
echo " -d coop.hobokenchicken.com"
|
|
echo " --agree-tos --no-eff-email"
|
|
echo ""
|
|
echo "2. Self-signed (for testing only):"
|
|
echo " openssl req -x509 -nodes -days 365 -newkey rsa:2048 \\"
|
|
echo " -keyout ${SSL_DIR}/key.pem \\"
|
|
echo " -out ${SSL_DIR}/cert.pem \\"
|
|
echo " -subj '/CN=coop.hobokenchicken.com'"
|
|
echo ""
|
|
echo "3. Place existing certificates:"
|
|
echo " cp your-cert.pem ${SSL_DIR}/cert.pem"
|
|
echo " cp your-key.pem ${SSL_DIR}/key.pem"
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
# ==========================================
|
|
# Main
|
|
# ==========================================
|
|
main() {
|
|
test_connectivity
|
|
generate_env
|
|
setup_ssl
|
|
configure_tautulli
|
|
configure_overseer
|
|
configure_plex
|
|
configure_firewall
|
|
|
|
echo ""
|
|
echo "🎉 Setup complete!"
|
|
echo "=================="
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo " 1. Edit .env file with your API keys"
|
|
echo " 2. Run: npm run setup:solana"
|
|
echo " 3. Setup SSL certificates"
|
|
echo " 4. Run: npm run deploy"
|
|
echo ""
|
|
echo "After deployment, configure webhooks in Tautulli and Overseer"
|
|
echo ""
|
|
}
|
|
|
|
main "$@"
|