diff --git a/app/api/README.md b/app/api/README.md index 05a7f9cc..a2409365 100644 --- a/app/api/README.md +++ b/app/api/README.md @@ -17,18 +17,22 @@ Some examples demonstrating how to call the API: ```bash # js +node meetings.js node meeting.js node join.js # php +php meetings.php php meeting.php php join.php # python +python3 meetings.py python3 meeting.py python3 join.py # bash +./meetings.sh ./meeting.sh ./join.sh ``` diff --git a/app/api/meetings/meetings.js b/app/api/meetings/meetings.js new file mode 100644 index 00000000..3b75d326 --- /dev/null +++ b/app/api/meetings/meetings.js @@ -0,0 +1,34 @@ +'use strict'; + +async function getMeetings() { + try { + // Use dynamic import with await + const { default: fetch } = await import('node-fetch'); + + const API_KEY_SECRET = 'mirotalksfu_default_secret'; + const MIROTALK_URL = 'https://sfu.mirotalk.com/api/v1/meetings'; + //const MIROTALK_URL = 'http://localhost:3010/api/v1/meetings'; + + const response = await fetch(MIROTALK_URL, { + method: 'GET', + headers: { + authorization: API_KEY_SECRET, + 'Content-Type': 'application/json', + }, + }); + const data = await response.json(); + if (data.error) { + console.log('Error:', data.error); + } else { + if (data && data.meetings) { + const meetings = data.meetings; + const formattedData = JSON.stringify({ meetings }, null, 2); + console.log(formattedData); + } + } + } catch (error) { + console.error('Error fetching data:', error); + } +} + +getMeetings(); diff --git a/app/api/meetings/meetings.php b/app/api/meetings/meetings.php new file mode 100644 index 00000000..70777136 --- /dev/null +++ b/app/api/meetings/meetings.php @@ -0,0 +1,29 @@ + { + // request meetings list + app.get([restApi.basePath + '/meetings'], (req, res) => { + // Check if endpoint allowed + if (restApi.allowed && !restApi.allowed.meetings) { + return res + .status(403) + .json({ + error: 'This endpoint has been disabled. Please contact the administrator for further information.', + }); + } // check if user was authorized for the api call - let host = req.headers.host; - let authorization = req.headers.authorization; - let api = new ServerApi(host, authorization); + const { host, authorization } = req.headers; + const api = new ServerApi(host, authorization); + if (!api.isAuthorized()) { + log.debug('MiroTalk get meetings - Unauthorized', { + header: req.headers, + body: req.body, + }); + return res.status(403).json({ error: 'Unauthorized!' }); + } + const meetings = Array.from(roomList.entries()).map(([id, room]) => { + const peers = Array.from(room.peers.values()).map((peer) => ({ + name: peer.peer_info.peer_name, + presenter: peer.peer_info.peer_presenter, + video: peer.peer_info.peer_video, + audio: peer.peer_info.peer_audio, + screen: peer.peer_info.peer_screen, + hand: peer.peer_info.peer_hand, + os: peer.peer_info.os_name ? `${peer.peer_info.os_name} ${peer.peer_info.os_version}` : '', + browser: peer.peer_info.browser_name + ? `${peer.peer_info.browser_name} ${peer.peer_info.browser_version}` + : '', + })); + return { + roomId: id, + peers: peers, + }; + }); + res.json({ meetings: meetings }); + // log.debug the output if all done + log.debug('MiroTalk get meetings - Authorized', { + header: req.headers, + body: req.body, + meetings: meetings, + }); + }); + + // request meeting room endpoint + app.post([restApi.basePath + '/meeting'], (req, res) => { + // Check if endpoint allowed + if (restApi.allowed && !restApi.allowed.meeting) { + return res + .status(403) + .json({ + error: 'This endpoint has been disabled. Please contact the administrator for further information.', + }); + } + // check if user was authorized for the api call + const { host, authorization } = req.headers; + const api = new ServerApi(host, authorization); if (!api.isAuthorized()) { log.debug('MiroTalk get meeting - Unauthorized', { header: req.headers, @@ -501,8 +558,7 @@ function startServer() { } // setup meeting URL let meetingURL = api.getMeetingURL(); - res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ meeting: meetingURL })); + res.json({ meeting: meetingURL }); // log.debug the output if all done log.debug('MiroTalk get meeting - Authorized', { header: req.headers, @@ -512,11 +568,18 @@ function startServer() { }); // request join room endpoint - app.post(['/api/v1/join'], (req, res) => { + app.post([restApi.basePath + '/join'], (req, res) => { + // Check if endpoint allowed + if (restApi.allowed && !restApi.allowed.join) { + return res + .status(403) + .json({ + error: 'This endpoint has been disabled. Please contact the administrator for further information.', + }); + } // check if user was authorized for the api call - let host = req.headers.host; - let authorization = req.headers.authorization; - let api = new ServerApi(host, authorization); + const { host, authorization } = req.headers; + const api = new ServerApi(host, authorization); if (!api.isAuthorized()) { log.debug('MiroTalk get join - Unauthorized', { header: req.headers, @@ -526,8 +589,7 @@ function startServer() { } // setup Join URL let joinURL = api.getJoinURL(req.body); - res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ join: joinURL })); + res.json({ join: joinURL }); // log.debug the output if all done log.debug('MiroTalk get join - Authorized', { header: req.headers, @@ -593,7 +655,7 @@ function startServer() { announcedAddress: announcedAddress, server: host, server_tunnel: tunnel, - api_docs: api_docs, + rest_api: restApi, mediasoup_worker_bin: mediasoup.workerBin, mediasoup_server_version: mediasoup.version, mediasoup_client_version: mediasoupClient.version, @@ -644,7 +706,7 @@ function startServer() { middleware: config.middleware, announcedAddress: announcedAddress, server: host, - api_docs: api_docs, + rest_api: restApi, mediasoup_worker_bin: mediasoup.workerBin, mediasoup_server_version: mediasoup.version, mediasoup_client_version: mediasoupClient.version, diff --git a/app/src/config.template.js b/app/src/config.template.js index a23be9c4..6bad141c 100644 --- a/app/src/config.template.js +++ b/app/src/config.template.js @@ -196,8 +196,15 @@ module.exports = { authToken: '', }, api: { - // app/api + // Default secret key for app/api keySecret: 'mirotalksfu_default_secret', + // Define which endpoints are allowed + allowed: { + meetings: false, + meeting: true, + join: true, + //... + }, }, sentry: { /* diff --git a/package.json b/package.json index efe1212c..21b3effb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mirotalksfu", - "version": "1.3.68", + "version": "1.3.69", "description": "WebRTC SFU browser-based video calls", "main": "Server.js", "scripts": { diff --git a/public/js/Room.js b/public/js/Room.js index 6686c706..ea712723 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.68 + * @version 1.3.69 * */ diff --git a/public/js/RoomClient.js b/public/js/RoomClient.js index 41390969..e2a23198 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.68 + * @version 1.3.69 * */ @@ -3689,12 +3689,6 @@ class RoomClient { ${getMsg}