[mirotalk] - add config server side, update dep

This commit is contained in:
Miroslav Pejic
2024-12-16 14:01:57 +01:00
parent 82c4cfa966
commit f410d5a0b8
10 changed files with 255 additions and 30 deletions
+1
View File
@@ -16,6 +16,7 @@ package-lock.json
# personal env
.env
config.js
docker-push.sh
docker-compose.yml
output
+4
View File
@@ -171,6 +171,8 @@ $ git clone https://github.com/miroslavpejic85/mirotalk.git
$ cd mirotalk
# copy .env.template to .env (edit it according to your needs)
$ cp .env.template .env
# Copy app/src/config.template.js in app/src/config.js (edit it according to your needs)
$ cp app/src/config.template.js app/src/config.js
# install dependencies
$ npm install
# start the server
@@ -198,6 +200,8 @@ $ git clone https://github.com/miroslavpejic85/mirotalk.git
$ cd mirotalk
# copy .env.template to .env (edit it according to your needs)
$ cp .env.template .env
# Copy app/src/config.template.js in app/src/config.js (edit it according to your needs)
$ cp app/src/config.template.js app/src/config.js
# Copy docker-compose.template.yml in docker-compose.yml (edit it according to your needs)
$ cp docker-compose.template.yml docker-compose.yml
# Get official image from Docker Hub
+105
View File
@@ -0,0 +1,105 @@
'use strict';
module.exports = {
/**
* Configuration for controlling the visibility of buttons in the MiroTalk P2P client.
* Set properties to true to show the corresponding buttons, or false to hide them.
* captionBtn, showSwapCameraBtn, showScreenShareBtn, showFullScreenBtn, showVideoPipBtn, showDocumentPipBtn -> (auto-detected).
*/
buttons: {
main: {
showShareRoomBtn: true, // For guests
showHideMeBtn: true,
showAudioBtn: true,
showVideoBtn: true,
showScreenBtn: true, // autodetected
showRecordStreamBtn: true,
showChatRoomBtn: true,
showCaptionRoomBtn: true,
showRoomEmojiPickerBtn: true,
showMyHandBtn: true,
showWhiteboardBtn: true,
showSnapshotRoomBtn: true,
showFileShareBtn: true,
showMySettingsBtn: true,
showAboutBtn: true, // Please keep me always true, Thank you!
},
chat: {
showTogglePinBtn: true,
showMaxBtn: true,
showSaveMessageBtn: true,
showMarkDownBtn: true,
showChatGPTBtn: true,
showFileShareBtn: true,
showShareVideoAudioBtn: true,
showParticipantsBtn: true,
},
caption: {
showTogglePinBtn: true,
showMaxBtn: true,
},
settings: {
showMicOptionsBtn: true,
showTabRoomPeerName: true,
showTabRoomParticipants: true,
showTabRoomSecurity: true,
showTabEmailInvitation: true,
showCaptionEveryoneBtn: true,
showMuteEveryoneBtn: true,
showHideEveryoneBtn: true,
showEjectEveryoneBtn: true,
showLockRoomBtn: true,
showUnlockRoomBtn: true,
},
remote: {
showAudioVolume: true,
audioBtnClickAllowed: true,
videoBtnClickAllowed: true,
showKickOutBtn: true,
showSnapShotBtn: true,
showFileShareBtn: true,
showShareVideoAudioBtn: true,
showPrivateMessageBtn: true,
showZoomInOutBtn: false,
showVideoFocusBtn: true,
},
local: {
showSnapShotBtn: true,
showVideoCircleBtn: true,
showZoomInOutBtn: false,
},
whiteboard: {
whiteboardLockBtn: false,
},
},
brand: {
app: {
name: 'MiroTalk',
title: 'MiroTalk<br />Free browser based Real-time video calls.<br />Simple, Secure, Fast.',
description:
'Start your next video call with a single click. No download, plug-in, or login is required. Just get straight to talking, messaging, and sharing your screen.',
},
site: {
landingTitle: 'MiroTalk a Free Secure Video Calls, Chat & Screen Sharing.',
newCallTitle: 'MiroTalk a Free Secure Video Calls, Chat & Screen Sharing.',
loginTitle: 'MiroTalk - Host Protected login required.',
clientTitle: 'MiroTalk WebRTC Video call, Chat Room & Screen Sharing.',
privacyPolicyTitle: 'MiroTalk - privacy and policy.',
stunTurnTitle: 'Test Stun/Turn Servers.',
notFoundTitle: 'MiroTalk - 404 Page not found.',
shortcutIcon: '../images/logo.svg',
appleTouchIcon: '../images/logo.svg',
},
html: {
features: true,
browsers: true,
teams: true, // please keep me always true ;)
tryEasier: true,
poweredBy: true,
sponsors: true,
advertisers: true,
footer: true,
},
//...
},
};
+34 -2
View File
@@ -39,7 +39,7 @@ dependencies: {
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.4.00
* @version 1.4.10
*
*/
@@ -66,6 +66,9 @@ const Host = require('./host');
const Logs = require('./logs');
const log = new Logs('server');
// Custom Brand and buttons
const config = safeRequire('./config');
// Email alerts and notifications
const nodemailer = require('./lib/nodemailer');
@@ -397,7 +400,7 @@ app.use((req, res, next) => {
method: req.method,
path: req.originalUrl,
body: req.body,
headers: req.headers,
//headers: req.headers,
});
next();
});
@@ -681,6 +684,16 @@ app.post(['/login'], (req, res) => {
}
});
// UI buttons configuration
app.get('/buttons', (req, res) => {
res.status(200).json({ message: config && config.buttons ? config.buttons : false });
});
// UI brand configuration
app.get('/brand', (req, res) => {
res.status(200).json({ message: config && config.brand ? config.brand : false });
});
/**
MiroTalk API v1
For api docs we use: https://swagger.io/
@@ -2003,3 +2016,22 @@ function removeIP(socket) {
}
}
}
/**
* Load modules if exists
* @param {string} filePath
* @returns
*/
function safeRequire(filePath) {
try {
// Resolve the absolute path of the module
const resolvedPath = require.resolve(filePath);
// Check if the file exists
if (fs.existsSync(resolvedPath)) {
return require(resolvedPath);
}
} catch (error) {
log.error('Module not found', filePath);
}
return null;
}
+2
View File
@@ -5,6 +5,8 @@ services:
hostname: mirotalk
volumes:
- .env:/src/.env:ro
# Rebranding:
# - ./app/src/config.js:/src/app/src/config.js:ro
# Optional volumes for real-time updates:
# - ./app/:/src/app/:ro
# - ./public/:/src/public/:ro
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "mirotalk",
"version": "1.4.00",
"version": "1.4.10",
"description": "A free WebRTC browser-based video call",
"main": "server.js",
"scripts": {
@@ -42,7 +42,7 @@
"homepage": "https://github.com/miroslavpejic85/mirotalk",
"dependencies": {
"@mattermost/client": "^10.2.0",
"@sentry/node": "^8.45.0",
"@sentry/node": "^8.45.1",
"axios": "^1.7.9",
"colors": "^1.4.0",
"compression": "^1.7.5",
+76 -23
View File
@@ -1,7 +1,10 @@
'use strict';
// Html pages
// Brand
const brandDataKey = 'brandDataP2P';
const brandData = window.sessionStorage.getItem(brandDataKey);
// Html pages
const landingTitle = document.getElementById('landingTitle');
const newCallTitle = document.getElementById('newCallTitle');
const loginTitle = document.getElementById('loginTitle');
@@ -28,7 +31,7 @@ const footer = document.getElementById('footer');
// Brand customizations...
const brand = {
let brand = {
app: {
name: 'MiroTalk',
title: 'MiroTalk<br />Free browser based Real-time video calls.<br />Simple, Secure, Fast.',
@@ -59,31 +62,79 @@ const brand = {
//...
};
// Handle brand...
/**
* Get started
*/
async function initBrand() {
await getBrand();
if (landingTitle) landingTitle.textContent = brand.site.landingTitle;
if (newCallTitle) newCallTitle.textContent = brand.site.newCallTitle;
if (loginTitle) loginTitle.textContent = brand.site.loginTitle;
if (privacyPolicyTitle) privacyPolicyTitle.textContent = brand.site.privacyPolicyTitle;
if (stunTurnTitle) stunTurnTitle.textContent = brand.site.stunTurnTitle;
if (clientTitle) clientTitle.textContent = brand.site.clientTitle;
if (notFoundTitle) notFoundTitle.textContent = brand.site.notFoundTitle;
handleBrand();
}
if (shortcutIcon) shortcutIcon.href = brand.site.shortcutIcon;
if (appleTouchIcon) appleTouchIcon.href = brand.site.appleTouchIcon;
/**
* Get brand from server
*/
async function getBrand() {
if (brandData) {
setBrand(JSON.parse(brandData));
} else {
try {
const response = await fetch('/brand', { timeout: 5000 });
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
const serverBrand = data.message;
if (serverBrand) {
setBrand(serverBrand);
console.log('FETCH BRAND SETTINGS', {
serverBrand: serverBrand,
clientBrand: brand,
});
window.sessionStorage.setItem(brandDataKey, JSON.stringify(serverBrand));
}
} catch (error) {
console.error('FETCH GET BRAND ERROR', error.message);
}
}
}
if (appTitle) appTitle.innerHTML = brand.app.title;
if (appDescription) appDescription.textContent = brand.app.description;
/**
* Set brand
* @param {object} data
*/
function setBrand(data) {
brand = data;
console.log('Set Brand done');
}
!brand.html.features && elementDisplay(features, false);
!brand.html.browsers && elementDisplay(browsers, false);
!brand.html.teams && elementDisplay(teams, false);
!brand.html.tryEasier && elementDisplay(tryEasier, false);
!brand.html.poweredBy && elementDisplay(poweredBy, false);
!brand.html.sponsors && elementDisplay(sponsors, false);
!brand.html.advertisers && elementDisplay(advertisers, false);
!brand.html.footer && elementDisplay(footer, false);
//...
/**
* Handle Brand
*/
function handleBrand() {
if (landingTitle) landingTitle.textContent = brand.site.landingTitle;
if (newCallTitle) newCallTitle.textContent = brand.site.newCallTitle;
if (loginTitle) loginTitle.textContent = brand.site.loginTitle;
if (privacyPolicyTitle) privacyPolicyTitle.textContent = brand.site.privacyPolicyTitle;
if (stunTurnTitle) stunTurnTitle.textContent = brand.site.stunTurnTitle;
if (clientTitle) clientTitle.textContent = brand.site.clientTitle;
if (notFoundTitle) notFoundTitle.textContent = brand.site.notFoundTitle;
if (shortcutIcon) shortcutIcon.href = brand.site.shortcutIcon;
if (appleTouchIcon) appleTouchIcon.href = brand.site.appleTouchIcon;
if (appTitle) appTitle.innerHTML = brand.app.title;
if (appDescription) appDescription.textContent = brand.app.description;
!brand.html.features && elementDisplay(features, false);
!brand.html.browsers && elementDisplay(browsers, false);
!brand.html.teams && elementDisplay(teams, false);
!brand.html.tryEasier && elementDisplay(tryEasier, false);
!brand.html.poweredBy && elementDisplay(poweredBy, false);
!brand.html.sponsors && elementDisplay(sponsors, false);
!brand.html.advertisers && elementDisplay(advertisers, false);
!brand.html.footer && elementDisplay(footer, false);
}
/**
* Handle Element display
@@ -95,3 +146,5 @@ function elementDisplay(element, display, mode = 'block') {
if (!element) return;
element.style.display = display ? mode : 'none';
}
initBrand();
+1 -1
View File
@@ -5,7 +5,7 @@
* Set properties to true to show the corresponding buttons, or false to hide them.
* captionBtn, showSwapCameraBtn, showScreenShareBtn, showFullScreenBtn, showVideoPipBtn, showDocumentPipBtn -> (auto-detected).
*/
const buttons = {
let buttons = {
main: {
showShareRoomBtn: true,
showHideMeBtn: true,
+28 -2
View File
@@ -15,7 +15,7 @@
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.4.00
* @version 1.4.10
*
*/
@@ -1198,6 +1198,7 @@ async function handleConnect() {
getHtmlElementsById();
setButtonsToolTip();
handleUsernameEmojiPicker();
await getButtons();
manageButtons();
handleButtonsRule();
setupMySettings();
@@ -1382,6 +1383,31 @@ function handleButtonsRule() {
: elemDisplay(whiteboardLockBtn, false);
}
/**
* Get Buttons config from server side and apply to current client
*/
async function getButtons() {
try {
const response = await axios.get('/buttons', {
timeout: 5000,
});
const serverButtons = response.data.message;
if (serverButtons) {
// Merge serverButtons into BUTTONS, keeping the existing keys in BUTTONS if they are not present in serverButtons
buttons = {
...buttons, // Spread current BUTTONS first to keep existing keys
...serverButtons, // Overwrite or add new keys from serverButtons
};
console.log('AXIOS ROOM BUTTONS SETTINGS', {
serverButtons: serverButtons,
clientButtons: buttons,
});
}
} catch (error) {
console.error('AXIOS GET CONFIG ERROR', error.message);
}
}
/**
* set your name for the conference
*/
@@ -10664,7 +10690,7 @@ function showAbout() {
Swal.fire({
background: swBg,
position: 'center',
title: '<strong>WebRTC P2P v1.4.00</strong>',
title: '<strong>WebRTC P2P v1.4.10</strong>',
imageAlt: 'mirotalk-about',
imageUrl: images.about,
customClass: { image: 'img-about' },
+2
View File
@@ -1020,6 +1020,7 @@ access to use this app.
- https://flatpickr.js.org/ (https://github.com/flatpickr/flatpickr)
- https://simonwep.github.io/pickr/ (https://github.com/simonwep/pickr)
- https://uaparser.dev/ (https://github.com/faisalman/ua-parser-js)
- https://www.npmjs.com/package/axios (https://github.com/axios/axios)
-->
<script defer src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/xss/dist/xss.min.js"></script>
@@ -1037,6 +1038,7 @@ access to use this app.
<script defer src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.es5.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/ua-parser-js@latest/dist/ua-parser.min.js"></script>
<script async src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script defer src="/socket.io/socket.io.js"></script>
<script defer src="../js/localStorage.js"></script>
<script defer src="../js/helpers.js"></script>