mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Web relay improvements, #4240
This commit is contained in:
		
							parent
							
								
									3b16b51b08
								
							
						
					
					
						commit
						9dac8b7807
					
				
					 3 changed files with 95 additions and 80 deletions
				
			
		
							
								
								
									
										33
									
								
								apprelays.js
									
										
									
									
									
								
							
							
						
						
									
										33
									
								
								apprelays.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -84,6 +84,8 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
 | 
			
		|||
    var tunnels = {};
 | 
			
		||||
    var errorCount = 0; // If we keep closing tunnels without processing requests, fail the requests
 | 
			
		||||
 | 
			
		||||
    parent.parent.debug('webrelay', 'CreateWebRelaySession, userid:' + userid + ', addr:' + addr + ', port:' + port);
 | 
			
		||||
 | 
			
		||||
    // Any HTTP cookie set by the device is going to be shared between all tunnels to that device.
 | 
			
		||||
    obj.webCookies = {};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -110,12 +112,14 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
 | 
			
		|||
 | 
			
		||||
    // Handle new HTTP request
 | 
			
		||||
    obj.handleRequest = function (req, res) {
 | 
			
		||||
        parent.parent.debug('webrelay', 'handleRequest, url:' + req.url);
 | 
			
		||||
        pendingRequests.push([req, res, false]);
 | 
			
		||||
        handleNextRequest();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handle new websocket request
 | 
			
		||||
    obj.handleWebSocket = function (ws, req) {
 | 
			
		||||
        parent.parent.debug('webrelay', 'handleWebSocket, url:' + req.url);
 | 
			
		||||
        pendingRequests.push([req, ws, true]);
 | 
			
		||||
        handleNextRequest();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -146,19 +150,26 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
 | 
			
		|||
 | 
			
		||||
    function launchNewTunnel() {
 | 
			
		||||
        // Launch a new tunnel
 | 
			
		||||
        parent.parent.debug('webrelay', 'launchNewTunnel');
 | 
			
		||||
        const tunnel = module.exports.CreateWebRelay(obj, db, args, domain);
 | 
			
		||||
        tunnel.onclose = function (tunnelId, processedCount) {
 | 
			
		||||
            if (tunnels == null) return;
 | 
			
		||||
            parent.parent.debug('webrelay', 'tunnel-onclose');
 | 
			
		||||
            if (processedCount == 0) { errorCount++; } // If this tunnel closed without processing any requests, mark this as an error
 | 
			
		||||
            delete tunnels[tunnelId];
 | 
			
		||||
            handleNextRequest();
 | 
			
		||||
        }
 | 
			
		||||
        tunnel.onconnect = function (tunnelId) {
 | 
			
		||||
            if (tunnels == null) return;
 | 
			
		||||
            parent.parent.debug('webrelay', 'tunnel-onconnect');
 | 
			
		||||
            if (pendingRequests.length > 0) {
 | 
			
		||||
                const x = pendingRequests.shift();
 | 
			
		||||
                if (x[2] == true) { tunnels[tunnelId].processWebSocket(x[0], x[1]); } else { tunnels[tunnelId].processRequest(x[0], x[1]); }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        tunnel.oncompleted = function (tunnelId) {
 | 
			
		||||
            if (tunnels == null) return;
 | 
			
		||||
            parent.parent.debug('webrelay', 'tunnel-oncompleted');
 | 
			
		||||
            errorCount = 0; // Something got completed, clear any error count
 | 
			
		||||
            if (pendingRequests.length > 0) {
 | 
			
		||||
                const x = pendingRequests.shift();
 | 
			
		||||
| 
						 | 
				
			
			@ -170,10 +181,14 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
 | 
			
		|||
        tunnels[tunnel.tunnelId] = tunnel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Close all tunnels
 | 
			
		||||
    obj.close = function () { close(); }
 | 
			
		||||
 | 
			
		||||
    // Close all tunnels
 | 
			
		||||
    function close() {
 | 
			
		||||
        // Set the session as closed
 | 
			
		||||
        if (obj.closed == true) return;
 | 
			
		||||
        parent.parent.debug('webrelay', 'tunnel-close');
 | 
			
		||||
        obj.closed = true;
 | 
			
		||||
 | 
			
		||||
        // Close all tunnels
 | 
			
		||||
| 
						 | 
				
			
			@ -291,7 +306,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
 | 
			
		||||
    function sendWebSocketFrameToDevice(op, payload) {
 | 
			
		||||
        // Select a random mask
 | 
			
		||||
        const mask = parent.parent.crypto.randomBytes(4)
 | 
			
		||||
        const mask = parent.parent.parent.crypto.randomBytes(4)
 | 
			
		||||
 | 
			
		||||
        // Setup header and mask
 | 
			
		||||
        var header = null;
 | 
			
		||||
| 
						 | 
				
			
			@ -376,7 +391,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
        // Encode a cookie for the mesh relay
 | 
			
		||||
        const cookieContent = { userid: userid, domainid: domain.id, nodeid: nodeid, tcpport: port };
 | 
			
		||||
        if (addr != null) { cookieContent.tcpaddr = addr; }
 | 
			
		||||
        const cookie = parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey);
 | 
			
		||||
        const cookie = parent.parent.parent.encodeCookie(cookieContent, parent.parent.parent.loginCookieEncryptionKey);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // Setup the correct URL with domain and use TLS only if needed.
 | 
			
		||||
| 
						 | 
				
			
			@ -385,9 +400,9 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
            var domainadd = '';
 | 
			
		||||
            if ((domain.dns == null) && (domain.id != '')) { domainadd = domain.id + '/' }
 | 
			
		||||
            const url = protocol + '://localhost:' + args.port + '/' + domainadd + (((obj.mtype == 3) && (obj.relaynodeid == null)) ? 'local' : 'mesh') + 'relay.ashx?p=14&auth=' + cookie; // Protocol 14 is Web-TCP
 | 
			
		||||
            parent.parent.debug('relay', 'TCP: Connection websocket to ' + url);
 | 
			
		||||
            parent.parent.parent.debug('relay', 'TCP: Connection websocket to ' + url);
 | 
			
		||||
            obj.wsClient = new WebSocket(url, options);
 | 
			
		||||
            obj.wsClient.on('open', function () { parent.parent.debug('relay', 'TCP: Relay websocket open'); });
 | 
			
		||||
            obj.wsClient.on('open', function () { parent.parent.parent.debug('relay', 'TCP: Relay websocket open'); });
 | 
			
		||||
            obj.wsClient.on('message', function (data) { // Make sure to handle flow control.
 | 
			
		||||
                if (obj.tls) {
 | 
			
		||||
                    // WS --> TLS
 | 
			
		||||
| 
						 | 
				
			
			@ -402,13 +417,13 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
                            // TLSSocket to encapsulate TLS communication, which then tunneled via SerialTunnel
 | 
			
		||||
                            const tlsoptions = { socket: obj.ser, rejectUnauthorized: false };
 | 
			
		||||
                            obj.tls = require('tls').connect(tlsoptions, function () {
 | 
			
		||||
                                parent.parent.debug('relay', "Web Relay Secure TLS Connection");
 | 
			
		||||
                                parent.parent.parent.debug('relay', "Web Relay Secure TLS Connection");
 | 
			
		||||
                                obj.relayActive = true;
 | 
			
		||||
                                parent.lastOperation = obj.lastOperation = Date.now(); // Update time of last opertion performed
 | 
			
		||||
                                if (obj.onconnect) { obj.onconnect(obj.tunnelId); } // Event connection
 | 
			
		||||
                            });
 | 
			
		||||
                            obj.tls.setEncoding('binary');
 | 
			
		||||
                            obj.tls.on('error', function (err) { parent.parent.debug('relay', "Web Relay TLS Connection Error", err); obj.close(); });
 | 
			
		||||
                            obj.tls.on('error', function (err) { parent.parent.parent.debug('relay', "Web Relay TLS Connection Error", err); obj.close(); });
 | 
			
		||||
 | 
			
		||||
                            // Decrypted tunnel from TLS communcation to be forwarded to the browser
 | 
			
		||||
                            obj.tls.on('data', function (data) { processHttpData(data); }); // TLS ---> Browser
 | 
			
		||||
| 
						 | 
				
			
			@ -423,8 +438,8 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
                    processRawHttpData(data);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            obj.wsClient.on('close', function () { parent.parent.debug('relay', 'TCP: Relay websocket closed'); obj.close(); });
 | 
			
		||||
            obj.wsClient.on('error', function (err) { parent.parent.debug('relay', 'TCP: Relay websocket error: ' + err); obj.close(); });
 | 
			
		||||
            obj.wsClient.on('close', function () { parent.parent.parent.debug('relay', 'TCP: Relay websocket closed'); obj.close(); });
 | 
			
		||||
            obj.wsClient.on('error', function (err) { parent.parent.parent.debug('relay', 'TCP: Relay websocket error: ' + err); obj.close(); });
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            console.log(ex);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -656,7 +671,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
    // Send data thru the relay tunnel. Written to use TLS if needed.
 | 
			
		||||
    function send(data) { try { if (obj.tls) { obj.tls.write(data); } else { obj.wsClient.send(data); } } catch (ex) { } }
 | 
			
		||||
 | 
			
		||||
    parent.parent.debug('relay', 'TCP: Request for web relay');
 | 
			
		||||
    parent.parent.parent.debug('relay', 'TCP: Request for web relay');
 | 
			
		||||
    return obj;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,6 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
 | 
			
		|||
    obj.webRelayServer = null;
 | 
			
		||||
    obj.port = 0;
 | 
			
		||||
    obj.cleanupTimer = null;
 | 
			
		||||
    var nextSessionId = 1;
 | 
			
		||||
    var relaySessions = {}            // RelayID --> Web Mutli-Tunnel
 | 
			
		||||
    const constants = (require('crypto').constants ? require('crypto').constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead.
 | 
			
		||||
    var tlsSessionStore = {};         // Store TLS session information for quick resume.
 | 
			
		||||
| 
						 | 
				
			
			@ -68,14 +67,14 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
 | 
			
		|||
            httpOnly: true,
 | 
			
		||||
            keys: [args.sessionkey], // If multiple instances of this server are behind a load-balancer, this secret must be the same for all instances
 | 
			
		||||
            secure: (args.tlsoffload == null), // Use this cookie only over TLS (Check this: https://expressjs.com/en/guide/behind-proxies.html)
 | 
			
		||||
            sameSite: args.sessionsamesite
 | 
			
		||||
            sameSite: (args.sessionsamesite ? args.sessionsamesite : 'lax')
 | 
			
		||||
        }
 | 
			
		||||
        if (args.sessiontime != null) { sessionOptions.maxAge = (args.sessiontime * 60 * 1000); }
 | 
			
		||||
        obj.app.use(obj.session(sessionOptions));
 | 
			
		||||
 | 
			
		||||
        // Add HTTP security headers to all responses
 | 
			
		||||
        obj.app.use(function (req, res, next) {
 | 
			
		||||
            parent.debug('webrequest', req.url + ' (RelayServer)');
 | 
			
		||||
            parent.debug('webrelay', req.url);
 | 
			
		||||
            res.removeHeader('X-Powered-By');
 | 
			
		||||
            res.set({
 | 
			
		||||
                'strict-transport-security': 'max-age=60000; includeSubDomains',
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +82,7 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
 | 
			
		|||
                'x-frame-options': 'SAMEORIGIN',
 | 
			
		||||
                'X-XSS-Protection': '1; mode=block',
 | 
			
		||||
                'X-Content-Type-Options': 'nosniff',
 | 
			
		||||
                'Content-Security-Policy': "default-src 'none'; style-src 'self' 'unsafe-inline';"
 | 
			
		||||
                'Content-Security-Policy': "default-src 'self'; style-src 'self' 'unsafe-inline';"
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Set the real IP address of the request
 | 
			
		||||
| 
						 | 
				
			
			@ -121,8 +120,8 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
 | 
			
		|||
                return next();
 | 
			
		||||
            } else {
 | 
			
		||||
                // If this is a normal request (GET, POST, etc) handle it here
 | 
			
		||||
                if ((req.session.userid != null) && (req.session.rid != null)) {
 | 
			
		||||
                    var relaySession = relaySessions[req.session.userid + '/' + req.session.rid];
 | 
			
		||||
                if ((req.session.userid != null) && (req.session.x != null)) {
 | 
			
		||||
                    var relaySession = relaySessions[req.session.userid + '/' + req.session.x];
 | 
			
		||||
                    if (relaySession != null) {
 | 
			
		||||
                        // The web relay session is valid, use it
 | 
			
		||||
                        relaySession.handleRequest(req, res);
 | 
			
		||||
| 
						 | 
				
			
			@ -154,8 +153,8 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
 | 
			
		|||
 | 
			
		||||
        // Handle incoming web socket calls
 | 
			
		||||
        obj.app.ws('/*', function (ws, req) {
 | 
			
		||||
            if ((req.session.userid != null) && (req.session.rid != null)) {
 | 
			
		||||
                var relaySession = relaySessions[req.session.userid + '/' + req.session.rid];
 | 
			
		||||
            if ((req.session.userid != null) && (req.session.x != null)) {
 | 
			
		||||
                var relaySession = relaySessions[req.session.userid + '/' + req.session.x];
 | 
			
		||||
                if (relaySession != null) {
 | 
			
		||||
                    // The multi-tunnel session is valid, use it
 | 
			
		||||
                    relaySession.handleWebSocket(ws, req);
 | 
			
		||||
| 
						 | 
				
			
			@ -173,10 +172,10 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
 | 
			
		|||
        obj.app.get('/control-redirect.ashx', function (req, res) {
 | 
			
		||||
            if ((req.session == null) || (req.session.userid == null)) { res.redirect('/'); return; }
 | 
			
		||||
            res.set({ 'Cache-Control': 'no-store' });
 | 
			
		||||
            parent.debug('web', 'webRelaySetup');
 | 
			
		||||
            parent.debug('webrelay', 'webRelaySetup');
 | 
			
		||||
 | 
			
		||||
            // Check that all the required arguments are present
 | 
			
		||||
            if ((req.session.userid == null) || (req.query.n == null) || (req.query.p == null) || ((req.query.appid != 1) && (req.query.appid != 2))) { res.redirect('/'); return; }
 | 
			
		||||
            if ((req.session.userid == null) || (req.session.x == null) || (req.query.n == null) || (req.query.p == null) || ((req.query.appid != 1) && (req.query.appid != 2))) { res.redirect('/'); return; }
 | 
			
		||||
 | 
			
		||||
            // Get the user and domain information
 | 
			
		||||
            const userid = req.session.userid;
 | 
			
		||||
| 
						 | 
				
			
			@ -188,36 +187,31 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
 | 
			
		|||
            const appid = parseInt(req.query.appid);
 | 
			
		||||
 | 
			
		||||
            // Check to see if we already have a multi-relay session that matches exactly this device and port for this user
 | 
			
		||||
            var relaySession = null;
 | 
			
		||||
            for (var i in relaySessions) {
 | 
			
		||||
                const xrelaySession = relaySessions[i];
 | 
			
		||||
                if ((xrelaySession.domain.id == domain.id) && (xrelaySession.userid == userid) && (xrelaySession.nodeid == nodeid) && (xrelaySession.addr == addr) && (xrelaySession.port == port) && (xrelaySession.appid == appid)) {
 | 
			
		||||
                    relaySession = xrelaySession; // We found an exact match
 | 
			
		||||
                }
 | 
			
		||||
            const xrelaySession = relaySessions[req.session.userid + '/' + req.session.x];
 | 
			
		||||
            if ((xrelaySession != null) && (xrelaySession.domain.id == domain.id) && (xrelaySession.userid == userid) && (xrelaySession.nodeid == nodeid) && (xrelaySession.addr == addr) && (xrelaySession.port == port) && (xrelaySession.appid == appid)) {
 | 
			
		||||
                // We found an exact match, we are all setup already, redirect to root
 | 
			
		||||
                res.redirect('/');
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (relaySession != null) {
 | 
			
		||||
                // Since we found a match, use it
 | 
			
		||||
                req.session.rid = relaySession.sessionId;
 | 
			
		||||
            } else {
 | 
			
		||||
                // Create a web relay session
 | 
			
		||||
                relaySession = require('./apprelays.js').CreateWebRelaySession(parent, db, req, args, domain, userid, nodeid, addr, port, appid);
 | 
			
		||||
                relaySession.onclose = function (sessionId) {
 | 
			
		||||
                    // Remove the relay session
 | 
			
		||||
                    delete relaySessions[sessionId];
 | 
			
		||||
                    // If there are not more relay sessions, clear the cleanup timer
 | 
			
		||||
                    if ((Object.keys(relaySessions).length == 0) && (obj.cleanupTimer != null)) { clearInterval(obj.cleanupTimer); obj.cleanupTimer = null; }
 | 
			
		||||
                }
 | 
			
		||||
                relaySession.sessionId = nextSessionId++;
 | 
			
		||||
            // There is a relay session, but it's not correct, close it.
 | 
			
		||||
            if (xrelaySession != null) { xrelaySession.close(); delete relaySessions[req.session.userid + '/' + req.session.x]; }
 | 
			
		||||
 | 
			
		||||
                // Set the multi-tunnel session
 | 
			
		||||
                relaySessions[userid + '/' + relaySession.sessionId] = relaySession;
 | 
			
		||||
                req.session.rid = relaySession.sessionId;
 | 
			
		||||
 | 
			
		||||
                // Setup the cleanup timer if needed
 | 
			
		||||
                if (obj.cleanupTimer == null) { obj.cleanupTimer = setInterval(checkTimeout, 10000); }
 | 
			
		||||
            // Create a web relay session
 | 
			
		||||
            const relaySession = require('./apprelays.js').CreateWebRelaySession(obj, db, req, args, domain, userid, nodeid, addr, port, appid);
 | 
			
		||||
            relaySession.onclose = function (sessionId) {
 | 
			
		||||
                // Remove the relay session
 | 
			
		||||
                delete relaySessions[sessionId];
 | 
			
		||||
                // If there are not more relay sessions, clear the cleanup timer
 | 
			
		||||
                if ((Object.keys(relaySessions).length == 0) && (obj.cleanupTimer != null)) { clearInterval(obj.cleanupTimer); obj.cleanupTimer = null; }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Set the multi-tunnel session
 | 
			
		||||
            relaySessions[userid + '/' + req.session.x] = relaySession;
 | 
			
		||||
 | 
			
		||||
            // Setup the cleanup timer if needed
 | 
			
		||||
            if (obj.cleanupTimer == null) { obj.cleanupTimer = setInterval(checkTimeout, 10000); }
 | 
			
		||||
 | 
			
		||||
            // Redirect to root
 | 
			
		||||
            res.redirect('/');
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										78
									
								
								webserver.js
									
										
									
									
									
								
							
							
						
						
									
										78
									
								
								webserver.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -5758,11 +5758,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        //obj.app.use(obj.bodyParser.urlencoded({ extended: false }));
 | 
			
		||||
 | 
			
		||||
        // Setup the cookie session
 | 
			
		||||
        var sessionOptions = {
 | 
			
		||||
            name: 'xid', // Recommended security practice to not use the default cookie name
 | 
			
		||||
            httpOnly: true,
 | 
			
		||||
            domain: (certificates.CommonName != 'un-configured' ? "." + certificates.CommonName : null),
 | 
			
		||||
            keys: [obj.args.sessionkey], // If multiple instances of this server are behind a load-balancer, this secret must be the same for all instances
 | 
			
		||||
            secure: (obj.args.tlsoffload == null), // Use this cookie only over TLS (Check this: https://expressjs.com/en/guide/behind-proxies.html)
 | 
			
		||||
            sameSite: (obj.args.sessionsamesite ? obj.args.sessionsamesite : 'lax')
 | 
			
		||||
| 
						 | 
				
			
			@ -5876,7 +5876,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            // If this is a web relay connection, handle it here.
 | 
			
		||||
            if ((obj.webRelayRouter != null) && (req.hostname == obj.args.relaydns)) { return obj.webRelayRouter(req, res); }
 | 
			
		||||
            if ((obj.webRelayRouter != null) && (req.hostname == obj.args.relaydns)) {
 | 
			
		||||
                if (['GET', 'POST', 'PUT', 'HEAD'].indexOf(req.method) >= 0) { return obj.webRelayRouter(req, res); } else { res.sendStatus(404); return; }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Get the domain for this request
 | 
			
		||||
            const domain = req.xdomain = getDomain(req);
 | 
			
		||||
| 
						 | 
				
			
			@ -6590,7 +6592,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
 | 
			
		|||
                    parent.debug('web', 'webRelaySetup');
 | 
			
		||||
 | 
			
		||||
                    // Check that all the required arguments are present
 | 
			
		||||
                    if ((req.session.userid == null) || (req.query.n == null) || (req.query.p == null) || ((req.query.appid != 1) && (req.query.appid != 2))) { res.redirect('/'); return; }
 | 
			
		||||
                    if ((req.session.userid == null) || (req.session.x == null) || (req.query.n == null) || (req.query.p == null) || ((req.query.appid != 1) && (req.query.appid != 2))) { res.redirect('/'); return; }
 | 
			
		||||
 | 
			
		||||
                    // Get the user and domain information
 | 
			
		||||
                    const userid = req.session.userid;
 | 
			
		||||
| 
						 | 
				
			
			@ -6602,45 +6604,49 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
 | 
			
		|||
                    const appid = parseInt(req.query.appid);
 | 
			
		||||
 | 
			
		||||
                    // Check to see if we already have a multi-relay session that matches exactly this device and port for this user
 | 
			
		||||
                    var relaySession = null;
 | 
			
		||||
                    for (var i in webRelaySessions) {
 | 
			
		||||
                        const xrelaySession = webRelaySessions[i];
 | 
			
		||||
                        if ((xrelaySession.domain.id == domain.id) && (xrelaySession.userid == userid) && (xrelaySession.nodeid == nodeid) && (xrelaySession.addr == addr) && (xrelaySession.port == port) && (xrelaySession.appid == appid)) {
 | 
			
		||||
                            relaySession = xrelaySession; // We found an exact match
 | 
			
		||||
                        }
 | 
			
		||||
                    const xrelaySession = webRelaySessions[req.session.userid + '/' + req.session.x];
 | 
			
		||||
                    if ((xrelaySession != null) && (xrelaySession.domain.id == domain.id) && (xrelaySession.userid == userid) && (xrelaySession.nodeid == nodeid) && (xrelaySession.addr == addr) && (xrelaySession.port == port) && (xrelaySession.appid == appid)) {
 | 
			
		||||
                        // We found an exact match, we are all setup already, redirect to root
 | 
			
		||||
                        res.redirect('/');
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (relaySession != null) {
 | 
			
		||||
                        // Since we found a match, use it
 | 
			
		||||
                        req.session.rid = relaySession.sessionId;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        // Create a web relay session
 | 
			
		||||
                        relaySession = require('./apprelays.js').CreateWebRelaySession(parent, db, req, args, domain, userid, nodeid, addr, port, appid);
 | 
			
		||||
                        relaySession.onclose = function (sessionId) {
 | 
			
		||||
                            // Remove the relay session
 | 
			
		||||
                            delete webRelaySessions[sessionId];
 | 
			
		||||
                            // If there are not more relay sessions, clear the cleanup timer
 | 
			
		||||
                            if ((Object.keys(webRelaySessions).length == 0) && (webRelayCleanupTimer != null)) { clearInterval(webRelayCleanupTimer); webRelayCleanupTimer = null; }
 | 
			
		||||
                        }
 | 
			
		||||
                        relaySession.sessionId = webRelayNextSessionId++;
 | 
			
		||||
 | 
			
		||||
                        // Set the multi-tunnel session
 | 
			
		||||
                        webRelaySessions[userid + '/' + relaySession.sessionId] = relaySession;
 | 
			
		||||
                        req.session.rid = relaySession.sessionId;
 | 
			
		||||
 | 
			
		||||
                        // Setup the cleanup timer if needed
 | 
			
		||||
                        if (webRelayCleanupTimer == null) { webRelayCleanupTimer = setInterval(checkWebRelaySessionsTimeout, 10000); }
 | 
			
		||||
                    // There is a relay session, but it's not correct, close it.
 | 
			
		||||
                    if (xrelaySession != null) {
 | 
			
		||||
                        xrelaySession.close();
 | 
			
		||||
                        delete webRelaySessions[req.session.userid + '/' + req.session.x];
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Create a web relay session
 | 
			
		||||
                    const relaySession = require('./apprelays.js').CreateWebRelaySession(obj, db, req, args, domain, userid, nodeid, addr, port, appid);
 | 
			
		||||
                    relaySession.onclose = function (sessionId) {
 | 
			
		||||
                        // Remove the relay session
 | 
			
		||||
                        delete webRelaySessions[sessionId];
 | 
			
		||||
                        // If there are not more relay sessions, clear the cleanup timer
 | 
			
		||||
                        if ((Object.keys(webRelaySessions).length == 0) && (obj.cleanupTimer != null)) { clearInterval(webRelayCleanupTimer); obj.cleanupTimer = null; }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Set the multi-tunnel session
 | 
			
		||||
                    webRelaySessions[userid + '/' + req.session.x] = relaySession;
 | 
			
		||||
 | 
			
		||||
                    // Setup the cleanup timer if needed
 | 
			
		||||
                    if (obj.cleanupTimer == null) { webRelayCleanupTimer = setInterval(checkWebRelaySessionsTimeout, 10000); }
 | 
			
		||||
 | 
			
		||||
                    // Redirect to root
 | 
			
		||||
                    res.redirect('/');
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // Handle all incoming requests as web relays
 | 
			
		||||
                obj.webRelayRouter.get('/*', function (req, res) { handleWebRelayRequest(req, res); })
 | 
			
		||||
                obj.webRelayRouter.get('/*', function (req, res) { try { handleWebRelayRequest(req, res); } catch (ex) { console.log(ex); } })
 | 
			
		||||
 | 
			
		||||
                // Handle all incoming requests as web relays
 | 
			
		||||
                obj.webRelayRouter.post('/*', function (req, res) { handleWebRelayRequest(req, res); })
 | 
			
		||||
                obj.webRelayRouter.post('/*', function (req, res) { try { handleWebRelayRequest(req, res); } catch (ex) { console.log(ex); } })
 | 
			
		||||
 | 
			
		||||
                // Handle all incoming requests as web relays
 | 
			
		||||
                obj.webRelayRouter.put('/*', function (req, res) { try { handleWebRelayRequest(req, res); } catch (ex) { console.log(ex); } })
 | 
			
		||||
 | 
			
		||||
                // Handle all incoming requests as web relays
 | 
			
		||||
                obj.webRelayRouter.head('/*', function (req, res) { try { handleWebRelayRequest(req, res); } catch (ex) { console.log(ex); } })
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Indicates to ExpressJS that the override public folder should be used to serve static files.
 | 
			
		||||
| 
						 | 
				
			
			@ -6685,8 +6691,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
 | 
			
		|||
 | 
			
		||||
    // Handle an incoming request as a web relay 
 | 
			
		||||
    function handleWebRelayRequest(req, res) {
 | 
			
		||||
        if ((req.session.userid != null) && (req.session.rid != null)) {
 | 
			
		||||
            var relaySession = webRelaySessions[req.session.userid + '/' + req.session.rid];
 | 
			
		||||
        if ((req.session.userid != null) && (req.session.x != null)) {
 | 
			
		||||
            var relaySession = webRelaySessions[req.session.userid + '/' + req.session.x];
 | 
			
		||||
            if (relaySession != null) {
 | 
			
		||||
                // The web relay session is valid, use it
 | 
			
		||||
                relaySession.handleRequest(req, res);
 | 
			
		||||
| 
						 | 
				
			
			@ -6702,8 +6708,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
 | 
			
		|||
 | 
			
		||||
    // Handle an incoming websocket connection as a web relay 
 | 
			
		||||
    function handleWebRelayWebSocket(ws, req) {
 | 
			
		||||
        if ((req.session.userid != null) && (req.session.rid != null)) {
 | 
			
		||||
            var relaySession = webRelaySessions[req.session.userid + '/' + req.session.rid];
 | 
			
		||||
        if ((req.session.userid != null) && (req.session.x != null)) {
 | 
			
		||||
            var relaySession = webRelaySessions[req.session.userid + '/' + req.session.x];
 | 
			
		||||
            if (relaySession != null) {
 | 
			
		||||
                // The multi-tunnel session is valid, use it
 | 
			
		||||
                relaySession.handleWebSocket(ws, req);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue