[mirotalksfu] - add token endpoint
هذا الالتزام موجود في:
@@ -73,6 +73,31 @@ paths:
|
||||
$ref: '#/definitions/JoinResponse'
|
||||
'403':
|
||||
description: 'Unauthorized!'
|
||||
/token:
|
||||
post:
|
||||
tags:
|
||||
- 'token'
|
||||
summary: 'Get token'
|
||||
description: 'Get token'
|
||||
parameters:
|
||||
- in: body
|
||||
name: token
|
||||
description: Custom Token.
|
||||
schema:
|
||||
$ref: '#/definitions/TokenRequest'
|
||||
consumes:
|
||||
- 'application/json'
|
||||
produces:
|
||||
- 'application/json'
|
||||
security:
|
||||
- secretApiKey: []
|
||||
responses:
|
||||
'200':
|
||||
description: 'Get token done'
|
||||
schema:
|
||||
$ref: '#/definitions/TokenResponse'
|
||||
'403':
|
||||
description: 'Unauthorized!'
|
||||
|
||||
securityDefinitions:
|
||||
secretApiKey:
|
||||
@@ -143,6 +168,11 @@ definitions:
|
||||
properties:
|
||||
join:
|
||||
type: string
|
||||
TokenResponse:
|
||||
type: 'object'
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
Peer:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
36
app/api/token/token.js
Normal file
36
app/api/token/token.js
Normal file
@@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
async function getMeeting() {
|
||||
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/token';
|
||||
//const MIROTALK_URL = 'http://localhost:3010/api/v1/token';
|
||||
|
||||
const response = await fetch(MIROTALK_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
authorization: API_KEY_SECRET,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
presenter: true,
|
||||
expire: '1h',
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data.error) {
|
||||
console.log('Error:', data.error);
|
||||
} else {
|
||||
console.log('token:', data.token);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
}
|
||||
}
|
||||
|
||||
getMeeting();
|
||||
37
app/api/token/token.php
Normal file
37
app/api/token/token.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
$API_KEY_SECRET = "mirotalksfu_default_secret";
|
||||
$MIROTALK_URL = "https://sfu.mirotalk.com/api/v1/token";
|
||||
#$MIROTALK_URL = "http://localhost:3010/api/v1/token";
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $MIROTALK_URL);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
|
||||
$headers = [
|
||||
'authorization:' . $API_KEY_SECRET,
|
||||
'Content-Type: application/json'
|
||||
];
|
||||
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
$data = array(
|
||||
"username" => "username",
|
||||
"password" => "password",
|
||||
"presenter" => true,
|
||||
"expire" => "1h",
|
||||
);
|
||||
|
||||
$data_string = json_encode($data);
|
||||
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
echo "Status code: $httpcode \n";
|
||||
$data = json_decode($response);
|
||||
echo "token: ", $data->{'token'}, "\n";
|
||||
29
app/api/token/token.py
Normal file
29
app/api/token/token.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# pip3 install requests
|
||||
import requests
|
||||
import json
|
||||
|
||||
API_KEY_SECRET = "mirotalksfu_default_secret"
|
||||
MIROTALK_URL = "https://sfu.mirotalk.com/api/v1/token"
|
||||
#MIROTALK_URL = "http://localhost:3010/api/v1/token"
|
||||
|
||||
headers = {
|
||||
"authorization": API_KEY_SECRET,
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
data = {
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"presenter": "true",
|
||||
"expire": "1h"
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
MIROTALK_URL,
|
||||
headers=headers,
|
||||
json=data
|
||||
)
|
||||
|
||||
print("Status code:", response.status_code)
|
||||
data = json.loads(response.text)
|
||||
print("token:", data["token"])
|
||||
11
app/api/token/token.sh
Executable file
11
app/api/token/token.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
API_KEY_SECRET="mirotalksfu_default_secret"
|
||||
MIROTALK_URL="https://sfu.mirotalk.com/api/v1/token"
|
||||
#MIROTALK_URL="http://localhost:3010/api/v1/token"
|
||||
|
||||
curl $MIROTALK_URL \
|
||||
--header "authorization: $API_KEY_SECRET" \
|
||||
--header "Content-Type: application/json" \
|
||||
--data '{"username":"username","password":"password","presenter":"true", "expire":"1h"}' \
|
||||
--request POST
|
||||
@@ -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.75
|
||||
* @version 1.3.76
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -579,7 +579,7 @@ function startServer() {
|
||||
return res.status(403).json({ error: 'Unauthorized!' });
|
||||
}
|
||||
// setup meeting URL
|
||||
let meetingURL = api.getMeetingURL();
|
||||
const meetingURL = api.getMeetingURL();
|
||||
res.json({ meeting: meetingURL });
|
||||
// log.debug the output if all done
|
||||
log.debug('MiroTalk get meeting - Authorized', {
|
||||
@@ -608,7 +608,7 @@ function startServer() {
|
||||
return res.status(403).json({ error: 'Unauthorized!' });
|
||||
}
|
||||
// setup Join URL
|
||||
let joinURL = api.getJoinURL(req.body);
|
||||
const joinURL = api.getJoinURL(req.body);
|
||||
res.json({ join: joinURL });
|
||||
// log.debug the output if all done
|
||||
log.debug('MiroTalk get join - Authorized', {
|
||||
@@ -618,6 +618,35 @@ function startServer() {
|
||||
});
|
||||
});
|
||||
|
||||
// request token endpoint
|
||||
app.post([restApi.basePath + '/token'], (req, res) => {
|
||||
// Check if endpoint allowed
|
||||
if (restApi.allowed && !restApi.allowed.token) {
|
||||
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 token - Unauthorized', {
|
||||
header: req.headers,
|
||||
body: req.body,
|
||||
});
|
||||
return res.status(403).json({ error: 'Unauthorized!' });
|
||||
}
|
||||
// Get Token
|
||||
const token = api.getToken(req.body);
|
||||
res.json({ token: token });
|
||||
// log.debug the output if all done
|
||||
log.debug('MiroTalk get token - Authorized', {
|
||||
header: req.headers,
|
||||
body: req.body,
|
||||
token: token,
|
||||
});
|
||||
});
|
||||
|
||||
// ####################################################
|
||||
// SLACK API
|
||||
// ####################################################
|
||||
|
||||
@@ -28,49 +28,46 @@ module.exports = class ServerApi {
|
||||
const { room, roomPassword, name, audio, video, screen, notify, token } = data;
|
||||
|
||||
const roomValue = room || uuidV4();
|
||||
const roomPasswordValue = roomPassword || false;
|
||||
const nameValue = name || 'User-' + this.getRandomNumber();
|
||||
const roomPasswordValue = roomPassword || false;
|
||||
const audioValue = audio || false;
|
||||
const videoValue = video || false;
|
||||
const screenValue = screen || false;
|
||||
const notifyValue = notify || false;
|
||||
const jwtToken = token ? '&token=' + this.getToken(token) : '';
|
||||
|
||||
let jwtToken = '';
|
||||
|
||||
if (token) {
|
||||
// JWT.io
|
||||
const { username, password, presenter, expire } = token;
|
||||
|
||||
const usernameValue = username || 'username';
|
||||
const passwordValue = password || 'password';
|
||||
const presenterValue = String(presenter);
|
||||
const expireValue = expire || JWT_EXP;
|
||||
|
||||
jwtToken =
|
||||
'&token=' +
|
||||
jwt.sign({ username: usernameValue, password: passwordValue, presenter: presenterValue }, JWT_KEY, {
|
||||
expiresIn: expireValue,
|
||||
});
|
||||
}
|
||||
return (
|
||||
const joinURL =
|
||||
'https://' +
|
||||
this._host +
|
||||
'/join?room=' +
|
||||
roomValue +
|
||||
'&roomPassword=' +
|
||||
roomPasswordValue +
|
||||
'&name=' +
|
||||
nameValue +
|
||||
'&audio=' +
|
||||
audioValue +
|
||||
'&video=' +
|
||||
videoValue +
|
||||
'&screen=' +
|
||||
screenValue +
|
||||
'¬ify=' +
|
||||
notifyValue +
|
||||
jwtToken
|
||||
);
|
||||
'/join?' +
|
||||
`room=${roomValue}` +
|
||||
`&roomPassword=${roomPasswordValue}` +
|
||||
`&name=${encodeURIComponent(nameValue)}` +
|
||||
`&audio=${audioValue}` +
|
||||
`&video=${videoValue}` +
|
||||
`&screen=${screenValue}` +
|
||||
`¬ify=${notifyValue}` +
|
||||
jwtToken;
|
||||
|
||||
return joinURL;
|
||||
}
|
||||
|
||||
getToken(token) {
|
||||
if (!token) return '';
|
||||
|
||||
const { username = 'username', password = 'password', presenter = false, expire } = token;
|
||||
|
||||
const expireValue = expire || JWT_EXP;
|
||||
|
||||
const payload = {
|
||||
username: String(username),
|
||||
password: String(password),
|
||||
presenter: String(presenter),
|
||||
};
|
||||
|
||||
const jwtToken = jwt.sign(payload, JWT_KEY, { expiresIn: expireValue });
|
||||
|
||||
return jwtToken;
|
||||
}
|
||||
|
||||
getRandomNumber() {
|
||||
|
||||
@@ -219,6 +219,7 @@ module.exports = {
|
||||
meetings: false,
|
||||
meeting: true,
|
||||
join: true,
|
||||
token: true,
|
||||
//...
|
||||
},
|
||||
},
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم