From 5e4e487fb44a476d59332a5148817ca87aeca845 Mon Sep 17 00:00:00 2001 From: Parham R Date: Thu, 18 May 2023 14:04:48 +0000 Subject: [PATCH 01/21] add js methods for unfriend contact, styles, routes, add contactsController.php --- appinfo/routes.php | 3 +++ css/style.css | 5 +++++ js/contacts.js | 27 +++++++++++++++++++++++++++ lib/Controller/ContactsController.php | 20 ++++++++++++++++++++ templates/contacts.php | 1 + 5 files changed, 56 insertions(+) create mode 100644 lib/Controller/ContactsController.php diff --git a/appinfo/routes.php b/appinfo/routes.php index 344fa282..659fb345 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -80,6 +80,9 @@ ['name' => 'app#contactsAccept', 'url' => '/contacts/accept', 'verb' => 'POST'], ['name' => 'app#contactsFindUsers', 'url' => '/contacts/users', 'verb' => 'GET'], + // contacts routes + ['name' => 'contacts#deleteContact', 'url' => '/contact/deleteContact', 'verb' => 'POST'], + // page routes ['name' => 'page#get_internal_metrics', 'url' => '/internal_metrics', 'verb' => 'GET'], ['name' => 'page#get_metrics', 'url' => '/metrics', 'verb' => 'GET'], diff --git a/css/style.css b/css/style.css index 831da1b3..17724383 100644 --- a/css/style.css +++ b/css/style.css @@ -273,6 +273,11 @@ width: 45% !important; border-bottom: 1px solid #ececec; } +.contacts-table tbody tr td:nth-child(4){ + width: 5% !important; + border-bottom: 1px solid var(--color-placeholder-light); + text-align: center; +} .contacts-profile-img{ height: 35px; margin: 2.5px 0px; diff --git a/js/contacts.js b/js/contacts.js index ba2a2b26..5e9dacf5 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -46,6 +46,9 @@ document.addEventListener("DOMContentLoaded", function(event) {

${username}@${provider}

+ + + `; } @@ -53,6 +56,11 @@ document.addEventListener("DOMContentLoaded", function(event) { element.innerHTML = result; $('#show_result').show(); + + var button = document.querySelector(".deleteContact"); + button.addEventListener("click", function() { + deleteContact($(this).data('idp'),$(this).data('username')); + }); } } }).fail(function (response, code) { @@ -91,6 +99,25 @@ document.addEventListener("DOMContentLoaded", function(event) { } + + function deleteContact(idp,username){ + var baseUrl = OC.generateUrl('/apps/sciencemesh'); + var data = 'idp=' + encodeURIComponent(idp) + '&username=' + encodeURIComponent(username); + $.ajax({ + url: baseUrl + '/contact/deleteContact', + type: 'POST', + contentType: 'application/x-www-form-urlencoded', + data:data + }).done(function (response) { + if (response === '' || response === false) { + console.log('failed'); + }else{ + console.log(response); + } + }).fail(function (response, code) { + alert('The token is invalid') + }); + } function secondsToDhms(seconds) { seconds = Number(seconds); var d = Math.floor(seconds / (3600 * 24)); diff --git a/lib/Controller/ContactsController.php b/lib/Controller/ContactsController.php new file mode 100644 index 00000000..67d5250e --- /dev/null +++ b/lib/Controller/ContactsController.php @@ -0,0 +1,20 @@ + Name Open Cloud Mesh Address + From 002959d5244b0fef7f667b10b16ce67f0d2a97f8 Mon Sep 17 00:00:00 2001 From: Parham R Date: Thu, 18 May 2023 17:06:45 +0300 Subject: [PATCH 02/21] Update ContactsController.php convert textplainresponse to plainresponse --- lib/Controller/ContactsController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Controller/ContactsController.php b/lib/Controller/ContactsController.php index 67d5250e..b8d4e5f1 100644 --- a/lib/Controller/ContactsController.php +++ b/lib/Controller/ContactsController.php @@ -15,6 +15,6 @@ class ContactsController extends Controller { public function deleteContact() { error_log('contact '.$_POST['username'].' is deleted'); - return new TextPlainResponse(true, Http::STATUS_OK); + return new PlainResponse(true, Http::STATUS_OK); } -} \ No newline at end of file +} From e0a4c1825e6a59ecd807bb5d95d66dd23b58620d Mon Sep 17 00:00:00 2001 From: Parham R Date: Thu, 18 May 2023 14:11:08 +0000 Subject: [PATCH 03/21] modify plaintext use case --- lib/Controller/ContactsController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Controller/ContactsController.php b/lib/Controller/ContactsController.php index b8d4e5f1..fdbab743 100644 --- a/lib/Controller/ContactsController.php +++ b/lib/Controller/ContactsController.php @@ -4,7 +4,7 @@ use OCP\IRequest; use OCP\AppFramework\Http; -use OCP\AppFramework\Http\TextPlainResponse; +use OCA\ScienceMesh\PlainResponse; use OCP\AppFramework\Controller; use OCA\ScienceMesh\RevaHttpClient; use OCA\ScienceMesh\Plugins\ScienceMeshGenerateTokenPlugin; From dee05883478e4d7b655a0df132ab4ff4e8807f68 Mon Sep 17 00:00:00 2001 From: Parham R Date: Thu, 18 May 2023 14:45:53 +0000 Subject: [PATCH 04/21] modify js for multiple elements --- js/contacts.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/js/contacts.js b/js/contacts.js index 5e9dacf5..767a8ad6 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -57,9 +57,11 @@ document.addEventListener("DOMContentLoaded", function(event) { $('#show_result').show(); - var button = document.querySelector(".deleteContact"); - button.addEventListener("click", function() { - deleteContact($(this).data('idp'),$(this).data('username')); + var button = $(".deleteContact"); + button.each(function( index , ele) { + ele.addEventListener("click", function() { + deleteContact($(this).data('idp'),$(this).data('username')); + }); }); } } From c181d1627d3598132633fcd87cbebeba293dcd40 Mon Sep 17 00:00:00 2001 From: Parham R Date: Wed, 24 May 2023 12:34:48 +0000 Subject: [PATCH 05/21] add share token via email --- appinfo/routes.php | 1 + css/style.css | 16 +++++++++- js/contacts.js | 51 ++++++++++++++++++++++++++++++-- lib/Controller/AppController.php | 50 +++++++++++++++++++++++++++++-- lib/RevaHttpClient.php | 4 +-- templates/contacts.php | 4 ++- 6 files changed, 118 insertions(+), 8 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 344fa282..a957f33a 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -77,6 +77,7 @@ ['name' => 'app#contacts', 'url' => '/contacts', 'verb' => 'GET'], ['name' => 'app#settings', 'url' => '/settings', 'verb' => 'GET'], ['name' => 'app#invitationsGenerate', 'url' => '/invitations/generate', 'verb' => 'GET'], + ['name' => 'app#invitationsSends', 'url' => '/invitations/emailsend', 'verb' => 'POST'], ['name' => 'app#contactsAccept', 'url' => '/contacts/accept', 'verb' => 'POST'], ['name' => 'app#contactsFindUsers', 'url' => '/contacts/users', 'verb' => 'GET'], diff --git a/css/style.css b/css/style.css index 831da1b3..6bf595b8 100644 --- a/css/style.css +++ b/css/style.css @@ -69,7 +69,7 @@ #token-generator{ color: white; cursor: pointer; - width: auto; + width: 22%; height: 36px; border-radius: 0.2em; border: 0; @@ -370,3 +370,17 @@ background-size: 20px !important; width: 30px; } + +#contact-search-input{ + margin-top: 20px; + margin-left: 10px; +} + +#recipient{ + width: 25% !important; + border-radius: 4px !important; +} + +#oc-dialog-0-content #oc-dialog-0-content-input{ + width: 100% !important; +} \ No newline at end of file diff --git a/js/contacts.js b/js/contacts.js index ba2a2b26..782795c0 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -61,23 +61,70 @@ document.addEventListener("DOMContentLoaded", function(event) { }); document.getElementById('token-generator').onclick = function () { var baseUrl = OC.generateUrl('/apps/sciencemesh'); + var recipient = document.getElementById("recipient"); $.ajax({ url: baseUrl + '/invitations/generate', type: 'GET', contentType: 'application/json', - //data: JSON.stringify(note) + data: { + email: recipient.value, + }, }).done(function (response) { if (response === '' || response === false) { var element = document.getElementById("invitation-details"); element.innerHTML = 'No Sciencemesh Connection'; } else { var element = document.getElementById("invitation-details"); - element.innerHTML = `

