Fix Android app connectivity issues and add detailed logging

- Add CORS headers to backend server to allow mobile app requests
- Implement request timeout (10s) in capacitor-bridge.js to prevent hanging
- Add comprehensive logging throughout authentication flow
- Add detailed error reporting in initApp for better debugging
- Log all API requests with request IDs for traceability

This fixes the 'Loading Plugin Compass...' infinite loop issue caused by
missing CORS headers and unhandled network timeouts.
This commit is contained in:
southseact-3d
2026-02-17 10:20:11 +00:00
parent 103951eb3c
commit 0c954449d3
3 changed files with 121 additions and 11 deletions

View File

@@ -7962,7 +7962,14 @@ async function extractZipToWorkspace(buffer, workspaceDir) {
}
function sendJson(res, statusCode, payload) { res.writeHead(statusCode, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(payload)); }
function sendJson(res, statusCode, payload) {
// CORS headers are already set in route(), but ensure they're preserved
const headers = {
'Content-Type': 'application/json'
};
res.writeHead(statusCode, headers);
res.end(JSON.stringify(payload));
}
function serveFile(res, filePath, contentType = 'text/html') { return fs.readFile(filePath).then((content) => { res.writeHead(200, { 'Content-Type': contentType }); res.end(content); }).catch(() => { res.writeHead(404); res.end('Not found'); }); }
function guessContentType(filePath) { const ext = path.extname(filePath); switch (ext) { case '.css': return 'text/css'; case '.js': return 'application/javascript'; case '.svg': return 'image/svg+xml'; case '.json': return 'application/json'; case '.html': return 'text/html'; default: return 'text/plain'; } }
function guessContentTypeFromExt(ext) { switch (ext) { case '.css': return 'text/css'; case '.js': return 'application/javascript'; case '.svg': return 'image/svg+xml'; case '.json': return 'application/json'; case '.png': return 'image/png'; case '.jpg': case '.jpeg': return 'image/jpeg'; case '.gif': return 'image/gif'; default: return 'application/octet-stream'; } }
@@ -18220,6 +18227,35 @@ async function route(req, res) {
const url = new URL(urlString, `http://${req.headers.host}`);
const pathname = url.pathname;
// Handle CORS preflight requests
const origin = req.headers.origin;
const allowedOrigins = [
'capacitor://localhost',
'http://localhost',
'https://localhost',
'https://plugincompass.com',
'http://plugincompass.com'
];
if (origin && allowedOrigins.some(allowed => origin.includes(allowed) || allowed.includes(origin))) {
res.setHeader('Access-Control-Allow-Origin', origin);
} else if (origin) {
// Allow any origin for mobile apps
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-User-Id, X-Request-ID');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Max-Age', '86400');
// Handle OPTIONS preflight
if (req.method === 'OPTIONS') {
res.writeHead(204);
res.end();
return;
}
// Track visitor
trackVisit(req, res);