mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-18 11:59:26 +00:00
Add LearnHouse Deployment Isolation Toolkit and debugging tools
- Introduced comprehensive documentation for diagnosing and fixing deployment isolation issues between DEV and LIVE instances. - Implemented enhanced debug API endpoints for deployment verification, URL hardcoding detection, cookie isolation testing, and session configuration checks. - Created scripts for visual demonstration of cookie isolation, enhanced debugging deployment, and verification of NextAuth cookie isolation. - Developed a master isolation verification script to run all isolation checks in sequence and summarize results. - Added detailed README and environment variable guidelines for proper deployment isolation.
This commit is contained in:
parent
2ace169ab1
commit
d32389a8ef
14 changed files with 1571 additions and 39 deletions
|
|
@ -143,9 +143,31 @@ Added comprehensive debug endpoints:
|
|||
|
||||
After implementing these changes:
|
||||
|
||||
1. Run `./verify-isolation.sh` to check deployment isolation
|
||||
2. Verify each deployment has its own database connection using `/api/v1/debug/deployment` endpoint
|
||||
3. Check that no cross-domain references appear in the frontend
|
||||
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
|
||||
|
||||
|
|
|
|||
123
ENHANCED_DEBUG_TOOLS.md
Normal file
123
ENHANCED_DEBUG_TOOLS.md
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
# 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
|
||||
```
|
||||
|
|
@ -18,7 +18,12 @@ We've identified that both DEV and LIVE deployments are accessing the same datab
|
|||
git pull origin dev
|
||||
```
|
||||
|
||||
- [ ] Verify the debug endpoint files exist:
|
||||
- [ ] 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
|
||||
```
|
||||
|
|
@ -80,19 +85,37 @@ We've identified that both DEV and LIVE deployments are accessing the same datab
|
|||
|
||||
### Step 5: Verification
|
||||
|
||||
- [ ] Run verification scripts:
|
||||
- [ ] Run the comprehensive isolation verification script:
|
||||
```bash
|
||||
./verify-isolation.sh
|
||||
./verify-db-isolation.sh
|
||||
./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
|
||||
|
||||
- [ ] Check URLs in frontend:
|
||||
- DEV: https://adr-lms.whitex.cloud/api/v1/debug/urls
|
||||
- LIVE: https://edu.adradviser.ro/api/v1/debug/urls
|
||||
- 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
|
||||
|
||||
|
|
@ -100,20 +123,30 @@ We've identified that both DEV and LIVE deployments are accessing the same datab
|
|||
|
||||
If isolation issues persist after implementation:
|
||||
|
||||
1. **Verify Database Connections**:
|
||||
- Confirm debug endpoints show different database hosts
|
||||
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`
|
||||
|
||||
2. **Clear Browser Data**:
|
||||
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
|
||||
|
||||
3. **Check Docker Network Isolation**:
|
||||
4. **Check Docker Network Isolation**:
|
||||
- Ensure each deployment uses its own Docker network
|
||||
- Verify hostnames resolve to different IP addresses within containers
|
||||
|
||||
4. **Validate URL Patching**:
|
||||
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:
|
||||
- `DATABASE_ISOLATION_FIX.md`
|
||||
- `DEPLOYMENT_TROUBLESHOOTING.md`
|
||||
- `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
|
||||
|
|
|
|||
74
ISOLATION_IMPROVEMENTS.md
Normal file
74
ISOLATION_IMPROVEMENTS.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# 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.
|
||||
107
ISOLATION_TOOLKIT_README.md
Normal file
107
ISOLATION_TOOLKIT_README.md
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
# 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).
|
||||
|
|
@ -2,7 +2,9 @@ import os
|
|||
from fastapi import APIRouter, Depends
|
||||
from src.routers import health
|
||||
from src.routers import usergroups
|
||||
from src.routers import dev, trail, users, auth, orgs, roles, search, debug
|
||||
from src.routers import dev, trail, users, auth, orgs, roles, search
|
||||
# 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.courses import chapters, collections, courses, assignments, certifications
|
||||
from src.routers.courses.activities import activities, blocks
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import os
|
||||
import json
|
||||
import socket
|
||||
import subprocess
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi import APIRouter, Request, Response
|
||||
from config.config import get_learnhouse_config
|
||||
|
||||
router = APIRouter()
|
||||
|
|
@ -12,18 +14,32 @@ async def debug_deployment():
|
|||
|
||||
# Parse database host safely
|
||||
db_host = "unknown"
|
||||
db_user = "unknown"
|
||||
db_name = "unknown"
|
||||
if '@' in learnhouse_config.database_config.sql_connection_string:
|
||||
try:
|
||||
parts = learnhouse_config.database_config.sql_connection_string.split('@')
|
||||
if len(parts) > 1:
|
||||
host_parts = parts[1].split('/')
|
||||
# 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]
|
||||
except Exception:
|
||||
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('@')
|
||||
|
|
@ -31,19 +47,51 @@ async def debug_deployment():
|
|||
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
|
||||
import socket
|
||||
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,
|
||||
"redis_host": redis_host,
|
||||
"database_name": learnhouse_config.database_config.sql_connection_string.split('/')[-1] if '/' in learnhouse_config.database_config.sql_connection_string else "unknown",
|
||||
"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_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')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51,21 +99,106 @@ async def debug_deployment():
|
|||
async def debug_urls(request: Request):
|
||||
"""Debug endpoint to detect hardcoded URLs in NextJS bundle"""
|
||||
try:
|
||||
# This only works if Next.js files are accessible from the API container
|
||||
# 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", "http://edu.adradviser.ro[^\"']*", "{}", ";"],
|
||||
["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
|
||||
)
|
||||
hardcoded_urls = list(set(result.stdout.strip().split('\n'))) if result.stdout.strip() else []
|
||||
if auth_result.stdout.strip():
|
||||
auth_configs = list(set(auth_result.stdout.strip().split('\n')))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Get the current domain for comparison
|
||||
current_domain = os.environ.get('NEXT_PUBLIC_LEARNHOUSE_DOMAIN', 'unknown')
|
||||
# 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": hardcoded_urls,
|
||||
"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')
|
||||
}
|
||||
except Exception as e:
|
||||
|
|
|
|||
269
apps/api/src/routers/debug_enhanced.py
Normal file
269
apps/api/src/routers/debug_enhanced.py
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
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"
|
||||
}
|
||||
|
|
@ -67,8 +67,8 @@ export const nextAuthOptions = {
|
|||
httpOnly: true,
|
||||
sameSite: 'lax',
|
||||
path: '/',
|
||||
// When working on localhost, the cookie domain must be omitted entirely (https://stackoverflow.com/a/1188145)
|
||||
domain: `.${LEARNHOUSE_TOP_DOMAIN}`,
|
||||
// When working on localhost or with different domains, use the current domain instead of a shared top domain
|
||||
domain: process.env.LEARNHOUSE_COOKIE_DOMAIN || (LEARNHOUSE_TOP_DOMAIN === 'localhost' ? undefined : `.${LEARNHOUSE_TOP_DOMAIN}`),
|
||||
secure: !isDevEnv,
|
||||
},
|
||||
},
|
||||
|
|
|
|||
264
create-cookie-demo.sh
Executable file
264
create-cookie-demo.sh
Executable file
|
|
@ -0,0 +1,264 @@
|
|||
#!/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."
|
||||
67
deploy-enhanced-debug.sh
Executable file
67
deploy-enhanced-debug.sh
Executable file
|
|
@ -0,0 +1,67 @@
|
|||
#!/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
|
||||
94
test-nextauth-cookie-isolation.sh
Executable file
94
test-nextauth-cookie-isolation.sh
Executable file
|
|
@ -0,0 +1,94 @@
|
|||
#!/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 "=============================================================="
|
||||
182
verify-all-isolation.sh
Executable file
182
verify-all-isolation.sh
Executable file
|
|
@ -0,0 +1,182 @@
|
|||
#!/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
|
||||
162
verify-enhanced-isolation.sh
Executable file
162
verify-enhanced-isolation.sh
Executable file
|
|
@ -0,0 +1,162 @@
|
|||
#!/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
|
||||
Loading…
Add table
Add a link
Reference in a new issue