New Token Generated!

`; + element.innerHTML = `

New Token Generated!

`; $('#test').show(); var button = document.querySelector("#share-token-btn"); button.addEventListener("click", function() { copyToClipboard(); }); + + var buttonEmail = document.querySelector("#share-token-btn-email"); + buttonEmail.addEventListener("click", function() { + OC.dialogs.prompt( + '', + 'Share Token', + function (result,input) { + var emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (input !== null) { + if(emailPattern.test(input)){ + $.ajax({ + url: 'invitations/emailsend', + method: 'POST', + data: { + email: input, + token: document.querySelector("input[name='meshtoken']").value + }, + success: function (response) { + if(response){ + alert('Email sent successfully!'); + }else{ + alert('Email sent failed! Please check the configuration.'); + } + }, + error: function (xhr, status, error) { + alert('Email sent failed! Please check the configuration.'); + } + }); + }else{ + alert('Please input Email correctly!') + } + // var email = result.trim(); + + }else{ + alert('Please input Email address!') + } + }, + '', + 'Please input the recipient email', + '', + '' + ); + + }); } }).fail(function (response, code) { alert('The token is invalid') diff --git a/lib/Controller/AppController.php b/lib/Controller/AppController.php index a868a7d9..c6136767 100644 --- a/lib/Controller/AppController.php +++ b/lib/Controller/AppController.php @@ -6,6 +6,9 @@ use OCA\ScienceMesh\PlainResponse; use OCP\IRequest; use OCP\IUserManager; +use OCP\Mail\IMailer; +use OCP\Mail\IMessage; +use OCP\Mail\IMailerException; use OCP\IURLGenerator; use OCP\IConfig; use OCP\AppFramework\Http; @@ -27,8 +30,9 @@ class AppController extends Controller { private $generateToken; private $acceptToken; private $httpClient; + private $mailer; - public function __construct($AppName, ITimeFactory $timeFactory, INotificationManager $notificationManager, IRequest $request, IConfig $config, IUserManager $userManager, IURLGenerator $urlGenerator, $userId, IUserSession $userSession, RevaHttpClient $httpClient) { + public function __construct($AppName, ITimeFactory $timeFactory, INotificationManager $notificationManager, IRequest $request, IConfig $config, IUserManager $userManager, IURLGenerator $urlGenerator, $userId, IUserSession $userSession, RevaHttpClient $httpClient, IMailer $mailer) { parent::__construct($AppName, $request); $this->userId = $userId; @@ -41,6 +45,8 @@ public function __construct($AppName, ITimeFactory $timeFactory, INotificationMa $this->serverConfig = new \OCA\ScienceMesh\ServerConfig($config, $urlGenerator, $userManager); $this->userSession = $userSession; $this->httpClient = $httpClient; + $this->mailer = $mailer; + } /** @@ -115,7 +121,8 @@ public function accept() { * @NoCSRFRequired */ public function invitationsGenerate() { - $invitationsData = $this->httpClient->generateTokenFromReva($this->userId); + $recipient = $this->request->getParam('email'); + $invitationsData = $this->httpClient->generateTokenFromReva($this->userId, $recipient); $inviteLinkStr = $invitationsData["invite_link"]; $meshDirectoryUrl = $this->config->getAppValue('sciencemesh', 'meshDirectoryUrl', 'https://sciencemesh.cesnet.cz/iop/meshdir/'); if (!$inviteLinkStr) { @@ -128,6 +135,22 @@ public function invitationsGenerate() { return new PlainResponse("$meshDirectoryUrl$inviteLinkStr", Http::STATUS_OK); } + /** + * @NoAdminRequired + * @NoCSRFRequired + */ + public function invitationsSends($AppName) { + $email = $this->request->getParam('email'); + $token = $this->request->getParam('token'); + + $recipientEmail = $email; + $subject = 'New Token generated by '.$AppName.' send from '.$this->userId ; + $message = 'You can open this URL to accept the invitation
'.$token; + + $mailer = $this->sendNotification($recipientEmail, $subject, $message); + return new TextPlainResponse($mailer, Http::STATUS_OK); + } + /** * @NoAdminRequired * @NoCSRFRequired @@ -157,4 +180,27 @@ public function contactsFindUsers() { $find_users = $this->httpClient->findAcceptedUsers($this->userId); return new PlainResponse($find_users, Http::STATUS_OK); } + + public function sendNotification(string $recipient, string $subject, string $message): bool + { + try { + // Create a new email message + $mail = $this->mailer->createMessage(); + $mail->setTo([$recipient]); + $mail->setSubject($subject); + $mail->setPlainBody($message); + + // Set the "from" email address + $fromEmail = $this->config->getSystemValue('fromemail', 'no-reply@cs3mesh4eosc.eu'); + $mail->setFrom([$fromEmail]); + + // Send the email + $this->mailer->send($mail); + + return true; + } catch (IMailerException $e) { + // Handle the exception or log the error + return false; + } + } } diff --git a/lib/RevaHttpClient.php b/lib/RevaHttpClient.php index 9115d312..40efa344 100644 --- a/lib/RevaHttpClient.php +++ b/lib/RevaHttpClient.php @@ -151,8 +151,8 @@ public function acceptInvite($providerDomain, $token, $userId) { return "Accepted invite"; } - public function generateTokenFromReva($userId) { - $tokenFromReva = $this->revaGet('sciencemesh/generate-invite', $userId); + public function generateTokenFromReva($userId, $recipient) { + $tokenFromReva = $this->revaGet('sciencemesh/generate-invite', $userId, array('recipient' => $recipient)); error_log('Got token from reva!' . $tokenFromReva); return json_decode($tokenFromReva, true); } diff --git a/templates/contacts.php b/templates/contacts.php index 84e40010..c6fdea48 100644 --- a/templates/contacts.php +++ b/templates/contacts.php @@ -8,8 +8,10 @@
+
* List of your ScienceMesh contacts. From 5e0be4028b19def05738e494babd4e7453183ceb Mon Sep 17 00:00:00 2001 From: Parham R Date: Wed, 24 May 2023 13:11:54 +0000 Subject: [PATCH 06/21] fix some styles, fix response --- css/style.css | 13 ++++++++++--- lib/Controller/AppController.php | 12 +++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/css/style.css b/css/style.css index 6bf595b8..65b40466 100644 --- a/css/style.css +++ b/css/style.css @@ -69,7 +69,7 @@ #token-generator{ color: white; cursor: pointer; - width: 22%; + width: auto; height: 36px; border-radius: 0.2em; border: 0; @@ -378,9 +378,16 @@ #recipient{ width: 25% !important; - border-radius: 4px !important; + border-radius: 3px !important; + height: 36px; } #oc-dialog-0-content #oc-dialog-0-content-input{ - width: 100% !important; + width: 95% !important; +} + +#share-token-btn-email{ + width: 30px; + background-size: 24px; + opacity: 0.5; } \ No newline at end of file diff --git a/lib/Controller/AppController.php b/lib/Controller/AppController.php index c6136767..ac2203a1 100644 --- a/lib/Controller/AppController.php +++ b/lib/Controller/AppController.php @@ -148,7 +148,7 @@ public function invitationsSends($AppName) { $message = 'You can open this URL to accept the invitation
'.$token; $mailer = $this->sendNotification($recipientEmail, $subject, $message); - return new TextPlainResponse($mailer, Http::STATUS_OK); + return new PlainResponse($mailer, Http::STATUS_OK); } /** @@ -186,21 +186,23 @@ public function sendNotification(string $recipient, string $subject, string $mes try { // Create a new email message $mail = $this->mailer->createMessage(); + $mail->setTo([$recipient]); $mail->setSubject($subject); $mail->setPlainBody($message); // Set the "from" email address - $fromEmail = $this->config->getSystemValue('fromemail', 'no-reply@cs3mesh4eosc.eu'); + $fromEmail = $this->config->getSystemValue('fromemail', 'no-reply@cs3mesh4eosc.eu'); $mail->setFrom([$fromEmail]); // Send the email $this->mailer->send($mail); - return true; + return true; } catch (IMailerException $e) { - // Handle the exception or log the error - return false; + error_log(json_encode($e)); + + return false; } } } From 0fb2d25a2aac80eb826215fde26aa825441a90bd Mon Sep 17 00:00:00 2001 From: Parham R Date: Thu, 25 May 2023 15:55:23 +0000 Subject: [PATCH 07/21] fix js structure for render contacts --- js/contacts.js | 149 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 125 insertions(+), 24 deletions(-) diff --git a/js/contacts.js b/js/contacts.js index 2c0e3545..683136f5 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -1,7 +1,64 @@ document.addEventListener("DOMContentLoaded", function(event) { //Everything will be for working with contacts - loadData(""); - + var baseUrl = OC.generateUrl('/apps/sciencemesh'); + $('#test_error').hide(); + $.ajax({ + url: baseUrl + '/contacts/users', + type: 'GET', + contentType: 'application/json', + }).done(function (response) { + if(response == '' || response === false) { + var element = document.getElementById("show_result"); + element.innerHTML= ` + + + No Sciencemesh Connection + + `; + $('#show_result').show(); + } else { + let acceptedUsers = JSON.parse(response); + if (acceptedUsers.length == 0) { + const result = ` + + +

