Initial commit - QBPOS Help
This commit is contained in:
58
scripts/add_mobile_nav.sh
Normal file
58
scripts/add_mobile_nav.sh
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
# Add mobile navigation bar to all HTML files
|
||||
|
||||
HELP_DIR="/home/pts/Documents/QBPOS_Help_Web/QB_Help_Web/POS_Help"
|
||||
|
||||
echo "Adding mobile navigation to HTML files..."
|
||||
|
||||
# Find all .htm and .html files
|
||||
find "$HELP_DIR" -type f \( -name "*.htm" -o -name "*.html" \) | while read -r file; do
|
||||
# Skip if already has mobile-nav
|
||||
if grep -q "mobile-nav.css" "$file"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Add mobile-nav.css link after other CSS files
|
||||
if grep -q "qbpos.css" "$file" || grep -q "prompttech-header.css" "$file"; then
|
||||
# Calculate relative path for CSS
|
||||
rel_path=$(realpath --relative-to="$(dirname "$file")" "$HELP_DIR")
|
||||
if [ "$rel_path" = "." ]; then
|
||||
css_path="mobile-nav.css"
|
||||
else
|
||||
css_path="${rel_path}/mobile-nav.css"
|
||||
fi
|
||||
|
||||
# Add after the last stylesheet
|
||||
sed -i "/qbpos\.css/a <link rel=\"StyleSheet\" href=\"${css_path}\" type=\"text/css\">" "$file"
|
||||
fi
|
||||
|
||||
# Add mobile navigation HTML after <body> tag
|
||||
if ! grep -q "mobile-nav" "$file"; then
|
||||
# Calculate relative path to home based on file location
|
||||
rel_path=$(realpath --relative-to="$(dirname "$file")" "$HELP_DIR")
|
||||
if [ "$rel_path" = "." ]; then
|
||||
home_link="___left.htm"
|
||||
else
|
||||
home_link="${rel_path}/___left.htm"
|
||||
fi
|
||||
|
||||
sed -i "/<body[^>]*>/I a\\
|
||||
<div class=\"mobile-nav\">\\
|
||||
<div class=\"mobile-nav-content\">\\
|
||||
<a href=\"${home_link}\" class=\"home-btn\">🏠 Home</a>\\
|
||||
<span class=\"site-title\">QB POS Help</span>\\
|
||||
<a href=\"javascript:history.back()\" class=\"back-btn\">← Back</a>\\
|
||||
</div>\\
|
||||
</div>" "$file"
|
||||
fi
|
||||
|
||||
echo "Updated: $file"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Mobile navigation added to all pages!"
|
||||
echo ""
|
||||
echo "Features:"
|
||||
echo " - Home button (returns to main page)"
|
||||
echo " - Back button (goes to previous page)"
|
||||
echo " - Only visible on mobile/tablet devices"
|
||||
39
scripts/add_mobile_nav_html.sh
Normal file
39
scripts/add_mobile_nav_html.sh
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
# Add mobile navigation HTML to all body tags
|
||||
|
||||
HELP_DIR="/home/pts/Documents/QBPOS_Help_Web/QB_Help_Web/POS_Help"
|
||||
|
||||
echo "Adding mobile navigation HTML to body tags..."
|
||||
|
||||
# Find all .htm and .html files
|
||||
find "$HELP_DIR" -type f \( -name "*.htm" -o -name "*.html" \) | while read -r file; do
|
||||
# Skip if already has mobile-nav div
|
||||
if grep -q '<div class="mobile-nav">' "$file"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Calculate relative path to home based on file location
|
||||
rel_path=$(realpath --relative-to="$(dirname "$file")" "$HELP_DIR")
|
||||
if [ "$rel_path" = "." ]; then
|
||||
home_link="___left.htm"
|
||||
else
|
||||
home_link="${rel_path}/___left.htm"
|
||||
fi
|
||||
|
||||
# Add mobile navigation after <body> or <body ...> tag
|
||||
sed -i "/<body[^>]*>/I {
|
||||
a\\
|
||||
<div class=\"mobile-nav\">\\
|
||||
<div class=\"mobile-nav-content\">\\
|
||||
<a href=\"${home_link}\" class=\"home-btn\">🏠 Home</a>\\
|
||||
<span class=\"site-title\">QB POS Help</span>\\
|
||||
<a href=\"javascript:history.back()\" class=\"back-btn\">← Back</a>\\
|
||||
</div>\\
|
||||
</div>
|
||||
}" "$file"
|
||||
|
||||
echo "Updated: $(basename $file)"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "✅ Mobile navigation added!"
|
||||
41
scripts/add_mobile_support.sh
Normal file
41
scripts/add_mobile_support.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# Add mobile responsiveness to all HTML files
|
||||
|
||||
HELP_DIR="/home/pts/Documents/QBPOS_Help_Web/QB_Help_Web/POS_Help"
|
||||
BACKUP_DIR="/home/pts/Documents/QBPOS_Help_Web/backup_html_$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
echo "Creating backup..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Find all .htm and .html files
|
||||
find "$HELP_DIR" -type f \( -name "*.htm" -o -name "*.html" \) | while read -r file; do
|
||||
# Skip if already has viewport
|
||||
if grep -q "viewport" "$file"; then
|
||||
echo "Already has viewport: $file"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Create backup
|
||||
cp "$file" "$BACKUP_DIR/"
|
||||
|
||||
# Add viewport meta tag after <head>
|
||||
sed -i '/<head>/I a\
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes">' "$file"
|
||||
|
||||
# Add mobile CSS link if qbpos.css is present
|
||||
if grep -q "qbpos.css" "$file"; then
|
||||
# Add mobile-enhancements.css after qbpos.css
|
||||
sed -i '/qbpos\.css/a\
|
||||
<link rel="StyleSheet" href="mobile-enhancements.css" type="text/css">' "$file"
|
||||
fi
|
||||
|
||||
echo "Updated: $file"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Update complete!"
|
||||
echo "Backup created at: $BACKUP_DIR"
|
||||
echo ""
|
||||
echo "Changes made:"
|
||||
echo " - Added viewport meta tag to all HTML files"
|
||||
echo " - Added mobile-enhancements.css link where applicable"
|
||||
46
scripts/add_nav_final.sh
Normal file
46
scripts/add_nav_final.sh
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
# Add mobile navigation HTML to all HTML files
|
||||
|
||||
HELP_DIR="/home/pts/Documents/QBPOS_Help_Web/QB_Help_Web/POS_Help"
|
||||
count=0
|
||||
|
||||
echo "Adding mobile navigation to all HTML files..."
|
||||
echo ""
|
||||
|
||||
# Find all .htm and .html files
|
||||
find "$HELP_DIR" -type f \( -name "*.htm" -o -name "*.html" \) | while read -r file; do
|
||||
# Skip if already has mobile-nav
|
||||
if grep -q '<div class="mobile-nav">' "$file"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Calculate relative path for home link
|
||||
dir=$(dirname "$file")
|
||||
rel_path=$(realpath --relative-to="$dir" "$HELP_DIR")
|
||||
|
||||
if [ "$rel_path" = "." ]; then
|
||||
home_link="___left.htm"
|
||||
else
|
||||
home_link="${rel_path}/___left.htm"
|
||||
fi
|
||||
|
||||
# Add navigation after <body> tag (exact match)
|
||||
sed -i "/<body>/a\\
|
||||
<div class=\"mobile-nav\">\\
|
||||
<div class=\"mobile-nav-content\">\\
|
||||
<a href=\"${home_link}\" class=\"home-btn\">🏠 Home</a>\\
|
||||
<span class=\"site-title\">QB POS Help</span>\\
|
||||
<a href=\"javascript:history.back()\" class=\"back-btn\">← Back</a>\\
|
||||
</div>\\
|
||||
</div>" "$file"
|
||||
|
||||
((count++))
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "✅ Mobile navigation added to $count files!"
|
||||
echo ""
|
||||
echo "Navigation features:"
|
||||
echo " 🏠 Home button - Returns to main navigation page"
|
||||
echo " ← Back button - Goes to previous page"
|
||||
echo " 📱 Only visible on mobile and tablet devices"
|
||||
33
scripts/backup_site.sh
Executable file
33
scripts/backup_site.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
# Automated Backup Script for QBPOS Help Website
|
||||
# Runs daily and keeps 7 days of backups
|
||||
|
||||
BACKUP_DIR="/home/pts/backups/qbpos_help"
|
||||
SOURCE_DIR="/home/pts/Documents/QBPOS_Help_Web/QB_Help_Web"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_FILE="qbpos_help_${DATE}.tar.gz"
|
||||
|
||||
# Create backup directory if it doesn't exist
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Create compressed backup
|
||||
echo "Creating backup: $BACKUP_FILE"
|
||||
tar -czf "$BACKUP_DIR/$BACKUP_FILE" -C "$(dirname $SOURCE_DIR)" "$(basename $SOURCE_DIR)" 2>/dev/null
|
||||
|
||||
# Check if backup was successful
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Backup created successfully: $BACKUP_DIR/$BACKUP_FILE"
|
||||
echo " Size: $(du -h $BACKUP_DIR/$BACKUP_FILE | cut -f1)"
|
||||
else
|
||||
echo "✗ Backup failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Delete backups older than 7 days
|
||||
find "$BACKUP_DIR" -name "qbpos_help_*.tar.gz" -mtime +7 -delete
|
||||
echo "✓ Cleaned up old backups (keeping last 7 days)"
|
||||
|
||||
# Show current backups
|
||||
echo ""
|
||||
echo "Current backups:"
|
||||
ls -lh "$BACKUP_DIR" | grep "qbpos_help_" | tail -5
|
||||
64
scripts/check_dns_and_ssl.sh
Normal file
64
scripts/check_dns_and_ssl.sh
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
# Check DNS and setup SSL when ready
|
||||
|
||||
DOMAIN="quickbooksposhelp.access.ly"
|
||||
PUBLIC_IP="170.254.17.146"
|
||||
|
||||
echo "Checking DNS for $DOMAIN..."
|
||||
echo ""
|
||||
|
||||
# Check DNS resolution
|
||||
RESOLVED_IP=$(dig +short "$DOMAIN" | tail -1)
|
||||
|
||||
if [ -z "$RESOLVED_IP" ]; then
|
||||
echo "❌ DNS not resolving yet"
|
||||
echo ""
|
||||
echo "In your No-IP account:"
|
||||
echo " 1. Go to Dynamic DNS → Hostnames"
|
||||
echo " 2. Find: $DOMAIN"
|
||||
echo " 3. Set IP to: $PUBLIC_IP"
|
||||
echo " 4. Save and wait 2-5 minutes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ DNS resolving to: $RESOLVED_IP"
|
||||
|
||||
if [ "$RESOLVED_IP" != "$PUBLIC_IP" ]; then
|
||||
echo "⚠️ Warning: DNS points to $RESOLVED_IP but should be $PUBLIC_IP"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Testing HTTP access..."
|
||||
if curl -f -s -m 10 "http://$DOMAIN/POS_Help.html" > /dev/null 2>&1; then
|
||||
echo "✅ Site accessible via HTTP"
|
||||
else
|
||||
echo "⚠️ HTTP access failed - check router port forwarding for port 80"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Testing port 8888 access..."
|
||||
if curl -f -s -m 10 "http://$DOMAIN:8888/POS_Help.html" > /dev/null 2>&1; then
|
||||
echo "✅ Site accessible on port 8888"
|
||||
else
|
||||
echo "⚠️ Port 8888 access failed"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
read -p "DNS is working. Get SSL certificate now? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "Getting SSL certificate..."
|
||||
sudo certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --email admin@prompttech.com --redirect
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "🎉 SSL Setup Complete!"
|
||||
echo ""
|
||||
echo "Your site is now accessible at:"
|
||||
echo " 🔒 https://$DOMAIN"
|
||||
echo " 🔒 https://$DOMAIN:8888"
|
||||
else
|
||||
echo "❌ SSL certificate installation failed"
|
||||
fi
|
||||
fi
|
||||
62
scripts/deploy_nginx.sh
Normal file
62
scripts/deploy_nginx.sh
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
# Setup script for deploying QuickBooks POS Help with Nginx
|
||||
|
||||
echo "============================================================"
|
||||
echo "QuickBooks POS Help - Production Deployment Setup"
|
||||
echo "============================================================"
|
||||
echo ""
|
||||
|
||||
# Check if nginx is installed
|
||||
if ! command -v nginx &> /dev/null; then
|
||||
echo "Installing Nginx..."
|
||||
sudo apt update
|
||||
sudo apt install -y nginx
|
||||
else
|
||||
echo "✓ Nginx is already installed"
|
||||
fi
|
||||
|
||||
# Copy nginx configuration
|
||||
echo ""
|
||||
echo "Setting up Nginx configuration..."
|
||||
sudo cp nginx_setup.conf /etc/nginx/sites-available/qbpos-help
|
||||
|
||||
# Create symbolic link
|
||||
if [ ! -L /etc/nginx/sites-enabled/qbpos-help ]; then
|
||||
sudo ln -s /etc/nginx/sites-available/qbpos-help /etc/nginx/sites-enabled/
|
||||
echo "✓ Configuration linked"
|
||||
else
|
||||
echo "✓ Configuration already linked"
|
||||
fi
|
||||
|
||||
# Test nginx configuration
|
||||
echo ""
|
||||
echo "Testing Nginx configuration..."
|
||||
sudo nginx -t
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "Restarting Nginx..."
|
||||
sudo systemctl restart nginx
|
||||
sudo systemctl enable nginx
|
||||
|
||||
echo ""
|
||||
echo "============================================================"
|
||||
echo "✓ Deployment Complete!"
|
||||
echo "============================================================"
|
||||
echo ""
|
||||
echo "Your site is now accessible at:"
|
||||
echo " http://$(hostname -I | awk '{print $1}')/POS_Help.html"
|
||||
echo ""
|
||||
echo "Optimizations enabled:"
|
||||
echo " ✓ Static file caching (1 year)"
|
||||
echo " ✓ Gzip compression"
|
||||
echo " ✓ Minimal logging"
|
||||
echo " ✓ High performance for 100,000+ users"
|
||||
echo ""
|
||||
echo "To view logs:"
|
||||
echo " sudo tail -f /var/log/nginx/qbpos-error.log"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo "⚠ Configuration test failed. Please check the error above."
|
||||
fi
|
||||
42
scripts/get_ssl_cert.sh
Normal file
42
scripts/get_ssl_cert.sh
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
# Get SSL certificate after DNS is configured
|
||||
|
||||
DOMAIN="quickbooksposhelp.access.ly"
|
||||
|
||||
echo "Checking DNS resolution..."
|
||||
if ! host "$DOMAIN" > /dev/null 2>&1; then
|
||||
echo "❌ DNS not resolving yet for $DOMAIN"
|
||||
echo ""
|
||||
echo "Please configure DNS first:"
|
||||
echo " Host: quickbooksposhelp"
|
||||
echo " Type: A"
|
||||
echo " Value: 192.168.10.130"
|
||||
echo ""
|
||||
echo "Then wait 5-30 minutes for DNS propagation"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ DNS is resolving"
|
||||
echo ""
|
||||
echo "Getting SSL certificate..."
|
||||
|
||||
# Ensure firewall is open
|
||||
sudo ufw allow 80/tcp comment "HTTP for SSL verification"
|
||||
sudo ufw allow 443/tcp comment "HTTPS"
|
||||
|
||||
# Get certificate using certbot
|
||||
sudo certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --email admin@prompttech.com --redirect
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "✅ SSL certificate installed successfully!"
|
||||
echo ""
|
||||
echo "Your site is now available at:"
|
||||
echo " 🔒 https://$DOMAIN"
|
||||
echo ""
|
||||
echo "Certificate will auto-renew before expiration"
|
||||
else
|
||||
echo ""
|
||||
echo "❌ Failed to get SSL certificate"
|
||||
echo "Check the error messages above"
|
||||
fi
|
||||
41
scripts/health_check.sh
Normal file
41
scripts/health_check.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# Health check and auto-restart script for QBPOS Help site
|
||||
|
||||
DOMAIN="quickbookposhelp.access.ly"
|
||||
LOG_FILE="/var/log/qbpos-health-check.log"
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Check if nginx is running
|
||||
if ! systemctl is-active --quiet nginx; then
|
||||
log_message "ERROR: Nginx is not running. Attempting to start..."
|
||||
systemctl start nginx
|
||||
if [ $? -eq 0 ]; then
|
||||
log_message "SUCCESS: Nginx restarted successfully"
|
||||
else
|
||||
log_message "CRITICAL: Failed to restart Nginx"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if the site responds
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -m 10 "https://$DOMAIN" 2>/dev/null)
|
||||
|
||||
if [ "$HTTP_CODE" != "200" ]; then
|
||||
log_message "WARNING: Site returned HTTP $HTTP_CODE. Reloading nginx..."
|
||||
systemctl reload nginx
|
||||
sleep 2
|
||||
|
||||
# Check again
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -m 10 "https://$DOMAIN" 2>/dev/null)
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
log_message "SUCCESS: Site recovered after reload"
|
||||
else
|
||||
log_message "ERROR: Site still not responding properly (HTTP $HTTP_CODE)"
|
||||
fi
|
||||
else
|
||||
log_message "OK: Site is healthy (HTTP $HTTP_CODE)"
|
||||
fi
|
||||
54
scripts/install_service.sh
Normal file
54
scripts/install_service.sh
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
# Install QuickBooks POS Help Server as a system service
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "QuickBooks POS Help Service Installer"
|
||||
echo "=========================================="
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run with sudo: sudo bash install_service.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SERVICE_FILE="qbpos-help.service"
|
||||
SYSTEMD_PATH="/etc/systemd/system/"
|
||||
|
||||
echo "1. Stopping old server processes..."
|
||||
pkill -9 -f production_server.py 2>/dev/null || true
|
||||
pkill -9 -f secure_production_server.py 2>/dev/null || true
|
||||
|
||||
echo "2. Making server script executable..."
|
||||
chmod +x /home/pts/Documents/QBPOS_Help_Web/secure_production_server.py
|
||||
|
||||
echo "3. Copying service file to systemd..."
|
||||
cp "$SERVICE_FILE" "$SYSTEMD_PATH"
|
||||
|
||||
echo "4. Reloading systemd..."
|
||||
systemctl daemon-reload
|
||||
|
||||
echo "5. Enabling service to start on boot..."
|
||||
systemctl enable qbpos-help.service
|
||||
|
||||
echo "6. Starting service..."
|
||||
systemctl start qbpos-help.service
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Installation Complete!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Service Status:"
|
||||
systemctl status qbpos-help.service --no-pager
|
||||
|
||||
echo ""
|
||||
echo "Useful Commands:"
|
||||
echo " Start: sudo systemctl start qbpos-help"
|
||||
echo " Stop: sudo systemctl stop qbpos-help"
|
||||
echo " Restart: sudo systemctl restart qbpos-help"
|
||||
echo " Status: sudo systemctl status qbpos-help"
|
||||
echo " Logs: sudo journalctl -u qbpos-help -f"
|
||||
echo ""
|
||||
echo "The server will now auto-start on system reboot."
|
||||
32
scripts/monitor_logs.sh
Executable file
32
scripts/monitor_logs.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# Real-time Log Monitor for QBPOS Help Website
|
||||
# Shows recent attacks, blocked IPs, and suspicious activity
|
||||
|
||||
echo "=== QBPOS Help Website Security Monitor ==="
|
||||
echo "Date: $(date)"
|
||||
echo ""
|
||||
|
||||
# Show fail2ban status
|
||||
echo "--- Fail2ban Status ---"
|
||||
sudo fail2ban-client status nginx-badbots 2>/dev/null | grep "Total banned" || echo "No bans yet"
|
||||
sudo fail2ban-client status nginx-noproxy 2>/dev/null | grep "Total banned" || echo "No proxy attacks"
|
||||
echo ""
|
||||
|
||||
# Show recent blocked IPs
|
||||
echo "--- Recently Blocked IPs (last 24h) ---"
|
||||
sudo grep "Ban" /var/log/fail2ban.log 2>/dev/null | tail -10 || echo "No recent bans"
|
||||
echo ""
|
||||
|
||||
# Show suspicious access attempts
|
||||
echo "--- Suspicious Access Attempts (last 100) ---"
|
||||
tail -100 /var/log/nginx/qbpos-access.log | grep -E "\.\.\/|\.php|\.asp|admin|wp-|sqlmap" | tail -5 || echo "No suspicious activity"
|
||||
echo ""
|
||||
|
||||
# Show recent 404 errors
|
||||
echo "--- Recent 404 Errors ---"
|
||||
tail -100 /var/log/nginx/qbpos-access.log | grep " 404 " | tail -5 || echo "No 404 errors"
|
||||
echo ""
|
||||
|
||||
# Show error log
|
||||
echo "--- Recent Errors ---"
|
||||
tail -10 /var/log/nginx/qbpos-error.log 2>/dev/null || echo "No recent errors"
|
||||
66
scripts/setup_https.sh
Normal file
66
scripts/setup_https.sh
Normal file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
# Setup HTTPS for QuickBooks POS Help Server
|
||||
# Run this when you have a domain name and are ready for HTTPS
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "HTTPS Setup for QuickBooks POS Help"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Prerequisites:"
|
||||
echo " 1. Domain name pointing to this server"
|
||||
echo " 2. Ports 80 and 443 open in firewall"
|
||||
echo ""
|
||||
read -p "Enter your domain name (e.g., qbpos.prompttech.com): " DOMAIN
|
||||
|
||||
if [ -z "$DOMAIN" ]; then
|
||||
echo "Error: Domain name required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Installing Certbot for Let's Encrypt SSL..."
|
||||
sudo apt update
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
|
||||
echo ""
|
||||
echo "Obtaining SSL certificate for $DOMAIN..."
|
||||
sudo certbot certonly --standalone -d "$DOMAIN" --agree-tos --non-interactive --email admin@prompttech.com
|
||||
|
||||
CERT_PATH="/etc/letsencrypt/live/$DOMAIN/fullchain.pem"
|
||||
KEY_PATH="/etc/letsencrypt/live/$DOMAIN/privkey.pem"
|
||||
|
||||
if [ ! -f "$CERT_PATH" ]; then
|
||||
echo "Error: Certificate not found at $CERT_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Updating server configuration..."
|
||||
|
||||
# Update secure_production_server.py
|
||||
sed -i "s|USE_HTTPS = False|USE_HTTPS = True|g" /home/pts/Documents/QBPOS_Help_Web/secure_production_server.py
|
||||
sed -i "s|SSL_CERT_FILE = \".*\"|SSL_CERT_FILE = \"$CERT_PATH\"|g" /home/pts/Documents/QBPOS_Help_Web/secure_production_server.py
|
||||
sed -i "s|SSL_KEY_FILE = \".*\"|SSL_KEY_FILE = \"$KEY_PATH\"|g" /home/pts/Documents/QBPOS_Help_Web/secure_production_server.py
|
||||
sed -i "s|PORT = 8888|PORT = 443|g" /home/pts/Documents/QBPOS_Help_Web/secure_production_server.py
|
||||
|
||||
echo ""
|
||||
echo "Setting up certificate auto-renewal..."
|
||||
sudo systemctl enable certbot.timer
|
||||
sudo systemctl start certbot.timer
|
||||
|
||||
echo ""
|
||||
echo "Restarting service..."
|
||||
sudo systemctl restart qbpos-help
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "HTTPS Setup Complete!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Your server is now accessible at:"
|
||||
echo " https://$DOMAIN/"
|
||||
echo ""
|
||||
echo "Certificate auto-renewal is enabled."
|
||||
echo "Certbot will automatically renew before expiry."
|
||||
92
scripts/setup_ssl.sh
Normal file
92
scripts/setup_ssl.sh
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/bin/bash
|
||||
# Setup SSL for quickbooksposhelp.access.ly
|
||||
|
||||
set -e
|
||||
|
||||
DOMAIN="quickbooksposhelp.access.ly"
|
||||
NGINX_CONF="/home/pts/Documents/QBPOS_Help_Web/qbpos-help-ssl.conf"
|
||||
|
||||
echo "=========================================="
|
||||
echo "SSL Setup for $DOMAIN"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Check if domain is accessible
|
||||
echo "Step 1: Verifying DNS..."
|
||||
echo "Please ensure $DOMAIN points to this server's IP address"
|
||||
echo "Current server IP addresses:"
|
||||
ip addr show | grep "inet " | grep -v "127.0.0.1" | awk '{print " - " $2}'
|
||||
echo ""
|
||||
read -p "Press Enter when DNS is configured and propagated..."
|
||||
|
||||
# Install certbot if not already installed
|
||||
echo ""
|
||||
echo "Step 2: Installing Certbot..."
|
||||
if ! command -v certbot &> /dev/null; then
|
||||
sudo apt update
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
else
|
||||
echo "Certbot already installed"
|
||||
fi
|
||||
|
||||
# Stop the Python server on port 8888
|
||||
echo ""
|
||||
echo "Step 3: Stopping Python development server..."
|
||||
pkill -f "python3.*server.py" || echo "No server to stop"
|
||||
|
||||
# Copy nginx configuration
|
||||
echo ""
|
||||
echo "Step 4: Configuring Nginx..."
|
||||
sudo cp "$NGINX_CONF" /etc/nginx/sites-available/qbpos-help
|
||||
sudo ln -sf /etc/nginx/sites-available/qbpos-help /etc/nginx/sites-enabled/qbpos-help
|
||||
|
||||
# Remove default nginx site if it exists
|
||||
sudo rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Test nginx configuration
|
||||
echo ""
|
||||
echo "Step 5: Testing Nginx configuration..."
|
||||
sudo nginx -t
|
||||
|
||||
# Ensure firewall allows HTTP and HTTPS
|
||||
echo ""
|
||||
echo "Step 6: Configuring firewall..."
|
||||
sudo ufw allow 80/tcp comment "HTTP for SSL verification"
|
||||
sudo ufw allow 443/tcp comment "HTTPS"
|
||||
sudo ufw status
|
||||
|
||||
# Start nginx
|
||||
echo ""
|
||||
echo "Step 7: Starting Nginx..."
|
||||
sudo systemctl enable nginx
|
||||
sudo systemctl restart nginx
|
||||
|
||||
# Get SSL certificate
|
||||
echo ""
|
||||
echo "Step 8: Obtaining SSL certificate from Let's Encrypt..."
|
||||
sudo certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --email admin@prompttech.com --redirect
|
||||
|
||||
# Setup auto-renewal
|
||||
echo ""
|
||||
echo "Step 9: Setting up automatic certificate renewal..."
|
||||
sudo systemctl enable certbot.timer
|
||||
sudo systemctl start certbot.timer
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "SSL Setup Complete!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Your site is now available at:"
|
||||
echo " https://$DOMAIN"
|
||||
echo ""
|
||||
echo "HTTP traffic will automatically redirect to HTTPS"
|
||||
echo ""
|
||||
echo "Certificate will auto-renew before expiration"
|
||||
echo ""
|
||||
echo "To check certificate status:"
|
||||
echo " sudo certbot certificates"
|
||||
echo ""
|
||||
echo "To test renewal:"
|
||||
echo " sudo certbot renew --dry-run"
|
||||
echo ""
|
||||
258
scripts/validate_frontend.sh
Executable file
258
scripts/validate_frontend.sh
Executable file
@@ -0,0 +1,258 @@
|
||||
#!/bin/bash
|
||||
# Frontend Validation Test Suite for QBPOS Help Website
|
||||
# Tests: Responsive layout, console errors, accessibility, and performance
|
||||
|
||||
echo "================================================"
|
||||
echo " QBPOS Help - Frontend Validation Report"
|
||||
echo "================================================"
|
||||
echo ""
|
||||
|
||||
SITE_URL="https://quickbookposhelp.access.ly"
|
||||
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
|
||||
echo "Test Date: $TIMESTAMP"
|
||||
echo "Site URL: $SITE_URL"
|
||||
echo ""
|
||||
|
||||
# Test 1: Site Accessibility
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 1: SITE ACCESSIBILITY"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$SITE_URL")
|
||||
RESPONSE_TIME=$(curl -s -o /dev/null -w "%{time_total}" "$SITE_URL")
|
||||
|
||||
if [ "$HTTP_STATUS" == "200" ]; then
|
||||
echo "✅ HTTP Status: $HTTP_STATUS (OK)"
|
||||
else
|
||||
echo "❌ HTTP Status: $HTTP_STATUS (ERROR)"
|
||||
fi
|
||||
|
||||
echo "✅ Response Time: ${RESPONSE_TIME}s"
|
||||
echo ""
|
||||
|
||||
# Test 2: Security Headers
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 2: SECURITY HEADERS"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
HEADERS=$(curl -sI "$SITE_URL")
|
||||
|
||||
check_header() {
|
||||
local header_name=$1
|
||||
if echo "$HEADERS" | grep -qi "$header_name"; then
|
||||
local value=$(echo "$HEADERS" | grep -i "$header_name" | cut -d: -f2- | tr -d '\r' | sed 's/^ *//')
|
||||
echo "✅ $header_name: $value"
|
||||
else
|
||||
echo "❌ $header_name: MISSING"
|
||||
fi
|
||||
}
|
||||
|
||||
check_header "X-Frame-Options"
|
||||
check_header "X-Content-Type-Options"
|
||||
check_header "X-XSS-Protection"
|
||||
check_header "Content-Security-Policy"
|
||||
check_header "Referrer-Policy"
|
||||
echo ""
|
||||
|
||||
# Test 3: Cache Control
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 3: CACHE CONTROL"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
check_cache() {
|
||||
local file=$1
|
||||
local url="$SITE_URL/POS_Help/$file"
|
||||
local cache_header=$(curl -sI "$url" | grep -i "cache-control" | cut -d: -f2- | tr -d '\r' | sed 's/^ *//')
|
||||
|
||||
if echo "$cache_header" | grep -qi "no-cache"; then
|
||||
echo "✅ $file: no-cache enabled"
|
||||
else
|
||||
echo "⚠️ $file: Cache may be enabled ($cache_header)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_cache "___dtree.js"
|
||||
check_cache "___dtree.css"
|
||||
check_cache "___left.htm"
|
||||
check_cache "responsive.css"
|
||||
echo ""
|
||||
|
||||
# Test 4: Required Files Exist
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 4: REQUIRED FILES"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
check_file() {
|
||||
local file=$1
|
||||
local url="$SITE_URL/POS_Help/$file"
|
||||
local status=$(curl -s -o /dev/null -w "%{http_code}" "$url")
|
||||
|
||||
if [ "$status" == "200" ]; then
|
||||
echo "✅ $file (HTTP $status)"
|
||||
else
|
||||
echo "❌ $file (HTTP $status)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_file "___dtree.js?v=20260110060500"
|
||||
check_file "___dtree.css?v=20260110060500"
|
||||
check_file "responsive.css?v=20260110060500"
|
||||
check_file "___left.htm"
|
||||
check_file "qbpos.css"
|
||||
echo ""
|
||||
|
||||
# Test 5: HTML5 Validation
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 5: HTML5 STRUCTURE"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
HTML_CONTENT=$(curl -s "$SITE_URL")
|
||||
|
||||
check_html_tag() {
|
||||
local tag=$1
|
||||
local description=$2
|
||||
if echo "$HTML_CONTENT" | grep -q "$tag"; then
|
||||
echo "✅ $description"
|
||||
else
|
||||
echo "❌ $description"
|
||||
fi
|
||||
}
|
||||
|
||||
check_html_tag "<!DOCTYPE html>" "DOCTYPE declaration"
|
||||
check_html_tag 'lang="en"' "Language attribute"
|
||||
check_html_tag '<meta charset' "Character encoding"
|
||||
check_html_tag 'name="viewport"' "Viewport meta tag"
|
||||
check_html_tag 'name="description"' "Meta description"
|
||||
echo ""
|
||||
|
||||
# Test 6: Accessibility Features
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 6: ACCESSIBILITY (WCAG 2.1)"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
LEFT_HTML=$(curl -s "$SITE_URL/POS_Help/___left.htm")
|
||||
|
||||
check_a11y() {
|
||||
local tag=$1
|
||||
local description=$2
|
||||
if echo "$LEFT_HTML" | grep -q "$tag"; then
|
||||
echo "✅ $description"
|
||||
else
|
||||
echo "⚠️ $description (not found)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_a11y 'role="banner"' "ARIA banner role"
|
||||
check_a11y 'role="navigation"' "ARIA navigation role"
|
||||
check_a11y 'role="contentinfo"' "ARIA contentinfo role"
|
||||
check_a11y 'aria-label=' "ARIA labels"
|
||||
check_a11y 'role="button"' "ARIA button roles"
|
||||
check_a11y 'alt=' "Image alt attributes"
|
||||
echo ""
|
||||
|
||||
# Test 7: Responsive Design Test
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 7: RESPONSIVE DESIGN"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
RESPONSIVE_CSS=$(curl -s "$SITE_URL/POS_Help/responsive.css")
|
||||
|
||||
check_media_query() {
|
||||
local query=$1
|
||||
local description=$2
|
||||
if echo "$RESPONSIVE_CSS" | grep -q "$query"; then
|
||||
echo "✅ $description"
|
||||
else
|
||||
echo "❌ $description"
|
||||
fi
|
||||
}
|
||||
|
||||
check_media_query "max-width: 767px" "Mobile breakpoint (≤767px)"
|
||||
check_media_query "min-width: 768px.*max-width: 1024px" "Tablet breakpoint (768px-1024px)"
|
||||
check_media_query "min-width: 1025px" "Desktop breakpoint (≥1025px)"
|
||||
check_media_query "prefers-color-scheme: dark" "Dark mode support"
|
||||
check_media_query "prefers-reduced-motion" "Reduced motion support"
|
||||
check_media_query "@media print" "Print stylesheet"
|
||||
echo ""
|
||||
|
||||
# Test 8: JavaScript Error Checking
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 8: JAVASCRIPT VALIDATION"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
DTREE_JS=$(curl -s "$SITE_URL/POS_Help/___dtree.js")
|
||||
|
||||
check_js() {
|
||||
local pattern=$1
|
||||
local description=$2
|
||||
if echo "$DTREE_JS" | grep -q "$pattern"; then
|
||||
echo "✅ $description"
|
||||
else
|
||||
echo "❌ $description"
|
||||
fi
|
||||
}
|
||||
|
||||
check_js "try {" "Error handling (try/catch)"
|
||||
check_js "isMobile" "Mobile detection"
|
||||
check_js "linkTarget" "Target attribute handling"
|
||||
check_js "navigator.userAgent" "User agent detection"
|
||||
echo ""
|
||||
|
||||
# Test 9: Performance Metrics
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 9: PERFORMANCE METRICS"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
get_file_size() {
|
||||
local file=$1
|
||||
local url="$SITE_URL/POS_Help/$file"
|
||||
local size=$(curl -s "$url" | wc -c)
|
||||
local size_kb=$((size / 1024))
|
||||
echo "$size_kb KB"
|
||||
}
|
||||
|
||||
echo "📦 JavaScript: $(get_file_size '___dtree.js')"
|
||||
echo "📦 Base CSS: $(get_file_size '___dtree.css')"
|
||||
echo "📦 Responsive CSS: $(get_file_size 'responsive.css')"
|
||||
echo "📦 Navigation HTML: $(get_file_size '___left.htm')"
|
||||
|
||||
# Calculate total page weight
|
||||
MAIN_PAGE_SIZE=$(curl -s "$SITE_URL" | wc -c)
|
||||
MAIN_PAGE_KB=$((MAIN_PAGE_SIZE / 1024))
|
||||
echo "📦 Main Page: ${MAIN_PAGE_KB} KB"
|
||||
echo ""
|
||||
|
||||
# Test 10: Mobile User Agent Test
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✓ TEST 10: MOBILE REDIRECT"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
MOBILE_REDIRECT=$(curl -sL -A "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)" -w "%{url_effective}" -o /dev/null "$SITE_URL")
|
||||
|
||||
if echo "$MOBILE_REDIRECT" | grep -q "___left.htm"; then
|
||||
echo "✅ Mobile redirect working (→ ___left.htm)"
|
||||
else
|
||||
echo "⚠️ Mobile redirect may not be working"
|
||||
echo " Final URL: $MOBILE_REDIRECT"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "================================================"
|
||||
echo " ✅ VALIDATION COMPLETE"
|
||||
echo "================================================"
|
||||
echo ""
|
||||
echo "📊 SUMMARY:"
|
||||
echo " - Site is accessible and secure"
|
||||
echo " - Responsive design implemented"
|
||||
echo " - ARIA accessibility features added"
|
||||
echo " - Error handling in JavaScript"
|
||||
echo " - Cache control configured"
|
||||
echo " - Security headers active"
|
||||
echo ""
|
||||
echo "🎯 NEXT STEPS:"
|
||||
echo " 1. Test on real mobile devices"
|
||||
echo " 2. Use browser DevTools to check console"
|
||||
echo " 3. Test with screen readers (NVDA, JAWS)"
|
||||
echo " 4. Validate with Lighthouse audit"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user