From 6b87eb685ce56ba9342046a427d2ad9dc5bef2d3 Mon Sep 17 00:00:00 2001 From: Miroslav Pejic Date: Fri, 2 Feb 2024 11:55:09 +0100 Subject: [PATCH] [mirotalksfu] - add IP whitelist middleware --- app/src/Server.js | 8 +++++++- app/src/config.template.js | 11 +++++++++++ app/src/middleware/IpWhitelist.js | 23 +++++++++++++++++++++++ package.json | 2 +- public/js/Room.js | 2 +- public/js/RoomClient.js | 2 +- 6 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 app/src/middleware/IpWhitelist.js diff --git a/app/src/Server.js b/app/src/Server.js index f0ddc888..75c4f7ee 100644 --- a/app/src/Server.js +++ b/app/src/Server.js @@ -40,7 +40,7 @@ dependencies: { * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.3.61 + * @version 1.3.62 * */ @@ -68,6 +68,7 @@ const swaggerUi = require('swagger-ui-express'); const swaggerDocument = yamlJS.load(path.join(__dirname + '/../api/swagger.yaml')); const Sentry = require('@sentry/node'); const { CaptureConsole } = require('@sentry/integrations'); +const restrictAccessByIP = require('./middleware/IpWhitelist.js'); const packageJson = require('../../package.json'); // Slack API @@ -205,6 +206,9 @@ function startServer() { app.use(bodyParser.urlencoded({ extended: true })); app.use(apiBasePath + '/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); // api docs + // IP Whitelist check ... + app.use(restrictAccessByIP); + // Logs requests app.use((req, res, next) => { log.debug('New request:', { @@ -502,6 +506,7 @@ function startServer() { node_version: process.versions.node, hostConfig: hostCfg, presenters: config.presenters, + middleware: config.middleware, announced_ip: announcedIP, server: host, server_tunnel: tunnel, @@ -549,6 +554,7 @@ function startServer() { node_version: process.versions.node, hostConfig: hostCfg, presenters: config.presenters, + middleware: config.middleware, announced_ip: announcedIP, server: host, api_docs: api_docs, diff --git a/app/src/config.template.js b/app/src/config.template.js index d52c1088..38dcb11e 100644 --- a/app/src/config.template.js +++ b/app/src/config.template.js @@ -67,6 +67,17 @@ module.exports = { ], join_first: true, // Set to true for traditional behavior, false to prioritize presenters }, + middleware: { + /* + Middleware: + - IP Whitelist: Access to the instance is restricted to only the specified IP addresses in the allowed list. This feature is disabled by default. + - ... + */ + IpWhitelist: { + enabled: false, + allowed: ['127.0.0.1', '::1'], + }, + }, console: { debug: true, colors: true, diff --git a/app/src/middleware/IpWhitelist.js b/app/src/middleware/IpWhitelist.js new file mode 100644 index 00000000..ff37605b --- /dev/null +++ b/app/src/middleware/IpWhitelist.js @@ -0,0 +1,23 @@ +'use strict'; + +const config = require('../config'); +const Logger = require('../Logger'); +const log = new Logger('RestrictAccessByIP'); + +const IpWhitelistEnabled = config.middleware ? config.middleware.IpWhitelist.enabled : false; +const allowedIPs = config.middleware ? config.middleware.IpWhitelist.allowed : []; + +const restrictAccessByIP = (req, res, next) => { + if (!IpWhitelistEnabled) return next(); + // + const clientIP = req.headers['x-forwarded-for'] || req.socket.remoteAddress || req.ip; + log.debug('Check IP', clientIP); + if (allowedIPs.includes(clientIP)) { + next(); + } else { + log.info('Forbidden: Access denied from this IP address', { clientIP: clientIP }); + res.status(403).json({ error: 'Forbidden', message: 'Access denied from this IP address.' }); + } +}; + +module.exports = restrictAccessByIP; diff --git a/package.json b/package.json index cf954283..317be309 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mirotalksfu", - "version": "1.3.61", + "version": "1.3.62", "description": "WebRTC SFU browser-based video calls", "main": "Server.js", "scripts": { diff --git a/public/js/Room.js b/public/js/Room.js index f28b6e3c..4b7e871f 100644 --- a/public/js/Room.js +++ b/public/js/Room.js @@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.3.61 + * @version 1.3.62 * */ diff --git a/public/js/RoomClient.js b/public/js/RoomClient.js index 02eab2f9..1e89233e 100644 --- a/public/js/RoomClient.js +++ b/public/js/RoomClient.js @@ -9,7 +9,7 @@ * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.3.61 + * @version 1.3.62 * */