There are no contacts!

+ + `; + var element = document.getElementById("show_result"); + element.innerHTML = result; + $('#show_result').show(); + } else { + let result = ''; + for(i in acceptedUsers) { + const displayName = acceptedUsers[i].display_name; + const username = acceptedUsers[i].id.opaque_id; + const idp = acceptedUsers[i].id.idp; + const provider = (idp.startsWith("http") ? new URL(idp).host : idp); + result += ` + + +

+ + +

${displayName}

+ + +

${username}@${provider}

+ + + `; + } + var element = document.getElementById("show_result"); + element.innerHTML = result; + + $('#show_result').show(); + } + } + }).fail(function (response, code) { + console.log(response) + //alert('The token is invalid') + }); document.getElementById('token-generator').onclick = function () { var baseUrl = OC.generateUrl('/apps/sciencemesh'); $.ajax({ @@ -30,7 +87,7 @@ document.addEventListener("DOMContentLoaded", function(event) { const searchInput = document.getElementById('contact-search-input'); const inputHandler = function(e) { const value = e.target.value; - loadData(value); + loadData(value); } function debounce(callback, wait) { @@ -82,35 +139,79 @@ document.addEventListener("DOMContentLoaded", function(event) { `; $('#show_result').show(); } else { - let acceptedUsers = JSON.parse(response); - let result = ''; - for(i in acceptedUsers) { - var displayName = acceptedUsers[i].display_name; - var username = acceptedUsers[i].id.opaque_id; - var idp = acceptedUsers[i].id.idp; - var provider = (idp.startsWith("http") ? new URL(idp).host : idp); - result += ` - - -

- - -

${displayName}

- - -

${username}@${provider}

- - - `; + let token = JSON.parse(response); + + if(token.length) { + for(tokenData in token) { + let acceptedUsers = JSON.parse(response); + let result = ''; + for(i in acceptedUsers) { + var displayName = acceptedUsers[i].display_name; + var username = acceptedUsers[i].id.opaque_id; + var idp = acceptedUsers[i].id.idp; + var provider = (idp.startsWith("http") ? new URL(idp).host : idp); + result += ` + + +

+ + +

${displayName}

+ + +

${username}@${provider}

+ + + `; + } + var element = document.getElementById("show_result"); + element.innerHTML = result; + + var button = $(".deleteContact"); + button.each(function( index , ele) { + ele.addEventListener("click", function() { + deleteContact($(this).data('idp'),$(this).data('username')); + }); + }); + + } + }else{ + const result = ` + + +

There are no contacts!

+ + `; var element = document.getElementById("show_result"); element.innerHTML = result; - $('#show_result').show(); + } + + $('#show_result').show(); + } }).fail(function (response, code) { console.log(response) //alert('The token is invalid') }); } + function deleteContact(idp,username){ + var baseUrl = OC.generateUrl('/apps/sciencemesh'); + var data = 'idp=' + encodeURIComponent(idp) + '&username=' + encodeURIComponent(username); + $.ajax({ + url: baseUrl + '/contact/deleteContact', + type: 'POST', + contentType: 'application/x-www-form-urlencoded', + data:data + }).done(function (response) { + if (response === '' || response === false) { + console.log('failed'); + }else{ + console.log(response); + } + }).fail(function (response, code) { + alert('The token is invalid') + }); + } }); \ No newline at end of file From 6764c3adea352975c80801037b86a0e6a950ec5a Mon Sep 17 00:00:00 2001 From: Parham R Date: Thu, 25 May 2023 16:03:25 +0000 Subject: [PATCH 08/21] fix render contacts --- js/contacts.js | 88 +++++++++++++------------------------------------- 1 file changed, 22 insertions(+), 66 deletions(-) diff --git a/js/contacts.js b/js/contacts.js index 683136f5..b895d8a8 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -139,79 +139,35 @@ document.addEventListener("DOMContentLoaded", function(event) { `; $('#show_result').show(); } else { - let token = JSON.parse(response); - - if(token.length) { - for(tokenData in token) { - let acceptedUsers = JSON.parse(response); - let result = ''; - for(i in acceptedUsers) { - var displayName = acceptedUsers[i].display_name; - var username = acceptedUsers[i].id.opaque_id; - var idp = acceptedUsers[i].id.idp; - var provider = (idp.startsWith("http") ? new URL(idp).host : idp); - result += ` - - -

- - -

${displayName}

- - -

${username}@${provider}

- - - `; - } - var element = document.getElementById("show_result"); - element.innerHTML = result; - - var button = $(".deleteContact"); - button.each(function( index , ele) { - ele.addEventListener("click", function() { - deleteContact($(this).data('idp'),$(this).data('username')); - }); - }); - - + let acceptedUsers = JSON.parse(response); + let result = ''; + for(i in acceptedUsers) { + var displayName = acceptedUsers[i].display_name; + var username = acceptedUsers[i].id.opaque_id; + var idp = acceptedUsers[i].id.idp; + var provider = (idp.startsWith("http") ? new URL(idp).host : idp); + result += ` + + +

+ + +

${displayName}

+ + +

${username}@${provider}

+ + + `; } - }else{ - const result = ` - - -

There are no contacts!

- - `; var element = document.getElementById("show_result"); element.innerHTML = result; - } - - $('#show_result').show(); - + $('#show_result').show(); } }).fail(function (response, code) { console.log(response) //alert('The token is invalid') }); } - function deleteContact(idp,username){ - var baseUrl = OC.generateUrl('/apps/sciencemesh'); - var data = 'idp=' + encodeURIComponent(idp) + '&username=' + encodeURIComponent(username); - $.ajax({ - url: baseUrl + '/contact/deleteContact', - type: 'POST', - contentType: 'application/x-www-form-urlencoded', - data:data - }).done(function (response) { - if (response === '' || response === false) { - console.log('failed'); - }else{ - console.log(response); - } - }).fail(function (response, code) { - alert('The token is invalid') - }); - } -}); \ No newline at end of file +}); From d779ae90d173fe4f64c95d5d4ffe7be85e4220f9 Mon Sep 17 00:00:00 2001 From: Parham R Date: Thu, 25 May 2023 16:05:28 +0000 Subject: [PATCH 09/21] fix render contacts --- js/contacts.js | 54 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/js/contacts.js b/js/contacts.js index b895d8a8..11d10b33 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -139,29 +139,45 @@ document.addEventListener("DOMContentLoaded", function(event) { `; $('#show_result').show(); } else { - let acceptedUsers = JSON.parse(response); - let result = ''; - for(i in acceptedUsers) { - var displayName = acceptedUsers[i].display_name; - var username = acceptedUsers[i].id.opaque_id; - var idp = acceptedUsers[i].id.idp; - var provider = (idp.startsWith("http") ? new URL(idp).host : idp); - result += ` + let token = JSON.parse(response); + + if(token.length) { + for(tokenData in token) { + let acceptedUsers = JSON.parse(response); + let result = ''; + for(i in acceptedUsers) { + var displayName = acceptedUsers[i].display_name; + var username = acceptedUsers[i].id.opaque_id; + var idp = acceptedUsers[i].id.idp; + var provider = (idp.startsWith("http") ? new URL(idp).host : idp); + result += ` + + +

+ + +

${displayName}

+ + +

${username}@${provider}

+ + + `; + } + var element = document.getElementById("show_result"); + element.innerHTML = result; + } + }else{ + const result = ` - -

- - -

${displayName}

- -

${username}@${provider}

+

There are no contacts!

- - `; + `; + var element = document.getElementById("show_result"); + element.innerHTML = result; + } - var element = document.getElementById("show_result"); - element.innerHTML = result; $('#show_result').show(); } From faa6527e69426dcc5f3e98e571a7ac54b5defd88 Mon Sep 17 00:00:00 2001 From: Parham R Date: Fri, 26 May 2023 12:51:47 +0000 Subject: [PATCH 10/21] fix response strucutre for connection test, fix Get strucutre --- lib/Controller/SettingsController.php | 6 +++--- lib/RevaHttpClient.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index e2ce2c3f..b40654d4 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -264,8 +264,8 @@ public function SaveSciencemeshSettings() public function checkConnectionSettings() { $revaHttpClient = new RevaHttpClient($this->sciencemeshConfig, false); - $response_sciencemesh_iop_url = json_decode(str_replace('\n', '', $revaHttpClient->ocmProvider($this->userId)), true); - - return new JSONResponse($response_sciencemesh_iop_url); + error_log('checkConnectionSettings:'.json_encode($revaHttpClient->ocmProvider($this->userId))); + $response_sciencemesh_iop_url = $revaHttpClient->ocmProvider($this->userId); + return new DataResponse($response_sciencemesh_iop_url); } } diff --git a/lib/RevaHttpClient.php b/lib/RevaHttpClient.php index 9115d312..f22ea1b9 100644 --- a/lib/RevaHttpClient.php +++ b/lib/RevaHttpClient.php @@ -129,8 +129,8 @@ public function createShare($user, $params) { return json_decode($responseText); } - public function ocmProvider() { - return $this->revaGet('ocm/ocm-provider'); + public function ocmProvider($userId) { + return $this->revaGet('ocm-provider', $userId); } public function findAcceptedUsers($userId) { From 41ca45197586eff93b8a0e73378dd7945479463e Mon Sep 17 00:00:00 2001 From: Parham R Date: Fri, 26 May 2023 20:54:17 +0000 Subject: [PATCH 11/21] fix JS structure + remove extra lines in php method --- js/settings.js | 3 ++- lib/RevaHttpClient.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/js/settings.js b/js/settings.js index 53f93e7e..617448a9 100644 --- a/js/settings.js +++ b/js/settings.js @@ -106,7 +106,8 @@ success: function onSuccess(res) { $(".section-sciencemesh").removeClass("icon-loading"); if(res){ - if (res.enabled) { + let result = JSON.parse(res) + if (result.enabled) { var message = t(OCA.ScienceMesh.AppName, "Connection is available"); }else{ var message = t(OCA.ScienceMesh.AppName, "Connection is not available"); diff --git a/lib/RevaHttpClient.php b/lib/RevaHttpClient.php index f22ea1b9..4dd3a8b4 100644 --- a/lib/RevaHttpClient.php +++ b/lib/RevaHttpClient.php @@ -85,7 +85,7 @@ private function curlPost($url, $user, $params = []) { } $output = curl_exec($ch); $info = curl_getinfo($ch); - error_log('curl output:' . var_export($output, true) . ' info: ' . var_export($info, true)); + // error_log('curl output:' . var_export($output, true) . ' info: ' . var_export($info, true)); curl_close($ch); return $output; } From b2bd7dc31bd970774abae7655e2e8c5d1d9541e9 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Sat, 27 May 2023 00:28:48 +0330 Subject: [PATCH 12/21] Update contacts.js --- js/contacts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/contacts.js b/js/contacts.js index 11d10b33..7f743195 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -87,7 +87,7 @@ document.addEventListener("DOMContentLoaded", function(event) { const searchInput = document.getElementById('contact-search-input'); const inputHandler = function(e) { const value = e.target.value; - loadData(value); + loadData(value); } function debounce(callback, wait) { From b887f3ff949a5c97a60a9ceeccd5742e4cf04774 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Sat, 27 May 2023 00:29:44 +0330 Subject: [PATCH 13/21] remove error_log --- lib/Controller/SettingsController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index b40654d4..fd0f5f4e 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -264,7 +264,6 @@ public function SaveSciencemeshSettings() public function checkConnectionSettings() { $revaHttpClient = new RevaHttpClient($this->sciencemeshConfig, false); - error_log('checkConnectionSettings:'.json_encode($revaHttpClient->ocmProvider($this->userId))); $response_sciencemesh_iop_url = $revaHttpClient->ocmProvider($this->userId); return new DataResponse($response_sciencemesh_iop_url); } From 0d474479a1cfd28d8d77e1c8b081b9b47786b796 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Sat, 27 May 2023 00:30:58 +0330 Subject: [PATCH 14/21] remove old commented codes --- lib/RevaHttpClient.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/RevaHttpClient.php b/lib/RevaHttpClient.php index 4dd3a8b4..2695a670 100644 --- a/lib/RevaHttpClient.php +++ b/lib/RevaHttpClient.php @@ -76,7 +76,6 @@ private function curlPost($url, $user, $params = []) { curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - // curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params, JSON_PRETTY_PRINT)); if ($this->revaLoopbackSecret) { @@ -85,7 +84,6 @@ private function curlPost($url, $user, $params = []) { } $output = curl_exec($ch); $info = curl_getinfo($ch); - // error_log('curl output:' . var_export($output, true) . ' info: ' . var_export($info, true)); curl_close($ch); return $output; } @@ -121,9 +119,6 @@ public function createShare($user, $params) { if (!isset($params['recipientHost'])) { throw new \Exception("Missing recipientHost", 400); } - // $params["loginType"] = "basic"; - // $params["loginUsername"] = $user; - // $params["loginPassword"] = "ha"; //$this->revaLoopbackSecret; error_log("Calling reva/sciencemesh/create-share " . json_encode($params)); $responseText = $this->revaPost('sciencemesh/create-share', $user, $params); return json_decode($responseText); @@ -156,4 +151,4 @@ public function generateTokenFromReva($userId) { error_log('Got token from reva!' . $tokenFromReva); return json_decode($tokenFromReva, true); } -} \ No newline at end of file +} From e0e3a878c84bbfc74bc9ae69eb5b1ee23e94b93a Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Sat, 27 May 2023 00:39:07 +0330 Subject: [PATCH 15/21] remove: wrong indentation --- js/contacts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/contacts.js b/js/contacts.js index 11d10b33..7f743195 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -87,7 +87,7 @@ document.addEventListener("DOMContentLoaded", function(event) { const searchInput = document.getElementById('contact-search-input'); const inputHandler = function(e) { const value = e.target.value; - loadData(value); + loadData(value); } function debounce(callback, wait) { From 95c9747a07df97728fc8844c9f99f54b53f5b363 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Sun, 28 May 2023 10:34:35 +0000 Subject: [PATCH 16/21] fix: change resourceId to remoteShareId --- lib/Controller/RevaController.php | 10 +++++----- lib/ShareProvider/ScienceMeshShareProvider.php | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/Controller/RevaController.php b/lib/Controller/RevaController.php index 5ca40253..732655a0 100644 --- a/lib/Controller/RevaController.php +++ b/lib/Controller/RevaController.php @@ -941,7 +941,8 @@ public function addReceivedShare($userId) { foreach($params['protocols'] as $protocol) { if (isset($protocol['webdavOptions'])) { $sharedSecret = $protocol['webdavOptions']['sharedSecret']; - // make sure you have webdav_endpoint = "https://nc1.docker/" under [grpc.services.ocmshareprovider] in the sending Reva's config + // make sure you have webdav_endpoint = "https://nc1.docker/" under + // [grpc.services.ocmshareprovider] in the sending Reva's config $uri = $protocol['webdavOptions']['uri']; // e.g. https://nc1.docker/remote.php/dav/ocm/vaKE36Wf1lJWCvpDcRQUScraVP5quhzA $remote = implode('/', array_slice(explode('/', $uri), 0, 3)); // e.g. https://nc1.docker break; @@ -951,10 +952,9 @@ public function addReceivedShare($userId) { throw new \Exception('sharedSecret not found'); } - // "remote" => $params["owner"]["idp"], // FIXME: 'nc1.docker' -> 'https://nc1.docker/' $shareData = [ - "remote" => $remote, - "remote_id" => $params["resourceId"]["opaqueId"], // FIXME: $this->shareProvider->createInternal($share) suppresses, so not getting an id there, see https://github.com/pondersource/sciencemesh-nextcloud/issues/57#issuecomment-1002143104 + "remote" => $remote, //https://nc1.docker + "remote_id" => $params["remoteShareId"], // the id of the share in the oc_share table of the remote. "share_token" => $sharedSecret, // 'tDPRTrLI4hE3C5T' "password" => "", "name" => rtrim($params["name"], "/"), // '/grfe' @@ -967,7 +967,7 @@ public function addReceivedShare($userId) { "is_external" => true, ]; - $id = $this->shareProvider->addScienceMeshShare($scienceMeshData,$shareData); + $id = $this->shareProvider->addScienceMeshShare($scienceMeshData, $shareData); return new JSONResponse($id, 201); } diff --git a/lib/ShareProvider/ScienceMeshShareProvider.php b/lib/ShareProvider/ScienceMeshShareProvider.php index 4a298de4..01ce2e1c 100644 --- a/lib/ShareProvider/ScienceMeshShareProvider.php +++ b/lib/ShareProvider/ScienceMeshShareProvider.php @@ -283,7 +283,6 @@ public function addReceivedShareToDB($shareData) { $accepted = 0; //pending $qb = $this->dbConnection->getQueryBuilder(); $qb->insert('share_external') - // ->setValue('share_type', $qb->createNamedParameter($share_type)) ->setValue('remote', $qb->createNamedParameter($shareData["remote"])) ->setValue('remote_id', $qb->createNamedParameter(trim($shareData["remote_id"], '"'))) ->setValue('share_token', $qb->createNamedParameter($shareData["share_token"])) From 658c2e1126bb5324ef9359a983cfbca42436db6c Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Tue, 6 Jun 2023 15:42:04 +0200 Subject: [PATCH 17/21] GetSentShareByToken in RevaController.php --- lib/Controller/RevaController.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/Controller/RevaController.php b/lib/Controller/RevaController.php index 732655a0..ea0bd5bb 100644 --- a/lib/Controller/RevaController.php +++ b/lib/Controller/RevaController.php @@ -1124,4 +1124,22 @@ public function GetSentShare($userId) { } return new JSONResponse(["error" => "GetSentShare failed"], Http::STATUS_BAD_REQUEST); } + + /** + * @PublicPage + * @NoCSRFRequired + * @return Http\DataResponse|JSONResponse + * + * GetSentShareByToken gets the information for a share by the given token. + */ + public function GetSentShareByToken() { + error_log("GetSentShareByToken"); + $token = $this->request->getParam("Spec")["Token"]; + $share = $this->shareProvider->getShareByToken($token); + if ($share) { + $response = $this->shareInfoToCs3Share($share); + return new JSONResponse($response, Http::STATUS_OK); + } + return new JSONResponse(["error" => "GetSentShare failed"], Http::STATUS_BAD_REQUEST); + } } From ca6e0b399261578bc792178b37413266fdde00d3 Mon Sep 17 00:00:00 2001 From: Michiel de Jong Date: Tue, 6 Jun 2023 15:42:50 +0200 Subject: [PATCH 18/21] Route for GetSentShareByToken --- appinfo/routes.php | 1 + 1 file changed, 1 insertion(+) diff --git a/appinfo/routes.php b/appinfo/routes.php index 81d10bfd..2e9b84db 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -43,6 +43,7 @@ ['name' => 'reva#addSentShare', 'url' => '/~{userId}/api/ocm/addSentShare', 'verb' => 'POST'], ['name' => 'reva#addReceivedShare', 'url' => '/~{userId}/api/ocm/addReceivedShare', 'verb' => 'POST'], ['name' => 'reva#GetSentShare', 'url' => '/~{userId}/api/ocm/GetSentShare', 'verb' => 'POST'], + ['name' => 'reva#GetSentShareByToken', 'url' => '/~nobody/api/ocm/GetSentShareByToken', 'verb' => 'POST'], ['name' => 'reva#Unshare', 'url' => '/~{userId}/api/ocm/Unshare', 'verb' => 'POST'], ['name' => 'reva#UpdateShare', 'url' => '/~{userId}/api/ocm/UpdateShare', 'verb' => 'POST'], ['name' => 'reva#ListSentShares', 'url' => '/~{userId}/api/ocm/ListSentShares', 'verb' => 'POST'], From cb8f6d0daee27faba0e2991ca1d516d855de7b4c Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Tue, 6 Jun 2023 13:50:17 +0000 Subject: [PATCH 19/21] fixed owncloud regula federatedr shares --- lib/AppInfo/ScienceMeshApp.php | 1 + lib/Plugins/ScienceMeshSearchPlugin.php | 2 +- .../FederatedShareProviderCopy.php | 2 + .../ScienceMeshShareProvider.php | 66 ++++++++++++------- 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/lib/AppInfo/ScienceMeshApp.php b/lib/AppInfo/ScienceMeshApp.php index e3c357b7..4d71d05d 100644 --- a/lib/AppInfo/ScienceMeshApp.php +++ b/lib/AppInfo/ScienceMeshApp.php @@ -7,6 +7,7 @@ class ScienceMeshApp extends App { public const APP_ID = 'sciencemesh'; + public const SCIENCEMESH_POSTFIX = ' (Sciencemesh)'; public const SHARE_TYPE_REMOTE = 6; public const SHARE_TYPE_SCIENCEMESH = 6; diff --git a/lib/Plugins/ScienceMeshSearchPlugin.php b/lib/Plugins/ScienceMeshSearchPlugin.php index ac725c8d..01023158 100644 --- a/lib/Plugins/ScienceMeshSearchPlugin.php +++ b/lib/Plugins/ScienceMeshSearchPlugin.php @@ -61,7 +61,7 @@ public function search($search) { 'label' => $user['display_name'] ." (". $domain . ")", 'value' => [ 'shareType' => ScienceMeshApp::SHARE_TYPE_SCIENCEMESH, - 'shareWith' => $user['id']['opaque_id'] ."@". $user['id']['idp'], + 'shareWith' => $user['id']['opaque_id'] . "@" . $user['id']['idp'] . ScienceMeshApp::SCIENCEMESH_POSTFIX, ], ]; } diff --git a/lib/ShareProvider/FederatedShareProviderCopy.php b/lib/ShareProvider/FederatedShareProviderCopy.php index f700fed7..64dc969e 100644 --- a/lib/ShareProvider/FederatedShareProviderCopy.php +++ b/lib/ShareProvider/FederatedShareProviderCopy.php @@ -40,6 +40,7 @@ use OCP\Share\IShareProvider; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; +use OCA\FederatedFileSharing\Address; use OCA\FederatedFileSharing\AddressHandler; use OCA\FederatedFileSharing\Notifications; use OCA\FederatedFileSharing\TokenHandler; @@ -144,6 +145,7 @@ public function identifier() { * @throws \Exception */ public function create(IShare $share) { + error_log("parent create"); $shareWith = $share->getSharedWith(); $itemSource = $share->getNodeId(); $itemType = $share->getNodeType(); diff --git a/lib/ShareProvider/ScienceMeshShareProvider.php b/lib/ShareProvider/ScienceMeshShareProvider.php index 4a298de4..1ccbd7fe 100644 --- a/lib/ShareProvider/ScienceMeshShareProvider.php +++ b/lib/ShareProvider/ScienceMeshShareProvider.php @@ -32,6 +32,7 @@ use OCA\FederatedFileSharing\TokenHandler; use OCA\ScienceMesh\AppInfo\ScienceMeshApp; + /** * Class ScienceMeshShareProvider * @@ -147,6 +148,15 @@ public function createInternal(IShare $share) { $data = $this->getRawShare($shareId); return $this->createShareObject($data); } + + function endsWith( $string, $search ) { + $length = strlen( $search ); + if( !$length ) { + return true; + } + return substr( $string, -$length ) === $search; + } + /** * Share a path * @@ -158,31 +168,39 @@ public function createInternal(IShare $share) { public function create(IShare $share) { $node = $share->getNode(); $shareWith = $share->getSharedWith(); - $pathParts = explode("/", $node->getPath()); - $sender = $pathParts[1]; - $sourceOffset = 3; - $targetOffset = 3; - $prefix = "/"; - $suffix = ($node->getType() == "dir" ? "/" : ""); - - // "home" is reva's default work space name, prepending that in the source path: - $sourcePath = $prefix . "home/" . implode("/", array_slice($pathParts, $sourceOffset)) . $suffix; - $targetPath = $prefix . implode("/", array_slice($pathParts, $targetOffset)) . $suffix; - $shareWithParts = explode("@", $shareWith); - $response = $this->revaHttpClient->createShare($sender, [ - 'sourcePath' => $sourcePath, - 'targetPath' => $targetPath, - 'type' => $node->getType(), - 'recipientUsername' => $shareWithParts[0], - 'recipientHost' => $shareWithParts[1] - ]); - if (!isset($response) || !isset($response->share) || !isset($response->share->owner) || !isset($response->share->owner->idp)) { - throw new \Exception("Unexpected response from reva"); + $isScienecemeshUser = $this->endsWith($shareWith, ScienceMeshApp::SCIENCEMESH_POSTFIX); + + if ($isScienecemeshUser) { + $shareWith = str_replace(ScienceMeshApp::SCIENCEMESH_POSTFIX, "", $shareWith); + + $pathParts = explode("/", $node->getPath()); + $sender = $pathParts[1]; + $sourceOffset = 3; + $targetOffset = 3; + $prefix = "/"; + $suffix = ($node->getType() == "dir" ? "/" : ""); + + // "home" is reva's default work space name, prepending that in the source path: + $sourcePath = $prefix . "home/" . implode("/", array_slice($pathParts, $sourceOffset)) . $suffix; + $targetPath = $prefix . implode("/", array_slice($pathParts, $targetOffset)) . $suffix; + $shareWithParts = explode("@", $shareWith); + $response = $this->revaHttpClient->createShare($sender, [ + 'sourcePath' => $sourcePath, + 'targetPath' => $targetPath, + 'type' => $node->getType(), + 'recipientUsername' => $shareWithParts[0], + 'recipientHost' => $shareWithParts[1] + ]); + if (!isset($response) || !isset($response->share) || !isset($response->share->owner) || !isset($response->share->owner->idp)) { + throw new \Exception("Unexpected response from reva"); + } + $share->setId("will-set-this-later"); + $share->setProviderId($response->share->owner->idp); + $share->setShareTime(new \DateTime()); + } else { + $share = parent::create($share); } - $share->setId("will-set-this-later"); - $share->setProviderId($response->share->owner->idp); - $share->setShareTime(new \DateTime()); - + return $share; } From b86ce6e60f172f5493905672c8828e52824473e0 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Tue, 6 Jun 2023 13:51:48 +0000 Subject: [PATCH 20/21] remove error_log --- lib/ShareProvider/FederatedShareProviderCopy.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ShareProvider/FederatedShareProviderCopy.php b/lib/ShareProvider/FederatedShareProviderCopy.php index 64dc969e..479643c6 100644 --- a/lib/ShareProvider/FederatedShareProviderCopy.php +++ b/lib/ShareProvider/FederatedShareProviderCopy.php @@ -145,7 +145,6 @@ public function identifier() { * @throws \Exception */ public function create(IShare $share) { - error_log("parent create"); $shareWith = $share->getSharedWith(); $itemSource = $share->getNodeId(); $itemType = $share->getNodeType(); From 4a310837213e4e35a493d5186883f6a4c9c48df3 Mon Sep 17 00:00:00 2001 From: Mohammad Mahdi Baghbani Pourvahid Date: Tue, 6 Jun 2023 20:25:26 +0000 Subject: [PATCH 21/21] fixed having multiple @ in name --- lib/ShareProvider/ScienceMeshShareProvider.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/ShareProvider/ScienceMeshShareProvider.php b/lib/ShareProvider/ScienceMeshShareProvider.php index 45ddc77d..f0597ea3 100644 --- a/lib/ShareProvider/ScienceMeshShareProvider.php +++ b/lib/ShareProvider/ScienceMeshShareProvider.php @@ -183,7 +183,12 @@ public function create(IShare $share) { // "home" is reva's default work space name, prepending that in the source path: $sourcePath = $prefix . "home/" . implode("/", array_slice($pathParts, $sourceOffset)) . $suffix; $targetPath = $prefix . implode("/", array_slice($pathParts, $targetOffset)) . $suffix; - $shareWithParts = explode("@", $shareWith); + + $split_point = '@'; + $parts = explode($split_point, $shareWith); + $last = array_pop($parts); + $shareWithParts = array(implode($split_point, $parts), $last); + $response = $this->revaHttpClient->createShare($sender, [ 'sourcePath' => $sourcePath, 'targetPath' => $targetPath,