diff --git a/sdkjs-plugins/content/zoom/3rd-Party.txt b/sdkjs-plugins/content/zoom/3rd-Party.txt index c347fd4c..4a61fc27 100644 --- a/sdkjs-plugins/content/zoom/3rd-Party.txt +++ b/sdkjs-plugins/content/zoom/3rd-Party.txt @@ -5,9 +5,7 @@ This plugin uses code from the following 3rd party projects. License: MIT License License File: jQuery.license -2. AWS Lambda service. - -3. Select2 gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options. (https://select2.org/) +2. Select2 gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options. (https://select2.org/) License: MIT License File: Select2.license \ No newline at end of file diff --git a/sdkjs-plugins/content/zoom/README.md b/sdkjs-plugins/content/zoom/README.md index b0139de4..beda7167 100644 --- a/sdkjs-plugins/content/zoom/README.md +++ b/sdkjs-plugins/content/zoom/README.md @@ -7,16 +7,20 @@ It is compatible with [self-hosted](https://github.com/ONLYOFFICE/DocumentServer ## How to use 1. Go to the plugins tab and click on Zoom. -2. Authozire in plugin with your Zoom account. -3. Add your meeting topic and click *Start meeting* or *Schedule meeting*, a link to the meeting will appear in the chat of editor. -4. To connect to meetings you need to click *go to Joining meeting*, enter meeteing info and click *Join*. +2. Add your meeting topic and choose Start a meeting or Schedule a meeting. ## How to install Detailed instructions can be found in [ONLYOFFICE API documentation](https://api.onlyoffice.com/plugin/installation). +## Configuration + +1. To use the meeting schedule create a JWT app at https://marketplace.zoom.us/develop/create. Fill the all necessary fields and activate the app. +2. To join to meetings create a Meeting SDK app at https://marketplace.zoom.us/develop/create. Fill the all necessary fields and activate the app. +2. Copy SDK Key, SDK Secret and JWT Token from your JWT and SDK apps credentials and paste it to specified fields in plugin, click Save. + ## Note -The Zoom plugin must be installed via the Onlyoffice plugin manager. +For desktop infromation about created meeting will be add to comments of the document, however in web version it will be send to the chat. ## Known issues A black window may appear in the safari browser when joining a meeting. In order for the problem to disappear, you need to resize the plugin window or zoom in on the browser. \ No newline at end of file diff --git a/sdkjs-plugins/content/zoom/deploy/zoom.plugin b/sdkjs-plugins/content/zoom/deploy/zoom.plugin index 6e9bf53f..13f135dc 100644 Binary files a/sdkjs-plugins/content/zoom/deploy/zoom.plugin and b/sdkjs-plugins/content/zoom/deploy/zoom.plugin differ diff --git a/sdkjs-plugins/content/zoom/index.html b/sdkjs-plugins/content/zoom/index.html index a7ba1c5d..0e068f4a 100644 --- a/sdkjs-plugins/content/zoom/index.html +++ b/sdkjs-plugins/content/zoom/index.html @@ -168,13 +168,7 @@
- - -
- - -
+
@@ -712,9 +706,20 @@
-

This plugin uses the OAuth authorization. Click on the button below and allow access for this plugin.

+
+
To use Zoom plugin, register this editor as a JWT app. Learn more here.
+
In the form, enter any application name and description, accept Terms and Conditions and generate a secret. Enter SDK Key, SDK Secret and JWT token below and save it.
+
+
Email +
+
SDK Key +
+
SDK Secret +
+
JWT Token +
- +
diff --git a/sdkjs-plugins/content/zoom/index_zoom.html b/sdkjs-plugins/content/zoom/index_zoom.html index cd3d3551..459b29a1 100644 --- a/sdkjs-plugins/content/zoom/index_zoom.html +++ b/sdkjs-plugins/content/zoom/index_zoom.html @@ -338,12 +338,12 @@ }); - - - - - - + + + + + + diff --git a/sdkjs-plugins/content/zoom/meeting.html b/sdkjs-plugins/content/zoom/meeting.html index 8575fff8..8965ee26 100644 --- a/sdkjs-plugins/content/zoom/meeting.html +++ b/sdkjs-plugins/content/zoom/meeting.html @@ -20,12 +20,12 @@ } - - - - - - + + + + + + diff --git a/sdkjs-plugins/content/zoom/oauth.html b/sdkjs-plugins/content/zoom/oauth.html deleted file mode 100644 index 8a970984..00000000 --- a/sdkjs-plugins/content/zoom/oauth.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - Mendeley - - - - - \ No newline at end of file diff --git a/sdkjs-plugins/content/zoom/scripts/zoom.js b/sdkjs-plugins/content/zoom/scripts/zoom.js index c46fb6b8..32c735d2 100644 --- a/sdkjs-plugins/content/zoom/scripts/zoom.js +++ b/sdkjs-plugins/content/zoom/scripts/zoom.js @@ -29,11 +29,11 @@ var Ps; "13 hour","14 hour","15 hour","16 hour","17 hour","18 hour","19 hour","20 hour","21 hour","22 hour","23 hour","24 hour"]; var minutes = ["0 minutes","15 minutes","30 minutes","45 minutes"]; var elements = { }; - var sProxyURL = "https://plugins-services.onlyoffice.com/proxy"; - var aEmails = []; - var tokenKey = ''; - var redirect_uri = (window.document.location.origin + window.document.location.pathname).replace('index', 'oauth'); - + var zoomProxyUrl = "https://zoom.onlyoffice.com/proxy"; + var email = ''; + var sdkKey = ''; + var sdkSecret = ''; + var tokenKey = ''; var oTheme; for (var nTime = 0; nTime < times.length; nTime++) { time_hour_data.push({id: times[nTime], text: times[nTime]}); @@ -135,37 +135,6 @@ var Ps; }; - OAuthError = function (error) { - console.log(error); - }; - - OAuthCallback = function(code) { - GetAccessToken(code); - }; - - function GetAccessToken(authorizationCode) { - showLoader(elements, true); - $.ajax({ - method: 'POST', - contentType: "text/plain", - data: JSON.stringify({ - "code": authorizationCode, - "redirect_uri": redirect_uri - }), - url: "https://plugins-services.onlyoffice.com/zoom/oauth" - }).success(function (oResponse) { - tokenKey = oResponse["access_token"]; - refresh_token = oResponse["refresh_token"]; - - if (tokenKey) - IsValidConfigData(); - - }).error(function(e){ - console.log(e); - showLoader(elements, false); - }); - } - window.switchForms = function(elmToHide, elmToShow) { $(elmToHide).toggleClass('display-none'); $(elmToShow).toggleClass('display-none'); @@ -201,9 +170,9 @@ var Ps; width : '100%', }); - $('#user-select').select2({ + $('#timezone').select2({ minimumResultsForSearch: 0, - width : '100%' + width : 'calc(100% - 24px)' }); $('#adv_settings').click(function() { @@ -213,19 +182,56 @@ var Ps; }); $('#saveConfigBtn').click(function() { - let link = `https://zoom.us/oauth/authorize?response_type=code&client_id=DolnuyZlS06lwmToTBFCQQ&redirect_uri=${redirect_uri}`; - window.open(link, null, "width=500,height=700"); + SaveCredentials(true); }); $('#topic-value').focus(function(){ if(this.value !== this.defaultValue){ this.select(); } }); + $('#emailField').focus(function() { + if(this.value !== this.defaultValue){ + this.select(); + } + }); + $('#sdkKeyField').focus(function() { + if(this.value !== this.defaultValue){ + this.select(); + } + }); + $('#sdkKeyField').change(function() { + if ($(this).hasClass('error_border')) + $(this).toggleClass('error_border'); + }); + $('#sdkSecretField').focus(function() { + if(this.value !== this.defaultValue){ + this.select(); + } + }); + $('#sdkSecretField').change(function() { + if ($(this).hasClass('error_border')) + $(this).toggleClass('error_border'); + }); + $('#tokenKeyField').focus(function() { + if(this.value !== this.defaultValue){ + this.select(); + } + }); + $('#tokenKeyField').change(function() { + if ($(this).hasClass('error_border')) + $(this).toggleClass('error_border'); + }); $('#reconf').click(function() { $('#create-meeting-container').toggleClass('display-none'); $('#configState').toggleClass('display-none'); }); $('#switch').click(function() { + if (sdkKey == "" || sdkSecret == "") { + alert("SDK Key or Secret are empty. Check your credentials."); + $('#reconf').trigger("click"); + return; + } + $('#create-meeting-container').toggleClass('display-none'); $('#iframe_join').toggleClass('display-none'); @@ -266,6 +272,13 @@ var Ps; Ps = new PerfectScrollbar("#create-meeting-container", {suppressScrollX: true}); Ps1 = new PerfectScrollbar("#configState", {suppressScrollX: true}); + + document.getElementById('emailField').value = localStorage.getItem($('#emailField').attr("data-id")) || ""; + document.getElementById('sdkKeyField').value = localStorage.getItem($('#sdkKeyField').attr("data-id")) || ""; + document.getElementById('sdkSecretField').value = localStorage.getItem($('#sdkSecretField').attr("data-id")) || ""; + document.getElementById('tokenKeyField').value = localStorage.getItem($('#tokenKeyField').attr("data-id")) || ""; + + SaveCredentials(false); }); function CheckDuration() @@ -319,52 +332,60 @@ var Ps; $('#recurring-conf').trigger('change'); } } - + async function IsValidConfigData() { + showLoader(elements, true); $.ajax({ method: 'POST', contentType: "text/plain", data: JSON.stringify({ - "headers": { - 'Authorization': 'Bearer ' + tokenKey, - }, - "method": "GET", - "target": "https://api.zoom.us/v2/users/" + 'Authorization': 'Bearer ' + tokenKey, + 'endPoint': email, + "method": "GET" }), - url: sProxyURL + url: zoomProxyUrl }).success(function (oResponse) { - localStorage.setItem("onlyoffice-zoom-token", tokenKey); + localStorage.setItem($('#emailField').attr("data-id"), email); + localStorage.setItem($('#sdkKeyField').attr("data-id"), sdkKey); + localStorage.setItem($('#sdkSecretField').attr("data-id"), sdkSecret); + localStorage.setItem($('#tokenKeyField').attr("data-id"), tokenKey); if (oResponse.message && oResponse.message.search("Invalid") != -1) { - alert('Invalid access token!'); + alert('Invalid access (JWT) token!'); showLoader(elements, false); return; } else if (oResponse.message && oResponse.message.search("Access token is expired") != -1) { - alert("Need reauthorization."); + alert("Access token (JWT) is expired."); showLoader(elements, false); return; } - if (localStorage.getItem($('#timezone').attr('data-id')) === null) { - if (oResponse.users && oResponse.users[0].timezone != "") { - localStorage.setItem($('#timezone').attr('data-id'), oResponse.users[0].timezone); - $('#timezone').val(oResponse.users[0].timezone); - $('#timezone').trigger('change'); + if (email !== "") { + if (localStorage.getItem($('#timezone').attr('data-id')) === null) { + if (oResponse.timezone != "") { + localStorage.setItem($('#timezone').attr('data-id'), oResponse.timezone); + $('#timezone').val(oResponse.timezone); + $('#timezone').trigger('change'); + } } } - - aEmails = oResponse.users.map(function(user, index) { - return {id: index, text: user.email}; - }); - $('#user-select').select2({ - data: aEmails, - width : '100%', - }); - if (aEmails.length == 1) { - $('#user').hide(); + else { + if (localStorage.getItem($('#timezone').attr('data-id')) === null) { + if (oResponse.users[0].timezone != "") { + localStorage.setItem($('#timezone').attr('data-id'), oResponse.users[0].timezone); + $('#timezone').val(oResponse.users[0].timezone); + $('#timezone').trigger('change'); + } + if (oResponse.users[0].email) { + email = oResponse.users[0].email; + $('#emailField').val(email); + localStorage.setItem($('#emailField').attr("data-id"), email); + } + } } - + + $('#configState').toggleClass('display-none'); $('#create-meeting-container').toggleClass('display-none'); @@ -375,6 +396,82 @@ var Ps; }); }; + async function SaveCredentials(bShowError) { + if (!IsEmptyFields(bShowError)) { + email = $('#emailField').val().trim(); + sdkKey = $('#sdkKeyField').val().trim(); + sdkSecret = $('#sdkSecretField').val().trim(); + tokenKey = $('#tokenKeyField').val().trim(); + + await IsValidConfigData(); + } + } + + function IsEmptyFields(bShowError) { + var isEmpty = null; + + if ($('#emailField').val() === '') { + isEmpty = true; + + if (bShowError) + if (!$('#emailField').hasClass('error_border')) + $('#emailField').toggleClass('error_border'); + } + else { + isEmpty = false; + + if (bShowError) + if ($('#emailField').hasClass('error_border')) + $('#emailField').toggleClass('error_border'); + } + if ($('#sdkKeyField').val() === '') { + isEmpty = true; + + if (bShowError) + if (!$('#sdkKeyField').hasClass('error_border')) + $('#sdkKeyField').toggleClass('error_border'); + } + else { + isEmpty = false; + + if (bShowError) + if ($('#sdkKeyField').hasClass('error_border')) + $('#sdkKeyField').toggleClass('error_border'); + } + + if ($('#sdkSecretField').val() === '') { + isEmpty = isEmpty && true; + + if (bShowError) + if (!$('#sdkSecretField').hasClass('error_border')) + $('#sdkSecretField').toggleClass('error_border'); + } + else { + isEmpty = isEmpty && false; + + if (bShowError) + if ($('#sdkSecretField').hasClass('error_border')) + $('#sdkSecretField').toggleClass('error_border'); + } + + if ($('#tokenKeyField').val() === '') { + isEmpty = isEmpty && true; + + if (bShowError) + if (!$('#tokenKeyField').hasClass('error_border')) + $('#tokenKeyField').toggleClass('error_border'); + } + else { + isEmpty = isEmpty && false; + + if (bShowError) + if ($('#tokenKeyField').hasClass('error_border')) + $('#tokenKeyField').toggleClass('error_border'); + } + + return isEmpty; + } + function CheckValidDate(aDateFromPicker, hour, min, timezone) { let [year, month, day] = [parseInt(aDateFromPicker[2]), parseInt(aDateFromPicker[0]) - 1, parseInt(aDateFromPicker[1])]; @@ -491,20 +588,15 @@ var Ps; } jsonData["timezone"] = sTimeZone; + jsonData['Authorization'] = 'Bearer ' + tokenKey; + jsonData['method'] = 'POST'; + jsonData['endPoint'] = email + '/meetings'; $.ajax({ type: 'POST', contentType: "text/plain", - data: JSON.stringify({ - "headers": { - "Authorization": 'Bearer ' + tokenKey, - "Content-Type": 'application/json' - }, - "data": JSON.stringify(jsonData), - "method": "POST", - "target": "https://api.zoom.us/v2/users/" + $('#user-select').select2('data')[0].text + '/meetings' - }), - url: sProxyURL + data: JSON.stringify(jsonData), + url: zoomProxyUrl }).success(function (oResponse) { if (oResponse.message && oResponse.message.search("Invalid") != -1) { alert("Invalid access (JWT) token."); @@ -541,7 +633,7 @@ var Ps; sTime = 'Time: ' + $('#date-value').val() + ' ' + $('#time-hour').val() + ' ' + $('#time-am-pm').val().toUpperCase() + ' ' + oResponse["timezone"]; var sJoinUrl = 'Join URL: ' + oResponse.join_url; var sConfId = 'Conference ID: ' + oResponse.id; - var sPassword = 'Password: ' + (oResponse.password ? oResponse.password : "—"); + var sPassword = 'Password: ' + oResponse.password; var sResult = sTopic + '\r' + sTime + '\r' + sJoinUrl +'\r' + sConfId + '\r' + sPassword + '\r'; Asc.scope.meeting_info = sResult; @@ -558,7 +650,7 @@ var Ps; else { window.Asc.plugin.executeMethod('CoAuthoringChatSendMessage', [Asc.scope.meeting_info], function(isTrue) { if (isTrue) - alert('Meeting was created, see info in chat'); + alert('Meeting was created'); else alert('Meeting was create, please update SDK for checking info about created meeting in chat.'); }); @@ -610,10 +702,6 @@ var Ps; minimumResultsForSearch: 0, width : 'calc(100% - 24px)' }); - $('#user-select').select2({ - minimumResultsForSearch: 0, - width : '100%' - }); }; })(window, undefined); diff --git a/sdkjs-plugins/content/zoom/translations/langs.json b/sdkjs-plugins/content/zoom/translations/langs.json new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/sdkjs-plugins/content/zoom/translations/langs.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/sdkjs-plugins/content/zoom/vendor/zoom-sdk/index.js b/sdkjs-plugins/content/zoom/vendor/zoom-sdk/index.js index bafc1e5a..bda0ccdb 100644 --- a/sdkjs-plugins/content/zoom/vendor/zoom-sdk/index.js +++ b/sdkjs-plugins/content/zoom/vendor/zoom-sdk/index.js @@ -1,4 +1,4 @@ -SIGNATURE_SERVER = "https://plugins-services.onlyoffice.com/zoom/sign"; +SIGNATURE_SERVER = "https://zoom.onlyoffice.com/sign"; window.addEventListener('DOMContentLoaded', function(event) { console.log('DOM fully loaded and parsed'); @@ -28,7 +28,7 @@ function websdkready() { // ZoomMtg.setZoomJSLib('http://localhost:9999/node_modules/@zoomus/websdk/dist/lib', '/av'); // Local version default, Angular Project change to use cdn version ZoomMtg.preLoadWasm(); // pre download wasm file to save time. - var CLIENT_ID = 'cJhYqnERQBSy9KxM9LGww'; + var SDK_KEY, SDK_SECRET; /** * NEVER PUT YOUR ACTUAL API SECRET IN CLIENT SIDE CODE, THIS IS JUST FOR QUICK PROTOTYPING @@ -96,6 +96,9 @@ function websdkready() { // click join meeting button window.joinMeeting = function () { showLoader(true); + SDK_KEY = localStorage.getItem('zoom-sdk-key') || ""; + SDK_SECRET = SDK_SECRET = localStorage.getItem('zoom-sdk-secret') || ""; + var meetingConfig = testTool.getMeetingConfig(); if (!meetingConfig.mn || !meetingConfig.name) { showLoader(false); @@ -112,13 +115,6 @@ function websdkready() { testTool.setCookie("meeting_number", meetingConfig.mn); testTool.setCookie("meeting_pwd", meetingConfig.pwd); - //const iat = Math.round(new Date().getTime() / 1000) - (new Date()).getTimezoneOffset() * 60 - 30; - //const iat = 1683819574; - //const exp = iat + 60 * 60 * 2; - //const exp = 1683826774; - //console.log(iat); - //console.log(exp); - $.ajax({ method: 'POST', contentType: "text/plain", @@ -126,25 +122,23 @@ function websdkready() { data: JSON.stringify({ 'meet_number': meetingConfig.mn, 'role_id': meetingConfig.role, - //'iat': iat, - //'exp': exp + 'sdk_key': SDK_KEY, + 'sdk_secret': SDK_SECRET }), url: SIGNATURE_SERVER }).success(function (oResponse) { - meetingConfig.signature = oResponse; - meetingConfig.sdkKey = CLIENT_ID; - - var joinUrl = document.location.protocol + "//" + document.location.host + document.location.pathname.replace("index_zoom.html", "meeting.html?") + testTool.serialize(meetingConfig); - window.parent.openMeeting(joinUrl); - showLoader(false); + meetingConfig.signature = oResponse; + meetingConfig.sdkKey = SDK_KEY; + var joinUrl = document.location.protocol + "//" + document.location.host + document.location.pathname.replace("index_zoom.html", "meeting.html?") + testTool.serialize(meetingConfig); + window.parent.openMeeting(joinUrl); + showLoader(false); }).error(function(oResponse) { alert('Server error. Contact to support.'); showLoader(false); }) }; - function copyToClipboard(elementId) { var aux = document.createElement("input"); aux.setAttribute("value", document.getElementById(elementId).getAttribute('link')); @@ -156,6 +150,9 @@ function websdkready() { // click copy jon link button window.copyJoinLink = function (element) { + SDK_KEY = localStorage.getItem('zoom-sdk-key') || ""; + SDK_SECRET = SDK_SECRET = localStorage.getItem('zoom-sdk-secret') || ""; + var meetingConfig = testTool.getMeetingConfig(); if (!meetingConfig.mn || !meetingConfig.name) { alert("Meeting ID or Your Name is empty"); @@ -178,12 +175,14 @@ function websdkready() { data: JSON.stringify({ 'meet_number': meetingConfig.mn, 'role_id': meetingConfig.role, + 'sdk_key': SDK_KEY, + 'sdk_secret': SDK_SECRET }), url: SIGNATURE_SERVER }).success(function (oResponse) { meetingConfig.signature = oResponse; - meetingConfig.sdkKey = CLIENT_ID; + meetingConfig.sdkKey = SDK_KEY; var joinUrl = document.location.protocol + "//" + document.location.host + document.location.pathname.replace("index_zoom.html", "meeting.html?") + testTool.serialize(meetingConfig); document.getElementById('copy_link_value').setAttribute('link', joinUrl); copyToClipboard('copy_link_value');