navflow-proxy-server
Version:
Dynamic WebSocket proxy server for NavFlow
89 lines (75 loc) • 2.38 kB
JavaScript
/**
* Authentication middleware for tunnel requests
*/
const { isValidTunnelId } = require('./utils');
/**
* Authentication middleware factory
* @param {TunnelManager} tunnelManager
* @returns {Function} Express middleware
*/
function createAuthMiddleware(tunnelManager) {
return (req, res, next) => {
// Skip auth for health check, device endpoints, test endpoints, and other system endpoints
if (req.path === '/health' || req.path === '/stats' || req.path === '/' || req.path.startsWith('/api/devices') || req.path.startsWith('/api/test')) {
return next();
}
// Get tunnel ID from header
const tunnelId = req.headers['x-tunnel-id'];
if (!tunnelId) {
return res.status(400).json({
error: 'Authentication required - missing X-Tunnel-ID header'
});
}
if (!isValidTunnelId(tunnelId)) {
return res.status(400).json({
error: 'Invalid tunnel ID format',
tunnelId: tunnelId
});
}
// Get password from header or query parameter
const password = req.headers['x-tunnel-auth'] || req.query.auth;
if (!password) {
return res.status(401).json({
error: 'Authentication required - missing X-Tunnel-Auth header'
});
}
// Validate tunnel and password
if (!tunnelManager.validateAuth(tunnelId, password)) {
// Check if tunnel exists at all
const tunnel = tunnelManager.getTunnel(tunnelId);
if (!tunnel) {
return res.status(404).json({
error: 'Tunnel not found - browser server may be disconnected',
tunnelId: tunnelId
});
}
return res.status(401).json({
error: 'Invalid authentication credentials',
tunnelId: tunnelId
});
}
// Update tunnel activity
tunnelManager.updateActivity(tunnelId);
// Add tunnel info to request
req.tunnel = {
id: tunnelId,
password: password
};
next();
};
}
/**
* WebSocket authentication for tunnel connections
* @param {WebSocket} ws
* @param {Object} req
* @returns {boolean} Whether authentication passed
*/
function authenticateWebSocket(ws, req) {
// WebSocket connections don't need password auth initially
// They establish the tunnel and receive credentials
return true;
}
module.exports = {
createAuthMiddleware,
authenticateWebSocket
};