[mirotalksfu] - improve restAPI and docs

هذا الالتزام موجود في:
Miroslav Pejic
2024-02-16 17:23:39 +01:00
الأصل 28158e77f8
التزام 01db0bec7c
11 ملفات معدلة مع 304 إضافات و78 حذوفات

عرض الملف

@@ -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
```

عرض الملف

@@ -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();

عرض الملف

@@ -0,0 +1,29 @@
<?php
$API_KEY_SECRET = "mirotalksfu_default_secret";
$MIROTALK_URL = "https://sfu.mirotalk.com/api/v1/meetings";
//$MIROTALK_URL = "http://localhost:3010/api/v1/meetings";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $MIROTALK_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPGET, true);
$headers = [
'authorization:' . $API_KEY_SECRET,
'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "Status code: $httpcode \n";
if ($response) {
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
} else {
echo "Failed to retrieve data.\n";
}

عرض الملف

@@ -0,0 +1,26 @@
# pip3 install requests
import requests
import json
API_KEY_SECRET = "mirotalksfu_default_secret"
MIROTALK_URL = "https://sfu.mirotalk.com/api/v1/meetings"
#MIROTALK_URL = "http://localhost:3010/api/v1/meetings"
headers = {
"authorization": API_KEY_SECRET,
"Content-Type": "application/json",
}
response = requests.get(
MIROTALK_URL,
headers=headers
)
print("Status code:", response.status_code)
if response.status_code == 200:
data = response.json()
pretty_printed_data = json.dumps(data, indent=4)
print(data)
else:
print("Failed to retrieve data. Error:", response.text)

10
app/api/meetings/meetings.sh Executable file
عرض الملف

@@ -0,0 +1,10 @@
#!/bin/bash
API_KEY_SECRET="mirotalksfu_default_secret"
MIROTALK_URL="https://sfu.mirotalk.com/api/v1/meetings"
#MIROTALK_URL="http://localhost:3010/api/v1/meetings"
curl $MIROTALK_URL \
--header "authorization: $API_KEY_SECRET" \
--header "Content-Type: application/json" \
--request GET

عرض الملف

@@ -2,8 +2,8 @@ swagger: '2.0'
info:
title: MiroTalk SFU API
description: API description for external applications that integrates with MiroTalk SFU.
version: 1.0.0
description: API description for external applications that integrate with MiroTalk SFU.
version: 1.0.1
basePath: /api/v1
@@ -12,6 +12,23 @@ schemes:
- http
paths:
/meetings:
get:
tags:
- 'meetings'
summary: 'Get meetings'
description: 'Get meetings'
produces:
- 'application/json'
security:
- secretApiKey: []
responses:
'200':
description: 'Get Meetings done'
schema:
$ref: '#/definitions/MeetingsResponse'
'403':
description: 'Unauthorized!'
/meeting:
post:
tags:
@@ -42,50 +59,7 @@ paths:
name: Join
description: Custom Join URL.
schema:
type: object
properties:
room:
type: string
default: 'test'
roomPassword:
type: ['boolean', 'string'] # Allow boolean or string type
default: false
name:
type: string
default: 'mirotalksfu'
audio:
type: boolean
default: false
video:
type: boolean
default: false
screen:
type: boolean
default: false
hide:
type: boolean
default: false
notify:
type: boolean
default: false
token:
type: object
description: |
Object containing authentication token details.
This token is required when host.protected or host.user_auth is enabled in the app/src/config.js file.
properties:
username:
type: string
default: 'username'
password:
type: string
default: 'password'
presenter:
type: boolean
default: true
expire:
type: string
default: '1h'
$ref: '#/definitions/JoinRequest'
consumes:
- 'application/json'
produces:
@@ -108,13 +82,93 @@ securityDefinitions:
description: 'Format like this: authorization: {API_KEY_SECRET}'
definitions:
MeetingsResponse:
type: object
properties:
meetings:
type: array
items:
$ref: '#/definitions/Meeting'
MeetingResponse:
type: 'object'
properties:
meeting:
type: 'string'
type: string
JoinRequest:
type: object
properties:
room:
type: string
default: 'test'
roomPassword:
type: ['boolean', 'string'] # Allow boolean or string type
default: false
name:
type: string
default: 'mirotalksfu'
audio:
type: boolean
default: false
video:
type: boolean
default: false
screen:
type: boolean
default: false
hide:
type: boolean
default: false
notify:
type: boolean
default: false
token:
$ref: '#/definitions/TokenRequest'
TokenRequest:
type: object
properties:
username:
type: string
default: 'username'
password:
type: string
default: 'password'
presenter:
type: boolean
default: true
expire:
type: string
default: '1h'
JoinResponse:
type: 'object'
properties:
join:
type: 'string'
type: string
Peer:
type: object
properties:
name:
type: string
presenter:
type: boolean
video:
type: boolean
audio:
type: boolean
screen:
type: boolean
hand:
type: boolean
os:
type: string
browser:
type: string
Meeting:
type: object
properties:
roomId:
type: string
peers:
type: array
items:
$ref: '#/definitions/Peer'

عرض الملف

@@ -41,7 +41,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.68
* @version 1.3.69
*
*/
@@ -106,8 +106,11 @@ const hostCfg = {
authenticated: !config.host.protected,
};
const apiBasePath = '/api/v1'; // api endpoint path
const api_docs = host + apiBasePath + '/docs'; // api docs
const restApi = {
basePath: '/api/v1', // api endpoint path
docs: host + '/api/v1/docs', // api docs
allowed: config.api?.allowed,
};
// Sentry monitoring
const sentryEnabled = config.sentry.enabled;
@@ -220,7 +223,7 @@ function startServer() {
app.use(express.json());
app.use(express.static(dir.public));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(apiBasePath + '/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); // api docs
app.use(restApi.basePath + '/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); // api docs
// IP Whitelist check ...
app.use(restrictAccessByIP);
@@ -483,15 +486,69 @@ function startServer() {
});
// ####################################################
// API
// REST API
// ####################################################
// request meeting room endpoint
app.post(['/api/v1/meeting'], (req, res) => {
// 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,

عرض الملف

@@ -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: {
/*