mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-18 11:59:26 +00:00
Remove outdated debug and verification scripts for deployment isolation
- Deleted `debug-services.sh`, `deploy-enhanced-debug.sh`, and `deploy-isolation-fix.sh` as they are no longer needed. - Removed `test-nextauth-cookie-isolation.sh`, `verify-all-isolation.sh`, `verify-db-isolation.sh`, `verify-enhanced-isolation.sh`, and `verify-isolation.sh` due to redundancy and updates in the verification process.
This commit is contained in:
parent
d32389a8ef
commit
ee64e9b52d
19 changed files with 1 additions and 2477 deletions
|
|
@ -1,101 +0,0 @@
|
||||||
# Environment Variables for Coolify Deployments
|
|
||||||
|
|
||||||
> ⚠️ **SECURITY NOTE**: This file contains placeholder values only. Replace ALL `YOUR_*` placeholders with your actual secure values before deployment. Never commit actual secrets to version control.
|
|
||||||
|
|
||||||
## Placeholder Values to Replace:
|
|
||||||
- `YOUR_DEV_REDIS_PASSWORD` - Strong password for development Redis instance
|
|
||||||
- `YOUR_LIVE_REDIS_PASSWORD` - Strong password for production Redis instance
|
|
||||||
- `YOUR_DEV_DB_PASSWORD` - Strong password for development database
|
|
||||||
- `YOUR_LIVE_DB_PASSWORD` - Strong password for production database
|
|
||||||
- `YOUR_DEV_NEXTAUTH_SECRET` - Cryptographically secure random string for dev auth
|
|
||||||
- `YOUR_LIVE_NEXTAUTH_SECRET` - Cryptographically secure random string for production auth
|
|
||||||
- `YOUR_RESEND_API_KEY` - Your actual Resend API key for email delivery
|
|
||||||
- `your-dev-domain.com` - Your development domain name
|
|
||||||
- `your-prod-domain.com` - Your production domain name
|
|
||||||
- `contact@.com` - Your organization contact email
|
|
||||||
|
|
||||||
## DEV Environment
|
|
||||||
```
|
|
||||||
DEPLOYMENT_NAME=dev
|
|
||||||
LEARNHOUSE_DOMAIN=your-dev-domain.com
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=your-dev-domain.com
|
|
||||||
LEARNHOUSE_CONTACT_EMAIL=contact@.com
|
|
||||||
LEARNHOUSE_EMAIL_PROVIDER=resend
|
|
||||||
LEARNHOUSE_IS_AI_ENABLED=false
|
|
||||||
LEARNHOUSE_REDIS_CONNECTION_STRING=redis://default:YOUR_DEV_REDIS_PASSWORD@redis-dev:6379/1 # Use deployment-specific Redis hostname
|
|
||||||
LEARNHOUSE_RESEND_API_KEY=YOUR_RESEND_API_KEY
|
|
||||||
LEARNHOUSE_SELF_HOSTED=true
|
|
||||||
LEARNHOUSE_SITE_DESCRIPTION=ADR LMS is platform tailored for learning experiences.
|
|
||||||
LEARNHOUSE_SITE_NAME=ADR LMS
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse_dev:YOUR_DEV_DB_PASSWORD@db-dev:5432/learnhouse_dev # Use deployment-specific database hostname
|
|
||||||
LEARNHOUSE_SSL=true
|
|
||||||
LEARNHOUSE_SYSTEM_EMAIL_ADDRESS=contact@.com
|
|
||||||
NEXTAUTH_SECRET=YOUR_DEV_NEXTAUTH_SECRET
|
|
||||||
NEXTAUTH_URL=https://your-dev-domain.com
|
|
||||||
NEXT_PUBLIC_API_URL=https://your-dev-domain.com/api/v1/
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_API_URL=https://your-dev-domain.com/api/v1/
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL=https://your-dev-domain.com/
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG=default
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_DOMAIN=your-dev-domain.com
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_MULTI_ORG=false
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN=your-dev-domain.com
|
|
||||||
POSTGRES_DB=learnhouse_dev
|
|
||||||
POSTGRES_PASSWORD=YOUR_DEV_DB_PASSWORD
|
|
||||||
POSTGRES_USER=learnhouse_dev
|
|
||||||
REDIS_PASSWORD=YOUR_DEV_REDIS_PASSWORD
|
|
||||||
```
|
|
||||||
|
|
||||||
## LIVE Environment
|
|
||||||
```
|
|
||||||
DEPLOYMENT_NAME=live
|
|
||||||
LEARNHOUSE_DOMAIN=your-prod-domain.com
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=your-prod-domain.com
|
|
||||||
LEARNHOUSE_CONTACT_EMAIL=contact@.com
|
|
||||||
LEARNHOUSE_EMAIL_PROVIDER=resend
|
|
||||||
LEARNHOUSE_IS_AI_ENABLED=false
|
|
||||||
LEARNHOUSE_REDIS_CONNECTION_STRING=redis://default:YOUR_LIVE_REDIS_PASSWORD@redis-live:6379/0 # Use deployment-specific Redis hostname
|
|
||||||
LEARNHOUSE_RESEND_API_KEY=YOUR_RESEND_API_KEY
|
|
||||||
LEARNHOUSE_SELF_HOSTED=true
|
|
||||||
LEARNHOUSE_SITE_DESCRIPTION=ADR LMS is platform tailored for learning experiences.
|
|
||||||
LEARNHOUSE_SITE_NAME=ADR LMS
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse:YOUR_LIVE_DB_PASSWORD@db-live:5432/learnhouse # Use deployment-specific database hostname
|
|
||||||
LEARNHOUSE_SSL=true
|
|
||||||
LEARNHOUSE_SYSTEM_EMAIL_ADDRESS=contact@.com
|
|
||||||
NEXTAUTH_SECRET=YOUR_LIVE_NEXTAUTH_SECRET
|
|
||||||
NEXTAUTH_URL=https://your-prod-domain.com
|
|
||||||
NEXT_PUBLIC_API_URL=https://your-prod-domain.com/api/v1/
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_API_URL=https://your-prod-domain.com/api/v1/
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL=https://your-prod-domain.com/
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG=default
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_DOMAIN=your-prod-domain.com
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_MULTI_ORG=false
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN=your-prod-domain.com
|
|
||||||
POSTGRES_DB=learnhouse
|
|
||||||
POSTGRES_PASSWORD=YOUR_LIVE_DB_PASSWORD
|
|
||||||
POSTGRES_USER=learnhouse
|
|
||||||
REDIS_PASSWORD=YOUR_LIVE_REDIS_PASSWORD
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key Differences for Isolation
|
|
||||||
|
|
||||||
The critical environment variables that ensure complete isolation:
|
|
||||||
|
|
||||||
1. **DEPLOYMENT_NAME**: Different for each environment (`dev` vs `live`)
|
|
||||||
2. **Domain Variables**: Point to different domains
|
|
||||||
3. **Database Hostnames**: Use deployment-specific hostnames (`db-dev` vs `db-live`)
|
|
||||||
4. **Redis Hostnames**: Use deployment-specific hostnames (`redis-dev` vs `redis-live`)
|
|
||||||
5. **Database Credentials**: Different databases and users
|
|
||||||
6. **Redis Connection**: Different Redis databases (1 vs 0)
|
|
||||||
7. **Secrets**: Different NEXTAUTH_SECRET values
|
|
||||||
|
|
||||||
## Deployment Isolation Strategy
|
|
||||||
|
|
||||||
To prevent cross-deployment contamination:
|
|
||||||
|
|
||||||
1. **Database Isolation**: Each deployment must use its own separate database server with a unique hostname
|
|
||||||
2. **Redis Isolation**: Each deployment must use its own Redis instance with a unique hostname
|
|
||||||
3. **Domain Isolation**: Each deployment must use its own domain and cookie domain
|
|
||||||
4. **URL Patching**: The Dockerfile includes runtime patching of hardcoded URLs
|
|
||||||
5. **Network Isolation**: Each deployment should use its own Docker network
|
|
||||||
|
|
||||||
See `DATABASE_ISOLATION_FIX.md` for detailed implementation steps.
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
||||||
# Database Isolation Fix for LearnHouse Deployments
|
|
||||||
|
|
||||||
## Issues Identified: Multiple Sources of Cross-Deployment Contamination
|
|
||||||
|
|
||||||
We have identified several issues causing cross-deployment contamination between DEV (adr-lms.whitex.cloud) and LIVE (edu.adradviser.ro) environments:
|
|
||||||
|
|
||||||
### 1. Shared Database Connection
|
|
||||||
|
|
||||||
Both deployments are connecting to the same database server, causing data sharing:
|
|
||||||
|
|
||||||
- DEV: `postgresql://learnhouse_dev:YOUR_DEV_DB_PASSWORD@db:5432/learnhouse_dev`
|
|
||||||
- LIVE: `postgresql://learnhouse:YOUR_LIVE_DB_PASSWORD@db:5432/learnhouse`
|
|
||||||
|
|
||||||
The container networking is not isolating these properly, causing both deployments to resolve `db` to the same physical database server.
|
|
||||||
|
|
||||||
### 2. Hardcoded URLs in Frontend Bundle
|
|
||||||
|
|
||||||
The DEV deployment contains hardcoded URLs pointing to the LIVE site:
|
|
||||||
- `http://edu.adradviser.ro/collections/new`
|
|
||||||
- `http://edu.adradviser.ro/courses?new=true`
|
|
||||||
|
|
||||||
These URLs are embedded in the JavaScript bundles at build time and aren't being properly updated at runtime.
|
|
||||||
|
|
||||||
### 3. Container API Access Inconsistencies
|
|
||||||
|
|
||||||
The API is accessed differently from inside containers versus from outside:
|
|
||||||
- Inside container: via `http://localhost:9000`
|
|
||||||
- External access: via domain's `/api/v1` path
|
|
||||||
|
|
||||||
This inconsistency complicates URL patching and can cause references to the wrong domain.
|
|
||||||
|
|
||||||
## How to Fix Deployment Isolation
|
|
||||||
|
|
||||||
### 1. Database Connection Isolation
|
|
||||||
|
|
||||||
Each deployment must use its own fully-qualified database hostname:
|
|
||||||
|
|
||||||
1. For DEV deployment:
|
|
||||||
```
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse_dev:YOUR_DEV_DB_PASSWORD@db-dev.${DEPLOYMENT_NAME}-network:5432/learnhouse_dev
|
|
||||||
```
|
|
||||||
|
|
||||||
2. For LIVE deployment:
|
|
||||||
```
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse:YOUR_LIVE_DB_PASSWORD@db-live.${DEPLOYMENT_NAME}-network:5432/learnhouse
|
|
||||||
```
|
|
||||||
|
|
||||||
This ensures:
|
|
||||||
- Each deployment uses a uniquely named database server
|
|
||||||
- The server hostname includes the deployment name for clarity
|
|
||||||
- The network name is deployment-specific
|
|
||||||
|
|
||||||
### 2. Enhanced URL Patching
|
|
||||||
|
|
||||||
We've improved the URL patching in Dockerfile_coolify to handle multiple URL formats:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Replace all occurrences of edu.adradviser.ro with the current domain
|
|
||||||
find /app/web/.next -type f -name "*.js" -exec sed -i "s|http://edu.adradviser.ro|$NEXT_PUBLIC_LEARNHOUSE_DOMAIN|g" {} \;
|
|
||||||
find /app/web/.next -type f -name "*.js" -exec sed -i "s|https://edu.adradviser.ro|$NEXT_PUBLIC_LEARNHOUSE_DOMAIN|g" {} \;
|
|
||||||
find /app/web/.next -type f -name "*.js" -exec sed -i "s|//edu.adradviser.ro|//$DOMAIN_ONLY|g" {} \;
|
|
||||||
find /app/web/.next -type f -name "*.js" -exec sed -i "s|\"href\":\"http://edu.adradviser.ro|\"href\":\"$NEXT_PUBLIC_LEARNHOUSE_DOMAIN|g" {} \;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Cookie Domain Isolation
|
|
||||||
|
|
||||||
Ensure each deployment uses its own cookie domain:
|
|
||||||
|
|
||||||
```
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=adr-lms.whitex.cloud # For DEV
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=edu.adradviser.ro # For LIVE
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. API URL Inside vs Outside Container
|
|
||||||
|
|
||||||
Address the inconsistency in how the API is accessed:
|
|
||||||
|
|
||||||
1. Inside container: `http://localhost:9000`
|
|
||||||
2. External access: via domain's `/api/v1` path
|
|
||||||
|
|
||||||
Solution:
|
|
||||||
- Added the debug endpoint at `/api/v1/debug` to ensure it's accessible externally
|
|
||||||
- Enhanced the URL patching to handle both internal and external URL formats
|
|
||||||
|
|
||||||
### 5. API Debug Endpoints
|
|
||||||
|
|
||||||
Added comprehensive debug endpoints:
|
|
||||||
|
|
||||||
1. `/api/v1/debug/deployment` - Shows deployment configuration details
|
|
||||||
2. `/api/v1/debug/urls` - Scans for any remaining hardcoded URLs in the frontend bundle
|
|
||||||
|
|
||||||
## Verification Process
|
|
||||||
|
|
||||||
After implementing these fixes, use this verification process:
|
|
||||||
|
|
||||||
1. **Deploy the API changes** to add the debug endpoints:
|
|
||||||
```bash
|
|
||||||
git add apps/api/src/routers/debug.py apps/api/src/router.py apps/api/app.py
|
|
||||||
git commit -m "Add isolation debug endpoints for deployment verification"
|
|
||||||
git push
|
|
||||||
# Deploy through your CI/CD process
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Verify database isolation** by accessing the debug endpoints:
|
|
||||||
```bash
|
|
||||||
# Check DEV deployment
|
|
||||||
curl -k https://adr-lms.whitex.cloud/api/v1/debug/deployment
|
|
||||||
|
|
||||||
# Check LIVE deployment
|
|
||||||
curl -k https://edu.adradviser.ro/api/v1/debug/deployment
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Check for hardcoded URLs** in the frontend bundle:
|
|
||||||
```bash
|
|
||||||
# Check DEV deployment
|
|
||||||
curl -k https://adr-lms.whitex.cloud/api/v1/debug/urls
|
|
||||||
|
|
||||||
# Check LIVE deployment
|
|
||||||
curl -k https://edu.adradviser.ro/api/v1/debug/urls
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Test with incognito browsers** to ensure sessions don't cross-contaminate
|
|
||||||
|
|
||||||
5. **Run the verification script** to perform all checks automatically:
|
|
||||||
```bash
|
|
||||||
./verify-isolation.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Solution:
|
|
||||||
- Added the debug endpoint at `/api/v1/debug` to ensure it's accessible externally
|
|
||||||
- Enhanced the URL patching to handle both internal and external URL formats
|
|
||||||
|
|
||||||
### 5. API Debug Endpoints
|
|
||||||
|
|
||||||
Added comprehensive debug endpoints:
|
|
||||||
|
|
||||||
1. `/api/v1/debug/deployment` - Shows deployment configuration details
|
|
||||||
2. `/api/v1/debug/urls` - Scans for any remaining hardcoded URLs in the frontend bundle
|
|
||||||
|
|
||||||
4. **Network Isolation**: Updated docker-compose-coolify.yml to use deployment-specific networks.
|
|
||||||
|
|
||||||
## Verification Steps
|
|
||||||
|
|
||||||
After implementing these changes:
|
|
||||||
|
|
||||||
1. **Deploy the enhanced debug tools**:
|
|
||||||
```bash
|
|
||||||
./deploy-enhanced-debug.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Run the enhanced verification script** for comprehensive isolation checks:
|
|
||||||
```bash
|
|
||||||
./verify-enhanced-isolation.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Verify cookie isolation** using the dedicated cookie debug endpoint:
|
|
||||||
```bash
|
|
||||||
curl -v https://adr-lms.whitex.cloud/api/v1/debug/cookies
|
|
||||||
curl -v https://edu.adradviser.ro/api/v1/debug/cookies
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Check session configuration** to ensure proper isolation:
|
|
||||||
```bash
|
|
||||||
curl https://adr-lms.whitex.cloud/api/v1/debug/session
|
|
||||||
curl https://edu.adradviser.ro/api/v1/debug/session
|
|
||||||
```
|
|
||||||
|
|
||||||
5. **Test with incognito browsers** to ensure sessions don't cross-contaminate between deployments
|
|
||||||
|
|
||||||
See `ENHANCED_DEBUG_TOOLS.md` for more detailed information on these debugging endpoints.
|
|
||||||
|
|
||||||
## Implementation Plan
|
|
||||||
|
|
||||||
1. Update database connection strings in Coolify environment variables for both deployments
|
|
||||||
2. Rebuild and redeploy both environments to apply the changes
|
|
||||||
3. Run the verification script to confirm isolation
|
|
||||||
4. Clear browser cookies and caches to test with clean state
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
# LearnHouse Deployment Troubleshooting Guide
|
|
||||||
|
|
||||||
## Current Status: Port Configuration Fixed ✅
|
|
||||||
|
|
||||||
### Recent Changes Made:
|
|
||||||
|
|
||||||
1. **Fixed Port Mismatch Issue** - The root cause of "no available server":
|
|
||||||
- Changed Docker Compose from port 3000 → 80
|
|
||||||
- Updated healthcheck from port 3000 → 80
|
|
||||||
- Added explicit Traefik port label: `traefik.http.services.*.loadbalancer.server.port=80`
|
|
||||||
|
|
||||||
2. **Enhanced Start Script** (`extra/start.sh`):
|
|
||||||
- Added explicit port assignments: PORT=8000, LEARNHOUSE_PORT=9000
|
|
||||||
- Fixed backend startup: Uses `uvicorn app:app --host 0.0.0.0 --port 9000`
|
|
||||||
- Fixed frontend startup: Uses Next.js standalone server on port 8000
|
|
||||||
|
|
||||||
3. **Added Debug Capabilities**:
|
|
||||||
- Created `debug-services.sh` script for troubleshooting
|
|
||||||
- Script checks PM2 processes, port usage, service connectivity
|
|
||||||
|
|
||||||
### Current Architecture:
|
|
||||||
|
|
||||||
```
|
|
||||||
Internet → Coolify/Traefik → Container:80 → Nginx → {
|
|
||||||
├── Frontend (Next.js standalone): localhost:8000
|
|
||||||
└── Backend API (FastAPI): localhost:9000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Network Isolation Configuration:
|
|
||||||
|
|
||||||
- **DEV deployment**: `DEPLOYMENT_NAME=dev` → `dev-network`
|
|
||||||
- **LIVE deployment**: `DEPLOYMENT_NAME=live` → `live-network`
|
|
||||||
- Each deployment has isolated databases, Redis instances, and networks
|
|
||||||
|
|
||||||
### Environment Variables Required:
|
|
||||||
|
|
||||||
See `COOLIFY_ENV_VARS.md` for complete list. Key variables for isolation:
|
|
||||||
|
|
||||||
- `DEPLOYMENT_NAME=live` (or `dev`)
|
|
||||||
- `LEARNHOUSE_COOKIE_DOMAIN=edu.adradviser.ro`
|
|
||||||
- `LEARNHOUSE_SQL_CONNECTION_STRING` (separate for each deployment)
|
|
||||||
- `LEARNHOUSE_REDIS_CONNECTION_STRING` (separate for each deployment)
|
|
||||||
|
|
||||||
### Current Error Status:
|
|
||||||
|
|
||||||
- ✅ **Port mismatch fixed**: Changed from 3000 to 80
|
|
||||||
- ✅ **Container accessibility**: Traefik can now route to port 80
|
|
||||||
- ✅ **Frontend running**: Next.js server operational on port 8000
|
|
||||||
- ✅ **Backend running**: FastAPI server operational on port 9000
|
|
||||||
- ❌ **Cross-deployment contamination**: LIVE calling DEV APIs and vice versa
|
|
||||||
- ⚠️ **Root cause**: Frontend build-time API URLs not properly isolated
|
|
||||||
|
|
||||||
### Identified Issues & Fixes:
|
|
||||||
|
|
||||||
**Problem**: Cross-deployment data contamination (LIVE sees DEV data)
|
|
||||||
**Root Cause**: Next.js build embeds API URLs at build-time, both deployments may share same URLs
|
|
||||||
**Solution**: Added runtime API URL patching in Docker container startup
|
|
||||||
|
|
||||||
**Current Fix Applied**:
|
|
||||||
1. ✅ Enhanced patched-start.sh to replace API URLs at runtime
|
|
||||||
2. ✅ Added debug endpoint `/api/v1/debug/deployment` for verification
|
|
||||||
3. ✅ Added deployment verification script `verify-isolation.sh`
|
|
||||||
|
|
||||||
### Next Debugging Steps:
|
|
||||||
|
|
||||||
1. **Deploy the updated configuration**
|
|
||||||
2. **Check container logs** for any startup errors
|
|
||||||
3. **Run debug script** inside container:
|
|
||||||
```bash
|
|
||||||
docker exec -it <container_name> /app/debug-services.sh
|
|
||||||
```
|
|
||||||
4. **Test internal services**:
|
|
||||||
```bash
|
|
||||||
# Test frontend
|
|
||||||
curl http://localhost:8000
|
|
||||||
# Test backend
|
|
||||||
curl http://localhost:9000
|
|
||||||
# Test nginx
|
|
||||||
curl http://localhost:80
|
|
||||||
```
|
|
||||||
|
|
||||||
### Troubleshooting Commands:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check PM2 processes
|
|
||||||
docker exec -it <container> pm2 list
|
|
||||||
|
|
||||||
# Check ports in use
|
|
||||||
docker exec -it <container> netstat -tlnp
|
|
||||||
|
|
||||||
# Check nginx config
|
|
||||||
docker exec -it <container> nginx -t
|
|
||||||
|
|
||||||
# View PM2 logs
|
|
||||||
docker exec -it <container> pm2 logs
|
|
||||||
|
|
||||||
# Run full debug
|
|
||||||
docker exec -it <container> /app/debug-services.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Expected Resolution:
|
|
||||||
|
|
||||||
The 502 errors should resolve once:
|
|
||||||
1. ✅ Frontend service starts correctly on port 8000 (WORKING)
|
|
||||||
2. ❌ Backend service starts correctly on port 9000 (FIXED - needs redeploy)
|
|
||||||
3. ✅ Nginx properly proxies requests between them (WORKING)
|
|
||||||
|
|
||||||
### Post-Deploy Verification:
|
|
||||||
|
|
||||||
After redeploying, verify isolation works:
|
|
||||||
```bash
|
|
||||||
# Run the automated verification script
|
|
||||||
./verify-isolation.sh
|
|
||||||
|
|
||||||
# Or manually test the debug endpoints
|
|
||||||
curl https://adr-lms.whitex.cloud/api/v1/debug/deployment
|
|
||||||
curl https://edu.adradviser.ro/api/v1/debug/deployment
|
|
||||||
|
|
||||||
# Check for cross-deployment API calls in browser Network tab
|
|
||||||
# Should see only same-domain API calls:
|
|
||||||
# - DEV: Only calls to adr-lms.whitex.cloud
|
|
||||||
# - LIVE: Only calls to edu.adradviser.ro
|
|
||||||
```
|
|
||||||
|
|
||||||
Expected output should show:
|
|
||||||
- ✅ Different database hosts for DEV vs LIVE
|
|
||||||
- ✅ Different cookie domains: adr-lms.whitex.cloud vs edu.adradviser.ro
|
|
||||||
- ✅ No cross-domain API calls in browser Network tab
|
|
||||||
- ✅ Separate content/courses on each deployment
|
|
||||||
|
|
||||||
The port configuration fix was the critical missing piece for Traefik routing.
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
# Enhanced Debug Endpoints for Isolation Troubleshooting
|
|
||||||
|
|
||||||
This document describes the enhanced debugging tools available to diagnose cross-deployment isolation issues between DEV and LIVE environments.
|
|
||||||
|
|
||||||
## Available Debug Endpoints
|
|
||||||
|
|
||||||
The following endpoints are available for diagnosing isolation issues:
|
|
||||||
|
|
||||||
### 1. Deployment Information
|
|
||||||
|
|
||||||
**Endpoint:** `/api/v1/debug/deployment`
|
|
||||||
|
|
||||||
This endpoint provides detailed information about the current deployment, including:
|
|
||||||
- Deployment name
|
|
||||||
- Hostname and container ID
|
|
||||||
- Database connection details (host, user, database name)
|
|
||||||
- Redis connection details
|
|
||||||
- Cookie domain configuration
|
|
||||||
- Environment variables related to deployment URLs
|
|
||||||
|
|
||||||
**Example Usage:**
|
|
||||||
```bash
|
|
||||||
curl https://adr-lms.whitex.cloud/api/v1/debug/deployment
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. URL Hardcoding Detection
|
|
||||||
|
|
||||||
**Endpoint:** `/api/v1/debug/urls`
|
|
||||||
|
|
||||||
This endpoint scans the NextJS bundle for hardcoded URLs that could lead to cross-contamination between deployments:
|
|
||||||
- Detects references to both DEV and LIVE domains
|
|
||||||
- Identifies NextAuth configuration issues
|
|
||||||
- Shows environment variables related to API URLs
|
|
||||||
|
|
||||||
**Example Usage:**
|
|
||||||
```bash
|
|
||||||
curl https://adr-lms.whitex.cloud/api/v1/debug/urls
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Cookie Isolation Testing
|
|
||||||
|
|
||||||
**Endpoint:** `/api/v1/debug/cookies`
|
|
||||||
|
|
||||||
This endpoint tests cookie isolation by:
|
|
||||||
- Setting a test cookie with the current deployment name
|
|
||||||
- Detecting any test cookies from other deployments
|
|
||||||
- Reporting the cookie domain in use
|
|
||||||
- Showing headers from the request
|
|
||||||
|
|
||||||
**Example Usage:**
|
|
||||||
```bash
|
|
||||||
curl https://adr-lms.whitex.cloud/api/v1/debug/cookies -v
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Session Configuration Check
|
|
||||||
|
|
||||||
**Endpoint:** `/api/v1/debug/session`
|
|
||||||
|
|
||||||
This endpoint examines session-related configuration:
|
|
||||||
- Shows request headers related to origins
|
|
||||||
- Reports NextAuth URL configuration
|
|
||||||
- Indicates where session requests would be sent
|
|
||||||
|
|
||||||
**Example Usage:**
|
|
||||||
```bash
|
|
||||||
curl https://adr-lms.whitex.cloud/api/v1/debug/session
|
|
||||||
```
|
|
||||||
|
|
||||||
## Using the Enhanced Verification Script
|
|
||||||
|
|
||||||
We've also created an enhanced isolation verification script that checks both DEV and LIVE deployments and provides a summary of their isolation status:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./verify-enhanced-isolation.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
The script will:
|
|
||||||
1. Check deployment configuration on both environments
|
|
||||||
2. Test cookie isolation
|
|
||||||
3. Look for hardcoded URLs
|
|
||||||
4. Verify session configuration
|
|
||||||
5. Analyze database isolation
|
|
||||||
6. Provide a summary of isolation status
|
|
||||||
|
|
||||||
## Resolving Isolation Issues
|
|
||||||
|
|
||||||
If the verification indicates isolation issues, ensure the following settings are unique between deployments:
|
|
||||||
|
|
||||||
1. **Database Connections**: Each deployment should use its own database
|
|
||||||
```
|
|
||||||
# DEV environment
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse_dev:YOUR_DEV_PASSWORD@db-dev:5432/learnhouse_dev
|
|
||||||
|
|
||||||
# LIVE environment
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse:YOUR_LIVE_PASSWORD@db-live:5432/learnhouse
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Cookie Domains**: Each deployment should have its own cookie domain
|
|
||||||
```
|
|
||||||
# DEV environment
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=adr-lms.whitex.cloud
|
|
||||||
|
|
||||||
# LIVE environment
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=edu.adradviser.ro
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Top Domain Configuration**: Ensure each deployment has the correct top domain
|
|
||||||
```
|
|
||||||
# DEV environment
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN=whitex.cloud
|
|
||||||
|
|
||||||
# LIVE environment
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN=adradviser.ro
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Deployment Name**: Set a descriptive name to help with debugging
|
|
||||||
```
|
|
||||||
# DEV environment
|
|
||||||
DEPLOYMENT_NAME=DEV
|
|
||||||
|
|
||||||
# LIVE environment
|
|
||||||
DEPLOYMENT_NAME=LIVE
|
|
||||||
```
|
|
||||||
|
|
@ -1,152 +0,0 @@
|
||||||
# LearnHouse Deployment Isolation Implementation Checklist
|
|
||||||
|
|
||||||
This checklist guides you through implementing complete isolation between DEV and LIVE LearnHouse deployments to prevent cross-deployment contamination.
|
|
||||||
|
|
||||||
## Issue Overview
|
|
||||||
|
|
||||||
We've identified that both DEV and LIVE deployments are accessing the same database and contain hardcoded URLs, causing:
|
|
||||||
- Data contamination (same courses appear in both deployments)
|
|
||||||
- Session mixing (logging in on one deployment affects the other)
|
|
||||||
- Inconsistent user experience (clicking links on DEV may lead to LIVE site)
|
|
||||||
|
|
||||||
## Implementation Checklist
|
|
||||||
|
|
||||||
### Step 1: Deploy API Changes
|
|
||||||
|
|
||||||
- [ ] Pull the latest code with isolation fixes:
|
|
||||||
```bash
|
|
||||||
git pull origin dev
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Deploy the enhanced debug tools first:
|
|
||||||
```bash
|
|
||||||
./deploy-enhanced-debug.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Verify the enhanced debug endpoints are working:
|
|
||||||
```bash
|
|
||||||
ls -la apps/api/src/routers/debug.py
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Deploy API changes to both environments using your CI/CD system
|
|
||||||
|
|
||||||
### Step 2: Update Environment Variables
|
|
||||||
|
|
||||||
#### For DEV Environment:
|
|
||||||
|
|
||||||
- [ ] Update database connection string:
|
|
||||||
```
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse_dev:YOUR_DEV_PASSWORD@db-dev:5432/learnhouse_dev
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Update Redis connection string:
|
|
||||||
```
|
|
||||||
LEARNHOUSE_REDIS_CONNECTION_STRING=redis://default:YOUR_DEV_REDIS_PASSWORD@redis-dev:6379/1
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Ensure domain settings are correct:
|
|
||||||
```
|
|
||||||
LEARNHOUSE_DOMAIN=adr-lms.whitex.cloud
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=adr-lms.whitex.cloud
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_DOMAIN=adr-lms.whitex.cloud
|
|
||||||
```
|
|
||||||
|
|
||||||
#### For LIVE Environment:
|
|
||||||
|
|
||||||
- [ ] Update database connection string:
|
|
||||||
```
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse:YOUR_LIVE_PASSWORD@db-live:5432/learnhouse
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Update Redis connection string:
|
|
||||||
```
|
|
||||||
LEARNHOUSE_REDIS_CONNECTION_STRING=redis://default:YOUR_LIVE_REDIS_PASSWORD@redis-live:6379/0
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Ensure domain settings are correct:
|
|
||||||
```
|
|
||||||
LEARNHOUSE_DOMAIN=edu.adradviser.ro
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=edu.adradviser.ro
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_DOMAIN=edu.adradviser.ro
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 3: Database Infrastructure
|
|
||||||
|
|
||||||
- [ ] Ensure each deployment has its own database server:
|
|
||||||
- DEV: db-dev
|
|
||||||
- LIVE: db-live
|
|
||||||
|
|
||||||
- [ ] If using shared infrastructure, ensure logical isolation through server names and proper networking
|
|
||||||
|
|
||||||
### Step 4: Rebuild & Deploy
|
|
||||||
|
|
||||||
- [ ] Rebuild and deploy both environments with updated environment variables
|
|
||||||
- [ ] Restart all services to apply changes
|
|
||||||
|
|
||||||
### Step 5: Verification
|
|
||||||
|
|
||||||
- [ ] Run the comprehensive isolation verification script:
|
|
||||||
```bash
|
|
||||||
./verify-all-isolation.sh
|
|
||||||
```
|
|
||||||
This will:
|
|
||||||
- Check deployment configuration
|
|
||||||
- Verify database isolation
|
|
||||||
- Test cookie isolation
|
|
||||||
- Check for hardcoded URLs
|
|
||||||
- Create a visual cookie isolation demo
|
|
||||||
|
|
||||||
- [ ] For more detailed verification, run individual scripts:
|
|
||||||
```bash
|
|
||||||
./verify-enhanced-isolation.sh # Basic deployment checks
|
|
||||||
./verify-db-isolation.sh # Database-specific checks
|
|
||||||
./test-nextauth-cookie-isolation.sh # Cookie isolation tests
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Test the visual cookie isolation demo:
|
|
||||||
```bash
|
|
||||||
./create-cookie-demo.sh
|
|
||||||
# Open the resulting HTML file in a browser
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Access debug endpoints directly:
|
|
||||||
- DEV: https://adr-lms.whitex.cloud/api/v1/debug/deployment
|
|
||||||
- LIVE: https://edu.adradviser.ro/api/v1/debug/deployment
|
|
||||||
- DEV: https://adr-lms.whitex.cloud/api/v1/debug/cookies
|
|
||||||
- LIVE: https://edu.adradviser.ro/api/v1/debug/cookies
|
|
||||||
- DEV: https://adr-lms.whitex.cloud/api/v1/debug/session
|
|
||||||
- LIVE: https://edu.adradviser.ro/api/v1/debug/session
|
|
||||||
|
|
||||||
- [ ] Test in incognito browsers to verify session isolation
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
If isolation issues persist after implementation:
|
|
||||||
|
|
||||||
1. **Use the Enhanced Debug Tools**:
|
|
||||||
- Look at the detailed reports in `/tmp/learnhouse-isolation-report/`
|
|
||||||
- Run specific tests: `./test-nextauth-cookie-isolation.sh` for cookie issues
|
|
||||||
- Check session configuration: `/api/v1/debug/session` endpoint
|
|
||||||
|
|
||||||
2. **Verify Database Connections**:
|
|
||||||
- Confirm debug endpoints show different database hosts and names
|
|
||||||
- Check actual database servers to confirm connections come from different sources
|
|
||||||
- Test with the database isolation script: `./verify-db-isolation.sh`
|
|
||||||
|
|
||||||
3. **Clear Browser Data**:
|
|
||||||
- Use incognito mode or clear all cookies/cache for proper testing
|
|
||||||
- Try the cookie isolation demo to visually check cookie behavior
|
|
||||||
|
|
||||||
4. **Check Docker Network Isolation**:
|
|
||||||
- Ensure each deployment uses its own Docker network
|
|
||||||
- Verify hostnames resolve to different IP addresses within containers
|
|
||||||
|
|
||||||
5. **Validate URL Patching**:
|
|
||||||
- Run URL debug endpoint to confirm no hardcoded references remain
|
|
||||||
- Check the enhanced URL report in `/api/v1/debug/urls` endpoint
|
|
||||||
|
|
||||||
For additional help, refer to the full documentation in:
|
|
||||||
- `ENHANCED_DEBUG_TOOLS.md` - Detailed guide to all debug endpoints
|
|
||||||
- `DATABASE_ISOLATION_FIX.md` - Database isolation specifics
|
|
||||||
- `DEPLOYMENT_TROUBLESHOOTING.md` - General deployment troubleshooting
|
|
||||||
- `ISOLATION_TOOLKIT_README.md` - Overview of all isolation tools
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
# LearnHouse Isolation Fix: Improvements Summary
|
|
||||||
|
|
||||||
We've developed a comprehensive set of tools, scripts, and documentation to help diagnose and fix deployment isolation issues between DEV and LIVE instances. Here's a summary of the improvements:
|
|
||||||
|
|
||||||
## 1. Enhanced Debug Endpoints
|
|
||||||
|
|
||||||
We expanded the API debug capabilities significantly:
|
|
||||||
|
|
||||||
- **`/api/v1/debug/deployment`**: Enhanced with detailed database, Redis, container, and hostname information
|
|
||||||
- **`/api/v1/debug/urls`**: Improved to detect cross-contamination from both domains and categorize findings
|
|
||||||
- **`/api/v1/debug/cookies`**: New endpoint to test cookie isolation and detect cross-deployment cookies
|
|
||||||
- **`/api/v1/debug/session`**: New endpoint to check session configuration and origins
|
|
||||||
|
|
||||||
## 2. Verification Scripts
|
|
||||||
|
|
||||||
We created several verification scripts for different aspects of isolation:
|
|
||||||
|
|
||||||
- **`verify-enhanced-isolation.sh`**: Comprehensive isolation checks for all aspects of deployment
|
|
||||||
- **`test-nextauth-cookie-isolation.sh`**: Focused testing for NextAuth cookie isolation
|
|
||||||
- **`verify-all-isolation.sh`**: Master script that runs all verification checks and produces a report
|
|
||||||
- **`create-cookie-demo.sh`**: Visual tool to demonstrate and test cookie behavior in browsers
|
|
||||||
|
|
||||||
## 3. Documentation
|
|
||||||
|
|
||||||
- **`ENHANCED_DEBUG_TOOLS.md`**: Detailed guide to all debug endpoints and how to use them
|
|
||||||
- **`ISOLATION_TOOLKIT_README.md`**: Overview of all tools available for isolation testing
|
|
||||||
- **Updated `ISOLATION_IMPLEMENTATION_CHECKLIST.md`**: Comprehensive checklist with new tools
|
|
||||||
- **Updated `DATABASE_ISOLATION_FIX.md`**: Enhanced verification methods
|
|
||||||
|
|
||||||
## 4. Developer Experience
|
|
||||||
|
|
||||||
- Visual cookie isolation demo with browser-based testing
|
|
||||||
- HTML reports for easy sharing and analyzing of results
|
|
||||||
- Colored terminal output for easy interpretation of verification results
|
|
||||||
- Container and hostname information for infrastructure verification
|
|
||||||
|
|
||||||
## 5. Implementation Details
|
|
||||||
|
|
||||||
The specific code improvements include:
|
|
||||||
|
|
||||||
1. **Enhanced database information**:
|
|
||||||
- Now shows database username, hostname and database name
|
|
||||||
- Extracts Redis instance information
|
|
||||||
|
|
||||||
2. **Cookie isolation testing**:
|
|
||||||
- Sets test cookies with deployment name
|
|
||||||
- Checks if cookies from one deployment are visible to another
|
|
||||||
- Visual browser-based tool to demonstrate isolation
|
|
||||||
|
|
||||||
3. **Session configuration verification**:
|
|
||||||
- Analyzes headers and environment variables that affect session behavior
|
|
||||||
- Shows where sessions would be sent based on current configuration
|
|
||||||
|
|
||||||
4. **Comprehensive URL checking**:
|
|
||||||
- Categorizes URLs by domain to identify cross-contamination
|
|
||||||
- Reports specific instances of hardcoded URLs in the frontend
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
To use these enhanced tools:
|
|
||||||
|
|
||||||
1. Deploy the enhanced debug module:
|
|
||||||
```bash
|
|
||||||
./deploy-enhanced-debug.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Run the comprehensive verification:
|
|
||||||
```bash
|
|
||||||
./verify-all-isolation.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Check the reports generated in `/tmp/learnhouse-isolation-report/`
|
|
||||||
|
|
||||||
These enhancements will make it much easier to diagnose and fix isolation issues between the DEV and LIVE LearnHouse deployments.
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
# LearnHouse Deployment Isolation Toolkit
|
|
||||||
|
|
||||||
This toolkit provides comprehensive tools and documentation for diagnosing and fixing deployment isolation issues between DEV and LIVE LearnHouse instances.
|
|
||||||
|
|
||||||
## Background
|
|
||||||
|
|
||||||
We identified cross-deployment contamination issues between DEV (adr-lms.whitex.cloud) and LIVE (edu.adradviser.ro) deployments, including:
|
|
||||||
|
|
||||||
- Data contamination (both deployments accessing the same database)
|
|
||||||
- Session mixing (cookies being shared between deployments)
|
|
||||||
- Inconsistent user experience (hardcoded URLs pointing to the wrong environment)
|
|
||||||
|
|
||||||
## Isolation Toolkit Components
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
|
|
||||||
1. **[ISOLATION_IMPLEMENTATION_CHECKLIST.md](./ISOLATION_IMPLEMENTATION_CHECKLIST.md)**
|
|
||||||
Step-by-step checklist for implementing complete isolation between deployments.
|
|
||||||
|
|
||||||
2. **[DATABASE_ISOLATION_FIX.md](./DATABASE_ISOLATION_FIX.md)**
|
|
||||||
Detailed explanation of database isolation issues and how to fix them.
|
|
||||||
|
|
||||||
3. **[DEPLOYMENT_TROUBLESHOOTING.md](./DEPLOYMENT_TROUBLESHOOTING.md)**
|
|
||||||
Guide for troubleshooting deployment and configuration issues.
|
|
||||||
|
|
||||||
4. **[ENHANCED_DEBUG_TOOLS.md](./ENHANCED_DEBUG_TOOLS.md)**
|
|
||||||
Documentation for the enhanced debugging endpoints.
|
|
||||||
|
|
||||||
5. **[COOLIFY_ENV_VARS.md](./COOLIFY_ENV_VARS.md)**
|
|
||||||
Environment variable templates for Coolify deployments.
|
|
||||||
|
|
||||||
### Debugging Tools
|
|
||||||
|
|
||||||
1. **Debug API Endpoints**
|
|
||||||
- `/api/v1/debug/deployment` - Get detailed deployment configuration
|
|
||||||
- `/api/v1/debug/urls` - Scan for hardcoded URLs in the frontend bundle
|
|
||||||
- `/api/v1/debug/cookies` - Test cookie isolation between deployments
|
|
||||||
- `/api/v1/debug/session` - Verify session configuration
|
|
||||||
|
|
||||||
2. **Verification Scripts**
|
|
||||||
- `verify-isolation.sh` - Basic isolation verification
|
|
||||||
- `verify-enhanced-isolation.sh` - Comprehensive isolation checks
|
|
||||||
- `verify-db-isolation.sh` - Database-specific isolation verification
|
|
||||||
- `test-nextauth-cookie-isolation.sh` - NextAuth cookie isolation test
|
|
||||||
|
|
||||||
3. **Visual Demonstration Tools**
|
|
||||||
- `create-cookie-demo.sh` - Creates an HTML tool to visually demonstrate cookie isolation
|
|
||||||
|
|
||||||
### Deployment Scripts
|
|
||||||
|
|
||||||
1. **`deploy-enhanced-debug.sh`**
|
|
||||||
Deploys the enhanced debugging endpoints to diagnose isolation issues.
|
|
||||||
|
|
||||||
2. **`deploy-isolation-fix.sh`**
|
|
||||||
Applies the complete isolation fixes to both deployments.
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
1. **Deploy debugging tools:**
|
|
||||||
```bash
|
|
||||||
./deploy-enhanced-debug.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Run the enhanced isolation verification:**
|
|
||||||
```bash
|
|
||||||
./verify-enhanced-isolation.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Test cookie isolation:**
|
|
||||||
```bash
|
|
||||||
./test-nextauth-cookie-isolation.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Create a visual cookie isolation demo:**
|
|
||||||
```bash
|
|
||||||
./create-cookie-demo.sh
|
|
||||||
# Then open cookie-isolation-demo.html in your browser
|
|
||||||
```
|
|
||||||
|
|
||||||
5. **Follow the implementation checklist:**
|
|
||||||
See [ISOLATION_IMPLEMENTATION_CHECKLIST.md](./ISOLATION_IMPLEMENTATION_CHECKLIST.md)
|
|
||||||
|
|
||||||
## Key Environment Variables for Isolation
|
|
||||||
|
|
||||||
For proper isolation, ensure each deployment has unique values for these variables:
|
|
||||||
|
|
||||||
### DEV Environment
|
|
||||||
```
|
|
||||||
DEPLOYMENT_NAME=DEV
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse_dev:PASSWORD@db-dev:5432/learnhouse_dev
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=adr-lms.whitex.cloud
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_DOMAIN=adr-lms.whitex.cloud
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN=whitex.cloud
|
|
||||||
```
|
|
||||||
|
|
||||||
### LIVE Environment
|
|
||||||
```
|
|
||||||
DEPLOYMENT_NAME=LIVE
|
|
||||||
LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse:PASSWORD@db-live:5432/learnhouse
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=edu.adradviser.ro
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_DOMAIN=edu.adradviser.ro
|
|
||||||
NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN=adradviser.ro
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
If you encounter issues during the isolation process, refer to [DEPLOYMENT_TROUBLESHOOTING.md](./DEPLOYMENT_TROUBLESHOOTING.md).
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
# Network Isolation Setup for LearnHouse Deployments
|
|
||||||
|
|
||||||
This setup provides complete network isolation between your DEV and LIVE LearnHouse deployments using a single dynamic Docker Compose file and environment variables.
|
|
||||||
|
|
||||||
> ⚠️ **NOTE**: This document uses example placeholder domains. Replace all example values with your actual domains before deployment. See [`COOLIFY_ENV_VARS.md`](COOLIFY_ENV_VARS.md) for a complete list of environment variables.
|
|
||||||
|
|
||||||
## Single Dynamic Compose File
|
|
||||||
|
|
||||||
- `docker-compose-coolify.yml` - Works for both DEV and LIVE deployments using environment variables
|
|
||||||
|
|
||||||
## Key Environment Variables for Isolation
|
|
||||||
|
|
||||||
### Required for Network Isolation
|
|
||||||
- `DEPLOYMENT_NAME` - Unique identifier for each deployment (e.g., "dev", "live", "staging")
|
|
||||||
- `LEARNHOUSE_DOMAIN` - Domain for this specific deployment
|
|
||||||
- `LEARNHOUSE_COOKIE_DOMAIN` - Exact domain for cookies (should match LEARNHOUSE_DOMAIN)
|
|
||||||
|
|
||||||
### How It Works
|
|
||||||
The compose file uses `${DEPLOYMENT_NAME:-learnhouse}` patterns to create:
|
|
||||||
- **Networks**: `{DEPLOYMENT_NAME}-network` (e.g., `dev-network`, `live-network`)
|
|
||||||
- **Traefik Routes**: `{DEPLOYMENT_NAME}` router names
|
|
||||||
- **Volumes**: Handled automatically by Coolify (each deployment gets isolated volumes)
|
|
||||||
|
|
||||||
## Coolify Deployment Instructions
|
|
||||||
|
|
||||||
### For DEV Environment
|
|
||||||
|
|
||||||
1. In Coolify, create a new resource/service
|
|
||||||
2. Use the standard `docker-compose-coolify.yml` file
|
|
||||||
3. Set these **key environment variables**:
|
|
||||||
```
|
|
||||||
DEPLOYMENT_NAME=dev
|
|
||||||
LEARNHOUSE_DOMAIN=your-dev-domain.example.com
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=your-dev-domain.example.com
|
|
||||||
NEXTAUTH_URL=https://your-dev-domain.example.com
|
|
||||||
# ... your other DEV environment variables
|
|
||||||
```
|
|
||||||
|
|
||||||
### For LIVE Environment
|
|
||||||
|
|
||||||
1. In Coolify, create a new resource/service
|
|
||||||
2. Use the same `docker-compose-coolify.yml` file
|
|
||||||
3. Set these **key environment variables**:
|
|
||||||
```
|
|
||||||
DEPLOYMENT_NAME=live
|
|
||||||
LEARNHOUSE_DOMAIN=your-prod-domain.example.com
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=your-prod-domain.example.com
|
|
||||||
NEXTAUTH_URL=https://your-prod-domain.example.com
|
|
||||||
# ... your other LIVE environment variables
|
|
||||||
```
|
|
||||||
|
|
||||||
## Network Isolation Results
|
|
||||||
|
|
||||||
With `DEPLOYMENT_NAME=dev`:
|
|
||||||
- Network: `dev-network`
|
|
||||||
- Traefik Router: `dev`
|
|
||||||
- Volumes: Automatically isolated by Coolify
|
|
||||||
|
|
||||||
With `DEPLOYMENT_NAME=live`:
|
|
||||||
- Network: `live-network`
|
|
||||||
- Traefik Router: `live`
|
|
||||||
- Volumes: Automatically isolated by Coolify
|
|
||||||
|
|
||||||
## Benefits
|
|
||||||
|
|
||||||
✅ **Single File Maintenance**: One compose file for all environments
|
|
||||||
✅ **Complete Backend Isolation**: Different networks prevent cross-communication
|
|
||||||
✅ **Separate Data Storage**: Coolify automatically isolates volumes per deployment
|
|
||||||
✅ **Unique Traefik Routes**: No router name conflicts
|
|
||||||
✅ **Exact Cookie Domain Matching**: Prevents any cookie sharing
|
|
||||||
✅ **Environment Flexibility**: Easy to add new environments (staging, testing, etc.)
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
|
|
||||||
After deployment, verify isolation:
|
|
||||||
|
|
||||||
1. **Check Docker networks**:
|
|
||||||
```bash
|
|
||||||
docker network ls | grep -E "(dev|live)-network"
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Verify volumes** (Coolify handles this automatically):
|
|
||||||
```bash
|
|
||||||
docker volume ls | grep your-project-name
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Test cookie domains** in browser DevTools:
|
|
||||||
- DEV cookies: domain `your-dev-domain.example.com`
|
|
||||||
- LIVE cookies: domain `your-prod-domain.example.com`
|
|
||||||
|
|
||||||
## Adding New Environments
|
|
||||||
|
|
||||||
To add a staging environment:
|
|
||||||
```
|
|
||||||
DEPLOYMENT_NAME=staging
|
|
||||||
LEARNHOUSE_DOMAIN=your-staging-domain.example.com
|
|
||||||
LEARNHOUSE_COOKIE_DOMAIN=your-staging-domain.example.com
|
|
||||||
```
|
|
||||||
|
|
||||||
This automatically creates `staging-network` and Coolify handles volume isolation.
|
|
||||||
|
|
||||||
## Current Status
|
|
||||||
|
|
||||||
✅ **Port Configuration Fixed**: Changed from port 3000 to 80 to match nginx configuration
|
|
||||||
✅ **Network Isolation Implemented**: Using `DEPLOYMENT_NAME` for unique networks
|
|
||||||
✅ **Environment Variables Configured**: Complete isolation between deployments
|
|
||||||
⚠️ **In Progress**: Resolving 404 API routing issues
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
If you encounter issues after deployment, use the debug script:
|
|
||||||
```bash
|
|
||||||
docker exec -it <container_name> /app/debug-services.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
See `DEPLOYMENT_TROUBLESHOOTING.md` for detailed troubleshooting steps.
|
|
||||||
|
|
@ -2,9 +2,7 @@ import os
|
||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
from src.routers import health
|
from src.routers import health
|
||||||
from src.routers import usergroups
|
from src.routers import usergroups
|
||||||
from src.routers import dev, trail, users, auth, orgs, roles, search
|
from src.routers import dev, trail, users, auth, orgs, roles, search, debug
|
||||||
# Use enhanced debug module with improved isolation diagnostics
|
|
||||||
from src.routers import debug_enhanced as debug
|
|
||||||
from src.routers.ai import ai
|
from src.routers.ai import ai
|
||||||
from src.routers.courses import chapters, collections, courses, assignments, certifications
|
from src.routers.courses import chapters, collections, courses, assignments, certifications
|
||||||
from src.routers.courses.activities import activities, blocks
|
from src.routers.courses.activities import activities, blocks
|
||||||
|
|
|
||||||
|
|
@ -1,269 +0,0 @@
|
||||||
import os
|
|
||||||
import json
|
|
||||||
import socket
|
|
||||||
import subprocess
|
|
||||||
from fastapi import APIRouter, Request, Response
|
|
||||||
from config.config import get_learnhouse_config
|
|
||||||
|
|
||||||
router = APIRouter()
|
|
||||||
|
|
||||||
@router.get("/deployment")
|
|
||||||
async def debug_deployment():
|
|
||||||
"""Debug endpoint for deployment verification and isolation testing"""
|
|
||||||
learnhouse_config = get_learnhouse_config()
|
|
||||||
|
|
||||||
# Parse database host safely
|
|
||||||
db_host = "unknown"
|
|
||||||
db_user = "unknown"
|
|
||||||
db_name = "unknown"
|
|
||||||
if '@' in learnhouse_config.database_config.sql_connection_string:
|
|
||||||
try:
|
|
||||||
# Split out username and host parts
|
|
||||||
auth_host_parts = learnhouse_config.database_config.sql_connection_string.split('@')
|
|
||||||
if len(auth_host_parts) > 1:
|
|
||||||
# Extract username
|
|
||||||
auth_parts = auth_host_parts[0].split('//')
|
|
||||||
if len(auth_parts) > 1:
|
|
||||||
user_parts = auth_parts[1].split(':')
|
|
||||||
if len(user_parts) > 0:
|
|
||||||
db_user = user_parts[0]
|
|
||||||
|
|
||||||
# Extract host and database name
|
|
||||||
host_parts = auth_host_parts[1].split('/')
|
|
||||||
if len(host_parts) > 0:
|
|
||||||
db_host = host_parts[0]
|
|
||||||
if len(host_parts) > 1:
|
|
||||||
db_name = host_parts[1]
|
|
||||||
except Exception as e:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Parse redis host safely
|
|
||||||
redis_host = "unknown"
|
|
||||||
redis_db = "unknown"
|
|
||||||
if '@' in learnhouse_config.redis_config.redis_connection_string:
|
|
||||||
try:
|
|
||||||
parts = learnhouse_config.redis_config.redis_connection_string.split('@')
|
|
||||||
if len(parts) > 1:
|
|
||||||
host_parts = parts[1].split(':')
|
|
||||||
if len(host_parts) > 0:
|
|
||||||
redis_host = host_parts[0]
|
|
||||||
if len(host_parts) > 1 and '/' in host_parts[1]:
|
|
||||||
redis_db = host_parts[1].split('/')[1]
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Get hostname information
|
|
||||||
hostname = "unknown"
|
|
||||||
try:
|
|
||||||
hostname = socket.gethostname()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Get process and container info
|
|
||||||
container_id = "unknown"
|
|
||||||
try:
|
|
||||||
# Try to get container ID from cgroup
|
|
||||||
with open('/proc/self/cgroup', 'r') as f:
|
|
||||||
for line in f:
|
|
||||||
if 'docker' in line:
|
|
||||||
container_id = line.strip().split('/')[-1]
|
|
||||||
break
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return {
|
|
||||||
"deployment_name": os.environ.get('DEPLOYMENT_NAME', 'NOT_SET'),
|
|
||||||
"hostname": hostname,
|
|
||||||
"container_id": container_id,
|
|
||||||
"cookie_domain": learnhouse_config.hosting_config.cookie_config.domain,
|
|
||||||
"api_domain": learnhouse_config.hosting_config.domain,
|
|
||||||
"database": {
|
|
||||||
"host": db_host,
|
|
||||||
"user": db_user,
|
|
||||||
"name": db_name,
|
|
||||||
},
|
|
||||||
"redis": {
|
|
||||||
"host": redis_host,
|
|
||||||
"db": redis_db
|
|
||||||
},
|
|
||||||
"env_vars": {
|
|
||||||
"NEXT_PUBLIC_LEARNHOUSE_DOMAIN": os.environ.get('NEXT_PUBLIC_LEARNHOUSE_DOMAIN', 'NOT_SET'),
|
|
||||||
"NEXT_PUBLIC_LEARNHOUSE_API_URL": os.environ.get('NEXT_PUBLIC_LEARNHOUSE_API_URL', 'NOT_SET'),
|
|
||||||
"NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN": os.environ.get('NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN', 'NOT_SET'),
|
|
||||||
"LEARNHOUSE_COOKIE_DOMAIN": os.environ.get('LEARNHOUSE_COOKIE_DOMAIN', 'NOT_SET')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@router.get("/urls")
|
|
||||||
async def debug_urls(request: Request):
|
|
||||||
"""Debug endpoint to detect hardcoded URLs in NextJS bundle"""
|
|
||||||
try:
|
|
||||||
# Define domains to check for hardcoding
|
|
||||||
known_domains = [
|
|
||||||
"edu.adradviser.ro", # LIVE domain
|
|
||||||
"adr-lms.whitex.cloud" # DEV domain
|
|
||||||
]
|
|
||||||
|
|
||||||
# Add any additional domains from environment variables
|
|
||||||
current_domain = os.environ.get('NEXT_PUBLIC_LEARNHOUSE_DOMAIN', '')
|
|
||||||
if current_domain and current_domain not in known_domains:
|
|
||||||
known_domains.append(current_domain)
|
|
||||||
|
|
||||||
# Build patterns for all domains to detect cross-contamination
|
|
||||||
patterns = []
|
|
||||||
for domain in known_domains:
|
|
||||||
patterns.extend([
|
|
||||||
f"http://{domain}[^\"']*",
|
|
||||||
f"https://{domain}[^\"']*",
|
|
||||||
f"//{domain}[^\"']*",
|
|
||||||
f"'{domain}'",
|
|
||||||
f"\"{domain}\"",
|
|
||||||
f"fetch\\(\"https://{domain}",
|
|
||||||
f"fetch\\(\"http://{domain}",
|
|
||||||
])
|
|
||||||
|
|
||||||
# Add general patterns for NextAuth configuration
|
|
||||||
patterns.extend([
|
|
||||||
"\"/api/auth/session\"",
|
|
||||||
"\"auth/session\"",
|
|
||||||
"fetch\\(\"/api/auth",
|
|
||||||
"domain:\"[^\"]*\"",
|
|
||||||
"baseUrl:\"[^\"]*\"",
|
|
||||||
"basePath:\"[^\"]*\"",
|
|
||||||
"NEXTAUTH_URL=\"[^\"]*\"",
|
|
||||||
"NEXTAUTH_URL='[^']*'"
|
|
||||||
])
|
|
||||||
|
|
||||||
all_urls = []
|
|
||||||
domain_matches = {domain: [] for domain in known_domains}
|
|
||||||
|
|
||||||
# Search for URLs in JS files
|
|
||||||
for pattern in patterns:
|
|
||||||
result = subprocess.run(
|
|
||||||
["find", "/app/web/.next", "-type", "f", "-name", "*.js", "-exec", "grep", "-o", pattern, "{}", ";"],
|
|
||||||
capture_output=True, text=True, timeout=10
|
|
||||||
)
|
|
||||||
if result.stdout.strip():
|
|
||||||
found_urls = list(set(result.stdout.strip().split('\n')))
|
|
||||||
all_urls.extend(found_urls)
|
|
||||||
|
|
||||||
# Categorize URLs by domain
|
|
||||||
for url in found_urls:
|
|
||||||
for domain in known_domains:
|
|
||||||
if domain in url:
|
|
||||||
domain_matches[domain].append(url)
|
|
||||||
|
|
||||||
# Look for NextAuth configuration
|
|
||||||
auth_configs = []
|
|
||||||
try:
|
|
||||||
auth_result = subprocess.run(
|
|
||||||
["find", "/app/web/.next", "-type", "f", "-name", "*.js", "-exec", "grep", "-o", "NEXTAUTH_URL[^,}]*", "{}", ";"],
|
|
||||||
capture_output=True, text=True, timeout=5
|
|
||||||
)
|
|
||||||
if auth_result.stdout.strip():
|
|
||||||
auth_configs = list(set(auth_result.stdout.strip().split('\n')))
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Gather environment variable information
|
|
||||||
env_vars = {
|
|
||||||
"NEXT_PUBLIC_LEARNHOUSE_DOMAIN": os.environ.get('NEXT_PUBLIC_LEARNHOUSE_DOMAIN', 'NOT_SET'),
|
|
||||||
"NEXT_PUBLIC_LEARNHOUSE_API_URL": os.environ.get('NEXT_PUBLIC_LEARNHOUSE_API_URL', 'NOT_SET'),
|
|
||||||
"NEXT_PUBLIC_API_URL": os.environ.get('NEXT_PUBLIC_API_URL', 'NOT_SET'),
|
|
||||||
"NEXTAUTH_URL": os.environ.get('NEXTAUTH_URL', 'NOT_SET'),
|
|
||||||
"NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN": os.environ.get('NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN', 'NOT_SET'),
|
|
||||||
"LEARNHOUSE_COOKIE_DOMAIN": os.environ.get('LEARNHOUSE_COOKIE_DOMAIN', 'NOT_SET')
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the top domain from an environment variable or extract from current domain
|
|
||||||
top_domain = os.environ.get('NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN', '')
|
|
||||||
if not top_domain and current_domain:
|
|
||||||
parts = current_domain.split('.')
|
|
||||||
if len(parts) >= 2:
|
|
||||||
top_domain = '.'.join(parts[-2:])
|
|
||||||
|
|
||||||
return {
|
|
||||||
"detected_hardcoded_urls": all_urls,
|
|
||||||
"domain_specific_matches": domain_matches,
|
|
||||||
"nextauth_configs": auth_configs,
|
|
||||||
"current_domain": current_domain,
|
|
||||||
"top_domain": top_domain,
|
|
||||||
"env_vars": env_vars,
|
|
||||||
"client_host": request.client.host,
|
|
||||||
"headers": dict(request.headers),
|
|
||||||
"deployment_name": os.environ.get('DEPLOYMENT_NAME', 'NOT_SET'),
|
|
||||||
"request_url": str(request.url)
|
|
||||||
}
|
|
||||||
except Exception as e:
|
|
||||||
return {
|
|
||||||
"error": str(e),
|
|
||||||
"message": "Could not scan for hardcoded URLs",
|
|
||||||
"deployment_name": os.environ.get('DEPLOYMENT_NAME', 'NOT_SET')
|
|
||||||
}
|
|
||||||
|
|
||||||
@router.get("/cookies")
|
|
||||||
async def debug_cookies(request: Request, response: Response):
|
|
||||||
"""Debug endpoint to test cookie isolation and behavior"""
|
|
||||||
# Get current configuration
|
|
||||||
learnhouse_config = get_learnhouse_config()
|
|
||||||
cookie_domain = learnhouse_config.hosting_config.cookie_config.domain
|
|
||||||
deployment_name = os.environ.get('DEPLOYMENT_NAME', 'unknown')
|
|
||||||
|
|
||||||
# Set a test cookie with the current configuration
|
|
||||||
response.set_cookie(
|
|
||||||
key=f"isolation-test-{deployment_name}",
|
|
||||||
value=deployment_name,
|
|
||||||
domain=cookie_domain,
|
|
||||||
httponly=True,
|
|
||||||
samesite="lax",
|
|
||||||
path="/"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Try to read any existing isolation test cookies
|
|
||||||
cookies = request.cookies
|
|
||||||
isolation_cookies = {}
|
|
||||||
|
|
||||||
for key, value in cookies.items():
|
|
||||||
if key.startswith("isolation-test-"):
|
|
||||||
isolation_cookies[key] = value
|
|
||||||
|
|
||||||
return {
|
|
||||||
"deployment_name": deployment_name,
|
|
||||||
"cookie_domain": cookie_domain,
|
|
||||||
"request_host": request.headers.get("host", "unknown"),
|
|
||||||
"detected_isolation_cookies": isolation_cookies,
|
|
||||||
"all_cookies": {k: "****" if not k.startswith("isolation-test") else v for k, v in cookies.items()},
|
|
||||||
"top_domain": os.environ.get('NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN', 'NOT_SET'),
|
|
||||||
"message": f"Set test cookie 'isolation-test-{deployment_name}={deployment_name}' with domain={cookie_domain}"
|
|
||||||
}
|
|
||||||
|
|
||||||
@router.get("/session")
|
|
||||||
async def debug_session(request: Request):
|
|
||||||
"""Debug endpoint to check session-related headers and environment variables"""
|
|
||||||
# Extract host information
|
|
||||||
host = request.headers.get("host", "unknown")
|
|
||||||
origin = request.headers.get("origin", "unknown")
|
|
||||||
referer = request.headers.get("referer", "unknown")
|
|
||||||
|
|
||||||
# Extract NextAuth related information
|
|
||||||
nextauth_url = os.environ.get('NEXTAUTH_URL', 'NOT_SET')
|
|
||||||
nextauth_url_internal = os.environ.get('NEXTAUTH_URL_INTERNAL', 'NOT_SET')
|
|
||||||
|
|
||||||
# Check if session requests would go to the correct place
|
|
||||||
session_destination = nextauth_url or f"https://{host}"
|
|
||||||
|
|
||||||
return {
|
|
||||||
"deployment_name": os.environ.get('DEPLOYMENT_NAME', 'unknown'),
|
|
||||||
"request_headers": {
|
|
||||||
"host": host,
|
|
||||||
"origin": origin,
|
|
||||||
"referer": referer,
|
|
||||||
},
|
|
||||||
"session_config": {
|
|
||||||
"NEXTAUTH_URL": nextauth_url,
|
|
||||||
"NEXTAUTH_URL_INTERNAL": nextauth_url_internal,
|
|
||||||
"detected_session_destination": session_destination
|
|
||||||
},
|
|
||||||
"cookie_domain": get_learnhouse_config().hosting_config.cookie_config.domain,
|
|
||||||
"message": "This endpoint helps diagnose where NextAuth session data would be sent"
|
|
||||||
}
|
|
||||||
|
|
@ -1,264 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Create a demonstration HTML file to visualize cookie isolation problems
|
|
||||||
# This script generates an HTML file that shows which cookies are visible across deployments
|
|
||||||
|
|
||||||
echo "Creating cookie isolation visualization tool..."
|
|
||||||
|
|
||||||
# Define HTML content
|
|
||||||
cat > /home/whitex/dev/github/learnhouse/cookie-isolation-demo.html << 'EOL'
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>LearnHouse Cookie Isolation Test</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
line-height: 1.6;
|
|
||||||
max-width: 1000px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
color: #0066cc;
|
|
||||||
border-bottom: 2px solid #eee;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
color: #0066cc;
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
.test-panel {
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
padding: 20px;
|
|
||||||
margin: 20px 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
background-color: #0066cc;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
padding: 10px 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
margin: 5px 0;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
background-color: #0055aa;
|
|
||||||
}
|
|
||||||
#results {
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-top: 20px;
|
|
||||||
min-height: 200px;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.success {
|
|
||||||
color: green;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.failure {
|
|
||||||
color: red;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.deployment {
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
.dev {
|
|
||||||
background-color: #e6f7ff;
|
|
||||||
border-left: 5px solid #0099ff;
|
|
||||||
}
|
|
||||||
.live {
|
|
||||||
background-color: #fff0e6;
|
|
||||||
border-left: 5px solid #ff9966;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin: 15px 0;
|
|
||||||
}
|
|
||||||
table, th, td {
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
th, td {
|
|
||||||
padding: 10px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
th {
|
|
||||||
background-color: #f2f2f2;
|
|
||||||
}
|
|
||||||
.info {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin: 20px 0;
|
|
||||||
border-left: 5px solid #999;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>LearnHouse Cookie Isolation Test</h1>
|
|
||||||
|
|
||||||
<div class="info">
|
|
||||||
<p>This tool helps visualize cookie isolation between DEV and LIVE LearnHouse deployments.
|
|
||||||
It will help you identify if cookies from one deployment are visible to the other, which
|
|
||||||
could lead to session contamination.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-panel">
|
|
||||||
<h2>1. Set Test Cookies</h2>
|
|
||||||
<p>First, set test cookies on both deployments:</p>
|
|
||||||
<button onclick="setDevCookie()">Set DEV Cookie</button>
|
|
||||||
<button onclick="setLiveCookie()">Set LIVE Cookie</button>
|
|
||||||
<div id="setCookieResult"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-panel">
|
|
||||||
<h2>2. Test Cookie Isolation</h2>
|
|
||||||
<p>Now check if cookies are properly isolated between deployments:</p>
|
|
||||||
<button onclick="testCookieIsolation()">Test Cookie Isolation</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Results</h2>
|
|
||||||
<div id="results">
|
|
||||||
<p>Results will appear here after running tests...</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const DEV_URL = 'http://adr-lms.whitex.cloud';
|
|
||||||
const LIVE_URL = 'http://edu.adradviser.ro';
|
|
||||||
|
|
||||||
// Function to fetch with CORS handling
|
|
||||||
async function fetchWithCors(url) {
|
|
||||||
try {
|
|
||||||
const response = await fetch(url, {
|
|
||||||
method: 'GET',
|
|
||||||
mode: 'cors',
|
|
||||||
credentials: 'include', // Important: include cookies
|
|
||||||
headers: {
|
|
||||||
'Accept': 'application/json',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await response.json();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Fetch error:', error);
|
|
||||||
return { error: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set cookie on DEV deployment
|
|
||||||
async function setDevCookie() {
|
|
||||||
document.getElementById('setCookieResult').innerHTML = 'Setting DEV cookie...';
|
|
||||||
const result = await fetchWithCors(`${DEV_URL}/api/v1/debug/cookies`);
|
|
||||||
document.getElementById('setCookieResult').innerHTML =
|
|
||||||
`<div class="deployment dev">Set DEV cookie: ${JSON.stringify(result.message || 'Failed')}</div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set cookie on LIVE deployment
|
|
||||||
async function setLiveCookie() {
|
|
||||||
document.getElementById('setCookieResult').innerHTML = 'Setting LIVE cookie...';
|
|
||||||
const result = await fetchWithCors(`${LIVE_URL}/api/v1/debug/cookies`);
|
|
||||||
document.getElementById('setCookieResult').innerHTML =
|
|
||||||
`<div class="deployment live">Set LIVE cookie: ${JSON.stringify(result.message || 'Failed')}</div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test if cookies are isolated between deployments
|
|
||||||
async function testCookieIsolation() {
|
|
||||||
document.getElementById('results').innerHTML = 'Testing cookie isolation...';
|
|
||||||
|
|
||||||
// Test DEV cookies
|
|
||||||
const devResult = await fetchWithCors(`${DEV_URL}/api/v1/debug/cookies`);
|
|
||||||
|
|
||||||
// Test LIVE cookies
|
|
||||||
const liveResult = await fetchWithCors(`${LIVE_URL}/api/v1/debug/cookies`);
|
|
||||||
|
|
||||||
// Analyze results
|
|
||||||
let html = '<h3>Cookie Isolation Test Results</h3>';
|
|
||||||
|
|
||||||
html += '<div class="deployment dev">';
|
|
||||||
html += '<h4>DEV Deployment Cookies</h4>';
|
|
||||||
html += '<table>';
|
|
||||||
html += '<tr><th>Cookie</th><th>Value</th></tr>';
|
|
||||||
|
|
||||||
const devCookies = devResult.detected_isolation_cookies || {};
|
|
||||||
if (Object.keys(devCookies).length === 0) {
|
|
||||||
html += '<tr><td colspan="2">No isolation test cookies found</td></tr>';
|
|
||||||
} else {
|
|
||||||
for (const [cookie, value] of Object.entries(devCookies)) {
|
|
||||||
html += `<tr><td>${cookie}</td><td>${value}</td></tr>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '</table></div>';
|
|
||||||
|
|
||||||
html += '<div class="deployment live">';
|
|
||||||
html += '<h4>LIVE Deployment Cookies</h4>';
|
|
||||||
html += '<table>';
|
|
||||||
html += '<tr><th>Cookie</th><th>Value</th></tr>';
|
|
||||||
|
|
||||||
const liveCookies = liveResult.detected_isolation_cookies || {};
|
|
||||||
if (Object.keys(liveCookies).length === 0) {
|
|
||||||
html += '<tr><td colspan="2">No isolation test cookies found</td></tr>';
|
|
||||||
} else {
|
|
||||||
for (const [cookie, value] of Object.entries(liveCookies)) {
|
|
||||||
html += `<tr><td>${cookie}</td><td>${value}</td></tr>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '</table></div>';
|
|
||||||
|
|
||||||
// Analysis
|
|
||||||
html += '<h4>Analysis</h4>';
|
|
||||||
|
|
||||||
const devHasLiveCookies = Object.keys(devCookies).some(c => c.includes('LIVE'));
|
|
||||||
const liveHasDevCookies = Object.keys(liveCookies).some(c => c.includes('DEV'));
|
|
||||||
|
|
||||||
if (!devHasLiveCookies && !liveHasDevCookies) {
|
|
||||||
html += '<div class="success">SUCCESS: Cookie isolation is working correctly!</div>';
|
|
||||||
html += '<p>The DEV cookies are not visible to the LIVE deployment, and vice versa.</p>';
|
|
||||||
html += '<p>This means that sessions should be properly isolated between deployments.</p>';
|
|
||||||
} else {
|
|
||||||
html += '<div class="failure">FAILURE: Cookie isolation is NOT working!</div>';
|
|
||||||
|
|
||||||
if (devHasLiveCookies) {
|
|
||||||
html += '<p>- DEV deployment can see LIVE cookies</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (liveHasDevCookies) {
|
|
||||||
html += '<p>- LIVE deployment can see DEV cookies</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '<p>This means session contamination is occurring between deployments.</p>';
|
|
||||||
html += '<p>Please ensure each deployment has a unique cookie domain set with:</p>';
|
|
||||||
html += '<pre>LEARNHOUSE_COOKIE_DOMAIN=adr-lms.whitex.cloud (for DEV)\nLEARNHOUSE_COOKIE_DOMAIN=edu.adradviser.ro (for LIVE)</pre>';
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('results').innerHTML = html;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
EOL
|
|
||||||
|
|
||||||
echo "Cookie isolation demonstration tool has been created at:"
|
|
||||||
echo "/home/whitex/dev/github/learnhouse/cookie-isolation-demo.html"
|
|
||||||
echo
|
|
||||||
echo "To use this tool:"
|
|
||||||
echo "1. Open the HTML file in a browser"
|
|
||||||
echo "2. Click 'Set DEV Cookie' and 'Set LIVE Cookie' buttons"
|
|
||||||
echo "3. Click 'Test Cookie Isolation' to see if cookies are properly isolated"
|
|
||||||
echo
|
|
||||||
echo "This tool demonstrates visually whether the cookie domains are properly isolated between deployments."
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
echo "=== LearnHouse Service Debug Script ==="
|
|
||||||
echo
|
|
||||||
echo "1. Checking PM2 processes:"
|
|
||||||
pm2 list
|
|
||||||
echo
|
|
||||||
echo "2. Checking which ports are in use:"
|
|
||||||
netstat -tlnp 2>/dev/null || ss -tlnp
|
|
||||||
echo
|
|
||||||
echo "3. Testing internal service connections:"
|
|
||||||
echo " - Testing frontend (port 8000):"
|
|
||||||
curl -s -o /dev/null -w "Status: %{http_code}\n" http://localhost:8000/ || echo "Frontend not responding"
|
|
||||||
echo " - Testing backend (port 9000):"
|
|
||||||
curl -s -o /dev/null -w "Status: %{http_code}\n" http://localhost:9000/ || echo "Backend not responding"
|
|
||||||
echo " - Testing nginx (port 80):"
|
|
||||||
curl -s -o /dev/null -w "Status: %{http_code}\n" http://localhost:80/ || echo "Nginx not responding"
|
|
||||||
echo
|
|
||||||
echo "4. Checking nginx configuration:"
|
|
||||||
nginx -t
|
|
||||||
echo
|
|
||||||
echo "5. Recent PM2 logs (last 10 lines):"
|
|
||||||
pm2 logs --lines 10
|
|
||||||
echo
|
|
||||||
echo "=== Debug Complete ==="
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Script to deploy enhanced isolation debugging tools
|
|
||||||
# This script will update the debug endpoints on both DEV and LIVE deployments
|
|
||||||
|
|
||||||
echo "===================================================================="
|
|
||||||
echo "LearnHouse Enhanced Debug Tools Deployment"
|
|
||||||
echo "===================================================================="
|
|
||||||
|
|
||||||
# ANSI color codes
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
RED='\033[0;31m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# Define git branches
|
|
||||||
DEV_BRANCH="isolation-debug"
|
|
||||||
MAIN_BRANCH="main"
|
|
||||||
|
|
||||||
# Ensure we have the latest code
|
|
||||||
echo -e "${BLUE}Fetching latest code...${NC}"
|
|
||||||
git fetch origin
|
|
||||||
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
|
||||||
|
|
||||||
# Create a new branch for our changes
|
|
||||||
echo -e "${BLUE}Creating branch for debug tools...${NC}"
|
|
||||||
git checkout -b $DEV_BRANCH
|
|
||||||
|
|
||||||
# Check if the debug files exist
|
|
||||||
if [ ! -f "apps/api/src/routers/debug_enhanced.py" ]; then
|
|
||||||
echo -e "${RED}Error: Enhanced debug module not found! Run the setup script first.${NC}"
|
|
||||||
git checkout $current_branch
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Stage and commit our changes
|
|
||||||
echo -e "${BLUE}Committing changes...${NC}"
|
|
||||||
git add apps/api/src/routers/debug_enhanced.py
|
|
||||||
git add apps/api/src/router.py
|
|
||||||
git add verify-enhanced-isolation.sh
|
|
||||||
git add ENHANCED_DEBUG_TOOLS.md
|
|
||||||
git commit -m "Add enhanced debug endpoints for deployment isolation troubleshooting"
|
|
||||||
|
|
||||||
# Push to origin
|
|
||||||
echo -e "${BLUE}Pushing changes to origin...${NC}"
|
|
||||||
if git push -u origin $DEV_BRANCH; then
|
|
||||||
echo -e "${GREEN}Successfully pushed changes to origin/$DEV_BRANCH${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}Failed to push changes. Please check your git configuration.${NC}"
|
|
||||||
git checkout $current_branch
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "===================================================================="
|
|
||||||
echo -e "${GREEN}Deployment preparation completed!${NC}"
|
|
||||||
echo ""
|
|
||||||
echo -e "To deploy these changes:"
|
|
||||||
echo -e "1. Create a pull request from ${BLUE}$DEV_BRANCH${NC} to ${BLUE}$MAIN_BRANCH${NC}"
|
|
||||||
echo -e "2. After review and merge, deploy to both environments"
|
|
||||||
echo -e "3. Use ${BLUE}./verify-enhanced-isolation.sh${NC} to check isolation"
|
|
||||||
echo ""
|
|
||||||
echo -e "Documentation: See ${BLUE}ENHANCED_DEBUG_TOOLS.md${NC} for endpoint usage"
|
|
||||||
echo "===================================================================="
|
|
||||||
|
|
||||||
# Return to original branch
|
|
||||||
git checkout $current_branch
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Deployment Isolation Fix Script
|
|
||||||
# This script will deploy the isolation fixes to both environments
|
|
||||||
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
RED='\033[0;31m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
echo -e "${BLUE}=== LearnHouse Deployment Isolation Fix Script ===${NC}"
|
|
||||||
echo -e "${YELLOW}This script will apply deployment isolation fixes${NC}"
|
|
||||||
|
|
||||||
# Verify script is running from correct directory
|
|
||||||
if [ ! -d "./apps/api" ] || [ ! -d "./apps/web" ]; then
|
|
||||||
echo -e "${RED}Error: This script must be run from the root of the learnhouse project${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if we have git access
|
|
||||||
if ! git status &>/dev/null; then
|
|
||||||
echo -e "${RED}Error: Unable to access git repository${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ensure we have the latest code
|
|
||||||
echo -e "\n${BLUE}Fetching latest code...${NC}"
|
|
||||||
git fetch
|
|
||||||
|
|
||||||
# Check for uncommitted changes
|
|
||||||
if [[ -n $(git status -s) ]]; then
|
|
||||||
echo -e "${YELLOW}Warning: There are uncommitted changes in the repository${NC}"
|
|
||||||
echo -e "Current changes:"
|
|
||||||
git status -s
|
|
||||||
|
|
||||||
read -p "Do you want to continue and commit these changes? (y/n) " -n 1 -r
|
|
||||||
echo
|
|
||||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
||||||
echo -e "${YELLOW}Fix aborted. Please commit or stash your changes first.${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Commit changes
|
|
||||||
git add apps/api/src/routers/debug.py apps/api/src/router.py apps/api/app.py Dockerfile_coolify
|
|
||||||
git commit -m "Add deployment isolation fixes"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Display what will be deployed
|
|
||||||
echo -e "\n${BLUE}The following fixes will be deployed:${NC}"
|
|
||||||
echo -e "1. Debug endpoints at /api/v1/debug/deployment and /api/v1/debug/urls"
|
|
||||||
echo -e "2. Enhanced URL patching in Dockerfile_coolify"
|
|
||||||
echo -e "3. Updated environment variable templates for database isolation"
|
|
||||||
|
|
||||||
read -p "Do you want to deploy these fixes now? (y/n) " -n 1 -r
|
|
||||||
echo
|
|
||||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
||||||
echo -e "${YELLOW}Deployment aborted.${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Push changes
|
|
||||||
echo -e "\n${BLUE}Pushing changes to repository...${NC}"
|
|
||||||
git push || { echo -e "${RED}Failed to push changes${NC}"; exit 1; }
|
|
||||||
|
|
||||||
echo -e "${GREEN}✓${NC} Code changes pushed successfully"
|
|
||||||
|
|
||||||
# Instructions for deployment
|
|
||||||
echo -e "\n${BLUE}=== Next Steps ===${NC}"
|
|
||||||
echo -e "1. Deploy the changes to both environments using your CI/CD system"
|
|
||||||
echo -e "2. Update environment variables for each deployment:"
|
|
||||||
echo -e "${YELLOW} DEV:${NC} LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse_dev:YOUR_PASSWORD@db-dev:5432/learnhouse_dev"
|
|
||||||
echo -e "${YELLOW} LIVE:${NC} LEARNHOUSE_SQL_CONNECTION_STRING=postgresql://learnhouse:YOUR_PASSWORD@db-live:5432/learnhouse"
|
|
||||||
echo -e "3. Verify deployment isolation using the verification scripts:"
|
|
||||||
echo -e " ${YELLOW}./verify-isolation.sh${NC}"
|
|
||||||
echo -e " ${YELLOW}./verify-db-isolation.sh${NC}"
|
|
||||||
echo -e "4. Restart both deployments after updating environment variables"
|
|
||||||
|
|
||||||
echo -e "\n${BLUE}=== Verification URLs ===${NC}"
|
|
||||||
echo -e "DEV debug endpoint: ${YELLOW}https://adr-lms.whitex.cloud/api/v1/debug/deployment${NC}"
|
|
||||||
echo -e "LIVE debug endpoint: ${YELLOW}https://edu.adradviser.ro/api/v1/debug/deployment${NC}"
|
|
||||||
echo -e "DEV URL check: ${YELLOW}https://adr-lms.whitex.cloud/api/v1/debug/urls${NC}"
|
|
||||||
echo -e "LIVE URL check: ${YELLOW}https://edu.adradviser.ro/api/v1/debug/urls${NC}"
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# NextAuth Cookie Isolation Test Script
|
|
||||||
# Tests whether the NextAuth session cookies are properly isolated between deployments
|
|
||||||
|
|
||||||
echo "=============================================================="
|
|
||||||
echo "NextAuth Cookie Isolation Test"
|
|
||||||
echo "=============================================================="
|
|
||||||
|
|
||||||
# Define deployment URLs
|
|
||||||
DEV_URL="http://adr-lms.whitex.cloud"
|
|
||||||
LIVE_URL="http://edu.adradviser.ro"
|
|
||||||
|
|
||||||
# Colors for output
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
RED='\033[0;31m'
|
|
||||||
YELLOW='\033[0;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# Function to check if curl is installed
|
|
||||||
if ! command -v curl &> /dev/null; then
|
|
||||||
echo -e "${RED}Error: curl is not installed. Please install curl first.${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Function to check if jq is installed (for prettier output)
|
|
||||||
if ! command -v jq &> /dev/null; then
|
|
||||||
echo -e "${YELLOW}Warning: jq is not installed. JSON output will not be formatted.${NC}"
|
|
||||||
JQ_CMD="cat"
|
|
||||||
else
|
|
||||||
JQ_CMD="jq"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${BLUE}Step 1: Checking NextAuth configuration in DEV environment...${NC}"
|
|
||||||
curl -s "${DEV_URL}/api/v1/debug/session" | $JQ_CMD
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo -e "${BLUE}Step 2: Checking NextAuth configuration in LIVE environment...${NC}"
|
|
||||||
curl -s "${LIVE_URL}/api/v1/debug/session" | $JQ_CMD
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo -e "${BLUE}Step 3: Testing cookie isolation with test cookies...${NC}"
|
|
||||||
echo "Setting test cookies on DEV deployment..."
|
|
||||||
curl -s -c /tmp/dev_cookies.txt "${DEV_URL}/api/v1/debug/cookies" > /dev/null
|
|
||||||
echo "Setting test cookies on LIVE deployment..."
|
|
||||||
curl -s -c /tmp/live_cookies.txt "${LIVE_URL}/api/v1/debug/cookies" > /dev/null
|
|
||||||
|
|
||||||
echo -e "${BLUE}Step 4: Checking for cookie isolation...${NC}"
|
|
||||||
echo "Sending DEV cookies to LIVE deployment..."
|
|
||||||
DEV_COOKIES_ON_LIVE=$(curl -s -b /tmp/dev_cookies.txt "${LIVE_URL}/api/v1/debug/cookies" | grep -o "isolation-test-DEV")
|
|
||||||
echo "Sending LIVE cookies to DEV deployment..."
|
|
||||||
LIVE_COOKIES_ON_DEV=$(curl -s -b /tmp/live_cookies.txt "${DEV_URL}/api/v1/debug/cookies" | grep -o "isolation-test-LIVE")
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
if [[ -z "$DEV_COOKIES_ON_LIVE" && -z "$LIVE_COOKIES_ON_DEV" ]]; then
|
|
||||||
echo -e "${GREEN}SUCCESS: Cookie isolation is working correctly!${NC}"
|
|
||||||
echo "The DEV cookies are not visible to the LIVE deployment, and vice versa."
|
|
||||||
echo "This means that sessions should be properly isolated."
|
|
||||||
else
|
|
||||||
echo -e "${RED}FAILURE: Cookie isolation is NOT working!${NC}"
|
|
||||||
|
|
||||||
if [[ ! -z "$DEV_COOKIES_ON_LIVE" ]]; then
|
|
||||||
echo "- DEV cookies are visible to the LIVE deployment"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -z "$LIVE_COOKIES_ON_DEV" ]]; then
|
|
||||||
echo "- LIVE cookies are visible to the DEV deployment"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "This means session contamination will occur between deployments."
|
|
||||||
echo "Please ensure each deployment has a unique cookie domain set with:"
|
|
||||||
echo " LEARNHOUSE_COOKIE_DOMAIN=adr-lms.whitex.cloud (for DEV)"
|
|
||||||
echo " LEARNHOUSE_COOKIE_DOMAIN=edu.adradviser.ro (for LIVE)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo -e "${BLUE}Step 5: Checking domain and cookie settings...${NC}"
|
|
||||||
echo "DEV settings:"
|
|
||||||
curl -s "${DEV_URL}/api/v1/debug/deployment" | grep -E "cookie_domain|api_domain" | $JQ_CMD
|
|
||||||
echo
|
|
||||||
echo "LIVE settings:"
|
|
||||||
curl -s "${LIVE_URL}/api/v1/debug/deployment" | grep -E "cookie_domain|api_domain" | $JQ_CMD
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo -e "${BLUE}Cleaning up temporary files...${NC}"
|
|
||||||
rm -f /tmp/dev_cookies.txt /tmp/live_cookies.txt
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "=============================================================="
|
|
||||||
echo "Test complete!"
|
|
||||||
echo "=============================================================="
|
|
||||||
|
|
@ -1,182 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Master Isolation Verification Script
|
|
||||||
# This script runs all isolation verification checks in sequence
|
|
||||||
|
|
||||||
echo "===================================================================="
|
|
||||||
echo "LearnHouse Deployment Isolation - Complete Verification Suite"
|
|
||||||
echo "===================================================================="
|
|
||||||
|
|
||||||
# Define colors for output
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
RED='\033[0;31m'
|
|
||||||
YELLOW='\033[0;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# Define the deployments
|
|
||||||
DEV_URL="http://adr-lms.whitex.cloud"
|
|
||||||
LIVE_URL="http://edu.adradviser.ro"
|
|
||||||
|
|
||||||
# Function to check if a command exists
|
|
||||||
command_exists() {
|
|
||||||
command -v "$1" >/dev/null 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check requirements
|
|
||||||
echo -e "${BLUE}Checking requirements...${NC}"
|
|
||||||
MISSING_TOOLS=0
|
|
||||||
|
|
||||||
if ! command_exists curl; then
|
|
||||||
echo -e "${RED}Missing required tool: curl${NC}"
|
|
||||||
MISSING_TOOLS=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command_exists jq; then
|
|
||||||
echo -e "${YELLOW}Warning: jq is not installed. JSON output will not be formatted.${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $MISSING_TOOLS -eq 1 ]; then
|
|
||||||
echo -e "${RED}Please install the missing tools and try again.${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${GREEN}All required tools are available.${NC}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Function to run a verification script and report result
|
|
||||||
run_verification() {
|
|
||||||
script="$1"
|
|
||||||
description="$2"
|
|
||||||
|
|
||||||
echo -e "${BLUE}Running: ${description}${NC}"
|
|
||||||
echo "--------------------------------------------------------------------"
|
|
||||||
|
|
||||||
if [ -x "$script" ]; then
|
|
||||||
if "$script"; then
|
|
||||||
result=$?
|
|
||||||
if [ $result -eq 0 ]; then
|
|
||||||
echo -e "${GREEN}✓ PASSED: ${description}${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}✗ FAILED: ${description} (Exit code: $result)${NC}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo -e "${RED}✗ ERROR: Failed to execute ${description}${NC}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo -e "${RED}✗ ERROR: Script not found or not executable: ${script}${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "--------------------------------------------------------------------"
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create output directory for reports
|
|
||||||
REPORT_DIR="/tmp/learnhouse-isolation-report"
|
|
||||||
mkdir -p "$REPORT_DIR"
|
|
||||||
echo -e "${BLUE}Reports will be saved in: ${REPORT_DIR}${NC}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Step 1: Run the enhanced deployment verification
|
|
||||||
echo -e "${BLUE}STEP 1: Testing basic deployment configuration${NC}"
|
|
||||||
curl -s "${DEV_URL}/api/v1/debug/deployment" > "${REPORT_DIR}/dev-deployment.json"
|
|
||||||
curl -s "${LIVE_URL}/api/v1/debug/deployment" > "${REPORT_DIR}/live-deployment.json"
|
|
||||||
run_verification "./verify-enhanced-isolation.sh" "Enhanced Deployment Verification"
|
|
||||||
|
|
||||||
# Step 2: Test database isolation specifically
|
|
||||||
echo -e "${BLUE}STEP 2: Testing database isolation${NC}"
|
|
||||||
run_verification "./verify-db-isolation.sh" "Database Isolation Check"
|
|
||||||
|
|
||||||
# Step 3: Test NextAuth cookie isolation
|
|
||||||
echo -e "${BLUE}STEP 3: Testing NextAuth cookies${NC}"
|
|
||||||
run_verification "./test-nextauth-cookie-isolation.sh" "NextAuth Cookie Isolation Test"
|
|
||||||
|
|
||||||
# Step 4: Check for hardcoded URLs in the frontend
|
|
||||||
echo -e "${BLUE}STEP 4: Checking for hardcoded URLs${NC}"
|
|
||||||
echo "Checking DEV deployment for LIVE URLs..."
|
|
||||||
curl -s "${DEV_URL}/api/v1/debug/urls" > "${REPORT_DIR}/dev-urls.json"
|
|
||||||
DEV_HARDCODED_COUNT=$(grep -o "edu.adradviser.ro" "${REPORT_DIR}/dev-urls.json" | wc -l)
|
|
||||||
|
|
||||||
echo "Checking LIVE deployment for DEV URLs..."
|
|
||||||
curl -s "${LIVE_URL}/api/v1/debug/urls" > "${REPORT_DIR}/live-urls.json"
|
|
||||||
LIVE_HARDCODED_COUNT=$(grep -o "adr-lms.whitex.cloud" "${REPORT_DIR}/live-urls.json" | wc -l)
|
|
||||||
|
|
||||||
if [ $DEV_HARDCODED_COUNT -eq 0 ] && [ $LIVE_HARDCODED_COUNT -eq 0 ]; then
|
|
||||||
echo -e "${GREEN}✓ PASSED: No cross-deployment hardcoded URLs found${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}✗ FAILED: Found hardcoded URLs:${NC}"
|
|
||||||
if [ $DEV_HARDCODED_COUNT -gt 0 ]; then
|
|
||||||
echo " - DEV deployment contains ${DEV_HARDCODED_COUNT} references to LIVE domain"
|
|
||||||
fi
|
|
||||||
if [ $LIVE_HARDCODED_COUNT -gt 0 ]; then
|
|
||||||
echo " - LIVE deployment contains ${LIVE_HARDCODED_COUNT} references to DEV domain"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo "--------------------------------------------------------------------"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Step 5: Create the cookie isolation demo
|
|
||||||
echo -e "${BLUE}STEP 5: Creating cookie isolation demonstration tool${NC}"
|
|
||||||
run_verification "./create-cookie-demo.sh" "Cookie Isolation Demo Creation"
|
|
||||||
|
|
||||||
# Summary of all tests
|
|
||||||
echo "===================================================================="
|
|
||||||
echo -e "${BLUE}SUMMARY OF ISOLATION VERIFICATION${NC}"
|
|
||||||
echo "===================================================================="
|
|
||||||
|
|
||||||
# Check deployment names
|
|
||||||
DEV_NAME=$(grep -o '"deployment_name":"[^"]*"' "${REPORT_DIR}/dev-deployment.json" | cut -d'"' -f4)
|
|
||||||
LIVE_NAME=$(grep -o '"deployment_name":"[^"]*"' "${REPORT_DIR}/live-deployment.json" | cut -d'"' -f4)
|
|
||||||
|
|
||||||
# Check database isolation
|
|
||||||
DEV_DB=$(grep -o '"name":"[^"]*"' "${REPORT_DIR}/dev-deployment.json" | head -1 | cut -d'"' -f4)
|
|
||||||
LIVE_DB=$(grep -o '"name":"[^"]*"' "${REPORT_DIR}/live-deployment.json" | head -1 | cut -d'"' -f4)
|
|
||||||
|
|
||||||
# Check cookie domain isolation
|
|
||||||
DEV_COOKIE=$(grep -o '"cookie_domain":"[^"]*"' "${REPORT_DIR}/dev-deployment.json" | cut -d'"' -f4)
|
|
||||||
LIVE_COOKIE=$(grep -o '"cookie_domain":"[^"]*"' "${REPORT_DIR}/live-deployment.json" | cut -d'"' -f4)
|
|
||||||
|
|
||||||
echo -e "Deployment Names:"
|
|
||||||
if [[ "$DEV_NAME" == "DEV" && "$LIVE_NAME" == "LIVE" ]]; then
|
|
||||||
echo -e " ${GREEN}✓ Correct: DEV='$DEV_NAME', LIVE='$LIVE_NAME'${NC}"
|
|
||||||
else
|
|
||||||
echo -e " ${RED}✗ Incorrect: DEV='$DEV_NAME', LIVE='$LIVE_NAME'${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "Database Isolation:"
|
|
||||||
if [[ "$DEV_DB" != "$LIVE_DB" && "$DEV_DB" != "unknown" && "$LIVE_DB" != "unknown" ]]; then
|
|
||||||
echo -e " ${GREEN}✓ Isolated: DEV='$DEV_DB', LIVE='$LIVE_DB'${NC}"
|
|
||||||
else
|
|
||||||
echo -e " ${RED}✗ Not isolated: DEV='$DEV_DB', LIVE='$LIVE_DB'${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "Cookie Domain Isolation:"
|
|
||||||
if [[ "$DEV_COOKIE" != "$LIVE_COOKIE" ]]; then
|
|
||||||
echo -e " ${GREEN}✓ Isolated: DEV='$DEV_COOKIE', LIVE='$LIVE_COOKIE'${NC}"
|
|
||||||
else
|
|
||||||
echo -e " ${RED}✗ Not isolated: DEV='$DEV_COOKIE', LIVE='$LIVE_COOKIE'${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "URL Hardcoding:"
|
|
||||||
if [ $DEV_HARDCODED_COUNT -eq 0 ] && [ $LIVE_HARDCODED_COUNT -eq 0 ]; then
|
|
||||||
echo -e " ${GREEN}✓ No cross-deployment hardcoded URLs${NC}"
|
|
||||||
else
|
|
||||||
echo -e " ${RED}✗ Found hardcoded URLs: DEV=$DEV_HARDCODED_COUNT, LIVE=$LIVE_HARDCODED_COUNT${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "Report files saved to: ${REPORT_DIR}"
|
|
||||||
echo "===================================================================="
|
|
||||||
|
|
||||||
# Final assessment
|
|
||||||
if [[ "$DEV_NAME" == "DEV" && "$LIVE_NAME" == "LIVE" &&
|
|
||||||
"$DEV_DB" != "$LIVE_DB" && "$DEV_DB" != "unknown" && "$LIVE_DB" != "unknown" &&
|
|
||||||
"$DEV_COOKIE" != "$LIVE_COOKIE" &&
|
|
||||||
$DEV_HARDCODED_COUNT -eq 0 && $LIVE_HARDCODED_COUNT -eq 0 ]]; then
|
|
||||||
echo -e "${GREEN}OVERALL RESULT: PASSED - Deployments appear to be properly isolated!${NC}"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo -e "${RED}OVERALL RESULT: FAILED - Deployment isolation issues detected!${NC}"
|
|
||||||
echo -e "Please refer to the ${BLUE}ISOLATION_IMPLEMENTATION_CHECKLIST.md${NC} to resolve these issues."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
@ -1,171 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Database Isolation Verification Script
|
|
||||||
# This script will verify database isolation between DEV and LIVE deployments
|
|
||||||
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
RED='\033[0;31m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
echo -e "${BLUE}=== Database Isolation Verification Script ===${NC}"
|
|
||||||
echo -e "${YELLOW}This script will verify database isolation between DEV and LIVE deployments${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# First check API debug endpoints for database information
|
|
||||||
echo -e "${BLUE}Checking API debug endpoints for database information...${NC}"
|
|
||||||
DEV_URL="https://adr-lms.whitex.cloud"
|
|
||||||
LIVE_URL="https://edu.adradviser.ro"
|
|
||||||
|
|
||||||
DEV_DEBUG=$(curl -s -m 10 -k "$DEV_URL/api/v1/debug/deployment" || echo '{"error":"Failed to connect"}')
|
|
||||||
LIVE_DEBUG=$(curl -s -m 10 -k "$LIVE_URL/api/v1/debug/deployment" || echo '{"error":"Failed to connect"}')
|
|
||||||
|
|
||||||
# Extract values using Python if available
|
|
||||||
if command -v python3 &> /dev/null; then
|
|
||||||
echo -e "${GREEN}✓${NC} Python3 available for JSON parsing"
|
|
||||||
DEV_DB_HOST=$(echo "$DEV_DEBUG" | python3 -c "import sys, json; print(json.load(sys.stdin).get('database_host', 'unknown'))" 2>/dev/null)
|
|
||||||
LIVE_DB_HOST=$(echo "$LIVE_DEBUG" | python3 -c "import sys, json; print(json.load(sys.stdin).get('database_host', 'unknown'))" 2>/dev/null)
|
|
||||||
DEV_DB_NAME=$(echo "$DEV_DEBUG" | python3 -c "import sys, json; print(json.load(sys.stdin).get('database_name', 'unknown'))" 2>/dev/null)
|
|
||||||
LIVE_DB_NAME=$(echo "$LIVE_DEBUG" | python3 -c "import sys, json; print(json.load(sys.stdin).get('database_name', 'unknown'))" 2>/dev/null)
|
|
||||||
|
|
||||||
echo -e "${YELLOW}From API Debug:${NC}"
|
|
||||||
echo -e "DEV DB: Host=${DEV_DB_HOST}, Name=${DEV_DB_NAME}"
|
|
||||||
echo -e "LIVE DB: Host=${LIVE_DB_HOST}, Name=${LIVE_DB_NAME}"
|
|
||||||
|
|
||||||
if [ "$DEV_DB_HOST" == "$LIVE_DB_HOST" ]; then
|
|
||||||
echo -e "${RED}⚠️ WARNING: Both deployments using same database host: $DEV_DB_HOST${NC}"
|
|
||||||
else
|
|
||||||
if [ "$DEV_DB_HOST" != "unknown" ] && [ "$LIVE_DB_HOST" != "unknown" ]; then
|
|
||||||
echo -e "${GREEN}✓ Database hosts are properly isolated between deployments${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${YELLOW}⚠️ Could not verify database hosts from API - falling back to manual checking${NC}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo -e "${YELLOW}Python3 not available for JSON parsing - falling back to manual checking${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\n${BLUE}Continuing with direct database verification...${NC}"
|
|
||||||
|
|
||||||
# Function to extract database connection details from environment variables
|
|
||||||
extract_db_details() {
|
|
||||||
# Get connection string from environment
|
|
||||||
local conn_string="$1"
|
|
||||||
|
|
||||||
# Extract username, password, host, port, and database name
|
|
||||||
local username=$(echo "$conn_string" | sed -E 's/^postgresql:\/\/([^:]+):.*/\1/')
|
|
||||||
local password=$(echo "$conn_string" | sed -E 's/^postgresql:\/\/[^:]+:([^@]+)@.*/\1/')
|
|
||||||
local host=$(echo "$conn_string" | sed -E 's/^postgresql:\/\/[^@]+@([^:]+):.*/\1/')
|
|
||||||
local port=$(echo "$conn_string" | sed -E 's/^postgresql:\/\/[^@]+@[^:]+:([^\/]+)\/.*/\1/')
|
|
||||||
local dbname=$(echo "$conn_string" | sed -E 's/^postgresql:\/\/[^@]+@[^\/]+\/([^?]+).*/\1/')
|
|
||||||
|
|
||||||
echo "Username: $username"
|
|
||||||
echo "Password: [HIDDEN]"
|
|
||||||
echo "Host: $host"
|
|
||||||
echo "Port: $port"
|
|
||||||
echo "Database: $dbname"
|
|
||||||
|
|
||||||
# Return values in a specific format for later use
|
|
||||||
echo "$host|$port|$dbname|$username|$password"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to test database connection
|
|
||||||
test_db_connection() {
|
|
||||||
local details="$1"
|
|
||||||
local host=$(echo "$details" | cut -d'|' -f1)
|
|
||||||
local port=$(echo "$details" | cut -d'|' -f2)
|
|
||||||
local dbname=$(echo "$details" | cut -d'|' -f3)
|
|
||||||
local username=$(echo "$details" | cut -d'|' -f4)
|
|
||||||
local password=$(echo "$details" | cut -d'|' -f5)
|
|
||||||
|
|
||||||
echo -e "${BLUE}Testing connection to $dbname on $host:$port...${NC}"
|
|
||||||
|
|
||||||
# Try to connect and run a simple query
|
|
||||||
if PGPASSWORD="$password" psql -h "$host" -p "$port" -U "$username" -d "$dbname" -c "SELECT 1;" > /dev/null 2>&1; then
|
|
||||||
echo -e "${GREEN}✓ Successfully connected to database $dbname on $host${NC}"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo -e "${RED}✗ Failed to connect to database $dbname on $host${NC}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to test if two databases share the same server
|
|
||||||
test_db_isolation() {
|
|
||||||
local dev_details="$1"
|
|
||||||
local live_details="$2"
|
|
||||||
|
|
||||||
local dev_host=$(echo "$dev_details" | cut -d'|' -f1)
|
|
||||||
local live_host=$(echo "$live_details" | cut -d'|' -f1)
|
|
||||||
|
|
||||||
echo -e "${BLUE}Checking database isolation...${NC}"
|
|
||||||
|
|
||||||
if [ "$dev_host" == "$live_host" ]; then
|
|
||||||
echo -e "${RED}✗ ISOLATION FAILURE: DEV and LIVE environments are using the same database host: $dev_host${NC}"
|
|
||||||
echo -e "${RED} This will cause cross-deployment contamination!${NC}"
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
echo -e "${GREEN}✓ Database isolation confirmed: DEV($dev_host) ≠ LIVE($live_host)${NC}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
|
|
||||||
# Get connection strings from environment or prompt user
|
|
||||||
if [ -z "$DEV_DB_URL" ]; then
|
|
||||||
echo -e "${YELLOW}DEV database connection string not found in environment.${NC}"
|
|
||||||
echo -e "Enter DEV database connection string (postgresql://user:pass@host:port/dbname):"
|
|
||||||
read -p "> " DEV_DB_URL
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$LIVE_DB_URL" ]; then
|
|
||||||
echo -e "${YELLOW}LIVE database connection string not found in environment.${NC}"
|
|
||||||
echo -e "Enter LIVE database connection string (postgresql://user:pass@host:port/dbname):"
|
|
||||||
read -p "> " LIVE_DB_URL
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract connection details
|
|
||||||
echo -e "\n${BLUE}DEV Database Details:${NC}"
|
|
||||||
DEV_DETAILS=$(extract_db_details "$DEV_DB_URL")
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo -e "${BLUE}LIVE Database Details:${NC}"
|
|
||||||
LIVE_DETAILS=$(extract_db_details "$LIVE_DB_URL")
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Test connections
|
|
||||||
DEV_CONNECTION_OK=false
|
|
||||||
LIVE_CONNECTION_OK=false
|
|
||||||
|
|
||||||
if test_db_connection "$DEV_DETAILS"; then
|
|
||||||
DEV_CONNECTION_OK=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test_db_connection "$LIVE_DETAILS"; then
|
|
||||||
LIVE_CONNECTION_OK=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If both connections work, test isolation
|
|
||||||
if $DEV_CONNECTION_OK && $LIVE_CONNECTION_OK; then
|
|
||||||
test_db_isolation "$DEV_DETAILS" "$LIVE_DETAILS"
|
|
||||||
ISOLATION_RESULT=$?
|
|
||||||
else
|
|
||||||
echo -e "${YELLOW}⚠️ Could not verify isolation because one or both database connections failed.${NC}"
|
|
||||||
ISOLATION_RESULT=2
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BLUE}=== Verification Results ===${NC}"
|
|
||||||
if [ $ISOLATION_RESULT -eq 0 ]; then
|
|
||||||
echo -e "${GREEN}✓ SUCCESS: Databases are properly isolated${NC}"
|
|
||||||
elif [ $ISOLATION_RESULT -eq 1 ]; then
|
|
||||||
echo -e "${RED}✗ FAILURE: Databases are not isolated!${NC}"
|
|
||||||
echo -e "${YELLOW}Action required: Update your database connection strings to use different hosts.${NC}"
|
|
||||||
echo -e "See DATABASE_ISOLATION_FIX.md for details."
|
|
||||||
else
|
|
||||||
echo -e "${YELLOW}⚠️ INCONCLUSIVE: Could not verify isolation${NC}"
|
|
||||||
echo -e "Fix connection issues and try again."
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit $ISOLATION_RESULT
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Enhanced isolation verification script
|
|
||||||
# This script helps verify that the DEV and LIVE deployments are properly isolated
|
|
||||||
|
|
||||||
echo "==================================================================================="
|
|
||||||
echo "LearnHouse Deployment Isolation Verification Tool"
|
|
||||||
echo "==================================================================================="
|
|
||||||
|
|
||||||
# Define the URLs of both deployments
|
|
||||||
DEV_URL="http://adr-lms.whitex.cloud"
|
|
||||||
LIVE_URL="http://edu.adradviser.ro"
|
|
||||||
|
|
||||||
# Colors for output
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
RED='\033[0;31m'
|
|
||||||
YELLOW='\033[0;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# Function to check if a command exists
|
|
||||||
command_exists() {
|
|
||||||
command -v "$1" >/dev/null 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if required tools are installed
|
|
||||||
if ! command_exists curl; then
|
|
||||||
echo -e "${RED}Error: curl is not installed. Please install curl and try again.${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command_exists jq; then
|
|
||||||
echo -e "${YELLOW}Warning: jq is not installed. JSON responses will not be formatted nicely.${NC}"
|
|
||||||
JSON_PROCESSOR="cat"
|
|
||||||
else
|
|
||||||
JSON_PROCESSOR="jq"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${BLUE}Checking deployment configurations...${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Function to fetch deployment info
|
|
||||||
fetch_deployment_info() {
|
|
||||||
local url="$1"
|
|
||||||
local name="$2"
|
|
||||||
|
|
||||||
echo -e "${BLUE}Checking ${name} deployment (${url})...${NC}"
|
|
||||||
echo "---------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
# Make API call
|
|
||||||
response=$(curl -s "${url}/api/v1/debug/deployment" -H "Accept: application/json")
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo -e "${RED}Failed to connect to ${name} deployment.${NC}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Display deployment info
|
|
||||||
echo -e "${GREEN}Deployment information:${NC}"
|
|
||||||
echo "$response" | $JSON_PROCESSOR
|
|
||||||
|
|
||||||
# Extract key information
|
|
||||||
deployment_name=$(echo "$response" | grep -o '"deployment_name":"[^"]*"' | cut -d'"' -f4)
|
|
||||||
cookie_domain=$(echo "$response" | grep -o '"cookie_domain":"[^"]*"' | cut -d'"' -f4)
|
|
||||||
database_host=$(echo "$response" | grep -o '"host":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
||||||
database_name=$(echo "$response" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "${BLUE}Summary:${NC}"
|
|
||||||
echo "Deployment name: ${deployment_name:-unknown}"
|
|
||||||
echo "Cookie domain: ${cookie_domain:-unknown}"
|
|
||||||
echo "Database host: ${database_host:-unknown}"
|
|
||||||
echo "Database name: ${database_name:-unknown}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check for cookie isolation
|
|
||||||
echo -e "${BLUE}Testing cookie isolation...${NC}"
|
|
||||||
cookie_response=$(curl -s "${url}/api/v1/debug/cookies" -H "Accept: application/json")
|
|
||||||
echo "$cookie_response" | $JSON_PROCESSOR
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check for hardcoded URLs
|
|
||||||
echo -e "${BLUE}Checking for hardcoded URLs...${NC}"
|
|
||||||
url_response=$(curl -s "${url}/api/v1/debug/urls" -H "Accept: application/json")
|
|
||||||
|
|
||||||
# Count hardcoded references to the other environment
|
|
||||||
other_url=""
|
|
||||||
if [[ "$url" == "$DEV_URL" ]]; then
|
|
||||||
other_url="edu.adradviser.ro"
|
|
||||||
else
|
|
||||||
other_url="adr-lms.whitex.cloud"
|
|
||||||
fi
|
|
||||||
|
|
||||||
hardcoded_count=$(echo "$url_response" | grep -o "$other_url" | wc -l)
|
|
||||||
|
|
||||||
if [[ $hardcoded_count -gt 0 ]]; then
|
|
||||||
echo -e "${RED}Warning: Found $hardcoded_count hardcoded references to $other_url${NC}"
|
|
||||||
echo "This could cause isolation issues!"
|
|
||||||
else
|
|
||||||
echo -e "${GREEN}No hardcoded references to the other environment found.${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for session configuration
|
|
||||||
echo -e "${BLUE}Testing session configuration...${NC}"
|
|
||||||
session_response=$(curl -s "${url}/api/v1/debug/session" -H "Accept: application/json")
|
|
||||||
echo "$session_response" | $JSON_PROCESSOR
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "---------------------------------------------------------------------------------"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check both deployments
|
|
||||||
fetch_deployment_info "$DEV_URL" "DEV"
|
|
||||||
echo ""
|
|
||||||
fetch_deployment_info "$LIVE_URL" "LIVE"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo -e "${BLUE}Analyzing isolation status...${NC}"
|
|
||||||
echo "---------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
# Simple test: check if both deployments respond with the correct deployment name
|
|
||||||
dev_name=$(curl -s "${DEV_URL}/api/v1/debug/deployment" | grep -o '"deployment_name":"[^"]*"' | cut -d'"' -f4)
|
|
||||||
live_name=$(curl -s "${LIVE_URL}/api/v1/debug/deployment" | grep -o '"deployment_name":"[^"]*"' | cut -d'"' -f4)
|
|
||||||
|
|
||||||
# Check database isolation
|
|
||||||
dev_db=$(curl -s "${DEV_URL}/api/v1/debug/deployment" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
||||||
live_db=$(curl -s "${LIVE_URL}/api/v1/debug/deployment" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
||||||
|
|
||||||
# Check cookie domain isolation
|
|
||||||
dev_cookie=$(curl -s "${DEV_URL}/api/v1/debug/deployment" | grep -o '"cookie_domain":"[^"]*"' | cut -d'"' -f4)
|
|
||||||
live_cookie=$(curl -s "${LIVE_URL}/api/v1/debug/deployment" | grep -o '"cookie_domain":"[^"]*"' | cut -d'"' -f4)
|
|
||||||
|
|
||||||
echo "SUMMARY OF ISOLATION STATUS:"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
if [[ "$dev_name" == "DEV" && "$live_name" == "LIVE" ]]; then
|
|
||||||
echo -e "${GREEN}✓ Both deployments report the correct deployment name.${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}✗ Deployment name mismatch! DEV reports '$dev_name', LIVE reports '$live_name'${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$dev_db" != "$live_db" ]]; then
|
|
||||||
echo -e "${GREEN}✓ Database isolation: Different database names ($dev_db vs $live_db)${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}✗ Database isolation failure! Both environments use the same database: $dev_db${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$dev_cookie" != "$live_cookie" ]]; then
|
|
||||||
echo -e "${GREEN}✓ Cookie domain isolation: Different cookie domains ($dev_cookie vs $live_cookie)${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}✗ Cookie domain isolation failure! Both environments use the same cookie domain: $dev_cookie${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "==================================================================================="
|
|
||||||
|
|
||||||
if [[ "$dev_db" == "$live_db" || "$dev_cookie" == "$live_cookie" ]]; then
|
|
||||||
echo -e "${RED}Isolation verification FAILED! The deployments are not properly isolated.${NC}"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo -e "${GREEN}Isolation verification PASSED! The deployments appear to be properly isolated.${NC}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Colors for better output
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
RED='\033[0;31m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
echo -e "${BLUE}🔍 LearnHouse Deployment Isolation Verification${NC}"
|
|
||||||
echo -e "${BLUE}===============================================${NC}"
|
|
||||||
|
|
||||||
# Check DEV deployment
|
|
||||||
echo ""
|
|
||||||
echo -e "${YELLOW}📋 DEV Deployment (adr-lms.whitex.cloud):${NC}"
|
|
||||||
echo "----------------------------------------"
|
|
||||||
echo "Testing API connection..."
|
|
||||||
DEV_RESPONSE=$(curl -s -k https://adr-lms.whitex.cloud/api/v1/debug/deployment 2>/dev/null)
|
|
||||||
DEV_HEALTH=$(curl -s -k https://adr-lms.whitex.cloud/api/health 2>/dev/null)
|
|
||||||
DEV_ROOT=$(curl -s -k https://adr-lms.whitex.cloud/ 2>/dev/null | head -200)
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo -e "${GREEN}✅ DEV API accessible${NC}"
|
|
||||||
echo " Health: $DEV_HEALTH"
|
|
||||||
echo " Debug Response: $DEV_RESPONSE"
|
|
||||||
if [[ "$DEV_ROOT" == *"LearnHouse"* ]] || [[ "$DEV_ROOT" == *"React"* ]] || [[ "$DEV_ROOT" == *"Next"* ]]; then
|
|
||||||
echo -e "${GREEN}✅ DEV Frontend serving properly${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${YELLOW}⚠️ DEV Frontend response unclear${NC}"
|
|
||||||
echo " Root response (first 100 chars): ${DEV_ROOT:0:100}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo -e "${RED}❌ DEV API not accessible${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Testing frontend..."
|
|
||||||
DEV_FRONTEND=$(curl -s -k -o /dev/null -w "%{http_code}" https://adr-lms.whitex.cloud/ 2>/dev/null)
|
|
||||||
if [ "$DEV_FRONTEND" = "200" ]; then
|
|
||||||
echo -e "${GREEN}✅ DEV Frontend accessible (HTTP $DEV_FRONTEND)${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}❌ DEV Frontend issue (HTTP $DEV_FRONTEND)${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check LIVE deployment
|
|
||||||
echo ""
|
|
||||||
echo -e "${YELLOW}📋 LIVE Deployment (edu.adradviser.ro):${NC}"
|
|
||||||
echo "---------------------------------------"
|
|
||||||
echo "Testing API connection..."
|
|
||||||
LIVE_RESPONSE=$(curl -s -k https://edu.adradviser.ro/api/v1/debug/deployment 2>/dev/null)
|
|
||||||
LIVE_HEALTH=$(curl -s -k https://edu.adradviser.ro/api/health 2>/dev/null)
|
|
||||||
LIVE_ROOT=$(curl -s -k https://edu.adradviser.ro/ 2>/dev/null | head -200)
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo -e "${GREEN}✅ LIVE API accessible${NC}"
|
|
||||||
echo " Health: $LIVE_HEALTH"
|
|
||||||
echo " Debug Response: $LIVE_RESPONSE"
|
|
||||||
if [[ "$LIVE_ROOT" == *"LearnHouse"* ]] || [[ "$LIVE_ROOT" == *"React"* ]] || [[ "$LIVE_ROOT" == *"Next"* ]]; then
|
|
||||||
echo -e "${GREEN}✅ LIVE Frontend serving properly${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${YELLOW}⚠️ LIVE Frontend response unclear${NC}"
|
|
||||||
echo " Root response (first 100 chars): ${LIVE_ROOT:0:100}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo -e "${RED}❌ LIVE API not accessible${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Testing frontend..."
|
|
||||||
LIVE_FRONTEND=$(curl -s -k -o /dev/null -w "%{http_code}" https://edu.adradviser.ro/ 2>/dev/null)
|
|
||||||
if [ "$LIVE_FRONTEND" = "200" ]; then
|
|
||||||
echo -e "${GREEN}✅ LIVE Frontend accessible (HTTP $LIVE_FRONTEND)${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}❌ LIVE Frontend issue (HTTP $LIVE_FRONTEND)${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Analysis
|
|
||||||
echo ""
|
|
||||||
echo -e "${BLUE}🔍 Cross-Deployment Isolation Analysis:${NC}"
|
|
||||||
echo "========================================"
|
|
||||||
|
|
||||||
# Check for hardcoded URLs
|
|
||||||
echo -e "\n${BLUE}Checking for hardcoded LIVE URLs in DEV frontend...${NC}"
|
|
||||||
LIVE_URLS_IN_DEV=$(echo "$DEV_ROOT" | grep -o "http://edu.adradviser.ro[^\"']*\|https://edu.adradviser.ro[^\"']*" | sort -u)
|
|
||||||
|
|
||||||
if [[ -n "$LIVE_URLS_IN_DEV" ]]; then
|
|
||||||
echo -e "${RED}⚠️ WARNING: Found hardcoded LIVE URLs in DEV frontend:${NC}"
|
|
||||||
echo "$LIVE_URLS_IN_DEV"
|
|
||||||
else
|
|
||||||
echo -e "${GREEN}✅ No hardcoded LIVE URLs found in DEV frontend${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for courses UUIDs
|
|
||||||
DEV_COURSES=$(echo "$DEV_ROOT" | grep -o "course_[a-zA-Z0-9-]*" | sort -u)
|
|
||||||
LIVE_COURSES=$(echo "$LIVE_ROOT" | grep -o "course_[a-zA-Z0-9-]*" | sort -u)
|
|
||||||
|
|
||||||
echo -e "\n${BLUE}Course UUIDs found in deployments:${NC}"
|
|
||||||
echo -e "${YELLOW}DEV courses:${NC} $(echo $DEV_COURSES | tr '\n' ' ')"
|
|
||||||
echo -e "${YELLOW}LIVE courses:${NC} $(echo $LIVE_COURSES | tr '\n' ' ')"
|
|
||||||
|
|
||||||
# Find common courses
|
|
||||||
if [[ -n "$DEV_COURSES" && -n "$LIVE_COURSES" ]]; then
|
|
||||||
# Using grep to find common entries
|
|
||||||
COMMON_COURSES=""
|
|
||||||
for course in $DEV_COURSES; do
|
|
||||||
if echo "$LIVE_COURSES" | grep -q "$course"; then
|
|
||||||
COMMON_COURSES="$COMMON_COURSES $course"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ -n "$COMMON_COURSES" ]]; then
|
|
||||||
echo -e "${RED}⚠️ WARNING: Found shared courses between deployments (contamination):${NC}"
|
|
||||||
echo "$COMMON_COURSES"
|
|
||||||
else
|
|
||||||
echo -e "${GREEN}✅ No shared courses found between deployments${NC}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract database hosts if responses are valid JSON
|
|
||||||
if command -v python3 >/dev/null 2>&1; then
|
|
||||||
echo -e "\n${BLUE}Database connection analysis:${NC}"
|
|
||||||
if [[ "$DEV_RESPONSE" == *"database_host"* ]]; then
|
|
||||||
DEV_DB=$(echo "$DEV_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('database_host', 'unknown'))" 2>/dev/null)
|
|
||||||
echo -e "DEV database: ${YELLOW}$DEV_DB${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}⚠️ Cannot analyze DEV database - debug endpoint not working${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$LIVE_RESPONSE" == *"database_host"* ]]; then
|
|
||||||
LIVE_DB=$(echo "$LIVE_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('database_host', 'unknown'))" 2>/dev/null)
|
|
||||||
echo -e "LIVE database: ${YELLOW}$LIVE_DB${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}⚠️ Cannot analyze LIVE database - debug endpoint not working${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$DEV_DB" && -n "$LIVE_DB" && "$DEV_DB" != "unknown" && "$LIVE_DB" != "unknown" ]]; then
|
|
||||||
if [ "$DEV_DB" = "$LIVE_DB" ]; then
|
|
||||||
echo -e "${RED}⚠️ WARNING: Both deployments using same database host: $DEV_DB${NC}"
|
|
||||||
echo -e "${RED} This is likely the cause of cross-deployment contamination!${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${GREEN}✅ Database isolation confirmed: DEV($DEV_DB) ≠ LIVE($LIVE_DB)${NC}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\n${BLUE}Cookie domain analysis:${NC}"
|
|
||||||
if [[ "$DEV_RESPONSE" == *"cookie_domain"* ]]; then
|
|
||||||
DEV_COOKIE=$(echo "$DEV_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('cookie_domain', 'unknown'))" 2>/dev/null)
|
|
||||||
echo -e "DEV cookie domain: ${YELLOW}$DEV_COOKIE${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}⚠️ Cannot analyze DEV cookie domain - debug endpoint not working${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$LIVE_RESPONSE" == *"cookie_domain"* ]]; then
|
|
||||||
LIVE_COOKIE=$(echo "$LIVE_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('cookie_domain', 'unknown'))" 2>/dev/null)
|
|
||||||
echo -e "LIVE cookie domain: ${YELLOW}$LIVE_COOKIE${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}⚠️ Cannot analyze LIVE cookie domain - debug endpoint not working${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$DEV_COOKIE" && -n "$LIVE_COOKIE" && "$DEV_COOKIE" != "unknown" && "$LIVE_COOKIE" != "unknown" ]]; then
|
|
||||||
if [ "$DEV_COOKIE" = "$LIVE_COOKIE" ]; then
|
|
||||||
echo -e "${RED}⚠️ WARNING: Both deployments using same cookie domain: $DEV_COOKIE${NC}"
|
|
||||||
echo -e "${RED} This could cause session contamination between deployments!${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${GREEN}✅ Cookie domain isolation confirmed: DEV($DEV_COOKIE) ≠ LIVE($LIVE_COOKIE)${NC}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo -e "${YELLOW}ℹ️ Python3 not available for JSON analysis${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\n${BLUE}🚀 Next Steps:${NC}"
|
|
||||||
echo "=============="
|
|
||||||
echo "1. If debug endpoints are not accessible, deploy the API changes first"
|
|
||||||
echo "2. Verify database connection strings are different between deployments"
|
|
||||||
echo "3. Check the Dockerfile_coolify for proper API URL replacement"
|
|
||||||
echo "4. Clear browser cache/cookies for both domains"
|
|
||||||
echo "5. Test in incognito mode to verify isolation"
|
|
||||||
echo "4. Check container logs: docker logs <container_name>"
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue