Major improvements: - Created startup orchestration system with health monitoring and graceful shutdown - Fixed user registration and login with simplified authentication flow - Rebuilt authentication forms from scratch with direct API integration - Implemented comprehensive debugging and error handling - Added Redis fallback functionality for disabled environments - Fixed CORS configuration for cross-origin frontend requests - Simplified password validation to 6+ characters (removed complexity requirements) - Added toast notifications at app level for better UX feedback - Created comprehensive startup/shutdown scripts with OODA methodology - Fixed database validation and connection issues - Implemented TokenService memory fallback when Redis is disabled Technical details: - New SimpleLoginForm.tsx and SimpleRegisterForm.tsx components - Enhanced CORS middleware with additional allowed origins - Simplified auth validators and removed strict password requirements - Added extensive logging and diagnostic capabilities - Fixed authentication middleware token validation - Implemented graceful Redis error handling throughout the stack - Created modular startup system with configurable health checks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
165 lines
6.8 KiB
HTML
165 lines
6.8 KiB
HTML
<\!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Frontend-Backend API Test</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 20px; background-color: #1a1a1a; color: white; }
|
|
.container { max-width: 800px; margin: 0 auto; }
|
|
.test-section { background: #2a2a2a; padding: 20px; margin: 20px 0; border-radius: 8px; }
|
|
.success { background-color: #10b981; color: white; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
|
.error { background-color: #ef4444; color: white; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
|
.loading { background-color: #3b82f6; color: white; padding: 10px; border-radius: 4px; margin: 10px 0; }
|
|
button { background: #3b82f6; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; margin: 5px; }
|
|
button:hover { background: #2563eb; }
|
|
input { background: #374151; color: white; border: 1px solid #4b5563; padding: 8px; border-radius: 4px; margin: 5px; }
|
|
pre { background: #111; padding: 10px; border-radius: 4px; overflow-x: auto; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>Shattered Void Frontend-Backend Test</h1>
|
|
|
|
<div class="test-section">
|
|
<h2>1. Backend Health Check</h2>
|
|
<button onclick="testHealth()">Test Health Endpoint</button>
|
|
<div id="health-result"></div>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>2. Registration Test</h2>
|
|
<div>
|
|
<input type="text" id="reg-username" placeholder="Username" value="testuser" />
|
|
<input type="email" id="reg-email" placeholder="Email" value="test@example.com" />
|
|
<input type="password" id="reg-password" placeholder="Password" value="SecurePass9$" />
|
|
</div>
|
|
<button onclick="testRegistration()">Test Registration</button>
|
|
<div id="registration-result"></div>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>3. Login Test</h2>
|
|
<div>
|
|
<input type="email" id="login-email" placeholder="Email" value="test@example.com" />
|
|
<input type="password" id="login-password" placeholder="Password" value="SecurePass9$" />
|
|
</div>
|
|
<button onclick="testLogin()">Test Login</button>
|
|
<div id="login-result"></div>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h2>4. CORS Test</h2>
|
|
<button onclick="testCORS()">Test CORS Headers</button>
|
|
<div id="cors-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const API_BASE = 'http://localhost:3000';
|
|
|
|
function showResult(elementId, message, type) {
|
|
const element = document.getElementById(elementId);
|
|
element.innerHTML = `<div class="${type}">${message}</div>`;
|
|
}
|
|
|
|
function showLoading(elementId) {
|
|
const element = document.getElementById(elementId);
|
|
element.innerHTML = '<div class="loading">Loading...</div>';
|
|
}
|
|
|
|
async function testHealth() {
|
|
showLoading('health-result');
|
|
try {
|
|
const response = await fetch(`${API_BASE}/health`);
|
|
const data = await response.json();
|
|
showResult('health-result', `<pre>${JSON.stringify(data, null, 2)}</pre>`, 'success');
|
|
} catch (error) {
|
|
showResult('health-result', `Error: ${error.message}`, 'error');
|
|
}
|
|
}
|
|
|
|
async function testRegistration() {
|
|
showLoading('registration-result');
|
|
try {
|
|
const username = document.getElementById('reg-username').value;
|
|
const email = document.getElementById('reg-email').value;
|
|
const password = document.getElementById('reg-password').value;
|
|
|
|
const response = await fetch(`${API_BASE}/api/auth/register`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ username, email, password })
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok && data.success) {
|
|
showResult('registration-result', `<pre>${JSON.stringify(data, null, 2)}</pre>`, 'success');
|
|
} else {
|
|
showResult('registration-result', `<pre>${JSON.stringify(data, null, 2)}</pre>`, 'error');
|
|
}
|
|
} catch (error) {
|
|
showResult('registration-result', `Error: ${error.message}`, 'error');
|
|
}
|
|
}
|
|
|
|
async function testLogin() {
|
|
showLoading('login-result');
|
|
try {
|
|
const email = document.getElementById('login-email').value;
|
|
const password = document.getElementById('login-password').value;
|
|
|
|
const response = await fetch(`${API_BASE}/api/auth/login`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ email, password })
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok && data.success) {
|
|
showResult('login-result', `<pre>${JSON.stringify(data, null, 2)}</pre>`, 'success');
|
|
} else {
|
|
showResult('login-result', `<pre>${JSON.stringify(data, null, 2)}</pre>`, 'error');
|
|
}
|
|
} catch (error) {
|
|
showResult('login-result', `Error: ${error.message}`, 'error');
|
|
}
|
|
}
|
|
|
|
async function testCORS() {
|
|
showLoading('cors-result');
|
|
try {
|
|
const response = await fetch(`${API_BASE}/api/auth/register`, {
|
|
method: 'OPTIONS',
|
|
headers: {
|
|
'Origin': 'http://localhost:5173',
|
|
'Access-Control-Request-Method': 'POST',
|
|
'Access-Control-Request-Headers': 'Content-Type'
|
|
}
|
|
});
|
|
|
|
const corsHeaders = {};
|
|
response.headers.forEach((value, key) => {
|
|
if (key.toLowerCase().includes('access-control') || key.toLowerCase().includes('vary')) {
|
|
corsHeaders[key] = value;
|
|
}
|
|
});
|
|
|
|
showResult('cors-result', `<pre>Status: ${response.status}\nCORS Headers:\n${JSON.stringify(corsHeaders, null, 2)}</pre>`, 'success');
|
|
} catch (error) {
|
|
showResult('cors-result', `Error: ${error.message}`, 'error');
|
|
}
|
|
}
|
|
|
|
// Test on page load
|
|
window.onload = function() {
|
|
testHealth();
|
|
};
|
|
</script>
|
|
</body>
|
|
</html>
|
|
EOF < /dev/null
|