changed the navbar to work.
All checks were successful
Build Frontend / Build Frontend (push) Successful in 35s
All checks were successful
Build Frontend / Build Frontend (push) Successful in 35s
This commit is contained in:
314
scripts/verify-login-fix.cjs
Normal file
314
scripts/verify-login-fix.cjs
Normal file
@@ -0,0 +1,314 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Verification Script for Navbar Login Fix
|
||||
*
|
||||
* This script verifies that the WebSocket authentication state synchronization
|
||||
* is working correctly after the navbar login fix deployment.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/verify-login-fix.js
|
||||
*/
|
||||
|
||||
const https = require('https');
|
||||
const http = require('http');
|
||||
|
||||
const API_URL = process.env.VITE_API_URL || 'https://api.turbotrades.dev';
|
||||
const WS_URL = process.env.VITE_WS_URL || 'wss://api.turbotrades.dev/ws';
|
||||
|
||||
const colors = {
|
||||
reset: '\x1b[0m',
|
||||
bright: '\x1b[1m',
|
||||
green: '\x1b[32m',
|
||||
red: '\x1b[31m',
|
||||
yellow: '\x1b[33m',
|
||||
blue: '\x1b[34m',
|
||||
cyan: '\x1b[36m',
|
||||
};
|
||||
|
||||
function log(message, color = colors.reset) {
|
||||
console.log(`${color}${message}${colors.reset}`);
|
||||
}
|
||||
|
||||
function success(message) {
|
||||
log(`✅ ${message}`, colors.green);
|
||||
}
|
||||
|
||||
function error(message) {
|
||||
log(`❌ ${message}`, colors.red);
|
||||
}
|
||||
|
||||
function warning(message) {
|
||||
log(`⚠️ ${message}`, colors.yellow);
|
||||
}
|
||||
|
||||
function info(message) {
|
||||
log(`ℹ️ ${message}`, colors.cyan);
|
||||
}
|
||||
|
||||
function section(message) {
|
||||
log(`\n${colors.bright}${message}${colors.reset}`);
|
||||
log('='.repeat(60));
|
||||
}
|
||||
|
||||
// Check if endpoint is reachable
|
||||
function checkEndpoint(url, description) {
|
||||
return new Promise((resolve) => {
|
||||
const urlObj = new URL(url);
|
||||
const client = urlObj.protocol === 'https:' ? https : http;
|
||||
|
||||
const options = {
|
||||
hostname: urlObj.hostname,
|
||||
port: urlObj.port || (urlObj.protocol === 'https:' ? 443 : 80),
|
||||
path: urlObj.pathname,
|
||||
method: 'GET',
|
||||
timeout: 5000,
|
||||
};
|
||||
|
||||
const req = client.request(options, (res) => {
|
||||
if (res.statusCode >= 200 && res.statusCode < 400) {
|
||||
success(`${description}: Reachable (Status: ${res.statusCode})`);
|
||||
resolve(true);
|
||||
} else {
|
||||
warning(`${description}: Returned status ${res.statusCode}`);
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
|
||||
req.on('error', (err) => {
|
||||
error(`${description}: ${err.message}`);
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
req.on('timeout', () => {
|
||||
error(`${description}: Request timed out`);
|
||||
req.destroy();
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
// Check WebSocket endpoint
|
||||
function checkWebSocket(url) {
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
const WebSocket = require('ws');
|
||||
const ws = new WebSocket(url);
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
ws.close();
|
||||
error('WebSocket: Connection timeout');
|
||||
resolve(false);
|
||||
}, 5000);
|
||||
|
||||
ws.on('open', () => {
|
||||
clearTimeout(timeout);
|
||||
success('WebSocket: Connection successful');
|
||||
ws.close();
|
||||
resolve(true);
|
||||
});
|
||||
|
||||
ws.on('error', (err) => {
|
||||
clearTimeout(timeout);
|
||||
error(`WebSocket: ${err.message}`);
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
error(`WebSocket: ws module not available (${err.message})`);
|
||||
warning('Install with: npm install ws');
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Read and verify frontend build files
|
||||
function checkFrontendBuild() {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const distPath = path.join(__dirname, '..', 'frontend', 'dist');
|
||||
const indexPath = path.join(distPath, 'index.html');
|
||||
|
||||
if (!fs.existsSync(distPath)) {
|
||||
error('Frontend dist directory not found');
|
||||
warning('Run: cd frontend && npm run build');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(indexPath)) {
|
||||
error('Frontend index.html not found in dist/');
|
||||
return false;
|
||||
}
|
||||
|
||||
const indexContent = fs.readFileSync(indexPath, 'utf8');
|
||||
|
||||
// Check for recent build by looking for assets
|
||||
const hasAssets = indexContent.includes('/assets/');
|
||||
const hasModernJS = indexContent.includes('type="module"');
|
||||
|
||||
if (hasAssets && hasModernJS) {
|
||||
success('Frontend build exists and looks valid');
|
||||
|
||||
// Get build timestamp from file modification time
|
||||
const stats = fs.statSync(indexPath);
|
||||
const buildTime = stats.mtime;
|
||||
const now = new Date();
|
||||
const ageMinutes = Math.floor((now - buildTime) / 1000 / 60);
|
||||
|
||||
if (ageMinutes < 60) {
|
||||
success(`Build age: ${ageMinutes} minutes (recent)`);
|
||||
} else if (ageMinutes < 1440) {
|
||||
info(`Build age: ${Math.floor(ageMinutes / 60)} hours`);
|
||||
} else {
|
||||
warning(`Build age: ${Math.floor(ageMinutes / 1440)} days (consider rebuilding)`);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
error('Frontend build appears invalid');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check source files for the fix
|
||||
function checkSourceCode() {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const websocketStorePath = path.join(__dirname, '..', 'frontend', 'src', 'stores', 'websocket.js');
|
||||
const authStorePath = path.join(__dirname, '..', 'frontend', 'src', 'stores', 'auth.js');
|
||||
|
||||
if (!fs.existsSync(websocketStorePath)) {
|
||||
error('WebSocket store not found');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(authStorePath)) {
|
||||
error('Auth store not found');
|
||||
return false;
|
||||
}
|
||||
|
||||
const websocketCode = fs.readFileSync(websocketStorePath, 'utf8');
|
||||
const authCode = fs.readFileSync(authStorePath, 'utf8');
|
||||
|
||||
// Check for the fix in websocket store
|
||||
const hasConnectedHandler = websocketCode.includes('case "connected":');
|
||||
const callsFetchUser = websocketCode.includes('authStore.fetchUser()');
|
||||
const declaresAuthStore = websocketCode.includes('const authStore = useAuthStore()');
|
||||
|
||||
if (hasConnectedHandler && callsFetchUser && declaresAuthStore) {
|
||||
success('WebSocket store has the navbar login fix');
|
||||
} else {
|
||||
error('WebSocket store missing the fix');
|
||||
if (!hasConnectedHandler) warning(' - Missing "connected" case handler');
|
||||
if (!callsFetchUser) warning(' - Not calling authStore.fetchUser()');
|
||||
if (!declaresAuthStore) warning(' - Not declaring authStore');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for debug logging (optional)
|
||||
const hasDebugLogs = websocketCode.includes('🟢 WebSocket received') ||
|
||||
authCode.includes('🔵 fetchUser called');
|
||||
|
||||
if (hasDebugLogs) {
|
||||
info('Debug logging is present (helpful for troubleshooting)');
|
||||
} else {
|
||||
info('Debug logging not present (clean for production)');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Main verification flow
|
||||
async function main() {
|
||||
log('\n' + '='.repeat(60), colors.bright);
|
||||
log(' NAVBAR LOGIN FIX - VERIFICATION SCRIPT', colors.bright);
|
||||
log('='.repeat(60) + '\n', colors.bright);
|
||||
|
||||
let allChecks = true;
|
||||
|
||||
// 1. Check source code
|
||||
section('1. Checking Source Code');
|
||||
const sourceCheck = checkSourceCode();
|
||||
allChecks = allChecks && sourceCheck;
|
||||
|
||||
// 2. Check frontend build
|
||||
section('2. Checking Frontend Build');
|
||||
const buildCheck = checkFrontendBuild();
|
||||
allChecks = allChecks && buildCheck;
|
||||
|
||||
// 3. Check API endpoints
|
||||
section('3. Checking API Endpoints');
|
||||
|
||||
const apiHealthCheck = await checkEndpoint(
|
||||
`${API_URL}/api/health`,
|
||||
'API Health Endpoint'
|
||||
);
|
||||
|
||||
const apiAuthCheck = await checkEndpoint(
|
||||
`${API_URL}/api/auth/me`,
|
||||
'Auth Endpoint (/api/auth/me)'
|
||||
);
|
||||
|
||||
const publicConfigCheck = await checkEndpoint(
|
||||
`${API_URL}/api/config/public`,
|
||||
'Public Config Endpoint'
|
||||
);
|
||||
|
||||
allChecks = allChecks && apiHealthCheck && apiAuthCheck && publicConfigCheck;
|
||||
|
||||
// 4. Check WebSocket
|
||||
section('4. Checking WebSocket Connection');
|
||||
const wsCheck = await checkWebSocket(WS_URL);
|
||||
allChecks = allChecks && wsCheck;
|
||||
|
||||
// Summary
|
||||
section('Verification Summary');
|
||||
|
||||
if (allChecks) {
|
||||
success('All checks passed! ✨');
|
||||
log('\n📋 Next Steps:', colors.bright);
|
||||
log(' 1. Deploy the frontend build to production');
|
||||
log(' 2. Clear browser cache (Ctrl+Shift+R)');
|
||||
log(' 3. Test Steam login in browser');
|
||||
log(' 4. Verify navbar updates after login\n');
|
||||
} else {
|
||||
error('Some checks failed!');
|
||||
log('\n📋 Recommended Actions:', colors.bright);
|
||||
|
||||
if (!sourceCheck) {
|
||||
log(' • Verify the code changes are committed');
|
||||
log(' • Pull latest changes: git pull origin main');
|
||||
}
|
||||
|
||||
if (!buildCheck) {
|
||||
log(' • Rebuild frontend: cd frontend && npm run build');
|
||||
}
|
||||
|
||||
if (!apiHealthCheck || !apiAuthCheck || !publicConfigCheck) {
|
||||
log(' • Check backend is running: pm2 status');
|
||||
log(' • Check backend logs: pm2 logs turbotrades-backend');
|
||||
log(' • Verify Nginx configuration');
|
||||
}
|
||||
|
||||
if (!wsCheck) {
|
||||
log(' • Check WebSocket endpoint in Nginx config');
|
||||
log(' • Verify backend WebSocket service is running');
|
||||
log(' • Check firewall rules for WebSocket connections');
|
||||
}
|
||||
|
||||
log('');
|
||||
}
|
||||
|
||||
process.exit(allChecks ? 0 : 1);
|
||||
}
|
||||
|
||||
// Run the script
|
||||
main().catch((err) => {
|
||||
error(`Unexpected error: ${err.message}`);
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user