# Custom Domain Setup Guide

This guide explains how to configure OpenLiteSpeed to support multiple custom domains for seller sales pages.

## Table of Contents
1. [Overview](#overview)
2. [OpenLiteSpeed Configuration](#openlitespeed-configuration)
3. [DNS Configuration](#dns-configuration)
4. [Cloudflare SSL Setup](#cloudflare-ssl-setup)
5. [Seller Instructions](#seller-instructions)
6. [Troubleshooting](#troubleshooting)

---

## Overview

The custom domain system allows sellers to use their own domains (e.g., `sellerdomain.com`) to display their sales pages instead of using the platform's domain structure (`platform.com/p/seller/page`).

### How It Works

1. **Middleware Detection**: `DetectCustomDomain` middleware checks incoming requests against verified domains in the database
2. **Domain Routing**:
   - `sellerdomain.com/` → Shows seller's default sales page
   - `sellerdomain.com/page-slug` → Shows specific sales page by slug
3. **Backward Compatibility**: Original URLs (`platform.com/p/seller/page-slug`) continue to work

---

## OpenLiteSpeed Configuration

### 1. Virtual Host Setup

OpenLiteSpeed needs to be configured to accept requests for any domain (wildcard vhost).

#### Option A: Single Virtual Host (Recommended)

Edit your main virtual host configuration:

**Location**: `/usr/local/lsws/conf/vhosts/[your-site]/vhconf.conf`

```apache
docRoot                   $VH_ROOT/public
vhDomain                  $VH_NAME, *.yourdomain.com, *
enableGzip                1
enableBrCache             1
enableIpGeo               1

errorlog $VH_ROOT/logs/$VH_NAME.error_log {
  useServer               0
  logLevel                ERROR
  rollingSize             10M
}

accesslog $VH_ROOT/logs/$VH_NAME.access_log {
  useServer               0
  logFormat               "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
  logHeaders              5
  rollingSize             10M
  keepDays                30
}

index  {
  useServer               0
  indexFiles              index.php, index.html
}

scripthandler  {
  add                     lsapi:lsphp81 php
}

rewrite  {
  enable                  1
  autoLoadHtaccess        1
  rules                   <<<END_rules
  # Laravel rewrite rules
  RewriteEngine On

  # Handle Authorization Header
  RewriteCond %{HTTP:Authorization} .
  RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

  # Redirect Trailing Slashes If Not A Folder
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} (.+)/$
  RewriteRule ^ %1 [L,R=301]

  # Send Requests To Front Controller
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^ index.php [L]
  END_rules
}
```

**Key Configuration Points:**

- `vhDomain $VH_NAME, *.yourdomain.com, *` - This accepts ALL domains
- `docRoot $VH_ROOT/public` - Points to Laravel's public directory
- `autoLoadHtaccess 1` - Automatically loads Laravel's .htaccess rules
- `index.php` as the front controller

#### Option B: WebAdmin GUI Configuration

1. Access OpenLiteSpeed WebAdmin: `https://your-server:7080`
2. Navigate to: **Virtual Hosts** → **[Your Site]** → **General**
3. Update **Domain Name** field:
   ```
   yourdomain.com, *.yourdomain.com, *
   ```
4. Save and **Graceful Restart**

### 2. Listener Configuration

Ensure your listeners are configured to accept all domains:

**Location**: `/usr/local/lsws/conf/httpd_config.conf`

```apache
listener HTTP {
  address                 *:80
  secure                  0
  map                     [your-site] *
}

listener HTTPS {
  address                 *:443
  secure                  1
  keyFile                 /path/to/ssl/privkey.pem
  certFile                /path/to/ssl/fullchain.pem
  certChain               1
  sslProtocol             24
  enableSpdy              15
  enableQuic              1
  map                     [your-site] *
}
```

**Key Points:**
- `map [your-site] *` - Maps ALL domains to your virtual host
- HTTPS listener requires valid SSL certificate (see Cloudflare SSL section)

### 3. Restart OpenLiteSpeed

After configuration changes:

```bash
# Graceful restart (recommended - no downtime)
/usr/local/lsws/bin/lswsctrl restart

# Or via systemctl
systemctl restart lsws
```

---

## DNS Configuration

### For Platform Administrator

**Server IP Setup:**

Your server needs a public IP address. All custom domains will point to this IP.

1. Check your server IP:
   ```bash
   curl ifconfig.me
   ```

2. Ensure firewall allows HTTP/HTTPS:
   ```bash
   # UFW (Ubuntu)
   ufw allow 80/tcp
   ufw allow 443/tcp

   # FirewallD (CentOS)
   firewall-cmd --permanent --add-service=http
   firewall-cmd --permanent --add-service=https
   firewall-cmd --reload
   ```

### For Sellers (Instructions to Provide)

Sellers need to configure DNS at their domain registrar or DNS provider.

#### Required DNS Records

**A Record (Required):**
```
Type: A
Name: @ (or leave blank for root domain)
Value: YOUR_SERVER_IP
TTL: 3600 (or auto)
```

**CNAME Record for www (Optional but recommended):**
```
Type: CNAME
Name: www
Value: yourdomain.com
TTL: 3600 (or auto)
```

#### Popular DNS Providers Instructions

**Cloudflare:**
1. Login to Cloudflare dashboard
2. Select your domain
3. Go to **DNS** → **Records**
4. Click **Add record**
5. Add A record pointing to server IP
6. **Important**: Orange cloud (proxy) should be enabled for SSL

**Namecheap:**
1. Login to Namecheap
2. Go to **Domain List** → **Manage**
3. Select **Advanced DNS**
4. Add A record with `@` and server IP
5. Add CNAME record with `www` pointing to `@`

**GoDaddy:**
1. Login to GoDaddy
2. Go to **My Products** → **DNS**
3. Add A record with name `@` and server IP
4. Add CNAME with name `www` and value `@`

#### DNS Propagation

DNS changes can take **24-48 hours** to propagate worldwide, but often complete within 1-2 hours.

**Check DNS propagation:**
- https://dnschecker.org
- https://www.whatsmydns.net

**Command line check:**
```bash
# Check A record
nslookup yourdomain.com

# Check from specific DNS server
dig @8.8.8.8 yourdomain.com
```

---

## Cloudflare SSL Setup

Cloudflare provides free SSL certificates and acts as a reverse proxy.

### Why Use Cloudflare?

- **Free SSL certificates** (automatic)
- **DDoS protection**
- **CDN for faster loading**
- **Easy DNS management**
- **Automatic SSL renewal**

### Step-by-Step Setup

#### 1. Add Domain to Cloudflare

1. Sign up at https://cloudflare.com (free plan)
2. Click **Add Site**
3. Enter your domain name
4. Select **Free Plan**
5. Cloudflare will scan existing DNS records
6. Review and click **Continue**

#### 2. Update Nameservers

Cloudflare will provide two nameservers (e.g., `alex.ns.cloudflare.com`, `kate.ns.cloudflare.com`)

1. Go to your domain registrar (where you bought the domain)
2. Find **Nameserver settings**
3. Replace existing nameservers with Cloudflare's nameservers
4. Save changes
5. Wait for verification (can take 24 hours)

#### 3. Configure SSL Settings

In Cloudflare dashboard:

1. Go to **SSL/TLS** tab
2. Select encryption mode: **Full (strict)** (recommended)
   - **Flexible**: Cloudflare ↔ User (HTTPS), Cloudflare ↔ Server (HTTP) - Not secure
   - **Full**: Cloudflare ↔ User (HTTPS), Cloudflare ↔ Server (HTTPS with self-signed) - Better
   - **Full (strict)**: Cloudflare ↔ User (HTTPS), Cloudflare ↔ Server (HTTPS with valid cert) - Best

3. Enable **Always Use HTTPS**:
   - Go to **SSL/TLS** → **Edge Certificates**
   - Turn on **Always Use HTTPS**

4. Enable **Automatic HTTPS Rewrites**:
   - In **Edge Certificates**
   - Turn on **Automatic HTTPS Rewrites**

#### 4. Origin SSL Certificate (For Full Strict Mode)

If using "Full (strict)", install Cloudflare Origin Certificate on your server:

1. In Cloudflare: **SSL/TLS** → **Origin Server** → **Create Certificate**
2. Select:
   - Key type: RSA (2048)
   - Hostnames: `yourdomain.com`, `*.yourdomain.com`
   - Validity: 15 years
3. Click **Create**
4. Copy the certificate and private key

**Install on server:**

```bash
# Create SSL directory
mkdir -p /etc/letsencrypt/live/yourdomain.com

# Save certificate
nano /etc/letsencrypt/live/yourdomain.com/fullchain.pem
# Paste certificate content

# Save private key
nano /etc/letsencrypt/live/yourdomain.com/privkey.pem
# Paste private key content

# Set permissions
chmod 644 /etc/letsencrypt/live/yourdomain.com/fullchain.pem
chmod 600 /etc/letsencrypt/live/yourdomain.com/privkey.pem
```

**Update OpenLiteSpeed listener:**

```apache
listener HTTPS {
  address                 *:443
  secure                  1
  keyFile                 /etc/letsencrypt/live/yourdomain.com/privkey.pem
  certFile                /etc/letsencrypt/live/yourdomain.com/fullchain.pem
  certChain               1
  sslProtocol             24
  enableSpdy              15
  enableQuic              1
  map                     [your-site] *
}
```

Restart OpenLiteSpeed:
```bash
/usr/local/lsws/bin/lswsctrl restart
```

#### 5. DNS Configuration in Cloudflare

1. Go to **DNS** → **Records**
2. Add A record:
   ```
   Type: A
   Name: @ (or domain root)
   IPv4 address: YOUR_SERVER_IP
   Proxy status: Proxied (orange cloud)
   TTL: Auto
   ```

3. Add CNAME for www:
   ```
   Type: CNAME
   Name: www
   Target: yourdomain.com
   Proxy status: Proxied (orange cloud)
   TTL: Auto
   ```

**Important**: Orange cloud = Proxied through Cloudflare (enables SSL, CDN, protection)

#### 6. Verify SSL

After DNS propagates (1-2 hours):

1. Visit `https://yourdomain.com`
2. Check for padlock icon in browser
3. Test SSL: https://www.ssllabs.com/ssltest/

---

## Seller Instructions

Provide this simplified guide to sellers:

### How to Connect Your Custom Domain

#### Step 1: Add Domain in Dashboard

1. Login to your seller account
2. Navigate to **My Stores** → **View My Domains**
3. Click **+ Add Custom Domain**
4. Enter your domain (e.g., `yourdomain.com`)
5. Optionally select a default sales page
6. Check **Set as primary domain** if this is your main domain
7. Click **Add Domain**

#### Step 2: Configure DNS

You need to point your domain to our server:

**Required DNS Record:**
```
Type: A
Name: @ (root)
Value: [YOUR_SERVER_IP]
```

**Optional (for www):**
```
Type: CNAME
Name: www
Value: yourdomain.com
```

**Where to add these records:**
- Go to where you bought your domain (GoDaddy, Namecheap, etc.)
- Find "DNS Settings" or "DNS Management"
- Add the records above

#### Step 3: Wait for DNS Propagation

DNS changes take 1-24 hours to complete. You can check status at:
- https://dnschecker.org

#### Step 4: Verify Domain

1. Once DNS is propagated, return to **View My Domains**
2. Click **View** on your domain
3. Click **Verify Domain Now**
4. If successful, your domain status will change to **Active**

#### Step 5: Access Your Pages

Once verified:
- **Root domain**: `https://yourdomain.com` (shows your default page)
- **Other pages**: `https://yourdomain.com/page-slug`

All your sales pages are now accessible via your custom domain!

---

## Troubleshooting

### Domain Not Loading

**Symptoms**: Domain shows error or doesn't load

**Checks:**
1. Verify DNS propagation:
   ```bash
   nslookup yourdomain.com
   # Should return your server IP
   ```

2. Check OpenLiteSpeed virtual host:
   ```bash
   # Check if vhost accepts wildcard domains
   grep "vhDomain" /usr/local/lsws/conf/vhosts/*/vhconf.conf
   # Should include: vhDomain *
   ```

3. Check OpenLiteSpeed is running:
   ```bash
   systemctl status lsws
   ```

4. Check error logs:
   ```bash
   tail -f /usr/local/lsws/logs/error.log
   tail -f /path/to/your/site/logs/laravel.log
   ```

### SSL Certificate Error

**Symptoms**: "Your connection is not private" or "NET::ERR_CERT_AUTHORITY_INVALID"

**Solution:**

1. **If using Cloudflare:**
   - Ensure SSL mode is set to **Full** or **Full (strict)**
   - Verify orange cloud is enabled (proxied)
   - Install Cloudflare Origin Certificate on server

2. **Check certificate paths:**
   ```bash
   ls -la /etc/letsencrypt/live/yourdomain.com/
   # Should show fullchain.pem and privkey.pem
   ```

3. **Verify OpenLiteSpeed listener config:**
   ```bash
   grep -A 5 "listener HTTPS" /usr/local/lsws/conf/httpd_config.conf
   # Check keyFile and certFile paths
   ```

### Page Shows Default Laravel Welcome Page

**Symptoms**: Custom domain loads but shows Laravel welcome screen instead of sales page

**Checks:**

1. Verify domain is verified in database:
   ```bash
   php artisan tinker
   >>> \App\Models\SellerDomain::where('domain', 'yourdomain.com')->first();
   # Should show is_active=1, verified_at should not be null
   ```

2. Check middleware is loaded:
   ```bash
   php artisan route:list | grep "DetectCustomDomain"
   ```

3. Check default sales page is set:
   - Login to seller account
   - View domain details
   - Ensure "Default Sales Page" is configured

### 404 Error on Custom Domain

**Symptoms**: Root domain works but `/page-slug` returns 404

**Checks:**

1. Verify sales page belongs to domain owner:
   ```bash
   php artisan tinker
   >>> $domain = \App\Models\SellerDomain::where('domain', 'yourdomain.com')->first();
   >>> $page = \App\Models\SalesPage::where('slug', 'your-slug')->where('user_id', $domain->user_id)->first();
   >>> $page; // Should return the page
   ```

2. Ensure sales page is active:
   - Check `is_active = 1` in sales_pages table

3. Check .htaccess rules are working:
   ```bash
   # Test URL rewriting
   curl -I https://yourdomain.com/page-slug
   # Should not return 404
   ```

### Multiple Sellers - Domain Conflicts

**Symptoms**: Two sellers try to use the same domain

**Prevention**: Domain uniqueness is enforced at database level:
```sql
-- Already implemented in migration
$table->string('domain')->unique();
```

**Resolution**: First seller to add the domain owns it. Second seller will get validation error.

### Performance Issues

**Symptoms**: Slow loading with custom domains

**Optimizations:**

1. **Enable OPcache** (PHP):
   ```bash
   nano /usr/local/lsws/lsphp81/etc/php/8.1/litespeed/php.ini

   # Add/uncomment:
   opcache.enable=1
   opcache.memory_consumption=128
   opcache.interned_strings_buffer=8
   opcache.max_accelerated_files=10000
   opcache.revalidate_freq=2
   ```

2. **Use Cloudflare CDN**:
   - Enable orange cloud (proxy)
   - Cloudflare caches static assets

3. **Laravel optimization**:
   ```bash
   php artisan config:cache
   php artisan route:cache
   php artisan view:cache
   ```

### DNS Propagation Taking Too Long

**Symptoms**: DNS changes not visible after 24 hours

**Checks:**

1. Verify nameservers are correct:
   ```bash
   dig NS yourdomain.com
   # Should show correct nameservers (e.g., Cloudflare NS)
   ```

2. Flush local DNS cache:
   ```bash
   # Windows
   ipconfig /flushdns

   # Mac
   sudo dscacheutil -flushcache

   # Linux
   sudo systemd-resolve --flush-caches
   ```

3. Check from multiple locations:
   - Use https://dnschecker.org
   - Test from different devices/networks

---

## Advanced Configuration

### Multiple Main Domains (Production)

If your platform uses different domains (e.g., `platform1.com`, `platform2.com`):

**Update .env:**
```env
APP_URL=https://platform1.com
MAIN_DOMAINS=platform1.com,platform2.com,localhost,127.0.0.1
```

**Update middleware:**
```php
// app/Http/Middleware/DetectCustomDomain.php
$host = $request->getHost();
$mainDomains = explode(',', env('MAIN_DOMAINS', 'localhost,127.0.0.1'));

if (!in_array($host, $mainDomains)) {
    // This is a custom domain
    // ... detection logic
}
```

### Load Balancer / Reverse Proxy Setup

If using Nginx or Apache as reverse proxy in front of OpenLiteSpeed:

**Nginx Example:**
```nginx
server {
    listen 80;
    server_name _;  # Accept all domains

    location / {
        proxy_pass http://127.0.0.1:8080;  # OpenLiteSpeed backend
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
```

### Wildcard SSL Certificate

For multiple subdomains under your main domain:

**Let's Encrypt Wildcard:**
```bash
certbot certonly --manual --preferred-challenges=dns \
  --email admin@yourdomain.com \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --agree-tos \
  -d yourdomain.com -d *.yourdomain.com
```

**Configure OpenLiteSpeed:**
```apache
listener HTTPS {
  keyFile                 /etc/letsencrypt/live/yourdomain.com/privkey.pem
  certFile                /etc/letsencrypt/live/yourdomain.com/fullchain.pem
  # ... other settings
}
```

---

## Security Considerations

### Domain Verification

- Always verify domain ownership before activation
- Current implementation: Manual verification
- Future: Automated verification via TXT record or file upload

### Rate Limiting

Consider implementing rate limiting for custom domains:

```php
// app/Http/Kernel.php
protected $middlewareGroups = [
    'web' => [
        // ... existing middleware
        \Illuminate\Routing\Middleware\ThrottleRequests::class.':60,1',
    ],
];
```

### DDoS Protection

Cloudflare provides automatic DDoS protection when proxied (orange cloud).

Additional protection:
```bash
# Fail2ban for OpenLiteSpeed
apt-get install fail2ban
```

### Input Validation

Domain validation is already implemented in `SellerDomainController`:

```php
$request->validate([
    'domain' => 'required|string|max:255|unique:seller_domains,domain',
]);
```

Additional validation in `cleanDomainName()` removes malicious characters.

---

## Monitoring & Logging

### Check Active Custom Domains

```bash
php artisan tinker
>>> \App\Models\SellerDomain::where('is_active', true)->count();
>>> \App\Models\SellerDomain::verified()->get(['domain', 'user_id', 'verified_at']);
```

### Monitor OpenLiteSpeed Access Logs

```bash
# Real-time monitoring
tail -f /usr/local/lsws/logs/access.log | grep -v "127.0.0.1"

# Count requests per domain
awk '{print $1}' /usr/local/lsws/logs/access.log | sort | uniq -c | sort -rn | head -20
```

### Laravel Logs

```bash
# Monitor application errors
tail -f storage/logs/laravel.log

# Search for custom domain related errors
grep "SellerDomain" storage/logs/laravel.log
```

---

## Maintenance Commands

### Clear All Caches

```bash
# Laravel caches
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

# OPcache (if enabled)
php artisan opcache:clear

# Restart OpenLiteSpeed
systemctl restart lsws
```

### Database Maintenance

```bash
# Check domain verification status
php artisan tinker
>>> \App\Models\SellerDomain::whereNull('verified_at')->get();

# Re-verify all domains
>>> \App\Models\SellerDomain::where('is_active', true)->each(function($d) {
    $d->markAsVerified();
});
```

---

## Support Resources

- **OpenLiteSpeed Documentation**: https://openlitespeed.org/kb/
- **Cloudflare Documentation**: https://developers.cloudflare.com/
- **Laravel Documentation**: https://laravel.com/docs
- **DNS Checker Tool**: https://dnschecker.org
- **SSL Test Tool**: https://www.ssllabs.com/ssltest/

---

## Changelog

**v1.0.0** - Initial implementation
- Custom domain detection middleware
- Multi-domain routing support
- Seller dashboard for domain management
- DNS verification instructions
