[mirotalk] - add config server side, update dep
This commit is contained in:
@@ -16,6 +16,7 @@ package-lock.json
|
||||
|
||||
# personal env
|
||||
.env
|
||||
config.js
|
||||
docker-push.sh
|
||||
docker-compose.yml
|
||||
output
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
@@ -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
@@ -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' },
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user