From f9264b5171acc2d07bf853d68634e8101eee931b Mon Sep 17 00:00:00 2001 From: Miroslav Pejic Date: Mon, 18 Mar 2024 09:31:09 +0100 Subject: [PATCH] [mirotalk] - add token api endpoint --- README.md | 32 +++++++++++++++------------ app/api/README.md | 4 ++++ app/api/swagger.yaml | 48 ++++++++++++++++++++++++++++++++++++++++- app/api/token/token.js | 36 +++++++++++++++++++++++++++++++ app/api/token/token.php | 37 +++++++++++++++++++++++++++++++ app/api/token/token.py | 31 ++++++++++++++++++++++++++ app/api/token/token.sh | 11 ++++++++++ app/src/server.js | 25 ++++++++++++++++++++- package.json | 2 +- public/js/client.js | 2 +- 10 files changed, 210 insertions(+), 18 deletions(-) create mode 100644 app/api/token/token.js create mode 100644 app/api/token/token.php create mode 100644 app/api/token/token.py create mode 100755 app/api/token/token.sh diff --git a/README.md b/README.md index 2fc9f739..6302842a 100644 --- a/README.md +++ b/README.md @@ -211,20 +211,24 @@ $ docker-compose down - `Rest API:` The [API documentation](https://docs.mirotalk.com/mirotalk-p2p/api/) uses [swagger](https://swagger.io/) at http://localhost:3000/api/v1/docs. Or check it out on [live](https://p2p.mirotalk.com/api/v1/docs). - ```bash - # The response will give you a entrypoint / Room URL for your meeting. - $ curl -X POST "http://localhost:3000/api/v1/meeting" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" - $ curl -X POST "https://p2p.mirotalk.com/api/v1/meeting" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" - $ curl -X POST "https://mirotalk.up.railway.app/api/v1/meeting" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" - # The response will give you a entrypoint / URL for the direct join to the meeting. - $ curl -X POST "http://localhost:3000/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true"}' - $ curl -X POST "https://p2p.mirotalk.com/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true"}' - $ curl -X POST "https://mirotalk.up.railway.app/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true"}' - # The response will give you an entry point/URL for direct joining to the meeting with a token. - $ curl -X POST "http://localhost:3000/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true","token":{"username":"username","password":"password","presenter":"true", "expire":"1h"}}' - $ curl -X POST "https://p2p.mirotalk.com/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true","token":{"username":"username","password":"password","presenter":"true", "expire":"1h"}}' - $ curl -X POST "https://mirotalk.up.railway.app/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true","token":{"username":"username","password":"password","presenter":"true", "expire":"1h"}}' - ``` +```bash +# The response will give you a entrypoint / Room URL for your meeting. +$ curl -X POST "http://localhost:3000/api/v1/meeting" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" +$ curl -X POST "https://p2p.mirotalk.com/api/v1/meeting" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" +$ curl -X POST "https://mirotalk.up.railway.app/api/v1/meeting" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" +# The response will give you a entrypoint / URL for the direct join to the meeting. +$ curl -X POST "http://localhost:3000/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true"}' +$ curl -X POST "https://p2p.mirotalk.com/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true"}' +$ curl -X POST "https://mirotalk.up.railway.app/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true"}' +# The response will give you an entry point/URL for direct joining to the meeting with a token. +$ curl -X POST "http://localhost:3000/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true","token":{"username":"username","password":"password","presenter":"true", "expire":"1h"}}' +$ curl -X POST "https://p2p.mirotalk.com/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true","token":{"username":"username","password":"password","presenter":"true", "expire":"1h"}}' +$ curl -X POST "https://mirotalk.up.railway.app/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"room":"test","name":"mirotalk","audio":"true","video":"true","screen":"false","hide":"false","notify":"true","token":{"username":"username","password":"password","presenter":"true", "expire":"1h"}}' +# The response will give you a valid token for a meeting. +$ curl -X POST "http://localhost:3000/api/v1/token" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"username":"username","password":"password","presenter":"true", "expire":"1h"}' +$ curl -X POST "https://p2p.mirotalk.com/api/v1/token" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"username":"username","password":"password","presenter":"true", "expire":"1h"}' +$ curl -X POST "https://mirotalk.up.railway.app/api/v1/join" -H "authorization: mirotalkp2p_default_secret" -H "Content-Type: application/json" --data '{"username":"username","password":"password","presenter":"true", "expire":"1h"}' +``` diff --git a/app/api/README.md b/app/api/README.md index 6751339a..272e394c 100644 --- a/app/api/README.md +++ b/app/api/README.md @@ -14,18 +14,22 @@ Use the following examples to make API calls: # Node.js node meeting.js node join.js +node token.js # PHP php meeting.php php join.php +php token.php # Python python3 meeting.py python3 join.py +python3 token.py # rename token in something else # Bash ./meeting.sh ./join.sh +./token.sh ``` The server response will contain a meeting URL that can be embedded in your client using an iframe. diff --git a/app/api/swagger.yaml b/app/api/swagger.yaml index e097af7c..ff462eda 100644 --- a/app/api/swagger.yaml +++ b/app/api/swagger.yaml @@ -3,7 +3,7 @@ swagger: '2.0' info: title: MiroTalk P2P API description: API description for external applications that integrates with MiroTalk P2P. - version: 1.0.0 + version: 1.0.1 basePath: /api/v1 @@ -98,6 +98,32 @@ paths: '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: type: 'apiKey' @@ -116,3 +142,23 @@ definitions: properties: join: type: 'string' + TokenRequest: + type: object + properties: + username: + type: string + default: 'username' + password: + type: string + default: 'password' + presenter: + type: boolean + default: true + expire: + type: string + default: '1h' + TokenResponse: + type: 'object' + properties: + token: + type: string diff --git a/app/api/token/token.js b/app/api/token/token.js new file mode 100644 index 00000000..ba66d17c --- /dev/null +++ b/app/api/token/token.js @@ -0,0 +1,36 @@ +'use strict'; + +async function getToken() { + try { + // Use dynamic import with await + const { default: fetch } = await import('node-fetch'); + + const API_KEY_SECRET = 'mirotalkp2p_default_secret'; + const MIROTALK_URL = 'https://p2p.mirotalk.com/api/v1/token'; + //const MIROTALK_URL = 'http://localhost:3000/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); + } +} + +getToken(); diff --git a/app/api/token/token.php b/app/api/token/token.php new file mode 100644 index 00000000..4cefd6a8 --- /dev/null +++ b/app/api/token/token.php @@ -0,0 +1,37 @@ + "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"; diff --git a/app/api/token/token.py b/app/api/token/token.py new file mode 100644 index 00000000..49fb6f04 --- /dev/null +++ b/app/api/token/token.py @@ -0,0 +1,31 @@ +# pip3 install requests +# rename token.py in get_token.py + +import requests +import json + +API_KEY_SECRET = "mirotalkp2p_default_secret" +MIROTALK_URL = "https://p2p.mirotalk.com/api/v1/token" +#MIROTALK_URL = "http://localhost:3000/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"]) diff --git a/app/api/token/token.sh b/app/api/token/token.sh new file mode 100755 index 00000000..5c130e91 --- /dev/null +++ b/app/api/token/token.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +API_KEY_SECRET="mirotalkp2p_default_secret" +MIROTALK_URL="https://p2p.mirotalk.com/api/v1/token" +#MIROTALK_URL="http://localhost:3000/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 \ No newline at end of file diff --git a/app/src/server.js b/app/src/server.js index c7fbb275..f784b052 100755 --- a/app/src/server.js +++ b/app/src/server.js @@ -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.3.03 + * @version 1.3.04 * */ @@ -523,6 +523,29 @@ app.post(['/login'], (req, res) => { For api docs we use: https://swagger.io/ */ +// request token endpoint +app.post([`${apiBasePath}/token`], (req, res) => { + // check if user was authorized for the api call + const { host, authorization } = req.headers; + const api = new ServerApi(host, authorization, api_key_secret); + 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, + }); +}); + // API request meeting room endpoint app.post([`${apiBasePath}/meeting`], (req, res) => { const { host, authorization } = req.headers; diff --git a/package.json b/package.json index ec2ffe3f..c34129ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mirotalk", - "version": "1.3.03", + "version": "1.3.04", "description": "A free WebRTC browser-based video call", "main": "server.js", "scripts": { diff --git a/public/js/client.js b/public/js/client.js index 54c43fe2..6999effc 100644 --- a/public/js/client.js +++ b/public/js/client.js @@ -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.3.03 + * @version 1.3.04 * */