diff --git a/advanced-features/openvidu-js-screen-share/LICENSE b/advanced-features/openvidu-js-screen-share/LICENSE deleted file mode 100644 index 8dada3ed..00000000 --- a/advanced-features/openvidu-js-screen-share/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/advanced-features/openvidu-js-screen-share/README.md b/advanced-features/openvidu-js-screen-share/README.md deleted file mode 100644 index bfc48190..00000000 --- a/advanced-features/openvidu-js-screen-share/README.md +++ /dev/null @@ -1,14 +0,0 @@ -[![License badge](https://img.shields.io/badge/license-Apache2-orange.svg)](http://www.apache.org/licenses/LICENSE-2.0) -[![OpenVidu Tests](https://github.com/OpenVidu/openvidu/actions/workflows/openvidu-ce-test.yml/badge.svg)](https://github.com/OpenVidu/openvidu/actions/workflows/openvidu-ce-test.yml) -[![Documentation Status](https://readthedocs.org/projects/openviduio-docs/badge/?version=stable)](https://docs.openvidu.io/en/stable/?badge=stable) -[![Docker badge](https://img.shields.io/docker/pulls/openvidu/openvidu-server-kms.svg)](https://hub.docker.com/r/openvidu/openvidu-server-kms) -[![Support badge](https://img.shields.io/badge/support-sof-yellowgreen.svg)](https://openvidu.discourse.group/) - -[![][OpenViduLogo]](http://openvidu.io) - -openvidu-js-screen-share -=== - -Visit [docs.openvidu.io/en/stable/tutorials/openvidu-js-screen-share/](http://docs.openvidu.io/en/stable/tutorials/openvidu-js-screen-share/) - -[OpenViduLogo]: https://secure.gravatar.com/avatar/5daba1d43042f2e4e85849733c8e5702?s=120 diff --git a/advanced-features/openvidu-js-screen-share/docker/Dockerfile b/advanced-features/openvidu-js-screen-share/docker/Dockerfile deleted file mode 100644 index 38dde55a..00000000 --- a/advanced-features/openvidu-js-screen-share/docker/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM node:16-alpine3.16 - -# Copy openvidu-basic-node -COPY ./openvidu-basic-node /opt/openvidu-basic-node - -# Install openvidu-basic-node dependencies -RUN npm --prefix /opt/openvidu-basic-node install - -# Copy static files to openvidu-basic-node -RUN mkdir -p /opt/openvidu-basic-node/public -COPY ./web /opt/openvidu-basic-node/public - -WORKDIR /opt/openvidu-basic-node - -COPY docker/entrypoint.sh . - -ENTRYPOINT [ "./entrypoint.sh" ] \ No newline at end of file diff --git a/advanced-features/openvidu-js-screen-share/docker/create_image.sh b/advanced-features/openvidu-js-screen-share/docker/create_image.sh deleted file mode 100644 index e7a4949f..00000000 --- a/advanced-features/openvidu-js-screen-share/docker/create_image.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -if [ $# -eq 0 ]; then - echo "No version argument provided. Usage: \"./create_image.sh \"" - exit 1 -fi - -pushd ../ - -cp -r ../openvidu-basic-node . - -trap 'rm -rf ./openvidu-basic-node' ERR - -docker build --pull --no-cache --rm=true -f docker/Dockerfile -t "$1" . - -rm -rf ./openvidu-basic-node \ No newline at end of file diff --git a/advanced-features/openvidu-js-screen-share/docker/entrypoint.sh b/advanced-features/openvidu-js-screen-share/docker/entrypoint.sh deleted file mode 100644 index aba13997..00000000 --- a/advanced-features/openvidu-js-screen-share/docker/entrypoint.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -if [ -n "${OPENVIDU_APPLICATION_SERVER_URL}" ]; then - # Replace OPENVIDU_APPLICATION_SERVER_URL at frontend app - sed -i \ - "s|var APPLICATION_SERVER_URL = \"http://localhost:5000/\";|var APPLICATION_SERVER_URL = \"${OPENVIDU_APPLICATION_SERVER_URL}/\";|" \ - public/app.js -else - sed -i \ - "s|var APPLICATION_SERVER_URL = \"http://localhost:5000/\";|var APPLICATION_SERVER_URL = \"\";|" \ - public/app.js -fi - -exec node index.js "$*" \ No newline at end of file diff --git a/advanced-features/openvidu-js-screen-share/nginx.conf b/advanced-features/openvidu-js-screen-share/nginx.conf deleted file mode 100644 index b9bee005..00000000 --- a/advanced-features/openvidu-js-screen-share/nginx.conf +++ /dev/null @@ -1,52 +0,0 @@ -events { - worker_connections 512; -} -http { - upstream openvidu-deployment { - server host.docker.internal:4443; - } - upstream server-application { - server host.docker.internal:5000; - } - upstream client-application { - server host.docker.internal:8080; - } - server { - listen 443 ssl; - ssl_certificate /etc/nginx/certs/cert.pem; - ssl_certificate_key /etc/nginx/certs/key.pem; - - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Proto https; - proxy_headers_hash_bucket_size 512; - proxy_redirect off; - - # Websockets - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # OpenVidu deployment API - location /openvidu/api { - proxy_pass http://openvidu-deployment; - } - - # OpenVidu WebSocket - location ~ /openvidu$ { - proxy_pass http://openvidu-deployment; - } - - # Server application requests - location /api/ { - proxy_pass http://server-application; - } - - # Client application requests - location / { - proxy_pass http://client-application; - } - } -} \ No newline at end of file diff --git a/advanced-features/openvidu-js-screen-share/web/app.js b/advanced-features/openvidu-js-screen-share/web/app.js deleted file mode 100644 index 045aa284..00000000 --- a/advanced-features/openvidu-js-screen-share/web/app.js +++ /dev/null @@ -1,263 +0,0 @@ -var LivekitClient = window.LivekitClient; -var room; -var myUserName; -var myRoomName; -var isScreenShared = false; -var screenSharePublication; - -/* OPENVIDU METHODS */ - -function joinRoom() { - myRoomName = document.getElementById('roomName').value; - myUserName = document.getElementById('userName').value; - - // --- 1) Get a Room object --- - - room = new LivekitClient.Room(); - - // --- 2) Specify the actions when events take place in the room --- - - // On every new Track received... - room.on( - LivekitClient.RoomEvent.TrackSubscribed, - (track, publication, participant) => { - const element = track.attach(); - element.id = track.sid; - element.className = 'removable'; - document.getElementById('video-container').appendChild(element); - if (track.kind === 'video' || track.kind === 'screen') { - appendUserData(element, participant.identity); - } - } - ); - - // On every new Track destroyed... - room.on( - LivekitClient.RoomEvent.TrackUnsubscribed, - (track, publication, participant) => { - track.detach(); - document.getElementById(track.sid)?.remove(); - if (track.kind === 'video' || track.kind === 'screen') { - removeUserData(participant); - } - } - ); - - // --- 3) Connect to the room with a valid access token --- - - // Get a token from the application backend - getToken(myRoomName, myUserName).then((token) => { - const livekitUrl = getLivekitUrlFromMetadata(token); - - // First param is the LiveKit server URL. Second param is the access token - room - .connect(livekitUrl, token) - .then(() => { - // --- 4) Set page layout for active call --- - - document.getElementById('room-title').innerText = myRoomName; - document.getElementById('join').style.display = 'none'; - document.getElementById('room').style.display = 'block'; - - // --- 5) Publish your local tracks --- - - room.localParticipant.setMicrophoneEnabled(true); - room.localParticipant.setCameraEnabled(true).then((publication) => { - const element = publication.track.attach(); - document.getElementById('video-container').appendChild(element); - initMainVideo(element, myUserName); - appendUserData(element, myUserName); - element.className = 'removable'; - }); - }) - .catch((error) => { - console.log( - 'There was an error connecting to the room:', - error.code, - error.message - ); - }); - }); -} - -function leaveRoom() { - // --- 6) Leave the room by calling 'disconnect' method over the Room object --- - - room.disconnect(); - - // Removing all HTML elements with user's nicknames. - // HTML videos are automatically removed when leaving a Room - removeAllUserData(); - - // Back to 'Join room' page - document.getElementById('join').style.display = 'block'; - document.getElementById('room').style.display = 'none'; -} - -async function toggleScreenShare() { - console.log('Toggling screen share'); - const enabled = !isScreenShared; - - if (enabled) { - // Enable screen sharing - try { - screenSharePublication = - await room.localParticipant?.setScreenShareEnabled(enabled); - } catch (error) { - console.error('Error enabling screen sharing', error); - } - - if (screenSharePublication) { - console.log('Screen sharing enabled', screenSharePublication); - isScreenShared = enabled; - - // Attach the screen share track to the video container - const element = screenSharePublication.track.attach(); - element.id = screenSharePublication.trackSid; - element.className = 'removable'; - document.getElementById('video-container').appendChild(element); - - // Add user data for the screen share - appendUserData(element, `${myUserName}_SCREEN`); - - // Listen for the 'ended' event to handle screen sharing stop - screenSharePublication.addListener('ended', async () => { - console.debug('Clicked native stop button. Stopping screen sharing'); - await stopScreenSharing(); - }); - } - } else { - // Disable screen sharing - await stopScreenSharing(); - } -} - -async function stopScreenSharing() { - try { - await room.localParticipant?.setScreenShareEnabled(false); - isScreenShared = false; - const trackSid = screenSharePublication?.trackSid; - - if (trackSid) { - document.getElementById(trackSid)?.remove(); - removeUserData({ identity: `${myUserName}_SCREEN` }); - } - screenSharePublication = undefined; - } catch (error) { - console.error('Error stopping screen sharing', error); - } -} - -window.onbeforeunload = function () { - if (room) room.disconnect(); -}; - -/* APPLICATION SPECIFIC METHODS */ - -window.addEventListener('load', function () { - generateParticipantInfo(); -}); - -function generateParticipantInfo() { - document.getElementById('roomName').value = 'RoomA'; - document.getElementById('userName').value = - 'Participant' + Math.floor(Math.random() * 100); -} - -function appendUserData(videoElement, participantIdentity) { - var dataNode = document.createElement('div'); - dataNode.className = 'removable'; - dataNode.id = 'data-' + participantIdentity; - dataNode.innerHTML = '

' + participantIdentity + '

'; - videoElement.parentNode.insertBefore(dataNode, videoElement.nextSibling); - addClickListener(videoElement, participantIdentity); -} - -function removeUserData(participant) { - var dataNode = document.getElementById('data-' + participant.identity); - dataNode?.parentNode.removeChild(dataNode); -} - -function removeAllUserData() { - var elementsToRemove = document.getElementsByClassName('removable'); - while (elementsToRemove[0]) { - elementsToRemove[0].parentNode.removeChild(elementsToRemove[0]); - } -} - -function addClickListener(videoElement, userData) { - videoElement.addEventListener('click', function () { - var mainVideo = $('#main-video video').get(0); - if (mainVideo.srcObject !== videoElement.srcObject) { - $('#main-video').fadeOut('fast', () => { - $('#main-video p').html(userData); - mainVideo.srcObject = videoElement.srcObject; - $('#main-video').fadeIn('fast'); - }); - } - }); -} - -function initMainVideo(videoElement, userData) { - document.querySelector('#main-video video').srcObject = - videoElement.srcObject; - document.querySelector('#main-video p').innerHTML = userData; - document.querySelector('#main-video video')['muted'] = true; -} - -function getLivekitUrlFromMetadata(token) { - if (!token) throw new Error('Trying to get metadata from an empty token'); - try { - const base64Url = token.split('.')[1]; - const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); - const jsonPayload = decodeURIComponent( - window - .atob(base64) - .split('') - .map((c) => { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }) - .join('') - ); - - const payload = JSON.parse(jsonPayload); - if (!payload?.metadata) throw new Error('Token does not contain metadata'); - const metadata = JSON.parse(payload.metadata); - return metadata.livekitUrl; - } catch (error) { - throw new Error('Error decoding and parsing token: ' + error); - } -} - -/** - * -------------------------------------------- - * GETTING A TOKEN FROM YOUR APPLICATION SERVER - * -------------------------------------------- - * The methods below request the creation of a Token to - * your application server. This keeps your OpenVidu deployment secure. - * - * In this sample code, there is no user control at all. Anybody could - * access your application server endpoints! In a real production - * environment, your application server must identify the user to allow - * access to the endpoints. - * - */ - -var APPLICATION_SERVER_URL = 'http://localhost:5000/'; - -function getToken(roomName, participantName) { - return new Promise((resolve, reject) => { - $.ajax({ - type: 'POST', - url: APPLICATION_SERVER_URL + 'token', - data: JSON.stringify({ - roomName, - participantName, - permissions: {}, - }), - headers: { 'Content-Type': 'application/json' }, - success: (token) => resolve(token), - error: (error) => reject(error), - }); - }); -} diff --git a/advanced-features/openvidu-js-screen-share/web/index.html b/advanced-features/openvidu-js-screen-share/web/index.html deleted file mode 100644 index 49a75717..00000000 --- a/advanced-features/openvidu-js-screen-share/web/index.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - openvidu-js-screen-share - - - - - - - - - - - - - - - - - - - - -
-
-
-
-

Join a video room

-
-

- - -

-

- - -

-

- -

-
-
-
- - -
- - - - - - diff --git a/advanced-features/openvidu-js-screen-share/web/resources/images/favicon.ico b/advanced-features/openvidu-js-screen-share/web/resources/images/favicon.ico deleted file mode 100644 index 0e2249ad..00000000 Binary files a/advanced-features/openvidu-js-screen-share/web/resources/images/favicon.ico and /dev/null differ diff --git a/advanced-features/openvidu-js-screen-share/web/resources/images/openvidu_globe_bg_transp_cropped.png b/advanced-features/openvidu-js-screen-share/web/resources/images/openvidu_globe_bg_transp_cropped.png deleted file mode 100644 index e0309e62..00000000 Binary files a/advanced-features/openvidu-js-screen-share/web/resources/images/openvidu_globe_bg_transp_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-js-screen-share/web/resources/images/openvidu_grey_bg_transp_cropped.png b/advanced-features/openvidu-js-screen-share/web/resources/images/openvidu_grey_bg_transp_cropped.png deleted file mode 100644 index 49f311a6..00000000 Binary files a/advanced-features/openvidu-js-screen-share/web/resources/images/openvidu_grey_bg_transp_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-js-screen-share/web/resources/images/openvidu_vert_white_bg_trans_cropped.png b/advanced-features/openvidu-js-screen-share/web/resources/images/openvidu_vert_white_bg_trans_cropped.png deleted file mode 100644 index a1c8b2d7..00000000 Binary files a/advanced-features/openvidu-js-screen-share/web/resources/images/openvidu_vert_white_bg_trans_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-js-screen-share/web/style.css b/advanced-features/openvidu-js-screen-share/web/style.css deleted file mode 100644 index 23a9cc9e..00000000 --- a/advanced-features/openvidu-js-screen-share/web/style.css +++ /dev/null @@ -1,296 +0,0 @@ -html { - position: relative; - min-height: 100%; -} - -nav { - height: 50px; - width: 100%; - z-index: 1; - background-color: #4d4d4d !important; - border-color: #4d4d4d !important; - border-top-right-radius: 0 !important; - border-top-left-radius: 0 !important; -} - -.navbar-header { - width: 100%; -} - -.nav-icon { - padding: 5px 15px 5px 15px; - float: right; -} - -nav a { - color: #ccc !important; -} - -nav i.fa { - font-size: 40px; - color: #ccc; -} - -nav a:hover { - color: #a9a9a9 !important; -} - -nav i.fa:hover { - color: #a9a9a9; -} - -#main-container { - padding-bottom: 80px; -} - -/*vertical-center { - position: relative; - top: 30%; - left: 50%; - transform: translate(-50%, -50%); -}*/ - -.horizontal-center { - margin: 0 auto; -} - -.form-control { - color: #0088aa; - font-weight: bold; -} - -.form-control:focus { - border-color: #0088aa; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(0, 136, 170, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(0, 136, 170, 0.6); -} - -input.btn { - font-weight: bold; -} - -.btn { - font-weight: bold !important; -} - -.btn-success { - background-color: #06d362 !important; - border-color: #06d362; -} - -.btn-success:hover { - background-color: #1abd61 !important; - border-color: #1abd61; -} - -.footer { - position: absolute; - bottom: 0; - width: 100%; - height: 60px; - background-color: #4d4d4d; -} - -.footer .text-muted { - margin: 20px 0; - float: left; - color: #ccc; -} - -.openvidu-logo { - height: 35px; - float: right; - margin: 12px 0; - -webkit-transition: all 0.1s ease-in-out; - -moz-transition: all 0.1s ease-in-out; - -o-transition: all 0.1s ease-in-out; - transition: all 0.1s ease-in-out; -} - -.openvidu-logo:hover { - -webkit-filter: grayscale(0.5); - filter: grayscale(0.5); -} - -.demo-logo { - margin: 0; - height: 22px; - float: left; - padding-right: 8px; -} - -a:hover .demo-logo { - -webkit-filter: brightness(0.7); - filter: brightness(0.7); -} - -#join-dialog { - margin-left: auto; - margin-right: auto; - max-width: 70%; -} - -#join-dialog h1 { - color: #4d4d4d; - font-weight: bold; - text-align: center; -} - -#img-div { - text-align: center; - margin-top: 3em; - margin-bottom: 3em; - /*position: relative; - top: 20%; - left: 50%; - transform: translate(-50%, -50%);*/ -} - -#img-div img { - height: 15%; -} - -#join-dialog label { - color: #0088aa; -} - -#join-dialog input.btn { - margin-top: 15px; -} - -#room-header { - margin-bottom: 20px; -} - -#room-title { - display: inline-block; -} - -#buttonLeaveRoom { - float: right; - margin-top: 20px; -} - -#buttonScreenShare { - float: right; - margin-top: 20px; - margin-left: 15px; -} - -#container-cameras video { - position: relative; - float: left; - width: 50%; - cursor: pointer; -} - -#container-cameras div { - float: left; - width: 50%; - position: relative; - margin-left: -50%; -} - -#container-cameras p { - display: inline-block; - background: #f8f8f8; - padding-left: 5px; - padding-right: 5px; - color: #777777; - font-weight: bold; - border-bottom-right-radius: 4px; -} - -#container-screens video { - position: relative; - float: left; - width: 50%; - cursor: pointer; -} - -#container-screens div { - float: left; - width: 50%; - position: relative; - margin-left: -50%; -} - -#container-screens p { - display: inline-block; - background: #f8f8f8; - padding-left: 5px; - padding-right: 5px; - color: #777777; - font-weight: bold; - border-bottom-right-radius: 4px; -} - -video { - width: 100%; - height: auto; -} - -#main-video p { - position: absolute; - display: inline-block; - background: #f8f8f8; - padding-left: 5px; - padding-right: 5px; - font-size: 22px; - color: #777777; - font-weight: bold; - border-bottom-right-radius: 4px; -} - -#room img { - width: 100%; - height: auto; - display: inline-block; - object-fit: contain; - vertical-align: baseline; -} - -#room #container-cameras img { - position: relative; - float: left; - width: 50%; - cursor: pointer; - object-fit: cover; - height: 180px; -} - - -/* xs ans md screen resolutions*/ - -@media screen and (max-width: 991px) and (orientation: portrait) { - #join-dialog { - max-width: inherit; - } - #img-div img { - height: 10%; - } - #img-div { - margin-top: 2em; - margin-bottom: 2em; - } - .container-fluid>.navbar-collapse, .container-fluid>.navbar-header, .container>.navbar-collapse, .container>.navbar-header { - margin-right: 0; - margin-left: 0; - } - .navbar-header i.fa { - font-size: 30px; - } - .navbar-header a.nav-icon { - padding: 7px 3px 7px 3px; - } -} - -@media only screen and (max-height: 767px) and (orientation: landscape) { - #img-div { - margin-top: 1em; - margin-bottom: 1em; - } - #join-dialog { - max-width: inherit; - } -} diff --git a/advanced-features/openvidu-recording-java/.gitignore b/advanced-features/openvidu-recording-java/.gitignore deleted file mode 100644 index 6c57dbc8..00000000 --- a/advanced-features/openvidu-recording-java/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -target/ -.vscode/* diff --git a/advanced-features/openvidu-recording-java/.springBeans b/advanced-features/openvidu-recording-java/.springBeans deleted file mode 100644 index 8b813b9a..00000000 --- a/advanced-features/openvidu-recording-java/.springBeans +++ /dev/null @@ -1,16 +0,0 @@ - - - 1 - - - - - - - java:io.openvidu.recording.java.App - - - - - - diff --git a/advanced-features/openvidu-recording-java/LICENSE b/advanced-features/openvidu-recording-java/LICENSE deleted file mode 100644 index 8dada3ed..00000000 --- a/advanced-features/openvidu-recording-java/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/advanced-features/openvidu-recording-java/README.md b/advanced-features/openvidu-recording-java/README.md deleted file mode 100644 index e1246643..00000000 --- a/advanced-features/openvidu-recording-java/README.md +++ /dev/null @@ -1,14 +0,0 @@ -[![License badge](https://img.shields.io/badge/license-Apache2-orange.svg)](http://www.apache.org/licenses/LICENSE-2.0) -[![OpenVidu Tests](https://github.com/OpenVidu/openvidu/actions/workflows/openvidu-ce-test.yml/badge.svg)](https://github.com/OpenVidu/openvidu/actions/workflows/openvidu-ce-test.yml) -[![Documentation Status](https://readthedocs.org/projects/openvidu/badge/?version=stable)](https://docs.openvidu.io/en/stable/?badge=stable) -[![Docker badge](https://img.shields.io/docker/pulls/openvidu/openvidu-server-kms.svg)](https://hub.docker.com/r/openvidu/openvidu-server-kms) -[![Support badge](https://img.shields.io/badge/support-sof-yellowgreen.svg)](https://openvidu.discourse.group/) - -[![][OpenViduLogo]](http://openvidu.io) - -openvidu-recording-java -=== - -Visit [docs.openvidu.io/en/stable/tutorials/openvidu-recording-java/](http://docs.openvidu.io/en/stable/tutorials/openvidu-recording-java/) - -[OpenViduLogo]: https://secure.gravatar.com/avatar/5daba1d43042f2e4e85849733c8e5702?s=120 diff --git a/advanced-features/openvidu-recording-java/docker/Dockerfile b/advanced-features/openvidu-recording-java/docker/Dockerfile deleted file mode 100644 index c31a97e5..00000000 --- a/advanced-features/openvidu-recording-java/docker/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ - -FROM maven:3.6.3 as build -WORKDIR /openvidu-recording-java -COPY ./pom.xml pom.xml -COPY ./src/main src/main - -RUN mvn clean install -RUN mvn -o package - -FROM alpine:3.11 - -RUN apk update && \ - apk add openjdk11-jre && \ - rm -rf /var/cache/apk/* - -# Install basic-webinar -RUN mkdir -p /opt/openvidu-recording-java -COPY --from=build /openvidu-recording-java/target/openvidu-recording-java-*.jar /opt/openvidu-recording-java/openvidu-recording-java.jar -# Entrypoint -COPY ./docker/entrypoint.sh /usr/local/bin -RUN chmod +x /usr/local/bin/entrypoint.sh - -CMD /usr/local/bin/entrypoint.sh - - - diff --git a/advanced-features/openvidu-recording-java/docker/create_image.sh b/advanced-features/openvidu-recording-java/docker/create_image.sh deleted file mode 100644 index 7555abd5..00000000 --- a/advanced-features/openvidu-recording-java/docker/create_image.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -if [ $# -eq 0 ]; then - echo "No version argument provided. Usage: \"./create_image.sh \"" - exit 1 -fi - -pushd ../ -docker build -f docker/Dockerfile -t "$1" . \ No newline at end of file diff --git a/advanced-features/openvidu-recording-java/docker/entrypoint.sh b/advanced-features/openvidu-recording-java/docker/entrypoint.sh deleted file mode 100644 index c9388d6c..00000000 --- a/advanced-features/openvidu-recording-java/docker/entrypoint.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -[ ! -z "${OPENVIDU_URL}" ] && echo "OPENVIDU_URL: ${OPENVIDU_URL}" || echo "OPENVIDU_URL: default" -[ ! -z "${OPENVIDU_SECRET}" ] && echo "OPENVIDU_SECRET: ${OPENVIDU_SECRET}" || echo "OPENVIDU_SECRET: default" -[ ! -z "${SERVER_PORT}" ] && echo "SERVER_PORT: ${SERVER_PORT}" || echo "SERVER_PORT: default" - -# Run Application -JAVA_PROPERTIES="-Djava.security.egd=file:/dev/./urandom" -[ ! -z "${OPENVIDU_URL}" ] && JAVA_PROPERTIES=" ${JAVA_PROPERTIES} -Dopenvidu.url=${OPENVIDU_URL}" -[ ! -z "${OPENVIDU_SECRET}" ] && JAVA_PROPERTIES=" ${JAVA_PROPERTIES} -Dopenvidu.secret=${OPENVIDU_SECRET}" -[ ! -z "${SERVER_PORT}" ] && JAVA_PROPERTIES=" ${JAVA_PROPERTIES} -Dserver.port=${SERVER_PORT}" - -java ${JAVA_PROPERTIES} -jar /opt/openvidu-recording-java/openvidu-recording-java.jar diff --git a/advanced-features/openvidu-recording-java/nginx.conf b/advanced-features/openvidu-recording-java/nginx.conf deleted file mode 100644 index 500c543d..00000000 --- a/advanced-features/openvidu-recording-java/nginx.conf +++ /dev/null @@ -1,44 +0,0 @@ -events { - worker_connections 512; -} -http { - upstream openvidu-deployment { - server host.docker.internal:4443; - } - upstream client-application { - server host.docker.internal:5000; - } - server { - listen 443 ssl; - ssl_certificate /etc/nginx/certs/cert.pem; - ssl_certificate_key /etc/nginx/certs/key.pem; - - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Proto https; - proxy_headers_hash_bucket_size 512; - proxy_redirect off; - - # Websockets - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # OpenVidu deployment API - location /openvidu/api { - proxy_pass http://openvidu-deployment; - } - - # OpenVidu WebSocket - location ~ /openvidu$ { - proxy_pass http://openvidu-deployment; - } - - # Client application requests - location / { - proxy_pass https://client-application; - } - } -} \ No newline at end of file diff --git a/advanced-features/openvidu-recording-java/pom.xml b/advanced-features/openvidu-recording-java/pom.xml deleted file mode 100644 index 8954aea9..00000000 --- a/advanced-features/openvidu-recording-java/pom.xml +++ /dev/null @@ -1,68 +0,0 @@ - - 4.0.0 - - io.openvidu - openvidu-recording-java - 2.27.0 - jar - - openvidu-recording-java - https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-recording-java - - - org.springframework.boot - spring-boot-starter-parent - 2.1.4.RELEASE - - - - UTF-8 - 11 - io.openvidu.recording.java.App - openvidu - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - - org.jetbrains.kotlin - kotlin-stdlib - 1.5.21 - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-devtools - - - io.livekit - livekit-server - 0.5.7 - - - com.squareup.okhttp3 - okhttp - 4.12.0 - - - org.json - json - 20231013 - - - diff --git a/advanced-features/openvidu-recording-java/src/main/java/io/openvidu/recording/java/App.java b/advanced-features/openvidu-recording-java/src/main/java/io/openvidu/recording/java/App.java deleted file mode 100644 index 7929909a..00000000 --- a/advanced-features/openvidu-recording-java/src/main/java/io/openvidu/recording/java/App.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.openvidu.recording.java; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class App -{ - public static void main( String[] args ) - { - SpringApplication.run(App.class, args); - } -} diff --git a/advanced-features/openvidu-recording-java/src/main/java/io/openvidu/recording/java/MyRestController.java b/advanced-features/openvidu-recording-java/src/main/java/io/openvidu/recording/java/MyRestController.java deleted file mode 100644 index c5549a49..00000000 --- a/advanced-features/openvidu-recording-java/src/main/java/io/openvidu/recording/java/MyRestController.java +++ /dev/null @@ -1,251 +0,0 @@ -package io.openvidu.recording.java; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import javax.annotation.PostConstruct; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.util.ResourceUtils; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import org.json.JSONObject; - -import io.livekit.server.*; -import livekit.LivekitEgress; -import livekit.LivekitEgress.EgressInfo; - -import livekit.LivekitEgress.EncodedFileOutput; -import livekit.LivekitEgress.EncodedFileType; -import livekit.LivekitEgress.EncodedFileOutput.Builder; - -@CrossOrigin(origins = "*") -@RestController -public class MyRestController { - - @Value("${LIVEKIT_URL}") - private String LIVEKIT_URL; - - @Value("${LIVEKIT_API_KEY}") - private String LIVEKIT_API_KEY; - - @Value("${LIVEKIT_API_SECRET}") - private String LIVEKIT_API_SECRET; - - @Value("${RECORDINGS_PATH}") - private String RECORDINGS_PATH; - - // OpenVidu object as entrypoint of the SDK - private EgressServiceClient egressClient; - - @PostConstruct() - public void initialize() { - - String livekitUrlHostname = LIVEKIT_URL.replaceFirst("^ws:", "http:").replaceFirst("^wss:", "https:"); - this.egressClient = EgressServiceClient.create(livekitUrlHostname, LIVEKIT_API_KEY, LIVEKIT_API_SECRET, true); - } - - /*******************/ - /*** Session API ***/ - /*******************/ - - /** - * @param params The JSON object with roomName and participantName - * @return The JWT token - */ - @PostMapping("/token") - public ResponseEntity getToken(@RequestBody(required = true) Map params) { - String roomName = params.get("roomName"); - String participantName = params.get("participantName"); - JSONObject response = new JSONObject(); - - if (roomName == null || participantName == null) { - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } - - // By default, tokens expire 6 hours after generation. - // You may override this by using token.setTtl(long millis). - AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); - token.setName(participantName); - token.setIdentity(participantName); - - JSONObject metadata = new JSONObject(); - metadata.put("livekitUrl", LIVEKIT_URL); - // add metadata to the token, which will be available in the participant's - // metadata - token.setMetadata(metadata.toString()); - token.addGrants(new RoomJoin(true), new RoomName(roomName)); - - response.put("token", token.toJwt()); - return new ResponseEntity<>(response.toMap(), HttpStatus.OK); - } - - /*******************/ - /** Recording API **/ - /*******************/ - - @RequestMapping(value = "/recordings/start", method = RequestMethod.POST) - public ResponseEntity startRecording(@RequestBody Map params) { - try { - String roomName = (String) params.get("roomName"); - String outputMode = (String) params.get("outputMode"); - Boolean videoOnly = (Boolean) params.get("videoOnly"); - Boolean audioOnly = (Boolean) params.get("audioOnly"); - String audioTrackId = (String) params.get("audioTrackId"); - String videoTrackId = (String) params.get("videoTrackId"); - - Builder outputBuilder = LivekitEgress.EncodedFileOutput.newBuilder() - .setFileType(EncodedFileType.DEFAULT_FILETYPE) - .setFilepath("/recordings/" + roomName + "-" + new Date().getTime()) - .setDisableManifest(true); - - EncodedFileOutput output = outputBuilder.build(); - - System.out.println("Starting recording " + roomName); - - LivekitEgress.EgressInfo egressInfo; - - if ("COMPOSED".equals(outputMode)) { - - System.out.println("Starting COMPOSED recording " + roomName); - egressInfo = this.egressClient - .startRoomCompositeEgress(roomName, output, "grid", null, null, audioOnly, videoOnly) - .execute().body(); - } else if ("INDIVIDUAL".equals(outputMode)) { - System.out.println("Starting INDIVIDUAL recording " + roomName); - egressInfo = this.egressClient.startTrackCompositeEgress(roomName, output, audioTrackId, videoTrackId) - .execute().body(); - } else { - return ResponseEntity.badRequest().body("outputMode is required"); - } - - return ResponseEntity.ok().body(generateEgressInfoResponse(egressInfo)); - - } catch (Exception e) { - System.out.println("Error starting recording " + e.getMessage()); - return ResponseEntity.badRequest().body("Error starting recording"); - } - } - - @RequestMapping(value = "/recordings/stop", method = RequestMethod.POST) - public ResponseEntity stopRecording(@RequestBody Map params) { - - String recordingId = (String) params.get("recordingId"); - - if (recordingId == null) { - return ResponseEntity.badRequest().body("recordingId is required"); - } - - System.out.println("Stoping recording | {recordingId}=" + recordingId); - - try { - LivekitEgress.EgressInfo egressInfo = this.egressClient.stopEgress(recordingId).execute().body(); - return ResponseEntity.ok().body(generateEgressInfoResponse(egressInfo)); - } catch (Exception e) { - System.out.println("Error stoping recording " + e.getMessage()); - return ResponseEntity.badRequest().body("Error stoping recording"); - } - } - - @RequestMapping(value = "/recordings", method = RequestMethod.DELETE) - public ResponseEntity deleteRecordings() { - - try { - File recordingsDir = ResourceUtils.getFile("classpath:static"); - deleteFiles(new File(RECORDINGS_PATH)); - deleteFiles(new File(recordingsDir.getAbsolutePath())); - JSONObject response = new JSONObject(); - response.put("message", "All recordings deleted"); - - return ResponseEntity.ok().body(response.toMap()); - } catch (IOException e) { - e.printStackTrace(); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error deleting recordings"); - } - } - - @RequestMapping(value = "/recordings/list", method = RequestMethod.GET) - public ResponseEntity listRecordings() { - - System.out.println("Listing recordings"); - - List recordings = new ArrayList<>(); - - try { - File recordingsDir = ResourceUtils.getFile("classpath:static"); - Files.walk(Path.of(RECORDINGS_PATH)).forEach(filePath -> { - JSONObject recordingsMap = new JSONObject(); - - if (Files.isRegularFile(filePath)) { - String fileName = filePath.getFileName().toString(); - String destinationPath = recordingsDir.getAbsolutePath() + File.separator + fileName; - - try { - Files.copy(filePath, Path.of(destinationPath), StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - e.printStackTrace(); - } - - recordingsMap.put("name", fileName); - recordingsMap.put("path", "/" + fileName); - - recordings.add(recordingsMap); - } - }); - } catch (IOException e) { - e.printStackTrace(); - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } - - JSONObject response = new JSONObject(); - response.put("recordings", recordings); - return new ResponseEntity<>(response.toMap(), HttpStatus.OK); - } - - private void deleteFiles(File directory) { - if (directory.exists() && directory.isDirectory()) { - File[] files = directory.listFiles(); - if (files != null) { - for (File file : files) { - if (file.isDirectory()) { - deleteFiles(file); - } else { - if (file.delete()) { - System.out.println("Deleted file: " + file.getAbsolutePath()); - } else { - System.out.println("Failed to delete file: " + file.getAbsolutePath()); - } - } - } - } - } - } - - private Map generateEgressInfoResponse(EgressInfo egressInfo) { - JSONObject info = new JSONObject(); - JSONObject response = new JSONObject(); - - info.put("egressId", egressInfo.getEgressId()); - info.put("roomName", egressInfo.getRoomName()); - info.put("status", egressInfo.getStatus().toString()); - - response.put("info", info); - return response.toMap(); - - } - -} diff --git a/advanced-features/openvidu-recording-java/src/main/resources/application-container.properties b/advanced-features/openvidu-recording-java/src/main/resources/application-container.properties deleted file mode 100644 index 5ab5cc01..00000000 --- a/advanced-features/openvidu-recording-java/src/main/resources/application-container.properties +++ /dev/null @@ -1,9 +0,0 @@ -spring.profiles.active=container - -server.port: 3000 -server.ssl.enabled: false - - -LIVEKIT_URL: ws://localhost:7880/ -LIVEKIT_API_KEY: http://localhost:4443/ -LIVEKIT_API_SECRET: MY_SECRET \ No newline at end of file diff --git a/advanced-features/openvidu-recording-java/src/main/resources/application.properties b/advanced-features/openvidu-recording-java/src/main/resources/application.properties deleted file mode 100644 index 93773915..00000000 --- a/advanced-features/openvidu-recording-java/src/main/resources/application.properties +++ /dev/null @@ -1,12 +0,0 @@ -server.port: 5000 -server.ssl.enabled: true -server.ssl.key-store: classpath:openvidu-selfsigned.jks -server.ssl.key-store-password: openvidu -server.ssl.key-store-type: JKS -server.ssl.key-alias: openvidu-selfsigned -spring.http.converters.preferred-json-mapper=gson - -LIVEKIT_URL: ws://localhost:7880/ -LIVEKIT_API_KEY: key1 -LIVEKIT_API_SECRET: abcdefghijklmnopqrstuvwxyz123456 -RECORDINGS_PATH: ../../openvidu-lk/local-deployment/cluster/recordings \ No newline at end of file diff --git a/advanced-features/openvidu-recording-java/src/main/resources/openvidu-selfsigned.jks b/advanced-features/openvidu-recording-java/src/main/resources/openvidu-selfsigned.jks deleted file mode 100644 index 4a02ecc4..00000000 Binary files a/advanced-features/openvidu-recording-java/src/main/resources/openvidu-selfsigned.jks and /dev/null differ diff --git a/advanced-features/openvidu-recording-java/src/main/resources/static/app.js b/advanced-features/openvidu-recording-java/src/main/resources/static/app.js deleted file mode 100644 index ce00514f..00000000 --- a/advanced-features/openvidu-recording-java/src/main/resources/static/app.js +++ /dev/null @@ -1,348 +0,0 @@ -var LivekitClient = window.LivekitClient; -var room; -var myRoomName; -var token; -var nickname; -var numVideos = 0; - -var localVideoPublication; -var localAudioPublication; - -/* OPENVIDU METHODS */ - -function joinRoom() { - // --- 0) Change the button --- - - document.getElementById('join-btn').disabled = true; - document.getElementById('join-btn').innerHTML = 'Joining...'; - const myParticipantName = `Participant${Math.floor(Math.random() * 100)}`; - const myRoomName = $('#roomName').val(); - - room = new LivekitClient.Room(); - - room.on( - LivekitClient.RoomEvent.TrackSubscribed, - (track, publication, participant) => { - const element = track.attach(); - element.id = track.sid; - document.getElementById('video-container').appendChild(element); - if (track.kind === 'video') { - var audioTrackId; - var videoTrackId; - participant.getTracks().forEach((track) => { - if (track.kind === 'audio') { - audioTrackId = track.trackInfo.sid; - } else if (track.kind === 'video') { - videoTrackId = track.trackInfo.sid; - } - }); - addIndividualRecordingButton(element.id, videoTrackId, audioTrackId); - updateNumVideos(1); - } - } - ); - - // On every new Track destroyed... - room.on( - LivekitClient.RoomEvent.TrackUnsubscribed, - (track, publication, participant) => { - track.detach(); - document.getElementById(track.sid)?.remove(); - if (track.kind === 'video') { - // removeUserData(participant); - updateNumVideos(-1); - } - } - ); - - room.on(LivekitClient.RoomEvent.RecordingStatusChanged, (isRecording) => { - console.log('Recording status changed: ' + status); - if (!isRecording) { - listRecordings(); - } - }); - - getToken(myRoomName, myParticipantName).then(async (token) => { - const livekitUrl = getLivekitUrlFromMetadata(token); - - try { - await room.connect(livekitUrl, token); - - var participantName = $('#user').val(); - $('#room-title').text(myRoomName); - $('#join').hide(); - $('#room').show(); - - const [audioPublication, videoPublication] = await Promise.all([ - room.localParticipant.setMicrophoneEnabled(true), - room.localParticipant.setCameraEnabled(true), - ]); - localVideoPublication = videoPublication; - localAudioPublication = audioPublication; - - console.log('Connected to room ' + myRoomName); - const element = videoPublication.track.attach(); - element.id = videoPublication.track.sid; - document.getElementById('video-container').appendChild(element); - addIndividualRecordingButton( - element.id, - videoPublication.track.sid, - audioPublication.track.sid - ); - updateNumVideos(1); - } catch (error) { - console.warn( - 'There was an error connecting to the room:', - error.code, - error.message - ); - enableBtn(); - } - - return false; - }); -} - -function leaveRoom() { - room.disconnect(); - room = null; - - $('#video-container').empty(); - numVideos = 0; - - $('#join').show(); - $('#room').hide(); - - enableBtn(); -} - -/* OPENVIDU METHODS */ - -function enableBtn() { - document.getElementById('join-btn').disabled = false; - document.getElementById('join-btn').innerHTML = 'Join!'; -} - -/* APPLICATION REST METHODS */ - -function getToken(roomName, participantName) { - return new Promise((resolve, reject) => { - // Video-call chosen by the user - httpRequest( - 'POST', - 'token', - { roomName, participantName }, - 'Error generating token', - (response) => resolve(response.token) - ); - }); -} - -async function httpRequest(method, url, body, errorMsg, successCallback) { - try { - const response = await fetch(url, { - method, - headers: { - 'Content-Type': 'application/json', - }, - body: method === 'GET' ? undefined : JSON.stringify(body), - }); - - if (response.ok) { - const data = await response.json(); - successCallback(data); - } else { - console.warn(errorMsg); - console.warn('Error: ' + response.statusText); - } - } catch (error) { - console.error(error); - } -} - -function startComposedRecording() { - var hasAudio = $('#has-audio-checkbox').prop('checked'); - var hasVideo = $('#has-video-checkbox').prop('checked'); - - httpRequest( - 'POST', - 'recordings/start', - { - roomName: room.roomInfo.name, - outputMode: 'COMPOSED', - videoOnly: hasVideo && !hasAudio, - audioOnly: hasAudio && !hasVideo, - }, - 'Start recording WRONG', - (res) => { - console.log(res); - document.getElementById('forceRecordingId').value = res.id; - checkBtnsRecordings(); - $('#textarea-http').text(JSON.stringify(res, null, '\t')); - } - ); -} - -function startIndividualRecording(videoTrackId, audioTrackId) { - return new Promise((resolve, reject) => { - httpRequest( - 'POST', - 'recordings/start', - { - roomName: room.roomInfo.name, - outputMode: 'INDIVIDUAL', - audioTrackId, - videoTrackId, - }, - 'Start recording WRONG', - (res) => { - console.log(res); - $('#textarea-http').text(JSON.stringify(res.info, null, '\t')); - resolve(res); - } - ); - }); -} - -function stopRecording(id) { - var forceRecordingId = id ? id : $('#forceRecordingId').val(); - httpRequest( - 'POST', - 'recordings/stop', - { - recordingId: forceRecordingId, - }, - 'Stop recording WRONG', - (res) => { - console.log(res); - $('#forceRecordingId').val(''); - $('#textarea-http').text(JSON.stringify(res.info, null, '\t')); - } - ); -} - -function listRecordings() { - httpRequest('GET', 'recordings/list', {}, 'List recordings WRONG', (res) => { - console.log(res); - $('#recording-list').empty(); - if (res.recordings && res.recordings.length > 0) { - res.recordings.forEach((recording) => { - var li = document.createElement('li'); - var a = document.createElement('a'); - a.href = recording.path; - a.target = '_blank'; - a.appendChild(document.createTextNode(recording.name)); - li.appendChild(a); - $('#recording-list').append(li); - }); - $('#delete-recordings-btn').prop('disabled', res.recordings.length === 0); - } - }); -} - -function deleteRecordings() { - httpRequest('DELETE', 'recordings', {}, 'Delete recordings WRONG', (res) => { - console.log(res); - $('#recording-list').empty(); - $('#delete-recordings-btn').prop('disabled', true); - $('#textarea-http').text(JSON.stringify(res, null, '\t')); - }); -} - -/* APPLICATION REST METHODS */ - -/* APPLICATION BROWSER METHODS */ - -events = ''; - -window.onbeforeunload = function () { - // Gracefully leave room - if (room) { - removeUser(); - leaveRoom(); - } -}; - -function getLivekitUrlFromMetadata(token) { - if (!token) throw new Error('Trying to get metadata from an empty token'); - try { - const base64Url = token.split('.')[1]; - const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); - const jsonPayload = decodeURIComponent( - window - .atob(base64) - .split('') - .map((c) => { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }) - .join('') - ); - - const payload = JSON.parse(jsonPayload); - if (!payload?.metadata) throw new Error('Token does not contain metadata'); - const metadata = JSON.parse(payload.metadata); - return metadata.livekitUrl; - } catch (error) { - throw new Error('Error decoding and parsing token: ' + error); - } -} - -function updateNumVideos(i) { - numVideos += i; - $('video').removeClass(); - switch (numVideos) { - case 1: - $('video').addClass('two'); - break; - case 2: - $('video').addClass('two'); - break; - case 3: - $('video').addClass('three'); - break; - case 4: - $('video').addClass('four'); - break; - } -} - -function checkBtnsRecordings() { - if (document.getElementById('forceRecordingId').value === '') { - document.getElementById('buttonStopRecording').disabled = true; - } else { - document.getElementById('buttonStopRecording').disabled = false; - } -} - -function addIndividualRecordingButton(elementId, videoTrackId, audioTrackId) { - const div = document.createElement('div'); - - var button = document.createElement('button'); - // button.id = elementId + '-button'; - button.className = 'recording-track-button btn btn-sm'; - - button.innerHTML = 'Record Track'; - button.style = 'position: absolute; left: 0; z-index: 1000;'; - - button.onclick = async () => { - if (button.innerHTML === 'Record Track') { - button.innerHTML = 'Stop Recording'; - button.className = 'recording-track-button btn btn-sm btn-danger'; - var res = await startIndividualRecording(videoTrackId, audioTrackId); - button.id = res.info.egressId; - } else { - button.innerHTML = 'Record Track'; - button.className = 'recording-track-button btn btn-sm'; - stopRecording(button.id); - } - }; - div.appendChild(button); - var element = document.getElementById(elementId); - element.parentNode.insertBefore(div, element.nextSibling); -} - -function clearHttpTextarea() { - $('#textarea-http').text(''); -} - -/* APPLICATION BROWSER METHODS */ diff --git a/advanced-features/openvidu-recording-java/src/main/resources/static/images/favicon.ico b/advanced-features/openvidu-recording-java/src/main/resources/static/images/favicon.ico deleted file mode 100644 index 0e2249ad..00000000 Binary files a/advanced-features/openvidu-recording-java/src/main/resources/static/images/favicon.ico and /dev/null differ diff --git a/advanced-features/openvidu-recording-java/src/main/resources/static/images/openvidu_globe_bg_transp_cropped.png b/advanced-features/openvidu-recording-java/src/main/resources/static/images/openvidu_globe_bg_transp_cropped.png deleted file mode 100644 index e0309e62..00000000 Binary files a/advanced-features/openvidu-recording-java/src/main/resources/static/images/openvidu_globe_bg_transp_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-recording-java/src/main/resources/static/images/openvidu_grey_bg_transp_cropped.png b/advanced-features/openvidu-recording-java/src/main/resources/static/images/openvidu_grey_bg_transp_cropped.png deleted file mode 100644 index 49f311a6..00000000 Binary files a/advanced-features/openvidu-recording-java/src/main/resources/static/images/openvidu_grey_bg_transp_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-recording-java/src/main/resources/static/images/openvidu_vert_white_bg_trans_cropped.png b/advanced-features/openvidu-recording-java/src/main/resources/static/images/openvidu_vert_white_bg_trans_cropped.png deleted file mode 100644 index a1c8b2d7..00000000 Binary files a/advanced-features/openvidu-recording-java/src/main/resources/static/images/openvidu_vert_white_bg_trans_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-recording-java/src/main/resources/static/index.html b/advanced-features/openvidu-recording-java/src/main/resources/static/index.html deleted file mode 100644 index 1ded9bdd..00000000 --- a/advanced-features/openvidu-recording-java/src/main/resources/static/index.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - openvidu-recording-node - - - - - - - - - - - - - - - - - - - - - -
-
-
- -
-
-

Join a video room

-
-

- - -

-

- -

-
-
-
-
- - -
- -
-
-
OpenVidu © 2023
- - - -
-
- - - - diff --git a/advanced-features/openvidu-recording-java/src/main/resources/static/style.css b/advanced-features/openvidu-recording-java/src/main/resources/static/style.css deleted file mode 100644 index dfea514d..00000000 --- a/advanced-features/openvidu-recording-java/src/main/resources/static/style.css +++ /dev/null @@ -1,474 +0,0 @@ -html { - position: relative; - min-height: 100%; -} - -body { - min-height: 100%; -} - -nav { - height: 50px; - width: 100%; - z-index: 1; - background-color: #4d4d4d !important; - border-color: #4d4d4d !important; - border-top-right-radius: 0 !important; - border-top-left-radius: 0 !important; -} - -.navbar-header { - width: 100%; -} - -.nav-icon { - padding: 5px 15px 5px 15px; - float: right; -} - -nav a { - color: #ccc !important; -} - -nav i.fa { - font-size: 40px; - color: #ccc; -} - -nav a:hover { - color: #a9a9a9 !important; -} - -nav i.fa:hover { - color: #a9a9a9; -} - -#main-container { - padding-bottom: 80px; - height: 100%; - margin-top: -70px; -} - -.vertical-center { - width: -webkit-fit-content; - width: fit-content; - margin: auto; -} - -.vertical-center#not-logged form { - width: -moz-fit-content; - margin: auto; -} - -.vertical-center#not-logged table { - width: -moz-fit-content; - margin: auto; -} - -.vertical-center table { - margin-top: 3em !important; -} - -.horizontal-center { - margin: 0 auto; -} - -.form-control { - color: #0088aa; - font-weight: bold; -} - -.form-control:focus { - border-color: #0088aa; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(0, 136, 170, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(0, 136, 170, 0.6); -} - -input.btn { - font-weight: bold; -} - -.btn { - font-weight: bold !important; -} - -.btn-success { - background-color: #06d362 !important; - border-color: #06d362; -} - -.btn-success:hover { - background-color: #1abd61 !important; - border-color: #1abd61; -} - -.btn-info { - background-color: #0088aa !important; - border-color: #0088aa; -} - -.btn-info:hover { - background-color: #00708c !important; - border-color: #00708c; -} - -.btn-warning { - background-color: #ffcc00 !important; - border-color: #ffcc00; - color: #4d4d4d; -} - -.btn-warning:hover { - background-color: #eabb3a !important; - border-color: #eabb3a; - color: #4d4d4d; -} - -.btn-warning:active { - color: #4d4d4d; -} - -.btn-warning:focus { - color: #4d4d4d; -} - -.btn-warning:active:focus { - color: #4d4d4d; -} - -.footer { - position: absolute; - bottom: 0; - width: 100%; - height: 60px; - background-color: #4d4d4d; -} - -.footer .text-muted { - margin: 20px 0; - float: left; - color: #ccc; -} - -.openvidu-logo { - height: 35px; - float: right; - margin: 12px 0; - -webkit-transition: all 0.1s ease-in-out; - -moz-transition: all 0.1s ease-in-out; - -o-transition: all 0.1s ease-in-out; - transition: all 0.1s ease-in-out; -} - -.openvidu-logo:hover { - -webkit-filter: grayscale(0.5); - filter: grayscale(0.5); -} - -.demo-logo { - margin: 0; - height: 22px; - float: left; - padding-right: 8px; -} - -a:hover .demo-logo { - -webkit-filter: brightness(0.7); - filter: brightness(0.7); -} - -#join { - padding-top: 40px; -} - -#not-logged { - padding-top: 40px; -} - -#join-dialog h1 { - color: #4d4d4d; - font-weight: bold; - text-align: center; -} - -#join-dialog label { - color: #0088aa; -} - -#join-dialog input.btn { - margin-top: 15px; -} - -#join-dialog hr { - background: #4d4d4d; -} - -#img-div { - text-align: center; - padding-bottom: 3em; -} - -#img-div img { - height: 15%; -} - -#logged { - width: 100%; -} - -#join { - max-width: 700px; - margin: auto; - margin-top: 100px; -} - -#room-header { - margin-bottom: 20px; - height: 8%; - margin-top: 70px; -} - -#room-header form { - display: inline-block; -} - -#room-header input.btn { - float: right; - margin-top: 20px; - margin-left: 5px; -} - -#room-title { - display: inline-block; -} - -#room-header .form-control { - width: initial; - float: right; - margin: 18px 0px 0px 5px; -} - -#video-container { - width: 100%; - max-height: 42%; - display: block; - overflow: hidden; -} - -#video-container video.two { - max-width: 50%; -} - -#video-container video.three { - max-width: 33.33%; -} - -#video-container video.four { - max-width: 25%; -} - -#video-container div { - position: absolute; - display: inline-flex; - margin-left: calc(-50% + 15px); -} - -#video-container p { - display: inline-block; - background: #f8f8f8; - padding-left: 5px; - padding-right: 5px; - color: #777777; - font-weight: bold; - border-bottom-right-radius: 4px; -} - -#video-container p.userName { - float: right; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 0px; - font-weight: lighter; - font-size: 12px; - background: #777777; - color: #f8f8f8; -} - -video { - width: auto; - height: auto; - max-height: 100%; - object-fit: scale-down; -} - -#room { - height: 100%; - padding-bottom: 80px; -} - -#room img { - width: 100%; - height: auto; - display: inline-block; - object-fit: contain; - vertical-align: baseline; -} - -#room #video-container img { - position: relative; - float: left; - width: 50%; - cursor: pointer; - object-fit: cover; - height: 180px; -} - -table i { - cursor: pointer; - margin-left: 1em; -} - -#tooltip-div { - text-align: left; -} - -#tooltip-div hr { - margin: 5px 0; -} - -#login-info { - text-align: right; -} - -#login-info form { - display: inline; -} - -#login-info div { - display: inline; - margin-right: 1em; -} - -#name-user { - font-weight: bold; -} - -#recording-btns { - display: inline-block; - padding-left: 15px; - padding-top: 20px; - width: 100%; - height: 40%; -} - -#recording-btns .btns { - margin-top: 10px; -} - -#recording-btns .btns .form-control { - width: initial; - display: inline; -} - -#recording-btns .btns form { - display: inline; - margin-left: 5px; -} - -#recording-btns textarea { - height: 100%; -} - -.textarea-container { - position: relative; - display: inline-block; - height: 74%; - margin-top: 20px; - resize: none; -} - -#textarea-http-container { - width: 59%; -} - -#recordings-list-container { - width: 39%; - overflow: auto; -} - -.textarea-container button { - position: absolute; - top: 1px; - right: 1px; - z-index: 1; -} - -.textarea-container span { - position: absolute; - bottom: 1px; - right: 1px; - padding: 3px; - border-bottom-right-radius: 4px; - z-index: 1; - color: #a5a5a5; - background-color: #ededee; - font-weight: 600; -} - -.textarea-container textarea { - height: 100%; - resize: none; -} - -.vertical-separator-bottom { - width: 2px; - height: 34px; - display: inline-block; - background-color: #cbcbcb; - margin: 0 8px 0 8px; - margin-bottom: -12px; -} - -.vertical-separator-top { - width: 2px; - height: 30px; - background-color: #cbcbcb; - margin: 20px 8px 0 15px; - float: right; -} - -/* xs ans md screen resolutions*/ - -@media screen and (max-width: 991px) { - #join { - padding-top: inherit; - } - - #not-logged { - padding-top: inherit; - } - - .container .navbar-header { - margin-right: 0 !important; - margin-left: 0 !important; - } - - .nav-icon { - padding: 9px 8px 9px 8px; - } - - nav i.fa { - font-size: 32px; - } - - .vertical-center { - padding-top: 10px; - } - - #img-div { - padding-bottom: 1em; - } - - #img-div img { - height: 10%; - } -} \ No newline at end of file diff --git a/advanced-features/openvidu-roles-java/.gitignore b/advanced-features/openvidu-roles-java/.gitignore deleted file mode 100644 index 950fc085..00000000 --- a/advanced-features/openvidu-roles-java/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -target/ diff --git a/advanced-features/openvidu-roles-java/LICENSE b/advanced-features/openvidu-roles-java/LICENSE deleted file mode 100644 index 8dada3ed..00000000 --- a/advanced-features/openvidu-roles-java/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/advanced-features/openvidu-roles-java/README.md b/advanced-features/openvidu-roles-java/README.md deleted file mode 100644 index c19ecf1c..00000000 --- a/advanced-features/openvidu-roles-java/README.md +++ /dev/null @@ -1,14 +0,0 @@ -[![License badge](https://img.shields.io/badge/license-Apache2-orange.svg)](http://www.apache.org/licenses/LICENSE-2.0) -[![OpenVidu Tests](https://github.com/OpenVidu/openvidu/actions/workflows/openvidu-ce-test.yml/badge.svg)](https://github.com/OpenVidu/openvidu/actions/workflows/openvidu-ce-test.yml) -[![Documentation Status](https://readthedocs.org/projects/openvidu/badge/?version=stable)](https://docs.openvidu.io/en/stable/?badge=stable) -[![Docker badge](https://img.shields.io/docker/pulls/openvidu/openvidu-server-kms.svg)](https://hub.docker.com/r/openvidu/openvidu-server-kms) -[![Support badge](https://img.shields.io/badge/support-sof-yellowgreen.svg)](https://openvidu.discourse.group/) - -[![][OpenViduLogo]](http://openvidu.io) - -openvidu-roles-java -=== - -Visit [docs.openvidu.io/en/stable/tutorials/openvidu-roles-java/](http://docs.openvidu.io/en/stable/tutorials/openvidu-roles-java/) - -[OpenViduLogo]: https://secure.gravatar.com/avatar/5daba1d43042f2e4e85849733c8e5702?s=120 \ No newline at end of file diff --git a/advanced-features/openvidu-roles-java/docker/Dockerfile b/advanced-features/openvidu-roles-java/docker/Dockerfile deleted file mode 100644 index 27e95286..00000000 --- a/advanced-features/openvidu-roles-java/docker/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ - -FROM maven:3.6.3 as build -WORKDIR /basic-webinar -COPY ./pom.xml pom.xml -COPY ./src/main src/main - -RUN mvn clean install -RUN mvn -o package - -FROM alpine:3.11 - -RUN apk update && \ - apk add openjdk11-jre && \ - rm -rf /var/cache/apk/* - -# Install basic-webinar -RUN mkdir -p /opt/openvidu-basic-webinar -COPY --from=build /basic-webinar/target/openvidu-roles-java-*.jar /opt/openvidu-basic-webinar/openvidu-basic-webinar.jar -# Entrypoint -COPY ./docker/entrypoint.sh /usr/local/bin -RUN chmod +x /usr/local/bin/entrypoint.sh - -CMD /usr/local/bin/entrypoint.sh - - - diff --git a/advanced-features/openvidu-roles-java/docker/create_image.sh b/advanced-features/openvidu-roles-java/docker/create_image.sh deleted file mode 100644 index f36d63ce..00000000 --- a/advanced-features/openvidu-roles-java/docker/create_image.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -if [ $# -eq 0 ]; then - echo "No version argument provided. Usage: \"./create_image.sh \"" - exit 1 -fi - -pushd ../ -docker build --pull --no-cache --rm=true -f docker/Dockerfile -t "$1" . \ No newline at end of file diff --git a/advanced-features/openvidu-roles-java/docker/entrypoint.sh b/advanced-features/openvidu-roles-java/docker/entrypoint.sh deleted file mode 100644 index 9088bdd4..00000000 --- a/advanced-features/openvidu-roles-java/docker/entrypoint.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -[ ! -z "${OPENVIDU_URL}" ] && echo "OPENVIDU_URL: ${OPENVIDU_URL}" || echo "OPENVIDU_URL: default" -[ ! -z "${OPENVIDU_SECRET}" ] && echo "OPENVIDU_SECRET: ${OPENVIDU_SECRET}" || echo "OPENVIDU_SECRET: default" -[ ! -z "${SERVER_PORT}" ] && echo "SERVER_PORT: ${SERVER_PORT}" || echo "SERVER_PORT: default" - -# Run Application -JAVA_PROPERTIES="-Djava.security.egd=file:/dev/./urandom" -[ ! -z "${OPENVIDU_URL}" ] && JAVA_PROPERTIES=" ${JAVA_PROPERTIES} -Dopenvidu.url=${OPENVIDU_URL}" -[ ! -z "${OPENVIDU_SECRET}" ] && JAVA_PROPERTIES=" ${JAVA_PROPERTIES} -Dopenvidu.secret=${OPENVIDU_SECRET}" -[ ! -z "${SERVER_PORT}" ] && JAVA_PROPERTIES=" ${JAVA_PROPERTIES} -Dserver.port=${SERVER_PORT}" - -java ${JAVA_PROPERTIES} -jar /opt/openvidu-basic-webinar/openvidu-basic-webinar.jar diff --git a/advanced-features/openvidu-roles-java/nginx.conf b/advanced-features/openvidu-roles-java/nginx.conf deleted file mode 100644 index 500c543d..00000000 --- a/advanced-features/openvidu-roles-java/nginx.conf +++ /dev/null @@ -1,44 +0,0 @@ -events { - worker_connections 512; -} -http { - upstream openvidu-deployment { - server host.docker.internal:4443; - } - upstream client-application { - server host.docker.internal:5000; - } - server { - listen 443 ssl; - ssl_certificate /etc/nginx/certs/cert.pem; - ssl_certificate_key /etc/nginx/certs/key.pem; - - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Proto https; - proxy_headers_hash_bucket_size 512; - proxy_redirect off; - - # Websockets - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # OpenVidu deployment API - location /openvidu/api { - proxy_pass http://openvidu-deployment; - } - - # OpenVidu WebSocket - location ~ /openvidu$ { - proxy_pass http://openvidu-deployment; - } - - # Client application requests - location / { - proxy_pass https://client-application; - } - } -} \ No newline at end of file diff --git a/advanced-features/openvidu-roles-java/pom.xml b/advanced-features/openvidu-roles-java/pom.xml deleted file mode 100644 index 66036a26..00000000 --- a/advanced-features/openvidu-roles-java/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - 4.0.0 - - io.openvidu - openvidu-roles-java - 2.27.0 - jar - - openvidu-roles-java - https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-roles-java - - - org.springframework.boot - spring-boot-starter-parent - 2.1.4.RELEASE - - - - UTF-8 - 1.8 - io.openvidu.js.java.App - openvidu - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - - junit - junit - test - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-devtools - - - org.json - json - 20231013 - - - io.livekit - livekit-server - 0.5.7 - - - - diff --git a/advanced-features/openvidu-roles-java/src/main/java/io/openvidu/js/java/App.java b/advanced-features/openvidu-roles-java/src/main/java/io/openvidu/js/java/App.java deleted file mode 100644 index eda169a2..00000000 --- a/advanced-features/openvidu-roles-java/src/main/java/io/openvidu/js/java/App.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.openvidu.js.java; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class App -{ - public static void main( String[] args ) - { - SpringApplication.run(App.class, args); - } -} diff --git a/advanced-features/openvidu-roles-java/src/main/java/io/openvidu/js/java/LoginController.java b/advanced-features/openvidu-roles-java/src/main/java/io/openvidu/js/java/LoginController.java deleted file mode 100644 index 2eb45ced..00000000 --- a/advanced-features/openvidu-roles-java/src/main/java/io/openvidu/js/java/LoginController.java +++ /dev/null @@ -1,76 +0,0 @@ -package io.openvidu.js.java; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javax.servlet.http.HttpSession; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; - -import org.springframework.web.bind.annotation.RestController; - -@CrossOrigin(origins = "*") -@RestController -public class LoginController { - - public class MyUser { - - String name; - String pass; - String role; - - public MyUser(String name, String pass, String role) { - this.name = name; - this.pass = pass; - this.role = role; - } - } - - public static Map users = new ConcurrentHashMap<>(); - - public LoginController() { - users.put("publisher1", new MyUser("publisher1", "pass", "PUBLISHER")); - users.put("publisher2", new MyUser("publisher2", "pass", "PUBLISHER")); - users.put("subscriber", new MyUser("subscriber", "pass", "SUBSCRIBER")); - } - - @PostMapping("/login") - public ResponseEntity login(@RequestBody(required = true) Map params, HttpSession httpSession) { - - String user = params.get("user"); - String pass = params.get("pass"); - Map response = new HashMap(); - - if (login(user, pass)) { - // Successful login - // Validate session and return OK - // Value stored in req.session allows us to identify the user in future requests - httpSession.setAttribute("loggedUser", user); - return new ResponseEntity<>(new HashMap(), HttpStatus.OK); - } else { - // Credentials are NOT valid - // Invalidate session and return error - httpSession.invalidate(); - response.put("message", "Invalid credentials"); - return new ResponseEntity<>(response, HttpStatus.UNAUTHORIZED); - } - } - - @PostMapping("/logout") - public ResponseEntity logout(HttpSession session) { - System.out.println("'" + session.getAttribute("loggedUser") + "' has logged out"); - session.invalidate(); - return new ResponseEntity<>(HttpStatus.OK); - } - - private boolean login(String user, String pass) { - if(user.isEmpty() || pass.isEmpty()) return false; - return (users.containsKey(user) && users.get(user).pass.equals(pass)); - } - -} diff --git a/advanced-features/openvidu-roles-java/src/main/java/io/openvidu/js/java/RoomController.java b/advanced-features/openvidu-roles-java/src/main/java/io/openvidu/js/java/RoomController.java deleted file mode 100644 index 565fe052..00000000 --- a/advanced-features/openvidu-roles-java/src/main/java/io/openvidu/js/java/RoomController.java +++ /dev/null @@ -1,85 +0,0 @@ -package io.openvidu.js.java; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpSession; - -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import io.livekit.server.AccessToken; -import io.livekit.server.CanPublish; -import io.livekit.server.CanSubscribe; -import io.livekit.server.RoomJoin; -import io.livekit.server.RoomName; - -import io.openvidu.js.java.LoginController.MyUser; - -@CrossOrigin(origins = "*") -@RestController -public class RoomController { - - @Value("${LIVEKIT_URL}") - private String LIVEKIT_URL; - - @Value("${LIVEKIT_API_KEY}") - private String LIVEKIT_API_KEY; - - @Value("${LIVEKIT_API_SECRET}") - private String LIVEKIT_API_SECRET; - - /** - * @param params The JSON object with roomName and participantName - * @return The JWT token - */ - @PostMapping("/token") - public ResponseEntity> getToken(@RequestBody(required = true) Map params, HttpSession httpSession) { - - String roomName = params.get("roomName"); - String participantName = params.get("participantName"); - Map response = new HashMap(); - - if(!isUserLogged(httpSession)) { - response.put("message", "User is not logged"); - return new ResponseEntity<>(response, HttpStatus.UNAUTHORIZED); - } - - if(roomName == null || participantName == null) { - response.put("message", "roomName and participantName are required"); - return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); - } - - MyUser user = LoginController.users.get(httpSession.getAttribute("loggedUser")); - Boolean canPublish = user.role.equals("PUBLISHER"); - - // By default, tokens expire 6 hours after generation. - // You may override this by using token.setTtl(long millis). - AccessToken token = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET); - token.setName(participantName); - token.setIdentity(participantName); - - JSONObject metadata = new JSONObject(); - metadata.put("livekitUrl", LIVEKIT_URL); - metadata.put("user", user.name); - metadata.put("role", user.role); - // add metadata to the token, which will be available in the participant's metadata - token.setMetadata(metadata.toString()); - token.addGrants(new RoomJoin(true), new RoomName(roomName), new CanPublish(canPublish), new CanSubscribe(true)); - - response.put("token", token.toJwt()); - return new ResponseEntity<>(response, HttpStatus.OK); - } - - - private boolean isUserLogged(HttpSession httpSession) { - return httpSession != null && httpSession.getAttribute("loggedUser") != null; - } - -} diff --git a/advanced-features/openvidu-roles-java/src/main/resources/application.properties b/advanced-features/openvidu-roles-java/src/main/resources/application.properties deleted file mode 100644 index fdd2327b..00000000 --- a/advanced-features/openvidu-roles-java/src/main/resources/application.properties +++ /dev/null @@ -1,11 +0,0 @@ -server.port: 5000 -server.ssl.enabled: true -server.ssl.key-store: classpath:openvidu-selfsigned.jks -server.ssl.key-store-password: openvidu -server.ssl.key-store-type: JKS -server.ssl.key-alias: openvidu-selfsigned - - -LIVEKIT_URL: ws://localhost:7880/ -LIVEKIT_API_KEY: devkey -LIVEKIT_API_SECRET: secret \ No newline at end of file diff --git a/advanced-features/openvidu-roles-java/src/main/resources/openvidu-selfsigned.jks b/advanced-features/openvidu-roles-java/src/main/resources/openvidu-selfsigned.jks deleted file mode 100644 index 4a02ecc4..00000000 Binary files a/advanced-features/openvidu-roles-java/src/main/resources/openvidu-selfsigned.jks and /dev/null differ diff --git a/advanced-features/openvidu-roles-java/src/main/resources/static/app.js b/advanced-features/openvidu-roles-java/src/main/resources/static/app.js deleted file mode 100644 index 57d8ded7..00000000 --- a/advanced-features/openvidu-roles-java/src/main/resources/static/app.js +++ /dev/null @@ -1,274 +0,0 @@ -var LivekitClient = window.LivekitClient; -var room; -var myRoomName; -var token; -var nickname; - -/* OPENVIDU METHODS */ - -function joinRoom() { - document.getElementById('join-btn').disabled = true; - document.getElementById('join-btn').innerHTML = 'Joining...'; - const myParticipantName = $('#myParticipantName').val(); - const myRoomName = $('#myRoomName').val(); - - room = new LivekitClient.Room(); - - room.on( - LivekitClient.RoomEvent.TrackSubscribed, - (track, publication, participant) => { - const element = track.attach(); - element.id = track.sid; - element.className = 'removable'; - document.getElementById('video-container').appendChild(element); - if (track.kind === 'video') { - var participantNickname; - try { - participantNickname = JSON.parse(participant.metadata).nickname; - } catch (error) { - console.warn('Error parsing participant metadata: ' + error); - } - appendUserData(element, participant.identity, participantNickname); - } - } - ); - - // On every new Track destroyed... - room.on( - LivekitClient.RoomEvent.TrackUnsubscribed, - (track, publication, participant) => { - track.detach(); - document.getElementById(track.sid)?.remove(); - if (track.kind === 'video') { - removeUserData(participant); - } - } - ); - - getToken(myRoomName, myParticipantName).then((token) => { - const livekitUrl = getLivekitUrlFromMetadata(token); - - room - .connect(livekitUrl, token) - .then(async () => { - var participantName = $('#user').val(); - $('#room-title').text(myRoomName); - $('#join').hide(); - $('#room').show(); - - const canPublish = room.localParticipant.permissions.canPublish; - - if (canPublish) { - const [microphonePublication, cameraPublication] = await Promise.all([ - room.localParticipant.setMicrophoneEnabled(true), - room.localParticipant.setCameraEnabled(true), - ]); - - const element = cameraPublication.track.attach(); - element.className = 'removable'; - document.getElementById('video-container').appendChild(element); - initMainVideo(element, myParticipantName, nickname); - appendUserData(element, myParticipantName, nickname); - } else { - initMainVideoThumbnail(); - } - }) - .catch((error) => { - console.warn( - 'There was an error connecting to the room:', - error.code, - error.message - ); - enableBtn(); - }); - }); - - return false; -} - -function leaveRoom() { - room.disconnect(); - room = null; - - // Removing all HTML elements with the user's nicknames - cleanRoomView(); - - $('#join').show(); - $('#room').hide(); - - enableBtn(); -} - -/* OPENVIDU METHODS */ - -function enableBtn() { - document.getElementById('join-btn').disabled = false; - document.getElementById('join-btn').innerHTML = 'Join!'; -} - -/* APPLICATION REST METHODS */ - -function logIn() { - nickname = $('#user').val(); - var pass = $('#pass').val(); - - httpPostRequest( - 'login', - { user: nickname, pass }, - 'Login WRONG', - (response) => { - $('#name-user').text(nickname); - $('#not-logged').hide(); - $('#logged').show(); - // Random myParticipantName and room - $('#myRoomName').val('Room ' + Math.floor(Math.random() * 10)); - $('#myParticipantName').val( - 'Participant ' + Math.floor(Math.random() * 100) - ); - } - ); -} - -function logOut() { - httpPostRequest('logout', {}, 'Logout WRONG', (response) => { - $('#not-logged').show(); - $('#logged').hide(); - }); - - enableBtn(); -} - -function getToken(roomName, participantName) { - return new Promise((resolve, reject) => { - // Video-call chosen by the user - httpPostRequest( - 'token', - { roomName, participantName }, - 'Error generating token', - (response) => resolve(response.token) - ); - }); -} - -async function httpPostRequest(url, body, errorMsg, successCallback) { - try { - const response = await fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(body), - }); - - if (response.ok) { - const data = await response.json(); - successCallback(data); - } else { - console.warn(errorMsg); - console.warn('Error: ', response); - } - } catch (error) { - console.error(error); - } -} - -/* APPLICATION REST METHODS */ - -/* APPLICATION BROWSER METHODS */ - -window.onbeforeunload = () => { - if (room) { - leaveRoom(); - } - logOut(); -}; - -function getLivekitUrlFromMetadata(token) { - if (!token) throw new Error('Trying to get metadata from an empty token'); - try { - const base64Url = token.split('.')[1]; - const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); - const jsonPayload = decodeURIComponent( - window - .atob(base64) - .split('') - .map((c) => { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }) - .join('') - ); - - const payload = JSON.parse(jsonPayload); - if (!payload?.metadata) throw new Error('Token does not contain metadata'); - const metadata = JSON.parse(payload.metadata); - return metadata.livekitUrl; - } catch (error) { - throw new Error('Error decoding and parsing token: ' + error); - } -} - -function appendUserData(videoElement, participantName, nickname) { - var dataNode = document.createElement('div'); - dataNode.className = 'removable'; - dataNode.id = 'data-' + participantName; - dataNode.innerHTML = ` -

${nickname}

-

${participantName}

- `; - videoElement.parentNode.insertBefore(dataNode, videoElement.nextSibling); - addClickListener(videoElement, participantName); -} - -function removeUserData(participant) { - var dataNode = document.getElementById('data-' + participant.identity); - dataNode?.parentNode.removeChild(dataNode); -} - -function removeAllUserData() { - var elementsToRemove = document.getElementsByClassName('removable'); - while (elementsToRemove[0]) { - elementsToRemove[0].parentNode.removeChild(elementsToRemove[0]); - } -} - -function cleanMainVideo() { - $('#main-video video').get(0).srcObject = null; - $('#main-video p').each(function () { - $(this).html(''); - }); -} - -function addClickListener(videoElement, clientData, serverData) { - videoElement.addEventListener('click', function () { - var mainVideo = $('#main-video video').get(0); - if (mainVideo.srcObject !== videoElement.srcObject) { - $('#main-video').fadeOut('fast', () => { - $('#main-video p.nickname').html(clientData); - $('#main-video p.participantName').html(serverData); - mainVideo.srcObject = videoElement.srcObject; - $('#main-video').fadeIn('fast'); - }); - } - }); -} - -function initMainVideo(videoElement, participantName, nickname) { - $('#main-video video').get(0).srcObject = videoElement.srcObject; - $('#main-video p.nickname').html(nickname); - $('#main-video p.participantName').html(participantName); -} - -function initMainVideoThumbnail() { - $('#main-video video').css( - 'background', - "url('images/subscriber-msg.jpg') round" - ); -} - -function cleanRoomView() { - removeAllUserData(); - cleanMainVideo(); - $('#main-video video').css('background', ''); -} - -/* APPLICATION BROWSER METHODS */ diff --git a/advanced-features/openvidu-roles-java/src/main/resources/static/images/favicon.ico b/advanced-features/openvidu-roles-java/src/main/resources/static/images/favicon.ico deleted file mode 100644 index 0e2249ad..00000000 Binary files a/advanced-features/openvidu-roles-java/src/main/resources/static/images/favicon.ico and /dev/null differ diff --git a/advanced-features/openvidu-roles-java/src/main/resources/static/images/openvidu_globe_bg_transp_cropped.png b/advanced-features/openvidu-roles-java/src/main/resources/static/images/openvidu_globe_bg_transp_cropped.png deleted file mode 100644 index e0309e62..00000000 Binary files a/advanced-features/openvidu-roles-java/src/main/resources/static/images/openvidu_globe_bg_transp_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-roles-java/src/main/resources/static/images/openvidu_grey_bg_transp_cropped.png b/advanced-features/openvidu-roles-java/src/main/resources/static/images/openvidu_grey_bg_transp_cropped.png deleted file mode 100644 index 49f311a6..00000000 Binary files a/advanced-features/openvidu-roles-java/src/main/resources/static/images/openvidu_grey_bg_transp_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-roles-java/src/main/resources/static/images/openvidu_vert_white_bg_trans_cropped.png b/advanced-features/openvidu-roles-java/src/main/resources/static/images/openvidu_vert_white_bg_trans_cropped.png deleted file mode 100644 index a1c8b2d7..00000000 Binary files a/advanced-features/openvidu-roles-java/src/main/resources/static/images/openvidu_vert_white_bg_trans_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-roles-java/src/main/resources/static/images/subscriber-msg.jpg b/advanced-features/openvidu-roles-java/src/main/resources/static/images/subscriber-msg.jpg deleted file mode 100644 index 1666fb40..00000000 Binary files a/advanced-features/openvidu-roles-java/src/main/resources/static/images/subscriber-msg.jpg and /dev/null differ diff --git a/advanced-features/openvidu-roles-java/src/main/resources/static/index.html b/advanced-features/openvidu-roles-java/src/main/resources/static/index.html deleted file mode 100644 index b1520ef7..00000000 --- a/advanced-features/openvidu-roles-java/src/main/resources/static/index.html +++ /dev/null @@ -1,210 +0,0 @@ - - - openvidu-roles-node - - - - - - - - - - - - - - - - - - - - -
-
-
- -
-
-

- -

-

- -

-

- -

-
- - - - - - - - - - - - - - - - - - - - - -
UserPassword - Role -
publisher1passPUBLISHER
publisher2passPUBLISHER
subscriberpassSUBSCRIBER
-
- - -
- -
-
-
OpenVidu © 2023
- -
-
- - diff --git a/advanced-features/openvidu-roles-java/src/main/resources/static/style.css b/advanced-features/openvidu-roles-java/src/main/resources/static/style.css deleted file mode 100644 index df8d5c94..00000000 --- a/advanced-features/openvidu-roles-java/src/main/resources/static/style.css +++ /dev/null @@ -1,382 +0,0 @@ -html { - position: relative; - min-height: 100%; -} - -nav { - height: 50px; - width: 100%; - z-index: 1; - background-color: #4d4d4d !important; - border-color: #4d4d4d !important; - border-top-right-radius: 0 !important; - border-top-left-radius: 0 !important; -} - -.navbar { - margin-bottom: 0px !important; -} - -.navbar-header { - width: 100%; -} - -.nav-icon { - padding: 5px 15px 5px 15px; - float: right; -} - -nav a { - color: #ccc !important; -} - -nav i.fa { - font-size: 40px; - color: #ccc; -} - -nav a:hover { - color: #a9a9a9 !important; -} - -nav i.fa:hover { - color: #a9a9a9; -} - -#main-container { - padding-bottom: 80px; - display: contents; -} - -.vertical-center { - width: -webkit-fit-content; - width: fit-content; - margin: auto; -} - -.vertical-center#not-logged form { - width: -moz-fit-content; - margin: auto; -} - -.vertical-center#not-logged table { - width: -moz-fit-content; - margin: auto; -} - -.vertical-center table { - margin-top: 3em !important; -} - -.horizontal-center { - margin: 0 auto; -} - -.form-control { - color: #0088aa; - font-weight: bold; -} - -.form-control:focus { - border-color: #0088aa; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(0, 136, 170, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(0, 136, 170, 0.6); -} - -input.btn { - font-weight: bold; -} - -.btn { - font-weight: bold !important; -} - -.btn-success { - background-color: #06d362 !important; - border-color: #06d362; -} - -.btn-success:hover { - background-color: #1abd61 !important; - border-color: #1abd61; -} - -.btn-info { - background-color: #0088aa !important; - border-color: #0088aa; -} - -.btn-info:hover { - background-color: #00708c !important; - border-color: #00708c; -} - -.btn-warning { - background-color: #ffcc00 !important; - border-color: #ffcc00; - color: #4d4d4d; -} - -.btn-warning:hover { - background-color: #eabb3a !important; - border-color: #eabb3a; - color: #4d4d4d; -} - -.btn-warning:active { - color: #4d4d4d; -} - -.btn-warning:focus { - color: #4d4d4d; -} - -.btn-warning:active:focus { - color: #4d4d4d; -} - -.footer { - position: absolute; - bottom: 0; - width: 100%; - height: 60px; - background-color: #4d4d4d; -} - -.footer .text-muted { - margin: 20px 0; - float: left; - color: #ccc; -} - -.openvidu-logo { - height: 35px; - float: right; - margin: 12px 0; - -webkit-transition: all 0.1s ease-in-out; - -moz-transition: all 0.1s ease-in-out; - -o-transition: all 0.1s ease-in-out; - transition: all 0.1s ease-in-out; -} - -.openvidu-logo:hover { - -webkit-filter: grayscale(0.5); - filter: grayscale(0.5); -} - -.demo-logo { - margin: 0; - height: 22px; - float: left; - padding-right: 8px; -} - -a:hover .demo-logo { - -webkit-filter: brightness(0.7); - filter: brightness(0.7); -} - -#join { - padding-top: 40px; -} - -#not-logged { - padding-top: 40px; -} - -#join-dialog h1 { - color: #4d4d4d; - font-weight: bold; - text-align: center; -} - -#join-dialog label { - color: #0088aa; -} - -#join-dialog input.btn { - margin-top: 15px; -} - -#join-dialog hr { - background: #4d4d4d; -} - -#img-div { - text-align: center; - padding-bottom: 3em; -} - -#img-div img { - height: 15%; -} - -#logged { - width: 100%; -} - -#join { - max-width: 700px; - margin: auto; -} - -#room-header { - margin-bottom: 20px; -} - -#room-header form { - display: inline; -} - -#room-title { - display: inline-block; -} - -#buttonLeaveRoom { - float: right; - margin-top: 20px; -} - -#video-container video { - position: relative; - float: left; - width: 50%; - cursor: pointer; -} - -#video-container div { - float: left; - width: 50%; - position: relative; - margin-left: -50%; -} - -#video-container p { - display: inline-block; - background: #f8f8f8; - padding-left: 5px; - padding-right: 5px; - color: #777777; - font-weight: bold; - border-bottom-right-radius: 4px; -} - -#video-container p.nickname { - float: right; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 0px; - font-weight: lighter; - font-size: 12px; - background: #777777; - color: #f8f8f8; -} - -video { - width: 100%; - height: auto; -} - -#main-video p { - position: absolute; - display: inline-block; - background: #f8f8f8; - padding-left: 5px; - padding-right: 5px; - font-size: 22px; - color: #777777; - font-weight: bold; - border-bottom-right-radius: 4px; -} - -#main-video p.nickname { - position: absolute; - right: 0; - font-size: 16px !important; - margin-right: 15px; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 0px; - font-weight: lighter; - font-size: 12px; - background: #777777; - color: #f8f8f8; -} - - -#room img { - width: 100%; - height: auto; - display: inline-block; - object-fit: contain; - vertical-align: baseline; -} - -#room #video-container img { - position: relative; - float: left; - width: 50%; - cursor: pointer; - object-fit: cover; - height: 180px; -} - -table i { - cursor: pointer; - margin-left: 1em; -} - -#tooltip-div { - text-align: left; -} - -#tooltip-div hr { - margin: 5px 0; -} - -#login-info { - text-align: right; -} - -#login-info form { - display: inline; -} - -#login-info div { - display: inline; - margin-right: 1em; -} - -#name-user { - font-weight: bold; -} - - -/* xs ans md screen resolutions*/ - -@media screen and (max-width: 991px) { - #join { - padding-top: inherit; - } - - #not-logged { - padding-top: inherit; - } - .container .navbar-header { - margin-right: 0 !important; - margin-left: 0 !important; - } - .nav-icon { - padding: 9px 8px 9px 8px; - } - nav i.fa { - font-size: 32px; - } - .vertical-center { - padding-top: 10px; - } - #img-div { - padding-bottom: 1em; - } - #img-div img { - height: 10%; - } -} \ No newline at end of file diff --git a/advanced-features/openvidu-roles-java/src/test/java/io/openvidu/js/java/test/AppTest.java b/advanced-features/openvidu-roles-java/src/test/java/io/openvidu/js/java/test/AppTest.java deleted file mode 100644 index 0ba99ec8..00000000 --- a/advanced-features/openvidu-roles-java/src/test/java/io/openvidu/js/java/test/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.openvidu.js.java.test; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Unit test for simple App. - */ -public class AppTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest( String testName ) - { - super( testName ); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( AppTest.class ); - } - - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); - } -} diff --git a/advanced-features/openvidu-roles-node/.gitignore b/advanced-features/openvidu-roles-node/.gitignore deleted file mode 100644 index dbe3e1ad..00000000 --- a/advanced-features/openvidu-roles-node/.gitignore +++ /dev/null @@ -1,60 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Typescript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env - -.vscode/ diff --git a/advanced-features/openvidu-roles-node/LICENSE b/advanced-features/openvidu-roles-node/LICENSE deleted file mode 100644 index 8dada3ed..00000000 --- a/advanced-features/openvidu-roles-node/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/advanced-features/openvidu-roles-node/README.md b/advanced-features/openvidu-roles-node/README.md deleted file mode 100644 index 8e57e05c..00000000 --- a/advanced-features/openvidu-roles-node/README.md +++ /dev/null @@ -1,14 +0,0 @@ -[![License badge](https://img.shields.io/badge/license-Apache2-orange.svg)](http://www.apache.org/licenses/LICENSE-2.0) -[![OpenVidu Tests](https://github.com/OpenVidu/openvidu/actions/workflows/openvidu-ce-test.yml/badge.svg)](https://github.com/OpenVidu/openvidu/actions/workflows/openvidu-ce-test.yml) -[![Documentation Status](https://readthedocs.org/projects/openvidu/badge/?version=stable)](https://docs.openvidu.io/en/stable/?badge=stable) -[![Docker badge](https://img.shields.io/docker/pulls/openvidu/openvidu-server-kms.svg)](https://hub.docker.com/r/openvidu/openvidu-server-kms) -[![Support badge](https://img.shields.io/badge/support-sof-yellowgreen.svg)](https://openvidu.discourse.group/) - -[![][OpenViduLogo]](http://openvidu.io) - -openvidu-roles-node -=== - -Visit [docs.openvidu.io/en/stable/tutorials/openvidu-roles-node/](http://docs.openvidu.io/en/stable/tutorials/openvidu-roles-node/) - -[OpenViduLogo]: https://secure.gravatar.com/avatar/5daba1d43042f2e4e85849733c8e5702?s=120 \ No newline at end of file diff --git a/advanced-features/openvidu-roles-node/docker/Dockerfile b/advanced-features/openvidu-roles-node/docker/Dockerfile deleted file mode 100644 index bed26f62..00000000 --- a/advanced-features/openvidu-roles-node/docker/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM node:16-alpine3.16 - -# Copy openvidu-roles-node -COPY . /opt/openvidu-roles-node - -# Install openvidu-roles-node dependencies -RUN npm --prefix /opt/openvidu-roles-node install - -WORKDIR /opt/openvidu-roles-node - -COPY docker/entrypoint.sh . - -ENTRYPOINT [ "./entrypoint.sh" ] \ No newline at end of file diff --git a/advanced-features/openvidu-roles-node/docker/create_image.sh b/advanced-features/openvidu-roles-node/docker/create_image.sh deleted file mode 100644 index c203bd6b..00000000 --- a/advanced-features/openvidu-roles-node/docker/create_image.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -if [ $# -eq 0 ]; then - echo "No version argument provided. Usage: \"./create_image.sh \"" - exit 1 -fi - -pushd ../ -docker build --pull --no-cache --rm=true -f docker/Dockerfile -t "$1" . diff --git a/advanced-features/openvidu-roles-node/docker/entrypoint.sh b/advanced-features/openvidu-roles-node/docker/entrypoint.sh deleted file mode 100644 index b7163954..00000000 --- a/advanced-features/openvidu-roles-node/docker/entrypoint.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -exec node server.js "$*" \ No newline at end of file diff --git a/advanced-features/openvidu-roles-node/nginx.conf b/advanced-features/openvidu-roles-node/nginx.conf deleted file mode 100644 index 500c543d..00000000 --- a/advanced-features/openvidu-roles-node/nginx.conf +++ /dev/null @@ -1,44 +0,0 @@ -events { - worker_connections 512; -} -http { - upstream openvidu-deployment { - server host.docker.internal:4443; - } - upstream client-application { - server host.docker.internal:5000; - } - server { - listen 443 ssl; - ssl_certificate /etc/nginx/certs/cert.pem; - ssl_certificate_key /etc/nginx/certs/key.pem; - - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Proto https; - proxy_headers_hash_bucket_size 512; - proxy_redirect off; - - # Websockets - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # OpenVidu deployment API - location /openvidu/api { - proxy_pass http://openvidu-deployment; - } - - # OpenVidu WebSocket - location ~ /openvidu$ { - proxy_pass http://openvidu-deployment; - } - - # Client application requests - location / { - proxy_pass https://client-application; - } - } -} \ No newline at end of file diff --git a/advanced-features/openvidu-roles-node/openviducert.pem b/advanced-features/openvidu-roles-node/openviducert.pem deleted file mode 100644 index 545ccee2..00000000 --- a/advanced-features/openvidu-roles-node/openviducert.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDgzCCAmugAwIBAgIJALDBPXTrlAhlMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV -BAYTAkVTMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhPcGVuVmlkdTEh -MB8GCSqGSIb3DQEJARYSb3BlbnZpZHVAZ21haWwuY29tMB4XDTE3MDUzMDE1MjQx -N1oXDTI3MDUyODE1MjQxN1owWDELMAkGA1UEBhMCRVMxEzARBgNVBAgMClNvbWUt -U3RhdGUxETAPBgNVBAoMCE9wZW5WaWR1MSEwHwYJKoZIhvcNAQkBFhJvcGVudmlk -dUBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDbK/i -LN80IBnGUbzA4AFl4KQEX6RCreythnfOSnIcQSTP+KjesZMFgsGV0LteDxeCJ+kq -4YoS+CW7ojvOEz3xjCgo4tFdevz8ZoeO0RBQIbARbPako4OXC6vWs6LHwCR0aDWo -9HfS1Uusb8g77csRPRlNA3DGR8dcRTiEBdfHS6Jh/7V7XiDlaxPXj+iIY8PyCqOf -gv4clDt17R+dendDsgYxbmZaodrppNocMQIyUaDIwI4DZOa8nQYk9uuUhkiAFAQB -O642bx6NI0qDu5KgtMmbaS6s+rMnrL8eeZOicqff6XoC6tk6GE8Fo4iYkxp2gAiT -sigaSwpNRWhupISVAgMBAAGjUDBOMB0GA1UdDgQWBBTi3sXqpf42vUNehFU6y4Pn -PTJFRDAfBgNVHSMEGDAWgBTi3sXqpf42vUNehFU6y4PnPTJFRDAMBgNVHRMEBTAD -AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBfl0C7XAbPdJzCjCsboMTzfC2B4uwspbST -MbUGnmNkTwzeOOsrLQmlCznKGprYV9vGR0MwBzYw2swWCzg/2MLN8swW7NF9gMkK -K61AANxT0qZV/aZhdM7W//pHJoQYsBsQT7cuTrL/VB/niD81uMA/mSWyXIn8KDIy -CPY6jiZ4qiIJnQWhWm1Cazv6O7wjDisvB1cCJhDvBv42KkFwtigt5MQnBEGOI2LD -iKCkXfj33E5B6n0sEel68WgYi6rx2tsR9lzAjCRF+jgNd7FfeUi999m7ykgEACR5 -OYRqkVcIXz30r9RxQyFqZLNzyO9oaVZpex8ZbWwEzNXG2ccddnMJ ------END CERTIFICATE----- diff --git a/advanced-features/openvidu-roles-node/openvidukey.pem b/advanced-features/openvidu-roles-node/openvidukey.pem deleted file mode 100644 index 9b47696d..00000000 --- a/advanced-features/openvidu-roles-node/openvidukey.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAw2yv4izfNCAZxlG8wOABZeCkBF+kQq3srYZ3zkpyHEEkz/io -3rGTBYLBldC7Xg8XgifpKuGKEvglu6I7zhM98YwoKOLRXXr8/GaHjtEQUCGwEWz2 -pKODlwur1rOix8AkdGg1qPR30tVLrG/IO+3LET0ZTQNwxkfHXEU4hAXXx0uiYf+1 -e14g5WsT14/oiGPD8gqjn4L+HJQ7de0fnXp3Q7IGMW5mWqHa6aTaHDECMlGgyMCO -A2TmvJ0GJPbrlIZIgBQEATuuNm8ejSNKg7uSoLTJm2kurPqzJ6y/HnmTonKn3+l6 -AurZOhhPBaOImJMadoAIk7IoGksKTUVobqSElQIDAQABAoIBAGr/2HFjFjbpGJOw -b0O/oqRQUh2e7EYiCoOcK37E3iPAO1KvmG6OFayfwjSwG9bNNpbqGU2EPeBTA/3v -PwV/HZxinB5+yhl/3IKp9LDqoR7uwwNXgNf2O3d5SXX91zO9bXhbEn5WlEDYzl00 -uxKtCVF//ZlgN+AoruxDbkVDGbkhKHGzvqOW+BWwbYHPOttQ9TQx2ss5+DekpDFV -/FuvXGOcSSV/N+WbDwsqUiM8ovkcflEgQjZYlAY4Ro2U2buf3fKEmy1jxSznNp30 -QA4WyYypyS8Hz6S/F4nsjtS3ufCurrWBv4vt2qB+8tH//07NUacjQWZdvEAtaJ+G -IyJgsOUCgYEA38b2SQiw74fwoK6so2XdpCzOObLQBOT1aeZQjt3v8XZ0MPzwWJZm -VkMBmolcEw24xA3jHhOQYafAGjRdaKxlRbJyGJqwENfAs7hO5JSLLWWXsorJQcb7 -1OVTFPt7NZopx2Kw7kGGuj9884w57cSl9lsuMptqk8W7pbTo5opOfl8CgYEA35CR -x23kaFDh8+zKUuSdIrkUJ66cazgOfF0FYKiDewd1sGEdZT+gq7Wo8Hi8cp9q+Kuq -MkGrTzu21yMi2fo7RKoSOtV4RQViu6PuoYR/KvRq4F4abHEAivAG4xhPQife84IB -NkDQXaE9EXTP7DXPwj4HV8CnC9LC2qPFU7GVeYsCgYBWPK6c5qSJKrIouif9sDwC -EOJIighwWmvZK9DPvefB/gw49MEK4qr9g0US8Oxyy07w/wkPhiqV97eoYZW9yPIe -Me6WXMaNNxgkKlr86+HW1NfpDmMQ3kYefWHPLDsHJSoElJvqtYXeMKlOkjOg1a+/ -iNP83Lftyr3N1jIK5jHpsQKBgE1+clm7qOnT547C7JrxLdrEZs0ehI/R3YuUPvHz -V6gEvPHHqAXZmVsL3CSG5WOiCNVrw9Ip2zTa0RUf08vVJkg1353PMyJRrJi4SVZp -dB8ym/1sASLHxNVkQC7l1UtsQKcN0Fe6/b8GzgFICW6qdHqzP55WZFD/3JUnIZZS -PyrjAoGBAMfuE0Nrw9Fq7f8+U/SsqiW9djJp4R34EF5n8qHkotfRoAbGktCGxLoF -QMbB9X0ibRMpxEKPHj+V0FXu9zUKFuqoriRc3alQYLNzJEdKeQQ/AN5xjG3ilM6D -/FunImbvSdJLjR9Ue6vlFdOquHevBCFDiHOJPQJ/y4qyZR5Avluw ------END RSA PRIVATE KEY----- diff --git a/advanced-features/openvidu-roles-node/package-lock.json b/advanced-features/openvidu-roles-node/package-lock.json deleted file mode 100644 index 449d94a3..00000000 --- a/advanced-features/openvidu-roles-node/package-lock.json +++ /dev/null @@ -1,1145 +0,0 @@ -{ - "name": "openvidu-roles-node", - "version": "2.27.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "openvidu-roles-node", - "version": "2.27.0", - "license": "Apache-2.0", - "dependencies": { - "body-parser": "1.20.2", - "cors": "2.8.5", - "dotenv": "^16.3.1", - "express": "4.18.2", - "express-session": "1.17.3", - "livekit-server-sdk": "1.2.7" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@types/node": { - "version": "20.8.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", - "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", - "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", - "dependencies": { - "camelcase": "^6.3.0", - "map-obj": "^4.1.0", - "quick-lru": "^5.1.1", - "type-fest": "^1.2.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-session": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", - "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", - "dependencies": { - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-headers": "~1.0.2", - "parseurl": "~1.3.3", - "safe-buffer": "5.2.1", - "uid-safe": "~2.1.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/express-session/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsonwebtoken/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/livekit-server-sdk": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/livekit-server-sdk/-/livekit-server-sdk-1.2.7.tgz", - "integrity": "sha512-tOhRb0vz1wBzMpTkP4ixptlC9MFME24PvG8Z/R7vBbQ1VGd6EdNr56voBSr+RCalYxaQqx0E9Gg4l+57m/Nlmw==", - "dependencies": { - "axios": "^1.3.6", - "camelcase-keys": "^7.0.0", - "jsonwebtoken": "^9.0.0", - "long": "^5.0.0", - "protobufjs": "^7.2.4" - } - }, - "node_modules/livekit-server-sdk/node_modules/axios": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", - "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/protobufjs": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", - "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/uid-safe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", - "dependencies": { - "random-bytes": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } -} diff --git a/advanced-features/openvidu-roles-node/package.json b/advanced-features/openvidu-roles-node/package.json deleted file mode 100644 index 6c6e32af..00000000 --- a/advanced-features/openvidu-roles-node/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "openvidu-roles-node", - "version": "2.27.0", - "description": "", - "main": "server.js", - "scripts": { - "test": "ng test" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/OpenVidu/openvidu-tutorials.git" - }, - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/OpenVidu/openvidu-tutorials/issues" - }, - "homepage": "https://github.com/OpenVidu/openvidu-tutorials#readme", - "dependencies": { - "body-parser": "1.20.2", - "cors": "2.8.5", - "dotenv": "^16.3.1", - "express": "4.18.2", - "express-session": "1.17.3", - "livekit-server-sdk": "1.2.7" - } -} diff --git a/advanced-features/openvidu-roles-node/public/app.js b/advanced-features/openvidu-roles-node/public/app.js deleted file mode 100644 index 7bc48a6b..00000000 --- a/advanced-features/openvidu-roles-node/public/app.js +++ /dev/null @@ -1,274 +0,0 @@ -var LivekitClient = window.LivekitClient; -var room; -var myRoomName; -var token; -var nickname; - -/* OPENVIDU METHODS */ - -function joinRoom() { - document.getElementById('join-btn').disabled = true; - document.getElementById('join-btn').innerHTML = 'Joining...'; - const myParticipantName = $('#myParticipantName').val(); - const myRoomName = $('#myRoomName').val(); - - room = new LivekitClient.Room(); - - room.on( - LivekitClient.RoomEvent.TrackSubscribed, - (track, publication, participant) => { - const element = track.attach(); - element.id = track.sid; - element.className = 'removable'; - document.getElementById('video-container').appendChild(element); - if (track.kind === 'video') { - var participantNickname; - try { - participantNickname = JSON.parse(participant.metadata).nickname; - } catch (error) { - console.warn('Error parsing participant metadata: ' + error); - } - appendUserData(element, participant.identity, participantNickname); - } - } - ); - - // On every new Track destroyed... - room.on( - LivekitClient.RoomEvent.TrackUnsubscribed, - (track, publication, participant) => { - track.detach(); - document.getElementById(track.sid)?.remove(); - if (track.kind === 'video') { - removeUserData(participant); - } - } - ); - - getToken(myRoomName, myParticipantName).then((token) => { - const livekitUrl = getLivekitUrlFromMetadata(token); - - room - .connect(livekitUrl, token) - .then(async () => { - var participantName = $('#user').val(); - $('#room-title').text(myRoomName); - $('#join').hide(); - $('#room').show(); - - const canPublish = room.localParticipant.permissions.canPublish; - - if (canPublish) { - const [microphonePublication, cameraPublication] = await Promise.all([ - room.localParticipant.setMicrophoneEnabled(true), - room.localParticipant.setCameraEnabled(true), - ]); - - const element = cameraPublication.track.attach(); - element.className = 'removable'; - document.getElementById('video-container').appendChild(element); - initMainVideo(element, myParticipantName, nickname); - appendUserData(element, myParticipantName, nickname); - } else { - initMainVideoThumbnail(); - } - }) - .catch((error) => { - console.warn( - 'There was an error connecting to the room:', - error.code, - error.message - ); - enableBtn(); - }); - }); - - return false; -} - -function leaveRoom() { - room.disconnect(); - room = null; - - // Removing all HTML elements with the user's nicknames - cleanRoomView(); - - $('#join').show(); - $('#room').hide(); - - enableBtn(); -} - -/* OPENVIDU METHODS */ - -function enableBtn() { - document.getElementById('join-btn').disabled = false; - document.getElementById('join-btn').innerHTML = 'Join!'; -} - -/* APPLICATION REST METHODS */ - -function logIn() { - nickname = $('#user').val(); - var pass = $('#pass').val(); - - httpPostRequest( - 'login', - { user: nickname, pass }, - 'Login WRONG', - (response) => { - $('#name-user').text(nickname); - $('#not-logged').hide(); - $('#logged').show(); - // Random myParticipantName and room - $('#myRoomName').val('Room ' + Math.floor(Math.random() * 10)); - $('#myParticipantName').val( - 'Participant ' + Math.floor(Math.random() * 100) - ); - } - ); -} - -function logOut() { - httpPostRequest('logout', {}, 'Logout WRONG', (response) => { - $('#not-logged').show(); - $('#logged').hide(); - }); - - enableBtn(); -} - -function getToken(roomName, participantName) { - return new Promise((resolve, reject) => { - // Video-call chosen by the user - httpPostRequest( - 'token', - { roomName, participantName }, - 'Error generating token', - (response) => resolve(response.token) - ); - }); -} - -async function httpPostRequest(url, body, errorMsg, successCallback) { - try { - const response = await fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(body), - }); - - if (response.ok) { - const data = await response.json(); - successCallback(data); - } else { - console.warn(errorMsg); - console.warn('Error: ' + response.statusText); - } - } catch (error) { - console.error(error); - } -} - -/* APPLICATION REST METHODS */ - -/* APPLICATION BROWSER METHODS */ - -window.onbeforeunload = () => { - if (room) { - leaveRoom(); - } - logOut(); -}; - -function getLivekitUrlFromMetadata(token) { - if (!token) throw new Error('Trying to get metadata from an empty token'); - try { - const base64Url = token.split('.')[1]; - const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); - const jsonPayload = decodeURIComponent( - window - .atob(base64) - .split('') - .map((c) => { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }) - .join('') - ); - - const payload = JSON.parse(jsonPayload); - if (!payload?.metadata) throw new Error('Token does not contain metadata'); - const metadata = JSON.parse(payload.metadata); - return metadata.livekitUrl; - } catch (error) { - throw new Error('Error decoding and parsing token: ' + error); - } -} - -function appendUserData(videoElement, participantName, nickname) { - var dataNode = document.createElement('div'); - dataNode.className = 'removable'; - dataNode.id = 'data-' + participantName; - dataNode.innerHTML = ` -

${nickname}

-

${participantName}

- `; - videoElement.parentNode.insertBefore(dataNode, videoElement.nextSibling); - addClickListener(videoElement, participantName); -} - -function removeUserData(participant) { - var dataNode = document.getElementById('data-' + participant.identity); - dataNode?.parentNode.removeChild(dataNode); -} - -function removeAllUserData() { - var elementsToRemove = document.getElementsByClassName('removable'); - while (elementsToRemove[0]) { - elementsToRemove[0].parentNode.removeChild(elementsToRemove[0]); - } -} - -function cleanMainVideo() { - $('#main-video video').get(0).srcObject = null; - $('#main-video p').each(function () { - $(this).html(''); - }); -} - -function addClickListener(videoElement, clientData, serverData) { - videoElement.addEventListener('click', function () { - var mainVideo = $('#main-video video').get(0); - if (mainVideo.srcObject !== videoElement.srcObject) { - $('#main-video').fadeOut('fast', () => { - $('#main-video p.nickname').html(clientData); - $('#main-video p.participantName').html(serverData); - mainVideo.srcObject = videoElement.srcObject; - $('#main-video').fadeIn('fast'); - }); - } - }); -} - -function initMainVideo(videoElement, participantName, nickname) { - $('#main-video video').get(0).srcObject = videoElement.srcObject; - $('#main-video p.nickname').html(nickname); - $('#main-video p.participantName').html(participantName); -} - -function initMainVideoThumbnail() { - $('#main-video video').css( - 'background', - "url('images/subscriber-msg.jpg') round" - ); -} - -function cleanRoomView() { - removeAllUserData(); - cleanMainVideo(); - $('#main-video video').css('background', ''); -} - -/* APPLICATION BROWSER METHODS */ diff --git a/advanced-features/openvidu-roles-node/public/images/favicon.ico b/advanced-features/openvidu-roles-node/public/images/favicon.ico deleted file mode 100644 index 0e2249ad..00000000 Binary files a/advanced-features/openvidu-roles-node/public/images/favicon.ico and /dev/null differ diff --git a/advanced-features/openvidu-roles-node/public/images/openvidu_globe_bg_transp_cropped.png b/advanced-features/openvidu-roles-node/public/images/openvidu_globe_bg_transp_cropped.png deleted file mode 100644 index e0309e62..00000000 Binary files a/advanced-features/openvidu-roles-node/public/images/openvidu_globe_bg_transp_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-roles-node/public/images/openvidu_grey_bg_transp_cropped.png b/advanced-features/openvidu-roles-node/public/images/openvidu_grey_bg_transp_cropped.png deleted file mode 100644 index 49f311a6..00000000 Binary files a/advanced-features/openvidu-roles-node/public/images/openvidu_grey_bg_transp_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-roles-node/public/images/openvidu_vert_white_bg_trans_cropped.png b/advanced-features/openvidu-roles-node/public/images/openvidu_vert_white_bg_trans_cropped.png deleted file mode 100644 index a1c8b2d7..00000000 Binary files a/advanced-features/openvidu-roles-node/public/images/openvidu_vert_white_bg_trans_cropped.png and /dev/null differ diff --git a/advanced-features/openvidu-roles-node/public/images/subscriber-msg.jpg b/advanced-features/openvidu-roles-node/public/images/subscriber-msg.jpg deleted file mode 100644 index 1666fb40..00000000 Binary files a/advanced-features/openvidu-roles-node/public/images/subscriber-msg.jpg and /dev/null differ diff --git a/advanced-features/openvidu-roles-node/public/index.html b/advanced-features/openvidu-roles-node/public/index.html deleted file mode 100644 index b1520ef7..00000000 --- a/advanced-features/openvidu-roles-node/public/index.html +++ /dev/null @@ -1,210 +0,0 @@ - - - openvidu-roles-node - - - - - - - - - - - - - - - - - - - - -
-
-
- -
-
-

- -

-

- -

-

- -

-
- - - - - - - - - - - - - - - - - - - - - -
UserPassword - Role -
publisher1passPUBLISHER
publisher2passPUBLISHER
subscriberpassSUBSCRIBER
-
- - -
- - - - diff --git a/advanced-features/openvidu-roles-node/public/style.css b/advanced-features/openvidu-roles-node/public/style.css deleted file mode 100644 index df8d5c94..00000000 --- a/advanced-features/openvidu-roles-node/public/style.css +++ /dev/null @@ -1,382 +0,0 @@ -html { - position: relative; - min-height: 100%; -} - -nav { - height: 50px; - width: 100%; - z-index: 1; - background-color: #4d4d4d !important; - border-color: #4d4d4d !important; - border-top-right-radius: 0 !important; - border-top-left-radius: 0 !important; -} - -.navbar { - margin-bottom: 0px !important; -} - -.navbar-header { - width: 100%; -} - -.nav-icon { - padding: 5px 15px 5px 15px; - float: right; -} - -nav a { - color: #ccc !important; -} - -nav i.fa { - font-size: 40px; - color: #ccc; -} - -nav a:hover { - color: #a9a9a9 !important; -} - -nav i.fa:hover { - color: #a9a9a9; -} - -#main-container { - padding-bottom: 80px; - display: contents; -} - -.vertical-center { - width: -webkit-fit-content; - width: fit-content; - margin: auto; -} - -.vertical-center#not-logged form { - width: -moz-fit-content; - margin: auto; -} - -.vertical-center#not-logged table { - width: -moz-fit-content; - margin: auto; -} - -.vertical-center table { - margin-top: 3em !important; -} - -.horizontal-center { - margin: 0 auto; -} - -.form-control { - color: #0088aa; - font-weight: bold; -} - -.form-control:focus { - border-color: #0088aa; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(0, 136, 170, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(0, 136, 170, 0.6); -} - -input.btn { - font-weight: bold; -} - -.btn { - font-weight: bold !important; -} - -.btn-success { - background-color: #06d362 !important; - border-color: #06d362; -} - -.btn-success:hover { - background-color: #1abd61 !important; - border-color: #1abd61; -} - -.btn-info { - background-color: #0088aa !important; - border-color: #0088aa; -} - -.btn-info:hover { - background-color: #00708c !important; - border-color: #00708c; -} - -.btn-warning { - background-color: #ffcc00 !important; - border-color: #ffcc00; - color: #4d4d4d; -} - -.btn-warning:hover { - background-color: #eabb3a !important; - border-color: #eabb3a; - color: #4d4d4d; -} - -.btn-warning:active { - color: #4d4d4d; -} - -.btn-warning:focus { - color: #4d4d4d; -} - -.btn-warning:active:focus { - color: #4d4d4d; -} - -.footer { - position: absolute; - bottom: 0; - width: 100%; - height: 60px; - background-color: #4d4d4d; -} - -.footer .text-muted { - margin: 20px 0; - float: left; - color: #ccc; -} - -.openvidu-logo { - height: 35px; - float: right; - margin: 12px 0; - -webkit-transition: all 0.1s ease-in-out; - -moz-transition: all 0.1s ease-in-out; - -o-transition: all 0.1s ease-in-out; - transition: all 0.1s ease-in-out; -} - -.openvidu-logo:hover { - -webkit-filter: grayscale(0.5); - filter: grayscale(0.5); -} - -.demo-logo { - margin: 0; - height: 22px; - float: left; - padding-right: 8px; -} - -a:hover .demo-logo { - -webkit-filter: brightness(0.7); - filter: brightness(0.7); -} - -#join { - padding-top: 40px; -} - -#not-logged { - padding-top: 40px; -} - -#join-dialog h1 { - color: #4d4d4d; - font-weight: bold; - text-align: center; -} - -#join-dialog label { - color: #0088aa; -} - -#join-dialog input.btn { - margin-top: 15px; -} - -#join-dialog hr { - background: #4d4d4d; -} - -#img-div { - text-align: center; - padding-bottom: 3em; -} - -#img-div img { - height: 15%; -} - -#logged { - width: 100%; -} - -#join { - max-width: 700px; - margin: auto; -} - -#room-header { - margin-bottom: 20px; -} - -#room-header form { - display: inline; -} - -#room-title { - display: inline-block; -} - -#buttonLeaveRoom { - float: right; - margin-top: 20px; -} - -#video-container video { - position: relative; - float: left; - width: 50%; - cursor: pointer; -} - -#video-container div { - float: left; - width: 50%; - position: relative; - margin-left: -50%; -} - -#video-container p { - display: inline-block; - background: #f8f8f8; - padding-left: 5px; - padding-right: 5px; - color: #777777; - font-weight: bold; - border-bottom-right-radius: 4px; -} - -#video-container p.nickname { - float: right; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 0px; - font-weight: lighter; - font-size: 12px; - background: #777777; - color: #f8f8f8; -} - -video { - width: 100%; - height: auto; -} - -#main-video p { - position: absolute; - display: inline-block; - background: #f8f8f8; - padding-left: 5px; - padding-right: 5px; - font-size: 22px; - color: #777777; - font-weight: bold; - border-bottom-right-radius: 4px; -} - -#main-video p.nickname { - position: absolute; - right: 0; - font-size: 16px !important; - margin-right: 15px; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 0px; - font-weight: lighter; - font-size: 12px; - background: #777777; - color: #f8f8f8; -} - - -#room img { - width: 100%; - height: auto; - display: inline-block; - object-fit: contain; - vertical-align: baseline; -} - -#room #video-container img { - position: relative; - float: left; - width: 50%; - cursor: pointer; - object-fit: cover; - height: 180px; -} - -table i { - cursor: pointer; - margin-left: 1em; -} - -#tooltip-div { - text-align: left; -} - -#tooltip-div hr { - margin: 5px 0; -} - -#login-info { - text-align: right; -} - -#login-info form { - display: inline; -} - -#login-info div { - display: inline; - margin-right: 1em; -} - -#name-user { - font-weight: bold; -} - - -/* xs ans md screen resolutions*/ - -@media screen and (max-width: 991px) { - #join { - padding-top: inherit; - } - - #not-logged { - padding-top: inherit; - } - .container .navbar-header { - margin-right: 0 !important; - margin-left: 0 !important; - } - .nav-icon { - padding: 9px 8px 9px 8px; - } - nav i.fa { - font-size: 32px; - } - .vertical-center { - padding-top: 10px; - } - #img-div { - padding-bottom: 1em; - } - #img-div img { - height: 10%; - } -} \ No newline at end of file diff --git a/advanced-features/openvidu-roles-node/server.js b/advanced-features/openvidu-roles-node/server.js deleted file mode 100644 index f1a5812d..00000000 --- a/advanced-features/openvidu-roles-node/server.js +++ /dev/null @@ -1,175 +0,0 @@ -/* CONFIGURATION */ -require('dotenv').config( - !!process.env.CONFIG ? { path: process.env.CONFIG } : {} -); -// For demo purposes we ignore self-signed certificate -process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; - -// Node imports -const express = require('express'); -const fs = require('fs'); -const session = require('express-session'); -const https = require('https'); -const bodyParser = require('body-parser'); -const AccessToken = require('livekit-server-sdk').AccessToken; -const cors = require('cors'); -const app = express(); - -// Environment variable: PORT where the node server is listening -const SERVER_PORT = process.env.SERVER_PORT || 5000; -// Environment variable: api key shared with our LiveKit deployment -const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY || 'devkey'; -// Environment variable: api secret shared with our LiveKit deployment -const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET || 'secret'; -// Environment variable: url of our LiveKit deployment -const LIVEKIT_URL = process.env.LIVEKIT_URL || 'ws://localhost:7880'; - -// Listen (start app with node server.js) -const options = { - key: fs.readFileSync('openvidukey.pem'), - cert: fs.readFileSync('openviducert.pem'), -}; - -// The users of our application -// They should be stored in a database -const users = [ - { - user: 'publisher1', - pass: 'pass', - role: 'PUBLISHER', - }, - { - user: 'publisher2', - pass: 'pass', - role: 'PUBLISHER', - }, - { - user: 'subscriber', - pass: 'pass', - role: 'SUBSCRIBER', - }, -]; - -// Enable CORS support -app.use( - cors({ - origin: '*', - }) -); - -// Server configuration -app.use( - session({ - saveUninitialized: true, - resave: false, - secret: 'MY_SECRET', - }) -); -// Set the static files location -app.use(express.static(__dirname + '/public')); -// Parse application/x-www-form-urlencoded -app.use( - bodyParser.urlencoded({ - extended: 'true', - }) -); -// Parse application/json -app.use(bodyParser.json()); - -// Parse application/vnd.api+json as json -app.use( - bodyParser.json({ - type: 'application/vnd.api+json', - }) -); - -https.createServer(options, app).listen(SERVER_PORT, () => { - console.log(`App listening on port ${SERVER_PORT}`); - console.log(`LIVEKIT API KEY: ${LIVEKIT_API_KEY}`); - console.log(`LIVEKIT API SECRET: ${LIVEKIT_API_SECRET}`); - console.log(`LIVEKIT URL: ${LIVEKIT_URL}`); - console.log(); - console.log('Access the app at https://localhost:' + SERVER_PORT); -}); - -/* CONFIGURATION */ - -/* REST API */ - -app.post('/login', (req, res) => { - // Retrieve params from body - const { user, pass } = req.body; - - if (login(user, pass)) { - // Successful login - // Validate session and return OK - // Value stored in req.session allows us to identify the user in future requests - console.log(`Successful login for user '${user}'`); - req.session.loggedUser = user; - res.status(200).json({}); - } else { - // Credentials are NOT valid - // Invalidate session and return error - console.log(`Invalid credentials for user '${user}'`); - req.session.destroy(); - res.status(401).json({ message: 'Invalid credentials' }); - } -}); - -app.post('/logout', function (req, res) { - console.log(`'${req.session.loggedUser}' has logged out`); - req.session.destroy(); - res.status(200).json({}); -}); - -app.post('/token', (req, res) => { - const {roomName, participantName} = req.body; - - if (!isLogged(req.session)) { - req.session.destroy(); - res.status(401).json({ message: 'User not logged' }); - return; - } - - console.log( - `Getting a token for room '${roomName}' and participant '${participantName}'` - ); - - if (!roomName || !participantName) { - res - .status(400) - .json({ message: 'roomName and participantName are required' }); - return; - } - - const user = users.find((u) => u.user === req.session.loggedUser); - const {role, user: nickname} = user; - const canPublish = role === 'PUBLISHER'; - const at = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET, { - identity: participantName, - // add metadata to the token, which will be available in the participant's metadata - metadata: JSON.stringify({ livekitUrl: LIVEKIT_URL, nickname, role }), - }); - at.addGrant({ - roomJoin: true, - room: roomName, - canPublish, - canSubscribe: true, - }); - res.status(200).json({ token: at.toJwt() }); -}); - -/* REST API */ - -/* AUXILIARY METHODS */ - -function login(user, pass) { - return users.find((u) => u.user === user && u.pass === pass); -} - -function isLogged(session) { - return session.loggedUser != null; -} - - -/* AUXILIARY METHODS */