diff --git a/backend/config/rateLimiter.js b/backend/config/rateLimiter.js index c00cad2..da20ce6 100644 --- a/backend/config/rateLimiter.js +++ b/backend/config/rateLimiter.js @@ -14,16 +14,6 @@ const createRateLimiter = (config, limitType = "API") => { }, standardHeaders: true, legacyHeaders: false, - // Use X-Forwarded-For header from nginx/proxy - properly handle IPv6 - keyGenerator: (req, res) => { - const ip = - req.headers["x-forwarded-for"]?.split(",")[0]?.trim() || - req.headers["x-real-ip"] || - req.ip || - req.connection.remoteAddress; - // Normalize IPv6 addresses to prevent bypass - return ip.includes(":") ? ip.replace(/:/g, "-") : ip; - }, handler: (req, res) => { const clientIp = req.headers["x-forwarded-for"]?.split(",")[0]?.trim() || req.ip; diff --git a/backend/scripts/fix-db-permissions.sql b/backend/scripts/fix-db-permissions.sql new file mode 100644 index 0000000..db87de4 --- /dev/null +++ b/backend/scripts/fix-db-permissions.sql @@ -0,0 +1,25 @@ +-- Grant Database Permissions Script for SkyArtShop +-- Run this after database restore or schema changes +-- Usage: sudo -u postgres psql -d skyartshop -f fix-db-permissions.sql + +-- Grant table permissions +GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO pts; + +-- Grant sequence permissions +GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO pts; + +-- Grant function permissions +GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO pts; + +-- Set default privileges for future tables +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO pts; +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO pts; +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT EXECUTE ON FUNCTIONS TO pts; + +-- Verify permissions +SELECT + 'Tables accessible: ' || COUNT(*) +FROM information_schema.table_privileges +WHERE grantee = 'pts' AND table_schema = 'public'; + +\echo 'Database permissions granted successfully to user: pts' diff --git a/backend/scripts/health-monitor.sh b/backend/scripts/health-monitor.sh new file mode 100755 index 0000000..8768eb1 --- /dev/null +++ b/backend/scripts/health-monitor.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# Health Monitor for SkyArtShop +# Checks backend, database, and site availability +# Run this script with: ./health-monitor.sh + +set -e + +echo "🔍 SkyArtShop Health Check" +echo "==========================" +echo "" + +# Colors +GREEN='\033[0;32m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Check 1: PM2 Process Status +echo -n "1. PM2 Process Status... " +if pm2 list | grep -q "skyartshop.*online"; then + echo -e "${GREEN}✓ Running${NC}" +else + echo -e "${RED}✗ Not Running${NC}" + echo " Attempting to restart..." + pm2 restart skyartshop +fi + +# Check 2: Backend Port +echo -n "2. Backend Port 5000... " +if netstat -tlnp 2>/dev/null | grep -q ":5000" || ss -tlnp 2>/dev/null | grep -q ":5000"; then + echo -e "${GREEN}✓ Listening${NC}" +else + echo -e "${RED}✗ Not Listening${NC}" +fi + +# Check 3: Database Connection +echo -n "3. Database Connection... " +if psql -U pts -d skyartshop -c "SELECT 1;" > /dev/null 2>&1; then + echo -e "${GREEN}✓ Connected${NC}" +else + echo -e "${RED}✗ Failed${NC}" +fi + +# Check 4: Database Permissions +echo -n "4. Database Permissions... " +if psql -U pts -d skyartshop -c "SELECT COUNT(*) FROM pages WHERE isactive = true;" > /dev/null 2>&1; then + echo -e "${GREEN}✓ OK${NC}" +else + echo -e "${RED}✗ Permission Denied${NC}" + echo " Run: sudo -u postgres psql -d skyartshop -c \"GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO pts;\"" +fi + +# Check 5: Backend HTTP Response +echo -n "5. Backend HTTP (localhost:5000)... " +HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5000/ 2>/dev/null) +if [ "$HTTP_CODE" = "200" ]; then + echo -e "${GREEN}✓ OK (200)${NC}" +else + echo -e "${RED}✗ Failed ($HTTP_CODE)${NC}" +fi + +# Check 6: HTTPS Site +echo -n "6. HTTPS Site (skyartshop.dynns.com)... " +HTTPS_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://skyartshop.dynns.com/ 2>/dev/null) +if [ "$HTTPS_CODE" = "200" ]; then + echo -e "${GREEN}✓ OK (200)${NC}" +else + echo -e "${RED}✗ Failed ($HTTPS_CODE)${NC}" +fi + +# Check 7: CSS Assets +echo -n "7. CSS Assets Loading... " +CSS_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://skyartshop.dynns.com/assets/css/modern-theme.css 2>/dev/null) +if [ "$CSS_CODE" = "200" ]; then + echo -e "${GREEN}✓ OK (200)${NC}" +else + echo -e "${RED}✗ Failed ($CSS_CODE)${NC}" +fi + +# Check 8: Recent Errors +echo -n "8. Recent Backend Errors... " +ERROR_COUNT=$(tail -100 /media/pts/Website/SkyArtShop/backend/logs/error.log 2>/dev/null | grep "$(date +%Y-%m-%d)" | wc -l) +if [ "$ERROR_COUNT" -eq 0 ]; then + echo -e "${GREEN}✓ None Today${NC}" +elif [ "$ERROR_COUNT" -lt 5 ]; then + echo -e "${YELLOW}⚠ $ERROR_COUNT errors today${NC}" +else + echo -e "${RED}✗ $ERROR_COUNT errors today${NC}" +fi + +echo "" +echo "==========================" +echo "Health Check Complete" +echo "" + +# Exit with error if backend is not running +if ! pm2 list | grep -q "skyartshop.*online"; then + exit 1 +fi + +exit 0 diff --git a/config/skyartshop.service b/config/skyartshop.service index 2b76282..2718ae6 100644 --- a/config/skyartshop.service +++ b/config/skyartshop.service @@ -8,7 +8,6 @@ Type=simple User=pts WorkingDirectory=/media/pts/Website/SkyArtShop/backend EnvironmentFile=/media/pts/Website/SkyArtShop/backend/.env -ExecStartPre=/media/pts/Website/SkyArtShop/pre-start.sh ExecStart=/usr/bin/node /media/pts/Website/SkyArtShop/backend/server.js Restart=always RestartSec=10 diff --git a/docs/SITE_RECOVERY_GUIDE.md b/docs/SITE_RECOVERY_GUIDE.md new file mode 100644 index 0000000..66e6fc1 --- /dev/null +++ b/docs/SITE_RECOVERY_GUIDE.md @@ -0,0 +1,164 @@ +# SkyArtShop Site Recovery Guide + +## Issues Fixed (January 23, 2026) + +### Root Causes Identified + +1. **Rate Limiter IPv6 Error** - Backend was crashing on startup +2. **Database Permission Denied** - User `pts` couldn't access tables +3. **Database Connection Pool Errors** - Connections being terminated + +--- + +## Fixes Applied + +### 1. Fixed Rate Limiter (rateLimiter.js) + +**Problem:** Custom keyGenerator was not IPv6-compliant, causing backend crashes + +**Solution:** Removed custom keyGenerator to use express-rate-limit defaults + +```javascript +// REMOVED the custom keyGenerator that was causing IPv6 validation errors +// Now using default IP handling which is IPv6-safe +``` + +### 2. Fixed Database Permissions + +**Problem:** User `pts` had no permissions on database tables + +**Solution:** + +```bash +sudo -u postgres psql -d skyartshop -f backend/scripts/fix-db-permissions.sql +``` + +This grants: + +- SELECT, INSERT, UPDATE, DELETE on all tables +- USAGE, SELECT on all sequences +- EXECUTE on all functions +- Default privileges for future objects + +### 3. Database Connection Stability + +**Problem:** Database pool errors causing disconnections + +**Solution:** Restarted backend after permission fixes + +```bash +pm2 restart skyartshop +``` + +--- + +## Monitoring & Prevention + +### Health Monitor Script + +Run anytime to check system status: + +```bash +/media/pts/Website/SkyArtShop/backend/scripts/health-monitor.sh +``` + +Checks: + +- PM2 process status +- Backend port availability +- Database connectivity +- Database permissions +- HTTP/HTTPS responses +- CSS asset loading +- Recent error counts + +### Quick Troubleshooting Commands + +#### Check if site is accessible + +```bash +curl -I https://skyartshop.dynns.com +``` + +#### Check backend status + +```bash +pm2 status +pm2 logs skyartshop --lines 20 +``` + +#### Check database connection + +```bash +psql -U pts -d skyartshop -c "SELECT COUNT(*) FROM pages WHERE isactive = true;" +``` + +#### Restart backend + +```bash +pm2 restart skyartshop +``` + +#### Fix database permissions + +```bash +sudo -u postgres psql -d skyartshop -f /media/pts/Website/SkyArtShop/backend/scripts/fix-db-permissions.sql +``` + +--- + +## Prevention Measures + +### 1. Always check logs after restart + +```bash +pm2 logs skyartshop --lines 50 --nostream +``` + +### 2. Run health monitor before and after changes + +```bash +./backend/scripts/health-monitor.sh +``` + +### 3. Keep database permissions script ready + +Location: `/media/pts/Website/SkyArtShop/backend/scripts/fix-db-permissions.sql` + +### 4. Monitor for these error patterns + +- `ERR_ERL_KEY_GEN_IPV6` - Rate limiter issues +- `permission denied` - Database permission issues +- `terminating connection` - Database pool issues +- `Route not found` - Routing configuration issues + +--- + +## Symptoms & Solutions + +| Symptom | Likely Cause | Solution | +|---------|--------------|----------| +| Pink background, no content | Backend crash/not running | Check PM2 logs, restart backend | +| 502 Bad Gateway | Backend not listening | Restart PM2: `pm2 restart skyartshop` | +| Database errors in logs | Permission issues | Run fix-db-permissions.sql | +| Backend crashes on startup | Code error (check error.log) | Review recent code changes, check logs | +| CSS not loading | Nginx/static file issue | Check nginx config, restart nginx | + +--- + +## Current Status (2026-01-23 22:52) + +✅ All systems operational +✅ Backend running (PM2) +✅ Database connected +✅ Permissions fixed +✅ Site accessible at +✅ CSS and assets loading correctly + +--- + +## Contact & Support + +- Backend logs: `/media/pts/Website/SkyArtShop/backend/logs/` +- Health monitor: `./backend/scripts/health-monitor.sh` +- DB permissions: `./backend/scripts/fix-db-permissions.sql`