From afbf2b7ff64df536eb720ae6ae48756a17fb94a9 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 11:03:57 -0800 Subject: [PATCH 001/130] User Changed listener added --- lib/AppInfo/Application.php | 6 +++ lib/Listeners/UserChangedListener.php | 77 +++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 lib/Listeners/UserChangedListener.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 3c6a81e..de58559 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -4,10 +4,16 @@ namespace OCA\EmailRecovery\AppInfo; use OCP\AppFramework\App; +use OCA\EmailRecovery\Listeners\UserChangedListener; +use OCP\AppFramework\Bootstrap\IRegistrationContext; +use OCP\User\Events\UserChangedEvent; class Application extends App { public function __construct(array $urlParams = array()) { $appName = 'email-recovery'; parent::__construct($appName, $urlParams); } + public function register(IRegistrationContext $context): void { + $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); + } } diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php new file mode 100644 index 0000000..4f1a910 --- /dev/null +++ b/lib/Listeners/UserChangedListener.php @@ -0,0 +1,77 @@ +util = $util; + $this->mailboxMapper = $mailboxMapper; + $this->logger = $logger; + } + + public function handle(Event $event): void { + if (!($event instanceof UserChangedEvent)) { + return; + } + + $feature = $event->getFeature(); + $user = $event->getUser(); + $username = $user->getUID(); + + $this->logger->error(">>>>>>>> username:: " . $username); + $this->logger->error(">>>>>>>> feature:: " . $feature); + $this->logger->error(">>>>>>>> user:: " . $user); + + + // if ($feature === self::QUOTA_FEATURE) { + // $updatedQuota = $event->getValue(); + // $quotaInBytes = (int) $this->util->computerFileSize($updatedQuota); + // $backend = $user->getBackend()->getBackendName(); + + // $this->updateQuota($username, $backend, $quotaInBytes); + // } + + // if ($feature === self::RECOVERY_EMAIL_FEATURE) { + // $recoveryEmail = $event->getValue(); + // $recoveryEmailAttribute = [ + // 'recoveryMailAddress' => $recoveryEmail + // ]; + + // } + } + + // private function updateQuota(string $username, string $backend, int $quotaInBytes) { + // try { + // if ($backend === 'SQL raw') { + // $this->mailboxMapper->updateMailboxQuota($username, $quotaInBytes); + // } + // if ($backend === 'LDAP') { + // $quotaAttribute = [ + // 'quota' => $quotaInBytes + // ]; + // } + // } catch (Exception $e) { + // $this->logger->error("Error setting quota for user $username " . $e->getMessage()); + // } + // } +} -- GitLab From 7a84d303ad77ae707cd714945822df8962b8c208 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 11:54:37 -0800 Subject: [PATCH 002/130] userchanged listner --- lib/Listeners/UserChangedListener.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php index 4f1a910..b7303db 100644 --- a/lib/Listeners/UserChangedListener.php +++ b/lib/Listeners/UserChangedListener.php @@ -30,6 +30,7 @@ class UserChangedListener implements IEventListener { } public function handle(Event $event): void { + $this->logger->debug('Handle event in UserReEnabledListener', ['event' => $event]); if (!($event instanceof UserChangedEvent)) { return; } -- GitLab From 574241431441ce9274eb37308866e2c1d1a3babf Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 11:56:22 -0800 Subject: [PATCH 003/130] userchanged listner --- lib/Listeners/UserChangedListener.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php index b7303db..7278795 100644 --- a/lib/Listeners/UserChangedListener.php +++ b/lib/Listeners/UserChangedListener.php @@ -5,27 +5,16 @@ declare(strict_types=1); namespace OCA\EmailRecovery\Listeners; use Exception; -use OCA\EmailRecovery\Db\MailboxMapper; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\ILogger; use OCP\User\Events\UserChangedEvent; -use OCP\Util; class UserChangedListener implements IEventListener { - private const QUOTA_FEATURE = 'quota'; - - private const RECOVERY_EMAIL_FEATURE = 'recovery-email'; - - private $util; - private $logger; - private $mailboxMapper; - public function __construct(Util $util, ILogger $logger, MailboxMapper $mailboxMapper) { - $this->util = $util; - $this->mailboxMapper = $mailboxMapper; + public function __construct(ILogger $logger) { $this->logger = $logger; } -- GitLab From 805e50fa3822d3d63089256e2396232459c60219 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 18:15:06 -0800 Subject: [PATCH 004/130] added logger --- lib/Listeners/UserChangedListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php index 7278795..e0b6947 100644 --- a/lib/Listeners/UserChangedListener.php +++ b/lib/Listeners/UserChangedListener.php @@ -13,9 +13,9 @@ use OCP\User\Events\UserChangedEvent; class UserChangedListener implements IEventListener { private $logger; - public function __construct(ILogger $logger) { $this->logger = $logger; + $this->logger->debug('Handle event in __construct'); } public function handle(Event $event): void { -- GitLab From 8f19f03878520673885a00b465c42d728a980639 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 18:20:33 -0800 Subject: [PATCH 005/130] logger added --- lib/AppInfo/Application.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index de58559..bb26bb9 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -14,6 +14,7 @@ class Application extends App { parent::__construct($appName, $urlParams); } public function register(IRegistrationContext $context): void { + \OC::$server->getLogger()->error("i m in register"); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } } -- GitLab From a30cd2cf8af0a28e00aa790f91d10742e8474c21 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 18:23:04 -0800 Subject: [PATCH 006/130] logger added --- lib/AppInfo/Application.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index bb26bb9..ae7b063 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -9,9 +9,9 @@ use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\User\Events\UserChangedEvent; class Application extends App { + public const APP_ID = 'email-recovery'; public function __construct(array $urlParams = array()) { - $appName = 'email-recovery'; - parent::__construct($appName, $urlParams); + parent::__construct(self::APP_ID, $urlParams); } public function register(IRegistrationContext $context): void { \OC::$server->getLogger()->error("i m in register"); -- GitLab From ccf9046198815ec4fd75904806a01d51e3d4b74f Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 18:28:57 -0800 Subject: [PATCH 007/130] logger added --- lib/AppInfo/Application.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index ae7b063..bfe090c 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -7,6 +7,7 @@ use OCP\AppFramework\App; use OCA\EmailRecovery\Listeners\UserChangedListener; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\User\Events\UserChangedEvent; +use OCP\AppFramework\Bootstrap\IBootContext; class Application extends App { public const APP_ID = 'email-recovery'; @@ -17,4 +18,6 @@ class Application extends App { \OC::$server->getLogger()->error("i m in register"); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } + public function boot(IBootContext $context): void { + } } -- GitLab From 6e108c0bd66966ca0e10d98e5662ac00d9def9aa Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 18:40:46 -0800 Subject: [PATCH 008/130] logger added --- lib/AppInfo/Application.php | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index bfe090c..ea01cc1 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -1,23 +1,49 @@ + * + * @author Florent VINCENT + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ namespace OCA\EmailRecovery\AppInfo; use OCP\AppFramework\App; -use OCA\EmailRecovery\Listeners\UserChangedListener; +use OCP\AppFramework\Bootstrap\IBootContext; +use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; +use OCA\EmailRecovery\Listeners\UserChangedListener; use OCP\User\Events\UserChangedEvent; -use OCP\AppFramework\Bootstrap\IBootContext; -class Application extends App { +class Application extends App implements IBootstrap { public const APP_ID = 'email-recovery'; - public function __construct(array $urlParams = array()) { + + public function __construct(array $urlParams = []) { parent::__construct(self::APP_ID, $urlParams); } + public function register(IRegistrationContext $context): void { - \OC::$server->getLogger()->error("i m in register"); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } + public function boot(IBootContext $context): void { } } -- GitLab From 1e4ced9205265bc681cf3f89d8c75c4277089a95 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 18:45:47 -0800 Subject: [PATCH 009/130] logger added --- lib/AppInfo/Application.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index ea01cc1..f174f17 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -41,9 +41,11 @@ class Application extends App implements IBootstrap { } public function register(IRegistrationContext $context): void { + \OC::$server->getLogger()->error("i m in register"); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } public function boot(IBootContext $context): void { + \OC::$server->getLogger()->error("i m in boot"); } } -- GitLab From 2b12aca9c7b9e235b22b8aa0096e67382124db37 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 18:52:46 -0800 Subject: [PATCH 010/130] logger added --- lib/Listeners/UserChangedListener.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php index e0b6947..11e7bec 100644 --- a/lib/Listeners/UserChangedListener.php +++ b/lib/Listeners/UserChangedListener.php @@ -15,11 +15,10 @@ class UserChangedListener implements IEventListener { public function __construct(ILogger $logger) { $this->logger = $logger; - $this->logger->debug('Handle event in __construct'); } public function handle(Event $event): void { - $this->logger->debug('Handle event in UserReEnabledListener', ['event' => $event]); + \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserChangedListener"); if (!($event instanceof UserChangedEvent)) { return; } @@ -28,9 +27,9 @@ class UserChangedListener implements IEventListener { $user = $event->getUser(); $username = $user->getUID(); - $this->logger->error(">>>>>>>> username:: " . $username); - $this->logger->error(">>>>>>>> feature:: " . $feature); - $this->logger->error(">>>>>>>> user:: " . $user); + \OC::$server->getLogger()->error(">>>>>>>> username:: " . $username); + \OC::$server->getLogger()->error(">>>>>>>> feature:: " . $feature); + \OC::$server->getLogger()->error(">>>>>>>> user:: " . $user); // if ($feature === self::QUOTA_FEATURE) { -- GitLab From 4d2191c70e7c4a5d22a91918d7076ae8f28fc0ad Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 19:00:14 -0800 Subject: [PATCH 011/130] changed --- lib/AppInfo/Application.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index f174f17..a2ec3dd 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -41,11 +41,11 @@ class Application extends App implements IBootstrap { } public function register(IRegistrationContext $context): void { - \OC::$server->getLogger()->error("i m in register"); + \OC::$server->getLogger()->error("I AM in register" . self::APP_ID); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } public function boot(IBootContext $context): void { - \OC::$server->getLogger()->error("i m in boot"); + \OC::$server->getLogger()->error("I AM in boot" . self::APP_ID); } } -- GitLab From 55e0c607b3320ff4d29bf2ac88d3398df63b6488 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 19:00:18 -0800 Subject: [PATCH 012/130] logger added --- lib/AppInfo/Application.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index a2ec3dd..5449ccc 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -41,11 +41,11 @@ class Application extends App implements IBootstrap { } public function register(IRegistrationContext $context): void { - \OC::$server->getLogger()->error("I AM in register" . self::APP_ID); + \OC::$server->getLogger()->error("I AM in register at " . self::APP_ID); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } public function boot(IBootContext $context): void { - \OC::$server->getLogger()->error("I AM in boot" . self::APP_ID); + \OC::$server->getLogger()->error("I AM in boot at " . self::APP_ID); } } -- GitLab From ab72f3860ff4c8f8f7d5aede1b2709ca468cd8cc Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 19:09:57 -0800 Subject: [PATCH 013/130] logger added --- lib/AppInfo/Application.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 5449ccc..27dc805 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -41,11 +41,11 @@ class Application extends App implements IBootstrap { } public function register(IRegistrationContext $context): void { - \OC::$server->getLogger()->error("I AM in register at " . self::APP_ID); + \OC::$server->getLogger()->error("I AM in register at email-recovery"); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } public function boot(IBootContext $context): void { - \OC::$server->getLogger()->error("I AM in boot at " . self::APP_ID); + \OC::$server->getLogger()->error("I AM in boot at email-recovery"); } } -- GitLab From fd7429ce50875b131bd3d3cae6cda6cfdcd82788 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 19:13:28 -0800 Subject: [PATCH 014/130] logger added --- lib/AppInfo/Application.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 27dc805..367b5fc 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -41,11 +41,11 @@ class Application extends App implements IBootstrap { } public function register(IRegistrationContext $context): void { - \OC::$server->getLogger()->error("I AM in register at email-recovery"); + \OC::$server->getLogger()->error("I AM in register at emailrecovery app."); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } public function boot(IBootContext $context): void { - \OC::$server->getLogger()->error("I AM in boot at email-recovery"); + \OC::$server->getLogger()->error("I AM in boot at emailrecovery app."); } } -- GitLab From 0ef96732370c178623a757352ba58588adbdb07b Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 19:33:54 -0800 Subject: [PATCH 015/130] logger added --- lib/AppInfo/Application.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 367b5fc..f899cf2 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -41,11 +41,11 @@ class Application extends App implements IBootstrap { } public function register(IRegistrationContext $context): void { - \OC::$server->getLogger()->error("I AM in register at emailrecovery app."); + // \OC::$server->getLogger()->error("I AM in register at emailrecovery app."); $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } public function boot(IBootContext $context): void { - \OC::$server->getLogger()->error("I AM in boot at emailrecovery app."); + // \OC::$server->getLogger()->error("I AM in boot at emailrecovery app."); } } -- GitLab From 600cd012a38b53ea31bfcc7c8f8f2670fa24f938 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 19:35:27 -0800 Subject: [PATCH 016/130] change reverted --- lib/AppInfo/Application.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index f899cf2..1a2d5c3 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -42,6 +42,7 @@ class Application extends App implements IBootstrap { public function register(IRegistrationContext $context): void { // \OC::$server->getLogger()->error("I AM in register at emailrecovery app."); + $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } -- GitLab From 4a496c634fa683261949721e8199e2059b0ea8a4 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 23:47:17 -0800 Subject: [PATCH 017/130] Email added on submit --- lib/Service/RecoveryEmailService.php | 67 +++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 460b7e8..0a4a975 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -11,19 +11,24 @@ use OCP\IUserManager; use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; use OCA\EcloudAccounts\Service\LDAPConnectionService; +use OCA\EcloudAccounts\AppInfo\Application; +use OCP\Mail\IEMailTemplate; +use OCP\Mail\IMailer; class RecoveryEmailService { private $LDAPConnectionService; private $config; private $appName; private $userManager; + private $mailer; - public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager) { + public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer) { $this->logger = $logger; $this->config = $config; $this->appName = $appName; $this->LDAPConnectionService = $LDAPConnectionService; $this->userManager = $userManager; + $this->mailer = $mailer; } public function getRecoveryEmail(string $username) : string { @@ -51,6 +56,7 @@ class RecoveryEmailService { $this->updateRecoveryEmailAtLDAPServer($username, $recoveryEmail); } $this->config->setUserValue($username, $this->appName, 'recovery-email', $recoveryEmail); + $this->sendVerificationEmail($username, $recoveryEmail); } @@ -65,4 +71,63 @@ class RecoveryEmailService { } $this->LDAPConnectionService->closeLDAPConnection($conn); } + public function sendVerificationEmail(string $uid, string $emailAddress) : void { + try { + $user = $this->userManager->get($uid); + $username = $user->getDisplayName(); + + // $language = $this->config->getUserValue($uid, 'core', 'lang', null); + $subject = 'Hi This is subject.'; + $message = 'Hi, '.$username.' This is message.'; + + $this->sendEmail($subject, $message, $emailAddress); + } catch (\Exception $e) { + $this->logger->error('Error sending notification email to user ' . $uid, ['exception' => $e]); + continue; + } + } + /** + * Send an Email + * + * @param string $subject + * @param string $message + * @param string $emailAddress + * + */ + public function sendEmail(string $subject, string $message, string $emailAddress) { + $message = preg_replace('/\[(.*?)\]\((.*?)\)/', "$1", $message); + $template = $this->mailer->createEMailTemplate(Application::APP_ID . '::sendMail'); + $template->setSubject($subject); + $template->addHeader(); + $template->addHeading($subject); + $this->setMailBody($template, $message); + $template->addFooter(); + + $email = $this->mailer->createMessage(); + $email->useTemplate($template); + $email->setTo([$emailAddress]); + + $this->mailer->send($email); + } + /** + * Special-treat list items and strip empty lines + * + * @param IEMailTemplate $template + * @param string $message + * + * @return void + */ + public function setMailBody(IEMailTemplate $template, string $message): void { + $lines = explode("\n", $message); + $finalHtml = ""; + $finalText = ""; + foreach ($lines as $line) { + if (trim($line) === '') { + continue; + } + $finalHtml .= "

" . $line . "

"; + $finalText .= $line; + } + $template->addBodyText($finalHtml, $finalText); + } } -- GitLab From 6d72bb55fbea74c3ebd5c92887554dbfddc4b0f7 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 29 Nov 2023 23:48:17 -0800 Subject: [PATCH 018/130] Email added on submit --- lib/Service/RecoveryEmailService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 0a4a975..09a43f6 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -11,7 +11,7 @@ use OCP\IUserManager; use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; use OCA\EcloudAccounts\Service\LDAPConnectionService; -use OCA\EcloudAccounts\AppInfo\Application; +use OCA\EmailRecovery\AppInfo\Application; use OCP\Mail\IEMailTemplate; use OCP\Mail\IMailer; -- GitLab From b9b4c503d14c2d8e8f59e021f3a6f57e527cdbb6 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 00:04:27 -0800 Subject: [PATCH 019/130] removed continue --- lib/Service/RecoveryEmailService.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 09a43f6..a40e483 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -83,7 +83,6 @@ class RecoveryEmailService { $this->sendEmail($subject, $message, $emailAddress); } catch (\Exception $e) { $this->logger->error('Error sending notification email to user ' . $uid, ['exception' => $e]); - continue; } } /** -- GitLab From 717daadad94c0d4f22787a2bf4626d1b823ccc2b Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 00:56:19 -0800 Subject: [PATCH 020/130] added new email template --- lib/Service/RecoveryEmailService.php | 98 ++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 20 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index a40e483..dac9572 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -11,9 +11,16 @@ use OCP\IUserManager; use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; use OCA\EcloudAccounts\Service\LDAPConnectionService; -use OCA\EmailRecovery\AppInfo\Application; use OCP\Mail\IEMailTemplate; use OCP\Mail\IMailer; +use OCP\Util; +use OCP\IUser; +use OCP\Security\ISecureRandom; +use OCP\L10N\IFactory; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\IURLGenerator; +use OCP\Security\ICrypto; +use OCP\Defaults; class RecoveryEmailService { private $LDAPConnectionService; @@ -21,14 +28,26 @@ class RecoveryEmailService { private $appName; private $userManager; private $mailer; + private $secureRandom; + protected $l10nFactory; + private $timeFactory; + private $crypto; + private $urlGenerator; + private $themingDefaults; - public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer) { + public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, ISecureRandom $secureRandom, IFactory $l10nFactory, ITimeFactory $timeFactory, ICrypto $crypto, IURLGenerator $urlGenerator, Defaults $themingDefaults) { $this->logger = $logger; $this->config = $config; $this->appName = $appName; $this->LDAPConnectionService = $LDAPConnectionService; $this->userManager = $userManager; $this->mailer = $mailer; + $this->secureRandom = $secureRandom; + $this->l10nFactory = $l10nFactory; + $this->timeFactory = $timeFactory; + $this->crypto = $crypto; + $this->urlGenerator = $urlGenerator; + $this->themingDefaults = $themingDefaults; } public function getRecoveryEmail(string $username) : string { @@ -71,20 +90,72 @@ class RecoveryEmailService { } $this->LDAPConnectionService->closeLDAPConnection($conn); } - public function sendVerificationEmail(string $uid, string $emailAddress) : void { + public function sendVerificationEmail(string $uid, string $recoverEmailAddress) : void { try { $user = $this->userManager->get($uid); $username = $user->getDisplayName(); - // $language = $this->config->getUserValue($uid, 'core', 'lang', null); - $subject = 'Hi This is subject.'; - $message = 'Hi, '.$username.' This is message.'; + $emailTemplate = $this->generateTemplate($user, $recoverEmailAddress); - $this->sendEmail($subject, $message, $emailAddress); + $email = $this->mailer->createMessage(); + $email->useTemplate($emailTemplate); + $email->setTo([$recoverEmailAddress]); + $email->setFrom([Util::getDefaultEmailAddress('no-reply')]); + + $this->mailer->send($email); } catch (\Exception $e) { $this->logger->error('Error sending notification email to user ' . $uid, ['exception' => $e]); } } + /** + * @param IUser $user + * @param string $recoverEmailAddress + * @return IEMailTemplate + */ + public function generateTemplate(IUser $user, string $recoverEmailAddress) { + $userId = $user->getUID(); + $lang = $this->config->getUserValue($userId, 'core', 'lang', null); + + $l10n = $this->l10nFactory->get('settings', $lang); + + $token = $this->secureRandom->generate( + 21, + ISecureRandom::CHAR_ALPHANUMERIC + ); + $tokenValue = $this->timeFactory->getTime() . ':' . $token; + $encryptedValue = $this->crypto->encrypt($tokenValue, $recoverEmailAddress . $this->config->getSystemValue('secret')); + $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue); + $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]); + + $displayName = $user->getDisplayName(); + + $emailTemplate = $this->mailer->createEMailTemplate('recovery-email.confirmation', [ + 'link' => $link, + 'displayname' => $displayName, + 'userid' => $userId, + 'instancename' => $this->themingDefaults->getName(), + 'resetTokenGenerated' => true, + ]); + + $emailTemplate->setSubject($l10n->t('Murena Account Recovery Verification')); + $emailTemplate->addHeader(); + $emailTemplate->addHeading($l10n->t('Hello %s', [$displayName])); + $emailTemplate->addBodyText($l10n->t('Welcome to your %s account, you can add, protect, and share your data.', [$this->themingDefaults->getName()])); + if ($user->getBackendClassName() !== 'LDAP') { + $emailTemplate->addBodyText($l10n->t('Your username is: %s', [$userId])); + } + + $leftButtonText = $l10n->t('Set your password'); + $emailTemplate->addBodyButton( + $leftButtonText, + $link + ); + + + $emailTemplate->addFooter('', $lang); + + return $emailTemplate; + } /** * Send an Email * @@ -94,19 +165,6 @@ class RecoveryEmailService { * */ public function sendEmail(string $subject, string $message, string $emailAddress) { - $message = preg_replace('/\[(.*?)\]\((.*?)\)/', "$1", $message); - $template = $this->mailer->createEMailTemplate(Application::APP_ID . '::sendMail'); - $template->setSubject($subject); - $template->addHeader(); - $template->addHeading($subject); - $this->setMailBody($template, $message); - $template->addFooter(); - - $email = $this->mailer->createMessage(); - $email->useTemplate($template); - $email->setTo([$emailAddress]); - - $this->mailer->send($email); } /** * Special-treat list items and strip empty lines -- GitLab From 68d1c79546e1ba8b318779ea3b12fbb68b400a2a Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 01:05:57 -0800 Subject: [PATCH 021/130] Change recovery email address --- lib/Service/RecoveryEmailService.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index dac9572..c2e57b0 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -100,8 +100,7 @@ class RecoveryEmailService { $email = $this->mailer->createMessage(); $email->useTemplate($emailTemplate); $email->setTo([$recoverEmailAddress]); - $email->setFrom([Util::getDefaultEmailAddress('no-reply')]); - + $email->setFrom([Util::getDefaultEmailAddress('no-reply') => $this->themingDefaults->getName()]); $this->mailer->send($email); } catch (\Exception $e) { $this->logger->error('Error sending notification email to user ' . $uid, ['exception' => $e]); @@ -124,7 +123,7 @@ class RecoveryEmailService { ); $tokenValue = $this->timeFactory->getTime() . ':' . $token; $encryptedValue = $this->crypto->encrypt($tokenValue, $recoverEmailAddress . $this->config->getSystemValue('secret')); - $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue); + $this->config->setUserValue($user->getUID(), 'core', 'changerecoverymail', $encryptedValue); $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]); $displayName = $user->getDisplayName(); @@ -140,12 +139,9 @@ class RecoveryEmailService { $emailTemplate->setSubject($l10n->t('Murena Account Recovery Verification')); $emailTemplate->addHeader(); $emailTemplate->addHeading($l10n->t('Hello %s', [$displayName])); - $emailTemplate->addBodyText($l10n->t('Welcome to your %s account, you can add, protect, and share your data.', [$this->themingDefaults->getName()])); - if ($user->getBackendClassName() !== 'LDAP') { - $emailTemplate->addBodyText($l10n->t('Your username is: %s', [$userId])); - } + $emailTemplate->addBodyText($l10n->t('You changed recovery email in your %s account.', [$this->themingDefaults->getName()])); - $leftButtonText = $l10n->t('Set your password'); + $leftButtonText = $l10n->t('Verify recovery email'); $emailTemplate->addBodyButton( $leftButtonText, $link -- GitLab From 563b2193fb1c48200fa4376e2fad775903020475 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 01:13:38 -0800 Subject: [PATCH 022/130] Change recovery email address --- lib/Service/RecoveryEmailService.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index c2e57b0..3fb30c3 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -123,7 +123,8 @@ class RecoveryEmailService { ); $tokenValue = $this->timeFactory->getTime() . ':' . $token; $encryptedValue = $this->crypto->encrypt($tokenValue, $recoverEmailAddress . $this->config->getSystemValue('secret')); - $this->config->setUserValue($user->getUID(), 'core', 'changerecoverymail', $encryptedValue); + $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue); + // $this->config->setUserValue($user->getUID(), 'core', 'changerecoverymail', $encryptedValue); $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]); $displayName = $user->getDisplayName(); -- GitLab From 78012aa8c63e8974964fee2fb6b0922a52d58dcd Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 11:29:46 -0800 Subject: [PATCH 023/130] token added --- lib/Service/RecoveryEmailService.php | 40 +++++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 3fb30c3..843653a 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -21,6 +21,9 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\IURLGenerator; use OCP\Security\ICrypto; use OCP\Defaults; +use OCP\BackgroundJob\IJobList; +use OCA\EmailRecovery\AppInfo\Application; +use OC\Authentication\Token\TokenCleanupJob; class RecoveryEmailService { private $LDAPConnectionService; @@ -34,8 +37,10 @@ class RecoveryEmailService { private $crypto; private $urlGenerator; private $themingDefaults; + private $jobList; + protected const TOKEN_LIFETIME = 60 * 60 * 24 * 1; // 1 day - public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, ISecureRandom $secureRandom, IFactory $l10nFactory, ITimeFactory $timeFactory, ICrypto $crypto, IURLGenerator $urlGenerator, Defaults $themingDefaults) { + public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, ISecureRandom $secureRandom, IFactory $l10nFactory, ITimeFactory $timeFactory, ICrypto $crypto, IURLGenerator $urlGenerator, Defaults $themingDefaults, IJobList $jobList) { $this->logger = $logger; $this->config = $config; $this->appName = $appName; @@ -48,6 +53,7 @@ class RecoveryEmailService { $this->crypto = $crypto; $this->urlGenerator = $urlGenerator; $this->themingDefaults = $themingDefaults; + $this->jobList = $jobList; } public function getRecoveryEmail(string $username) : string { @@ -117,14 +123,8 @@ class RecoveryEmailService { $l10n = $this->l10nFactory->get('settings', $lang); - $token = $this->secureRandom->generate( - 21, - ISecureRandom::CHAR_ALPHANUMERIC - ); - $tokenValue = $this->timeFactory->getTime() . ':' . $token; - $encryptedValue = $this->crypto->encrypt($tokenValue, $recoverEmailAddress . $this->config->getSystemValue('secret')); - $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue); - // $this->config->setUserValue($user->getUID(), 'core', 'changerecoverymail', $encryptedValue); + $token = $this->createToken($user, 'recovery-email', $recoverEmailAddress); + $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]); $displayName = $user->getDisplayName(); @@ -148,11 +148,31 @@ class RecoveryEmailService { $link ); - $emailTemplate->addFooter('', $lang); return $emailTemplate; } + private function createToken(IUser $user, string $subject, string $recoverEmail = ''): string { + $token = $this->secureRandom->generate( + 21, + ISecureRandom::CHAR_DIGITS. + ISecureRandom::CHAR_LOWER. + ISecureRandom::CHAR_UPPER + ); + $tokenValue = $this->timeFactory->getTime() .':'. $token; + $encryptedValue = $this->crypto->encrypt($tokenValue, $recoverEmail . $this->config->getSystemValue('secret')); + $this->config->setUserValue($user->getUID(), Application::APP_ID, $subject, $encryptedValue); + $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-verified', 'false'); + $jobArgs = json_encode([ + 'userId' => $user->getUID(), + 'subject' => $subject, + 'pp' => $recoverEmail, + 'notBefore' => $this->timeFactory->getTime() + self::TOKEN_LIFETIME * 2, // multiply to provide a grace period + ]); + $this->jobList->add(TokenCleanupJob::class, $jobArgs); + + return $token; + } /** * Send an Email * -- GitLab From 70664ffb0493dc23531b09c4b8b1f7a47461aba9 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 11:43:05 -0800 Subject: [PATCH 024/130] token added --- lib/Controller/EmailRecoveryController.php | 2 +- src/App.vue | 2 ++ src/main.html | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index ce4f7a5..6e5fba1 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -74,7 +74,7 @@ class EmailRecoveryController extends Controller { public function getRecoveryEmail() { $response = new JSONResponse(); $userId = $this->userSession->getUser()->getUID(); - $data = array("recoveryEmail" => $this->config->getUserValue($userId, $this->appName, 'recovery-email')); + $data = array("recoveryEmail" => $this->config->getUserValue($userId, $this->appName, 'recovery-email'), "isRecoveryEmailVerification" => $this->config->getUserValue($userId, $this->appName, 'recovery-email-verified')); $response->setData($data); return $response; } diff --git a/src/App.vue b/src/App.vue index 43751d2..98ea819 100644 --- a/src/App.vue +++ b/src/App.vue @@ -16,6 +16,7 @@ export default { showError: false, placeholder: t('email-recovery', 'Recovery Email'), value: t('email-recovery', 'Change Recovery Email'), + isRecoveryEmailVerification: false, } }, methods: { @@ -24,6 +25,7 @@ export default { .get(generateUrl('/apps/email-recovery/get_recovery_email')) .then(response => { this.recoveryEmail = response.data.recoveryEmail + this.isRecoveryEmailVerification = response.data.isRecoveryEmailVerification }) }, updateRecoveryEmail() { diff --git a/src/main.html b/src/main.html index a354bff..ebca01e 100644 --- a/src/main.html +++ b/src/main.html @@ -13,7 +13,9 @@ v-model="recoveryEmail" :placeholder="placeholder" /> - + + + Date: Thu, 30 Nov 2023 11:50:08 -0800 Subject: [PATCH 025/130] verification email ui chagnes --- src/main.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.html b/src/main.html index ebca01e..a126cee 100644 --- a/src/main.html +++ b/src/main.html @@ -22,7 +22,7 @@ :value="value" />

- {{ t("email-recovery","Changes saved") }} + {{ t("email-recovery","Email address have been saved. An email has been sent to you for verification.") }}

Date: Thu, 30 Nov 2023 11:50:40 -0800 Subject: [PATCH 026/130] verification email ui chagnes --- src/main.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.html b/src/main.html index a126cee..88b9796 100644 --- a/src/main.html +++ b/src/main.html @@ -13,8 +13,8 @@ v-model="recoveryEmail" :placeholder="placeholder" /> - - + + Date: Thu, 30 Nov 2023 11:56:12 -0800 Subject: [PATCH 027/130] change in email template --- lib/Service/RecoveryEmailService.php | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 843653a..6b0be28 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -137,17 +137,18 @@ class RecoveryEmailService { 'resetTokenGenerated' => true, ]); - $emailTemplate->setSubject($l10n->t('Murena Account Recovery Verification')); + $emailTemplate->setSubject($l10n->t('Recovery Email Update in Your %s Account', [$this->themingDefaults->getName()])); $emailTemplate->addHeader(); $emailTemplate->addHeading($l10n->t('Hello %s', [$displayName])); - $emailTemplate->addBodyText($l10n->t('You changed recovery email in your %s account.', [$this->themingDefaults->getName()])); - + $emailTemplate->addBodyText($l10n->t('This is to inform you that the recovery email for your %s account has been successfully updated. If you did not initiate this change, please contact our support team immediately.', [$this->themingDefaults->getName()])); + $emailTemplate->addBodyText($l10n->t('To verify your new recovery email, please click on the following button.')); $leftButtonText = $l10n->t('Verify recovery email'); $emailTemplate->addBodyButton( $leftButtonText, $link ); - + $emailTemplate->addBodyText($l10n->t('Please note that this link will be valid for the next 30 minutes.')); + $emailTemplate->addBodyText($l10n->t('Thank you for choosing %s.', [$this->themingDefaults->getName()])); $emailTemplate->addFooter('', $lang); return $emailTemplate; @@ -173,16 +174,6 @@ class RecoveryEmailService { return $token; } - /** - * Send an Email - * - * @param string $subject - * @param string $message - * @param string $emailAddress - * - */ - public function sendEmail(string $subject, string $message, string $emailAddress) { - } /** * Special-treat list items and strip empty lines * -- GitLab From 797fcf4736a22b16e52c997b0068701973f24c58 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 12:00:11 -0800 Subject: [PATCH 028/130] change in label --- lib/Service/RecoveryEmailService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 6b0be28..68a2a10 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -123,7 +123,7 @@ class RecoveryEmailService { $l10n = $this->l10nFactory->get('settings', $lang); - $token = $this->createToken($user, 'recovery-email', $recoverEmailAddress); + $token = $this->createToken($user, 'recovery-email-token', $recoverEmailAddress); $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]); -- GitLab From add1f343eb5ade629b53fed6d345ae9ac90a4e6c Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 12:21:14 -0800 Subject: [PATCH 029/130] added controller --- appinfo/routes.php | 3 ++- lib/Controller/EmailRecoveryController.php | 23 +++++++++++++++------- lib/Service/RecoveryEmailService.php | 5 +++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 742a3e3..95f84cd 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -29,6 +29,7 @@ return [ ['name' => 'email_recovery_api#preflighted_cors', 'url' => '/api/{path}', 'verb' => 'OPTIONS', 'requirements' => ['path' => '.+']], ['name' => 'email_recovery_api#show', 'url' => '/api/recovery-email/{id}', 'verb' => 'GET'], - ['name' => 'email_recovery_api#update', 'url' => '/api/recovery-email/{id}', 'verb' => 'PUT'] + ['name' => 'email_recovery_api#update', 'url' => '/api/recovery-email/{id}', 'verb' => 'PUT'], + ['name' => 'email_recovery#verify_recovery_email', 'url' => '/recovery-email/verify', 'verb' => 'GET'] ] ]; diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 6e5fba1..1b378ad 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -71,13 +71,22 @@ class EmailRecoveryController extends Controller { * @NoAdminRequired */ - public function getRecoveryEmail() { - $response = new JSONResponse(); - $userId = $this->userSession->getUser()->getUID(); - $data = array("recoveryEmail" => $this->config->getUserValue($userId, $this->appName, 'recovery-email'), "isRecoveryEmailVerification" => $this->config->getUserValue($userId, $this->appName, 'recovery-email-verified')); - $response->setData($data); - return $response; - } + public function getRecoveryEmail() { + $response = new JSONResponse(); + $userId = $this->userSession->getUser()->getUID(); + $data = array("recoveryEmail" => $this->config->getUserValue($userId, $this->appName, 'recovery-email'), "isRecoveryEmailVerification" => $this->config->getUserValue($userId, $this->appName, 'recovery-email-verified')); + $response->setData($data); + return $response; + } + /** + * @NoAdminRequired + * @PublicPage + */ + + public function verifyRecoveryEmail() { + echo 'verify here'; + die; + } /** * @NoAdminRequired */ diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 68a2a10..32f9f40 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -125,7 +125,7 @@ class RecoveryEmailService { $token = $this->createToken($user, 'recovery-email-token', $recoverEmailAddress); - $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]); + $link = $this->urlGenerator->linkToRouteAbsolute('email_recovery.recovery-email.verify', ['userId' => $user->getUID(), 'token' => $token]); $displayName = $user->getDisplayName(); @@ -140,7 +140,7 @@ class RecoveryEmailService { $emailTemplate->setSubject($l10n->t('Recovery Email Update in Your %s Account', [$this->themingDefaults->getName()])); $emailTemplate->addHeader(); $emailTemplate->addHeading($l10n->t('Hello %s', [$displayName])); - $emailTemplate->addBodyText($l10n->t('This is to inform you that the recovery email for your %s account has been successfully updated. If you did not initiate this change, please contact our support team immediately.', [$this->themingDefaults->getName()])); + $emailTemplate->addBodyText($l10n->t('This is to inform you that the recovery email for your %s account has been successfully updated.', [$this->themingDefaults->getName()])); $emailTemplate->addBodyText($l10n->t('To verify your new recovery email, please click on the following button.')); $leftButtonText = $l10n->t('Verify recovery email'); $emailTemplate->addBodyButton( @@ -148,6 +148,7 @@ class RecoveryEmailService { $link ); $emailTemplate->addBodyText($l10n->t('Please note that this link will be valid for the next 30 minutes.')); + $emailTemplate->addBodyText($l10n->t('If you did not initiate this change, please contact our support team immediately.')); $emailTemplate->addBodyText($l10n->t('Thank you for choosing %s.', [$this->themingDefaults->getName()])); $emailTemplate->addFooter('', $lang); -- GitLab From 2267bdeb5f70cf72a5d71f12dbf6ae62921a3fe9 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 12:50:51 -0800 Subject: [PATCH 030/130] link changes --- lib/Service/RecoveryEmailService.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 32f9f40..958cd29 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -124,8 +124,7 @@ class RecoveryEmailService { $l10n = $this->l10nFactory->get('settings', $lang); $token = $this->createToken($user, 'recovery-email-token', $recoverEmailAddress); - - $link = $this->urlGenerator->linkToRouteAbsolute('email_recovery.recovery-email.verify', ['userId' => $user->getUID(), 'token' => $token]); + $link = $this->urlGenerator->linkToRouteAbsolute('email_recovery.emailrecoverycontroller.verifyRecoveryEmail', ['userId' => $user->getUID(), 'token' => $token]); $displayName = $user->getDisplayName(); -- GitLab From 18e6ff68f1a166f74251a655060b81e64fac7f94 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 12:59:19 -0800 Subject: [PATCH 031/130] verify email --- lib/Service/RecoveryEmailService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 958cd29..96f2517 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -124,7 +124,7 @@ class RecoveryEmailService { $l10n = $this->l10nFactory->get('settings', $lang); $token = $this->createToken($user, 'recovery-email-token', $recoverEmailAddress); - $link = $this->urlGenerator->linkToRouteAbsolute('email_recovery.emailrecoverycontroller.verifyRecoveryEmail', ['userId' => $user->getUID(), 'token' => $token]); + $link = $this->urlGenerator->linkToRouteAbsolute($this->appName .'.email_recovery.verify_recovery_email', ['userId' => $user->getUID(), 'token' => $token]); $displayName = $user->getDisplayName(); -- GitLab From 41a7c7680eb0412fff65040e5749427fb1e9f4f9 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 16:03:40 -0800 Subject: [PATCH 032/130] verifyemail --- lib/Controller/EmailRecoveryController.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 1b378ad..70e605f 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -83,8 +83,11 @@ class EmailRecoveryController extends Controller { * @PublicPage */ - public function verifyRecoveryEmail() { + public function verifyRecoveryEmail(string $userId, string $token) { echo 'verify here'; + echo $userId; + echo '<>'; + echo $token; die; } /** -- GitLab From 3943205f625345d1cb1ab9c65d55eb1f1594d31c Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 16:05:14 -0800 Subject: [PATCH 033/130] csrf and public page addded --- lib/Controller/EmailRecoveryController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 70e605f..f4f36ff 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -81,6 +81,7 @@ class EmailRecoveryController extends Controller { /** * @NoAdminRequired * @PublicPage + * @NoCSRFRequired */ public function verifyRecoveryEmail(string $userId, string $token) { -- GitLab From f04cce5c7de64ec4d4d75f57b2bef4d0e0179cd7 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 17:04:37 -0800 Subject: [PATCH 034/130] Added verify revovery email --- lib/Controller/EmailRecoveryController.php | 33 +++++++++++++++++----- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index f4f36ff..b387dfc 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -35,6 +35,11 @@ use OCP\AppFramework\Http\JSONResponse; use OCA\EmailRecovery\Service\RecoveryEmailService; use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; +use OCP\IUserManager; +use OCP\Security\VerificationToken\IVerificationToken; +use OCP\Security\VerificationToken\InvalidTokenException; +use Exception; +use OCA\EmailRecovery\AppInfo\Application; class EmailRecoveryController extends Controller { /** @var IConfig */ @@ -49,6 +54,8 @@ class EmailRecoveryController extends Controller { private $userSession; private $recoveryEmailService; + private $userManager; + private $verificationToken; public function __construct( string $appName, @@ -57,7 +64,9 @@ class EmailRecoveryController extends Controller { ILogger $logger, IL10N $l, IUserSession $userSession, - RecoveryEmailService $recoveryEmailService + RecoveryEmailService $recoveryEmailService, + IUserManager $userManager, + IVerificationToken $verificationToken ) { parent::__construct($appName, $request); $this->config = $config; @@ -65,6 +74,8 @@ class EmailRecoveryController extends Controller { $this->l = $l; $this->userSession = $userSession; $this->recoveryEmailService = $recoveryEmailService; + $this->userManager = $userManager; + $this->verificationToken = $verificationToken; } /** @@ -83,14 +94,22 @@ class EmailRecoveryController extends Controller { * @PublicPage * @NoCSRFRequired */ - public function verifyRecoveryEmail(string $userId, string $token) { - echo 'verify here'; - echo $userId; - echo '<>'; - echo $token; - die; + $this->checkPasswordResetToken($token, $userId); + $this->config->setUserValue($userId, Application::APP_ID, 'recovery-email-verified', 'true'); } + private function checkPasswordResetToken(string $userId, string $token) { + try { + $user = $this->userManager->get($userId); + $recoveryEmail = $this->config->getUserValue($userId, 'email-recovery', 'recovery-email', ''); + $this->verificationToken->check($token, $user, 'recovery-email-token', $user ? $recoveryEmail : '', true); + } catch (InvalidTokenException $e) { + $error = $e->getCode() === InvalidTokenException::TOKEN_EXPIRED + ? 'Could not reset password because the token is expired' + : 'Could not reset password because the token is invalid'; + throw new Exception($error, (int)$e->getCode(), $e); + } + } /** * @NoAdminRequired */ -- GitLab From e7c691e2fe4762321e0e553b976bafc4ce276c43 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 17:15:24 -0800 Subject: [PATCH 035/130] error page --- lib/Controller/EmailRecoveryController.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index b387dfc..a19f55f 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -40,6 +40,7 @@ use OCP\Security\VerificationToken\IVerificationToken; use OCP\Security\VerificationToken\InvalidTokenException; use Exception; use OCA\EmailRecovery\AppInfo\Application; +use OCP\AppFramework\Http\TemplateResponse; class EmailRecoveryController extends Controller { /** @var IConfig */ @@ -107,7 +108,11 @@ class EmailRecoveryController extends Controller { $error = $e->getCode() === InvalidTokenException::TOKEN_EXPIRED ? 'Could not reset password because the token is expired' : 'Could not reset password because the token is invalid'; - throw new Exception($error, (int)$e->getCode(), $e); + + return new TemplateResponse( + 'core', 'error', [ + 'errors' => [['error' => $error]] + ], TemplateResponse::RENDER_AS_GUEST); } } /** -- GitLab From 461918be72fcecedfbfbe95ed4c00b5d1f9db653 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 17:30:04 -0800 Subject: [PATCH 036/130] verified logic changes --- lib/Controller/EmailRecoveryController.php | 37 +++++++++++++++------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index a19f55f..4ef070c 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -95,26 +95,39 @@ class EmailRecoveryController extends Controller { * @PublicPage * @NoCSRFRequired */ - public function verifyRecoveryEmail(string $userId, string $token) { - $this->checkPasswordResetToken($token, $userId); - $this->config->setUserValue($userId, Application::APP_ID, 'recovery-email-verified', 'true'); - } - private function checkPasswordResetToken(string $userId, string $token) { + public function verifyRecoveryEmail(string $userId, string $token): TemplateResponse { try { - $user = $this->userManager->get($userId); - $recoveryEmail = $this->config->getUserValue($userId, 'email-recovery', 'recovery-email', ''); - $this->verificationToken->check($token, $user, 'recovery-email-token', $user ? $recoveryEmail : '', true); + $this->validatePasswordResetToken($userId, $token); + + $this->config->setUserValue($userId, Application::APP_ID, 'recovery-email-verified', 'true'); + + $message = 'You verified recovery email successfully.'; + + return new TemplateResponse( + 'core', 'success', [ + 'title' => $message, + 'message' => $message, + ], TemplateResponse::RENDER_AS_GUEST + ); } catch (InvalidTokenException $e) { $error = $e->getCode() === InvalidTokenException::TOKEN_EXPIRED - ? 'Could not reset password because the token is expired' - : 'Could not reset password because the token is invalid'; - + ? 'Could not reset password because the token is expired' + : 'Could not reset password because the token is invalid'; + return new TemplateResponse( 'core', 'error', [ 'errors' => [['error' => $error]] - ], TemplateResponse::RENDER_AS_GUEST); + ], TemplateResponse::RENDER_AS_GUEST + ); } } + private function validatePasswordResetToken(string $userId, string $token): void { + $user = $this->userManager->get($userId); + $recoveryEmail = $this->config->getUserValue($userId, 'email-recovery', 'recovery-email', ''); + + $this->verificationToken->check($token, $user, 'recovery-email-token', $user ? $recoveryEmail : '', true); + } + /** * @NoAdminRequired */ -- GitLab From 49bccfa8ad6e20cb252bce192281ccac7cd0285d Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 17:32:43 -0800 Subject: [PATCH 037/130] verified logic changes --- lib/Controller/EmailRecoveryController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 4ef070c..8e06e3f 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -102,7 +102,7 @@ class EmailRecoveryController extends Controller { $this->config->setUserValue($userId, Application::APP_ID, 'recovery-email-verified', 'true'); $message = 'You verified recovery email successfully.'; - + return new TemplateResponse( 'core', 'success', [ 'title' => $message, @@ -111,8 +111,8 @@ class EmailRecoveryController extends Controller { ); } catch (InvalidTokenException $e) { $error = $e->getCode() === InvalidTokenException::TOKEN_EXPIRED - ? 'Could not reset password because the token is expired' - : 'Could not reset password because the token is invalid'; + ? 'Could not verify recovery email because the token is expired' + : 'Could not verify recovery email because the token is invalid'; return new TemplateResponse( 'core', 'error', [ -- GitLab From 535d6ca03f3d83d2749b613853b37d1b5b362b63 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 17:50:34 -0800 Subject: [PATCH 038/130] token changes --- lib/Controller/EmailRecoveryController.php | 3 +-- lib/Service/RecoveryEmailService.php | 15 ++++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 8e06e3f..2372a72 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -122,9 +122,8 @@ class EmailRecoveryController extends Controller { } } private function validatePasswordResetToken(string $userId, string $token): void { - $user = $this->userManager->get($userId); $recoveryEmail = $this->config->getUserValue($userId, 'email-recovery', 'recovery-email', ''); - + $user = $this->userManager->get($userId); $this->verificationToken->check($token, $user, 'recovery-email-token', $user ? $recoveryEmail : '', true); } diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 96f2517..0b0f8e1 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -24,6 +24,7 @@ use OCP\Defaults; use OCP\BackgroundJob\IJobList; use OCA\EmailRecovery\AppInfo\Application; use OC\Authentication\Token\TokenCleanupJob; +use OCP\Security\VerificationToken\IVerificationToken; class RecoveryEmailService { private $LDAPConnectionService; @@ -38,9 +39,10 @@ class RecoveryEmailService { private $urlGenerator; private $themingDefaults; private $jobList; + private $verificationToken; protected const TOKEN_LIFETIME = 60 * 60 * 24 * 1; // 1 day - public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, ISecureRandom $secureRandom, IFactory $l10nFactory, ITimeFactory $timeFactory, ICrypto $crypto, IURLGenerator $urlGenerator, Defaults $themingDefaults, IJobList $jobList) { + public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, ISecureRandom $secureRandom, IFactory $l10nFactory, ITimeFactory $timeFactory, ICrypto $crypto, IURLGenerator $urlGenerator, Defaults $themingDefaults, IJobList $jobList, IVerificationToken $verificationToken) { $this->logger = $logger; $this->config = $config; $this->appName = $appName; @@ -54,6 +56,7 @@ class RecoveryEmailService { $this->urlGenerator = $urlGenerator; $this->themingDefaults = $themingDefaults; $this->jobList = $jobList; + $this->verificationToken = $verificationToken; } public function getRecoveryEmail(string $username) : string { @@ -99,8 +102,6 @@ class RecoveryEmailService { public function sendVerificationEmail(string $uid, string $recoverEmailAddress) : void { try { $user = $this->userManager->get($uid); - $username = $user->getDisplayName(); - $emailTemplate = $this->generateTemplate($user, $recoverEmailAddress); $email = $this->mailer->createMessage(); @@ -154,12 +155,8 @@ class RecoveryEmailService { return $emailTemplate; } private function createToken(IUser $user, string $subject, string $recoverEmail = ''): string { - $token = $this->secureRandom->generate( - 21, - ISecureRandom::CHAR_DIGITS. - ISecureRandom::CHAR_LOWER. - ISecureRandom::CHAR_UPPER - ); + $token = $this->verificationToken->create($user, 'recovery-email-token', $recoverEmail); + $tokenValue = $this->timeFactory->getTime() .':'. $token; $encryptedValue = $this->crypto->encrypt($tokenValue, $recoverEmail . $this->config->getSystemValue('secret')); $this->config->setUserValue($user->getUID(), Application::APP_ID, $subject, $encryptedValue); -- GitLab From 2718df21ea0d88ef2d150e3396b3e05b3df61eef Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 17:54:37 -0800 Subject: [PATCH 039/130] changes --- lib/Controller/EmailRecoveryController.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 2372a72..68533cc 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -100,6 +100,9 @@ class EmailRecoveryController extends Controller { $this->validatePasswordResetToken($userId, $token); $this->config->setUserValue($userId, Application::APP_ID, 'recovery-email-verified', 'true'); + + $user = $this->userManager->get($userId); + $this->verificationToken->delete($token, $user, 'recovery-email-token'); $message = 'You verified recovery email successfully.'; -- GitLab From bf9ad21ece757de5a33040cb13fd48c85d0bb38f Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 18:03:52 -0800 Subject: [PATCH 040/130] changes --- lib/Controller/EmailRecoveryController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 68533cc..2b243cf 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -99,9 +99,9 @@ class EmailRecoveryController extends Controller { try { $this->validatePasswordResetToken($userId, $token); - $this->config->setUserValue($userId, Application::APP_ID, 'recovery-email-verified', 'true'); - $user = $this->userManager->get($userId); + $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-verified', 'true'); + $this->verificationToken->delete($token, $user, 'recovery-email-token'); $message = 'You verified recovery email successfully.'; -- GitLab From 7771006b6404bd05dec1c9dfb3ab2970d595da52 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 22:26:37 -0800 Subject: [PATCH 041/130] added loadstate --- lib/Controller/EmailRecoveryController.php | 5 ++--- lib/Service/RecoveryEmailService.php | 6 +++++- lib/Settings/RecoveryEmailSettings.php | 4 +++- src/App.vue | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 2b243cf..ee40b02 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -39,7 +39,6 @@ use OCP\IUserManager; use OCP\Security\VerificationToken\IVerificationToken; use OCP\Security\VerificationToken\InvalidTokenException; use Exception; -use OCA\EmailRecovery\AppInfo\Application; use OCP\AppFramework\Http\TemplateResponse; class EmailRecoveryController extends Controller { @@ -86,7 +85,7 @@ class EmailRecoveryController extends Controller { public function getRecoveryEmail() { $response = new JSONResponse(); $userId = $this->userSession->getUser()->getUID(); - $data = array("recoveryEmail" => $this->config->getUserValue($userId, $this->appName, 'recovery-email'), "isRecoveryEmailVerification" => $this->config->getUserValue($userId, $this->appName, 'recovery-email-verified')); + $data = array("recoveryEmail" => $this->config->getUserValue($userId, $this->appName, 'recovery-email')); $response->setData($data); return $response; } @@ -100,7 +99,7 @@ class EmailRecoveryController extends Controller { $this->validatePasswordResetToken($userId, $token); $user = $this->userManager->get($userId); - $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-verified', 'true'); + $this->config->setUserValue($user->getUID(), $this->appName, 'recovery-email-verified', 'true'); $this->verificationToken->delete($token, $user, 'recovery-email-token'); diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 0b0f8e1..cb044ad 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -63,6 +63,10 @@ class RecoveryEmailService { return $this->config->getUserValue($username, $this->appName, 'recovery-email', ''); } + public function getRecoveryEmailVerificationStatus(string $username) : string { + return $this->config->getUserValue($username, $this->appName, 'recovery-email-verified'); + } + public function validateRecoveryEmail(string $username, string $recoveryEmail) : bool { $user = $this->userManager->get($username); $email = $user->getEMailAddress(); @@ -156,7 +160,7 @@ class RecoveryEmailService { } private function createToken(IUser $user, string $subject, string $recoverEmail = ''): string { $token = $this->verificationToken->create($user, 'recovery-email-token', $recoverEmail); - + $tokenValue = $this->timeFactory->getTime() .':'. $token; $encryptedValue = $this->crypto->encrypt($tokenValue, $recoverEmail . $this->config->getSystemValue('secret')); $this->config->setUserValue($user->getUID(), Application::APP_ID, $subject, $encryptedValue); diff --git a/lib/Settings/RecoveryEmailSettings.php b/lib/Settings/RecoveryEmailSettings.php index 1c99049..ab0a879 100644 --- a/lib/Settings/RecoveryEmailSettings.php +++ b/lib/Settings/RecoveryEmailSettings.php @@ -48,8 +48,10 @@ class RecoveryEmailSettings implements ISettings { public function getForm(): TemplateResponse { $username = $this->userSession->getUser()->getUID(); $recoveryEmail = $this->recoveryEmailService->getRecoveryEmail($username); - + $isRecoveryEmailVerification = $this->recoveryEmailService->getRecoveryEmailVerificationStatus($username); + $this->initialState->provideInitialState('recoveryEmail', $recoveryEmail); + $this->initialState->provideInitialState('isRecoveryEmailVerification', $isRecoveryEmailVerification); return new TemplateResponse( $this->appName, 'email_recovery_settings' diff --git a/src/App.vue b/src/App.vue index 98ea819..c2124a4 100644 --- a/src/App.vue +++ b/src/App.vue @@ -16,7 +16,7 @@ export default { showError: false, placeholder: t('email-recovery', 'Recovery Email'), value: t('email-recovery', 'Change Recovery Email'), - isRecoveryEmailVerification: false, + isRecoveryEmailVerification: loadState('email-recovery', 'isRecoveryEmailVerification'), } }, methods: { -- GitLab From 62f49ff1cfc9d64f6df282ad20297315fa9ff560 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 22:28:12 -0800 Subject: [PATCH 042/130] added loadstate --- lib/Controller/EmailRecoveryController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index ee40b02..a3f2612 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -89,6 +89,7 @@ class EmailRecoveryController extends Controller { $response->setData($data); return $response; } + /** * @NoAdminRequired * @PublicPage -- GitLab From 7ff0c1cf9dabab62f56680a886fefcee2b1f9e95 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 22:36:59 -0800 Subject: [PATCH 043/130] check changes --- src/App.vue | 1 - src/main.html | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/App.vue b/src/App.vue index c2124a4..4d7115e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -25,7 +25,6 @@ export default { .get(generateUrl('/apps/email-recovery/get_recovery_email')) .then(response => { this.recoveryEmail = response.data.recoveryEmail - this.isRecoveryEmailVerification = response.data.isRecoveryEmailVerification }) }, updateRecoveryEmail() { diff --git a/src/main.html b/src/main.html index 88b9796..212f344 100644 --- a/src/main.html +++ b/src/main.html @@ -13,7 +13,7 @@ v-model="recoveryEmail" :placeholder="placeholder" /> - + Date: Thu, 30 Nov 2023 22:48:30 -0800 Subject: [PATCH 044/130] disable method added --- src/App.vue | 6 ++++++ src/main.html | 1 + 2 files changed, 7 insertions(+) diff --git a/src/App.vue b/src/App.vue index 4d7115e..ed5b12b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -19,6 +19,11 @@ export default { isRecoveryEmailVerification: loadState('email-recovery', 'isRecoveryEmailVerification'), } }, + computed: { + isButtonDisabled() { + return this.recoveryEmail === loadState('email-recovery', 'recoveryEmail') + }, + }, methods: { getRecoveryEmail() { axios @@ -40,6 +45,7 @@ export default { } ) .then(response => { + this.isRecoveryEmailVerification = false this.showConfirmation = true setTimeout(function() { this.showConfirmation = false diff --git a/src/main.html b/src/main.html index 212f344..f63406a 100644 --- a/src/main.html +++ b/src/main.html @@ -20,6 +20,7 @@ id="recoveryButton" type="submit" :value="value" + :disabled="isButtonDisabled" />

{{ t("email-recovery","Email address have been saved. An email has been sent to you for verification.") }} -- GitLab From 425302e6ef5f5b647f7ec593ea3a1c0c71c1a53e Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 30 Nov 2023 22:53:19 -0800 Subject: [PATCH 045/130] isButtonDisabled changes --- src/App.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.vue b/src/App.vue index ed5b12b..8bd72bb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -21,7 +21,7 @@ export default { }, computed: { isButtonDisabled() { - return this.recoveryEmail === loadState('email-recovery', 'recoveryEmail') + return this.recoveryEmail === loadState('email-recovery', 'recoveryEmail') || this.recoveryEmail.trim() === '' }, }, methods: { -- GitLab From d98f67251d9c296a5c63f219a388343167741ae0 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 10:56:01 -0800 Subject: [PATCH 046/130] verification email is encrypted --- lib/Controller/EmailRecoveryController.php | 62 ++++++++++++---------- lib/Service/RecoveryEmailService.php | 40 ++++++++------ 2 files changed, 59 insertions(+), 43 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index a3f2612..4c9a442 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -40,6 +40,8 @@ use OCP\Security\VerificationToken\IVerificationToken; use OCP\Security\VerificationToken\InvalidTokenException; use Exception; use OCP\AppFramework\Http\TemplateResponse; +use OCP\Security\ICrypto; +use OCP\IL10N; class EmailRecoveryController extends Controller { /** @var IConfig */ @@ -56,7 +58,8 @@ class EmailRecoveryController extends Controller { private $recoveryEmailService; private $userManager; private $verificationToken; - + private $crypto; + private $l10n; public function __construct( string $appName, IRequest $request, @@ -66,7 +69,9 @@ class EmailRecoveryController extends Controller { IUserSession $userSession, RecoveryEmailService $recoveryEmailService, IUserManager $userManager, - IVerificationToken $verificationToken + IVerificationToken $verificationToken, + ICrypto $crypto, + IL10N $l10n, ) { parent::__construct($appName, $request); $this->config = $config; @@ -76,6 +81,8 @@ class EmailRecoveryController extends Controller { $this->recoveryEmailService = $recoveryEmailService; $this->userManager = $userManager; $this->verificationToken = $verificationToken; + $this->crypto = $crypto; + $this->l10n = $l10n; } /** @@ -95,40 +102,39 @@ class EmailRecoveryController extends Controller { * @PublicPage * @NoCSRFRequired */ - public function verifyRecoveryEmail(string $userId, string $token): TemplateResponse { + public function verifyRecoveryEmail(string $token, string $userId, string $key): TemplateResponse { try { - $this->validatePasswordResetToken($userId, $token); + $email = $this->crypto->decrypt($key); + $ref = substr(hash('sha256', $email), 0, 8); $user = $this->userManager->get($userId); - $this->config->setUserValue($user->getUID(), $this->appName, 'recovery-email-verified', 'true'); - - $this->verificationToken->delete($token, $user, 'recovery-email-token'); + $verificationKey = 'verifyRecoveryMail' . $ref; + $this->verificationToken->check($token, $user, $verificationKey, $email); - $message = 'You verified recovery email successfully.'; - - return new TemplateResponse( - 'core', 'success', [ - 'title' => $message, - 'message' => $message, - ], TemplateResponse::RENDER_AS_GUEST - ); + $userValueKey = 'recovery-email-verified'; + $this->config->setUserValue($user->getUID(), $this->appName, $userValueKey, 'true'); + + $this->verificationToken->delete($token, $user, $verificationKey); + + $responseParams = [ + 'title' => $this->l10n->t('You verified recovery email successfully.'), + 'message' => $this->l10n->t('You verified recovery email successfully.'), + ]; + + return new TemplateResponse('core', 'success', $responseParams, TemplateResponse::RENDER_AS_GUEST); } catch (InvalidTokenException $e) { $error = $e->getCode() === InvalidTokenException::TOKEN_EXPIRED - ? 'Could not verify recovery email because the token is expired' - : 'Could not verify recovery email because the token is invalid'; - - return new TemplateResponse( - 'core', 'error', [ - 'errors' => [['error' => $error]] - ], TemplateResponse::RENDER_AS_GUEST - ); + ? $this->l10n->t('Could not verify recovery email because the token is expired') + : $this->l10n->t('Could not verify recovery email because the token is invalid'); + + $errorParams = [ + 'errors' => [['error' => $error]], + ]; + + return new TemplateResponse('core', 'error', $errorParams, TemplateResponse::RENDER_AS_GUEST); } } - private function validatePasswordResetToken(string $userId, string $token): void { - $recoveryEmail = $this->config->getUserValue($userId, 'email-recovery', 'recovery-email', ''); - $user = $this->userManager->get($userId); - $this->verificationToken->check($token, $user, 'recovery-email-token', $user ? $recoveryEmail : '', true); - } + /** * @NoAdminRequired diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index cb044ad..a2d5be0 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -40,7 +40,7 @@ class RecoveryEmailService { private $themingDefaults; private $jobList; private $verificationToken; - protected const TOKEN_LIFETIME = 60 * 60 * 24 * 1; // 1 day + protected const TOKEN_LIFETIME = 60 * 10; // 10 minutes public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, ISecureRandom $secureRandom, IFactory $l10nFactory, ITimeFactory $timeFactory, ICrypto $crypto, IURLGenerator $urlGenerator, Defaults $themingDefaults, IJobList $jobList, IVerificationToken $verificationToken) { $this->logger = $logger; @@ -103,14 +103,14 @@ class RecoveryEmailService { } $this->LDAPConnectionService->closeLDAPConnection($conn); } - public function sendVerificationEmail(string $uid, string $recoverEmailAddress) : void { + public function sendVerificationEmail(string $uid, string $recoveryEmailAddress) : void { try { $user = $this->userManager->get($uid); - $emailTemplate = $this->generateTemplate($user, $recoverEmailAddress); + $emailTemplate = $this->generateTemplate($user, $recoveryEmailAddress); $email = $this->mailer->createMessage(); $email->useTemplate($emailTemplate); - $email->setTo([$recoverEmailAddress]); + $email->setTo([$recoveryEmailAddress]); $email->setFrom([Util::getDefaultEmailAddress('no-reply') => $this->themingDefaults->getName()]); $this->mailer->send($email); } catch (\Exception $e) { @@ -119,17 +119,26 @@ class RecoveryEmailService { } /** * @param IUser $user - * @param string $recoverEmailAddress + * @param string $recoveryEmailAddress * @return IEMailTemplate */ - public function generateTemplate(IUser $user, string $recoverEmailAddress) { + public function generateTemplate(IUser $user, string $recoveryEmailAddress) { $userId = $user->getUID(); $lang = $this->config->getUserValue($userId, 'core', 'lang', null); $l10n = $this->l10nFactory->get('settings', $lang); - $token = $this->createToken($user, 'recovery-email-token', $recoverEmailAddress); - $link = $this->urlGenerator->linkToRouteAbsolute($this->appName .'.email_recovery.verify_recovery_email', ['userId' => $user->getUID(), 'token' => $token]); + $token = $this->createToken($user, $recoveryEmailAddress); + $key = $this->crypto->encrypt($recoveryEmailAddress); + + $link = $this->urlGenerator->linkToRouteAbsolute( + $this->appName .'email_recovery.verify_recovery_email', + [ + 'userId' => $user->getUID(), + 'token' => $token, + 'key' => $key + ] + ); $displayName = $user->getDisplayName(); @@ -158,17 +167,18 @@ class RecoveryEmailService { return $emailTemplate; } - private function createToken(IUser $user, string $subject, string $recoverEmail = ''): string { - $token = $this->verificationToken->create($user, 'recovery-email-token', $recoverEmail); - + private function createToken(IUser $user, string $recoveryEmail = ''): string { + $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); + $token = $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail); + $tokenValue = $this->timeFactory->getTime() .':'. $token; - $encryptedValue = $this->crypto->encrypt($tokenValue, $recoverEmail . $this->config->getSystemValue('secret')); - $this->config->setUserValue($user->getUID(), Application::APP_ID, $subject, $encryptedValue); + $encryptedValue = $this->crypto->encrypt($tokenValue, $recoveryEmail . $this->config->getSystemValue('secret')); + $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-token', $encryptedValue); $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-verified', 'false'); $jobArgs = json_encode([ 'userId' => $user->getUID(), - 'subject' => $subject, - 'pp' => $recoverEmail, + 'subject' => 'recovery-email-token', + 'pp' => $recoveryEmail, 'notBefore' => $this->timeFactory->getTime() + self::TOKEN_LIFETIME * 2, // multiply to provide a grace period ]); $this->jobList->add(TokenCleanupJob::class, $jobArgs); -- GitLab From 6bc16f575f423c519103503ba294601f667d45ad Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 11:00:45 -0800 Subject: [PATCH 047/130] verification email is encrypted --- lib/Controller/EmailRecoveryController.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 4c9a442..9f11eb4 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -41,7 +41,6 @@ use OCP\Security\VerificationToken\InvalidTokenException; use Exception; use OCP\AppFramework\Http\TemplateResponse; use OCP\Security\ICrypto; -use OCP\IL10N; class EmailRecoveryController extends Controller { /** @var IConfig */ @@ -59,7 +58,6 @@ class EmailRecoveryController extends Controller { private $userManager; private $verificationToken; private $crypto; - private $l10n; public function __construct( string $appName, IRequest $request, @@ -70,8 +68,7 @@ class EmailRecoveryController extends Controller { RecoveryEmailService $recoveryEmailService, IUserManager $userManager, IVerificationToken $verificationToken, - ICrypto $crypto, - IL10N $l10n, + ICrypto $crypto ) { parent::__construct($appName, $request); $this->config = $config; @@ -82,7 +79,6 @@ class EmailRecoveryController extends Controller { $this->userManager = $userManager; $this->verificationToken = $verificationToken; $this->crypto = $crypto; - $this->l10n = $l10n; } /** @@ -117,15 +113,15 @@ class EmailRecoveryController extends Controller { $this->verificationToken->delete($token, $user, $verificationKey); $responseParams = [ - 'title' => $this->l10n->t('You verified recovery email successfully.'), - 'message' => $this->l10n->t('You verified recovery email successfully.'), + 'title' => $this->l->t('You verified recovery email successfully.'), + 'message' => $this->l->t('You verified recovery email successfully.'), ]; return new TemplateResponse('core', 'success', $responseParams, TemplateResponse::RENDER_AS_GUEST); } catch (InvalidTokenException $e) { $error = $e->getCode() === InvalidTokenException::TOKEN_EXPIRED - ? $this->l10n->t('Could not verify recovery email because the token is expired') - : $this->l10n->t('Could not verify recovery email because the token is invalid'); + ? $this->l->t('Could not verify recovery email because the token is expired') + : $this->l->t('Could not verify recovery email because the token is invalid'); $errorParams = [ 'errors' => [['error' => $error]], -- GitLab From 78bb7da208ab60765e962d92e4b4a47210e778a4 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 11:07:56 -0800 Subject: [PATCH 048/130] added resend button --- appinfo/routes.php | 4 ++- lib/Controller/EmailRecoveryController.php | 30 ++++++++++++++++++++++ src/App.vue | 21 +++++++++++++++ src/main.html | 8 ++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 95f84cd..0cf6162 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -30,6 +30,8 @@ return [ 'verb' => 'OPTIONS', 'requirements' => ['path' => '.+']], ['name' => 'email_recovery_api#show', 'url' => '/api/recovery-email/{id}', 'verb' => 'GET'], ['name' => 'email_recovery_api#update', 'url' => '/api/recovery-email/{id}', 'verb' => 'PUT'], - ['name' => 'email_recovery#verify_recovery_email', 'url' => '/recovery-email/verify', 'verb' => 'GET'] + ['name' => 'email_recovery#verify_recovery_email', 'url' => '/recovery-email/verify', 'verb' => 'GET'], + ['name' => 'email_recovery#resend_recovery_email', 'url' => '/resend_recovery_email', 'verb' => 'POST'], + ] ]; diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 9f11eb4..da448a1 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -162,4 +162,34 @@ class EmailRecoveryController extends Controller { return $response; } } + + /** + * @NoAdminRequired + */ + public function resendRecoveryEmail(string $recoveryEmail) { + $userId = $this->userSession->getUser()->getUID(); + $response = new Response(); + try { + if ($this->recoveryEmailService->validateRecoveryEmail($userId, $recoveryEmail)) { + $this->recoveryEmailService->sendVerificationEmail($userId, $recoveryEmail); + $response->setStatus(200); + return $response; + } + } catch (Exception $e) { + $response->setStatus(500); + if ($e instanceof InvalidRecoveryEmailException) { + $response->setStatus(400); + $this->l->t('Invalid Recovery Email'); + $response->setData(['message' => 'Invalid Recovery Email']); + } + if ($e instanceof SameRecoveryEmailAsEmailException) { + $response->setStatus(400); + $this->l->t('Error! User email address cannot be saved as recovery email address!'); + $response->setData(['message' => 'Error! User email address cannot be saved as recovery email address!']); + } + + $this->logger->error("Error setting recovery email for user $userId" . $e->getMessage()); + return $response; + } + } } diff --git a/src/App.vue b/src/App.vue index 8bd72bb..c1f8f51 100644 --- a/src/App.vue +++ b/src/App.vue @@ -61,6 +61,27 @@ export default { }) }) }, + resendVerificationEmail() { + this.showError = false + this.errorKey = '' + axios + .post( + generateUrl('/apps/email-recovery/resend_recovery_email'), + { + recoveryEmail: this.recoveryEmail, + } + ) + .then(response => { + this.isRecoveryEmailVerification = false + }) + .catch(err => { + this.errorKey = 'Error sending recovery verification email' + if (err.response && err.response.message) { + this.errorKey = err.response.message + } + this.showError = true + }) + }, }, } diff --git a/src/main.html b/src/main.html index f63406a..0aef549 100644 --- a/src/main.html +++ b/src/main.html @@ -22,6 +22,14 @@ :value="value" :disabled="isButtonDisabled" /> + +

{{ t("email-recovery","Email address have been saved. An email has been sent to you for verification.") }}

-- GitLab From 818109f9299f144610d3eff6a6aa8b4671988560 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 11:17:01 -0800 Subject: [PATCH 049/130] added resend button --- scss/main.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scss/main.scss b/scss/main.scss index 1e7ae3b..dd15474 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -27,13 +27,14 @@ width: 400px; } #recoveryEmail, - #recoveryButton { + #recoveryButton, + #resendRecoveryButton { flex-shrink: 1; width: 100%; min-width: 150px; } - #recoveryButton { + #recoveryButton, #resendRecoveryButton { margin-top: 15px; } } -- GitLab From 7abb33f51bd8a2b5c7403519ce4907e3ef7582a0 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 11:19:57 -0800 Subject: [PATCH 050/130] link changes --- lib/Service/RecoveryEmailService.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index a2d5be0..403481a 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -130,15 +130,7 @@ class RecoveryEmailService { $token = $this->createToken($user, $recoveryEmailAddress); $key = $this->crypto->encrypt($recoveryEmailAddress); - - $link = $this->urlGenerator->linkToRouteAbsolute( - $this->appName .'email_recovery.verify_recovery_email', - [ - 'userId' => $user->getUID(), - 'token' => $token, - 'key' => $key - ] - ); + $link = $this->urlGenerator->linkToRouteAbsolute($this->appName .'.email_recovery.verify_recovery_email', ['userId' => $user->getUID(), 'token' => $token, 'key' => $key]); $displayName = $user->getDisplayName(); -- GitLab From 6eb3e6f5076236f482aa3f74b874de7bba200a68 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 11:24:52 -0800 Subject: [PATCH 051/130] message --- src/App.vue | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/App.vue b/src/App.vue index c1f8f51..611f6ff 100644 --- a/src/App.vue +++ b/src/App.vue @@ -62,6 +62,7 @@ export default { }) }, resendVerificationEmail() { + this.showConfirmation = false this.showError = false this.errorKey = '' axios @@ -73,6 +74,10 @@ export default { ) .then(response => { this.isRecoveryEmailVerification = false + this.showConfirmation = true + setTimeout(function() { + this.showConfirmation = false + }, 3000) }) .catch(err => { this.errorKey = 'Error sending recovery verification email' -- GitLab From 8ada5475e73628e98b52b2163bd6ef6b77d4b323 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 11:39:38 -0800 Subject: [PATCH 052/130] recovery email found exception added --- lib/Controller/EmailRecoveryController.php | 23 +++++++++++-------- ...ecoveryEmailAlreadyFoundEmailException.php | 11 +++++++++ lib/Service/RecoveryEmailService.php | 14 +++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 lib/Exception/RecoveryEmailAlreadyFoundEmailException.php diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index da448a1..9c6357f 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -35,6 +35,7 @@ use OCP\AppFramework\Http\JSONResponse; use OCA\EmailRecovery\Service\RecoveryEmailService; use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; +use OCA\EmailRecovery\Exception\RecoveryEmailAlreadyFoundEmailException; use OCP\IUserManager; use OCP\Security\VerificationToken\IVerificationToken; use OCP\Security\VerificationToken\InvalidTokenException; @@ -149,15 +150,16 @@ class EmailRecoveryController extends Controller { $response->setStatus(500); if ($e instanceof InvalidRecoveryEmailException) { $response->setStatus(400); - $this->l->t('Invalid Recovery Email'); - $response->setData(['message' => 'Invalid Recovery Email']); + $response->setData(['message' => $this->l->t('Invalid Recovery Email')]); } if ($e instanceof SameRecoveryEmailAsEmailException) { $response->setStatus(400); - $this->l->t('Error! User email address cannot be saved as recovery email address!'); - $response->setData(['message' => 'Error! User email address cannot be saved as recovery email address!']); + $response->setData(['message' => $this->l->t('Error! User email address cannot be saved as recovery email address!')]); + } + if ($e instanceof RecoveryEmailAlreadyFoundEmailException) { + $response->setStatus(400); + $response->setData(['message' => $this->l->t('Recovery email address is already taken.')]); } - $this->logger->error("Error setting recovery email for user $userId" . $e->getMessage()); return $response; } @@ -179,15 +181,16 @@ class EmailRecoveryController extends Controller { $response->setStatus(500); if ($e instanceof InvalidRecoveryEmailException) { $response->setStatus(400); - $this->l->t('Invalid Recovery Email'); - $response->setData(['message' => 'Invalid Recovery Email']); + $response->setData(['message' => $this->l->t('Invalid Recovery Email')]); } if ($e instanceof SameRecoveryEmailAsEmailException) { $response->setStatus(400); - $this->l->t('Error! User email address cannot be saved as recovery email address!'); - $response->setData(['message' => 'Error! User email address cannot be saved as recovery email address!']); + $response->setData(['message' => $this->l->t('Error! User email address cannot be saved as recovery email address!')]); + } + if ($e instanceof RecoveryEmailAlreadyFoundEmailException) { + $response->setStatus(400); + $response->setData(['message' => $this->l->t('Recovery email address is already taken.')]); } - $this->logger->error("Error setting recovery email for user $userId" . $e->getMessage()); return $response; } diff --git a/lib/Exception/RecoveryEmailAlreadyFoundEmailException.php b/lib/Exception/RecoveryEmailAlreadyFoundEmailException.php new file mode 100644 index 0000000..0406f77 --- /dev/null +++ b/lib/Exception/RecoveryEmailAlreadyFoundEmailException.php @@ -0,0 +1,11 @@ +logger->info("User ID $username's requested recovery email is the same as email"); throw new SameRecoveryEmailAsEmailException(); } + if (!empty($recoveryEmail) && $this->checkRecoveryEmailAvailable($recoveryEmail)) { + $this->logger->info("User ID $username's requested recovery email address is already taken"); + throw new RecoveryEmailAlreadyFoundEmailException(); + } return true; } + public function checkRecoveryEmailAvailable(string $recoveryEmail): bool { + $recoveryEmail = strtolower($recoveryEmail); + $users = $this->config->getUsersForUserValue('email-recovery', 'recovery-email', $recoveryEmail); + if (count($users)) { + return true; + } + return false; + } + public function updateRecoveryEmail(string $username, string $recoveryEmail) : void { $user = $this->userManager->get($username); if ($this->LDAPConnectionService->isUserOnLDAPBackend($user) && $this->LDAPConnectionService->isLDAPEnabled()) { -- GitLab From 281fd792447b125a624b22748cedf4a67bc77c88 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 11:48:04 -0800 Subject: [PATCH 053/130] jsondata changes --- lib/Controller/EmailRecoveryController.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 9c6357f..4b71214 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -30,7 +30,6 @@ use OCP\IConfig; use OCP\ILogger; use \OCP\IL10N; use OCP\IUserSession; -use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\JSONResponse; use OCA\EmailRecovery\Service\RecoveryEmailService; use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; @@ -139,7 +138,7 @@ class EmailRecoveryController extends Controller { public function setRecoveryEmail(string $recoveryEmail) { $userId = $this->userSession->getUser()->getUID(); - $response = new Response(); + $response = new JSONResponse(); try { if ($this->recoveryEmailService->validateRecoveryEmail($userId, $recoveryEmail)) { $this->recoveryEmailService->updateRecoveryEmail($userId, $recoveryEmail); @@ -170,7 +169,7 @@ class EmailRecoveryController extends Controller { */ public function resendRecoveryEmail(string $recoveryEmail) { $userId = $this->userSession->getUser()->getUID(); - $response = new Response(); + $response = new JSONResponse(); try { if ($this->recoveryEmailService->validateRecoveryEmail($userId, $recoveryEmail)) { $this->recoveryEmailService->sendVerificationEmail($userId, $recoveryEmail); -- GitLab From d7d9d49c6902169d562eb348d06bf3907a8da15d Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 11:49:03 -0800 Subject: [PATCH 054/130] removed listener unncessary code --- lib/Listeners/UserChangedListener.php | 33 --------------------------- 1 file changed, 33 deletions(-) diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php index 11e7bec..3912014 100644 --- a/lib/Listeners/UserChangedListener.php +++ b/lib/Listeners/UserChangedListener.php @@ -4,7 +4,6 @@ declare(strict_types=1); namespace OCA\EmailRecovery\Listeners; -use Exception; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\ILogger; @@ -30,37 +29,5 @@ class UserChangedListener implements IEventListener { \OC::$server->getLogger()->error(">>>>>>>> username:: " . $username); \OC::$server->getLogger()->error(">>>>>>>> feature:: " . $feature); \OC::$server->getLogger()->error(">>>>>>>> user:: " . $user); - - - // if ($feature === self::QUOTA_FEATURE) { - // $updatedQuota = $event->getValue(); - // $quotaInBytes = (int) $this->util->computerFileSize($updatedQuota); - // $backend = $user->getBackend()->getBackendName(); - - // $this->updateQuota($username, $backend, $quotaInBytes); - // } - - // if ($feature === self::RECOVERY_EMAIL_FEATURE) { - // $recoveryEmail = $event->getValue(); - // $recoveryEmailAttribute = [ - // 'recoveryMailAddress' => $recoveryEmail - // ]; - - // } } - - // private function updateQuota(string $username, string $backend, int $quotaInBytes) { - // try { - // if ($backend === 'SQL raw') { - // $this->mailboxMapper->updateMailboxQuota($username, $quotaInBytes); - // } - // if ($backend === 'LDAP') { - // $quotaAttribute = [ - // 'quota' => $quotaInBytes - // ]; - // } - // } catch (Exception $e) { - // $this->logger->error("Error setting quota for user $username " . $e->getMessage()); - // } - // } } -- GitLab From 3629aeadfa5988d2ce7a83fd77fc122a69502515 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 11:54:17 -0800 Subject: [PATCH 055/130] removed listener unncessary code --- src/App.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/App.vue b/src/App.vue index 611f6ff..fd71d0d 100644 --- a/src/App.vue +++ b/src/App.vue @@ -52,6 +52,7 @@ export default { }, 3000) }) .catch(err => { + console.error(err) this.errorKey = 'Error setting recovery email' if (err.response && err.response.message) { this.errorKey = err.response.message @@ -80,6 +81,7 @@ export default { }, 3000) }) .catch(err => { + console.error(err) this.errorKey = 'Error sending recovery verification email' if (err.response && err.response.message) { this.errorKey = err.response.message -- GitLab From f586eef1d3f245182db142515e659573a1dd0126 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 12:00:31 -0800 Subject: [PATCH 056/130] err.response.data.message changes --- src/App.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/App.vue b/src/App.vue index fd71d0d..375254f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -54,8 +54,8 @@ export default { .catch(err => { console.error(err) this.errorKey = 'Error setting recovery email' - if (err.response && err.response.message) { - this.errorKey = err.response.message + if (err.response && err.response.data.message) { + this.errorKey = err.response.data.message } this.showError = true this.getRecoveryEmail() @@ -83,8 +83,8 @@ export default { .catch(err => { console.error(err) this.errorKey = 'Error sending recovery verification email' - if (err.response && err.response.message) { - this.errorKey = err.response.message + if (err.response && err.response.data.message) { + this.errorKey = err.response.data.message } this.showError = true }) -- GitLab From f8b43b028a2332423288a81bfa3576571f58df5c Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 1 Dec 2023 15:18:20 -0800 Subject: [PATCH 057/130] true by default --- lib/Service/RecoveryEmailService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 01e9615..50e16f0 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -65,7 +65,7 @@ class RecoveryEmailService { } public function getRecoveryEmailVerificationStatus(string $username) : string { - return $this->config->getUserValue($username, $this->appName, 'recovery-email-verified'); + return $this->config->getUserValue($username, $this->appName, 'recovery-email-verified','true'); } public function validateRecoveryEmail(string $username, string $recoveryEmail) : bool { -- GitLab From f9ea693316107a1d69aa6e66595e028a476999f1 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Tue, 5 Dec 2023 00:02:36 -0800 Subject: [PATCH 058/130] logger issue --- lib/Listeners/UserChangedListener.php | 1 - lib/Service/RecoveryEmailService.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php index 3912014..1c9e44d 100644 --- a/lib/Listeners/UserChangedListener.php +++ b/lib/Listeners/UserChangedListener.php @@ -28,6 +28,5 @@ class UserChangedListener implements IEventListener { \OC::$server->getLogger()->error(">>>>>>>> username:: " . $username); \OC::$server->getLogger()->error(">>>>>>>> feature:: " . $feature); - \OC::$server->getLogger()->error(">>>>>>>> user:: " . $user); } } diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 50e16f0..5a0394d 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -65,7 +65,7 @@ class RecoveryEmailService { } public function getRecoveryEmailVerificationStatus(string $username) : string { - return $this->config->getUserValue($username, $this->appName, 'recovery-email-verified','true'); + return $this->config->getUserValue($username, $this->appName, 'recovery-email-verified', 'true'); } public function validateRecoveryEmail(string $username, string $recoveryEmail) : bool { -- GitLab From bea071df13aaaf6058957c4fc9ed18aafb8aa2b6 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 02:17:52 -0800 Subject: [PATCH 059/130] UserConfigChangedEvent added in application --- lib/AppInfo/Application.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 1a2d5c3..27c2285 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -31,7 +31,7 @@ use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCA\EmailRecovery\Listeners\UserChangedListener; -use OCP\User\Events\UserChangedEvent; +use OCP\User\Events\UserConfigChangedEvent; class Application extends App implements IBootstrap { public const APP_ID = 'email-recovery'; @@ -43,7 +43,7 @@ class Application extends App implements IBootstrap { public function register(IRegistrationContext $context): void { // \OC::$server->getLogger()->error("I AM in register at emailrecovery app."); - $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); + $context->registerEventListener(UserConfigChangedEvent::class, UserChangedListener::class); } public function boot(IBootContext $context): void { -- GitLab From 8ea482206db47adb3366366217af2b27c2a3c4a5 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 02:26:10 -0800 Subject: [PATCH 060/130] user config change --- lib/AppInfo/Application.php | 4 ++-- ...erChangedListener.php => UserConfigChangedListener.php} | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) rename lib/Listeners/{UserChangedListener.php => UserConfigChangedListener.php} (79%) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 27c2285..3e568ce 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -30,7 +30,7 @@ use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; -use OCA\EmailRecovery\Listeners\UserChangedListener; +use OCA\EmailRecovery\Listeners\UserConfigChangedListener; use OCP\User\Events\UserConfigChangedEvent; class Application extends App implements IBootstrap { @@ -43,7 +43,7 @@ class Application extends App implements IBootstrap { public function register(IRegistrationContext $context): void { // \OC::$server->getLogger()->error("I AM in register at emailrecovery app."); - $context->registerEventListener(UserConfigChangedEvent::class, UserChangedListener::class); + $context->registerEventListener(UserConfigChangedEvent::class, UserConfigChangedListener::class); } public function boot(IBootContext $context): void { diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserConfigChangedListener.php similarity index 79% rename from lib/Listeners/UserChangedListener.php rename to lib/Listeners/UserConfigChangedListener.php index 1c9e44d..f8b91b9 100644 --- a/lib/Listeners/UserChangedListener.php +++ b/lib/Listeners/UserConfigChangedListener.php @@ -7,9 +7,8 @@ namespace OCA\EmailRecovery\Listeners; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\ILogger; -use OCP\User\Events\UserChangedEvent; -class UserChangedListener implements IEventListener { +class UserConfigChangedListener implements IEventListener { private $logger; public function __construct(ILogger $logger) { @@ -17,8 +16,8 @@ class UserChangedListener implements IEventListener { } public function handle(Event $event): void { - \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserChangedListener"); - if (!($event instanceof UserChangedEvent)) { + \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserConfigChangedListener"); + if (!($event instanceof UserConfigChangedEvent)) { return; } -- GitLab From 23b39e5f8966ff1abb0445733b7d223bb4704000 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 03:48:02 -0800 Subject: [PATCH 061/130] commented instanceof --- lib/Listeners/UserConfigChangedListener.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Listeners/UserConfigChangedListener.php b/lib/Listeners/UserConfigChangedListener.php index f8b91b9..00e8c77 100644 --- a/lib/Listeners/UserConfigChangedListener.php +++ b/lib/Listeners/UserConfigChangedListener.php @@ -17,9 +17,10 @@ class UserConfigChangedListener implements IEventListener { public function handle(Event $event): void { \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserConfigChangedListener"); - if (!($event instanceof UserConfigChangedEvent)) { - return; - } + // \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserConfigChangedListener"); + // if (!($event instanceof UserConfigChangedEvent)) { + // return; + // } $feature = $event->getFeature(); $user = $event->getUser(); -- GitLab From 7749c5929ea68fe0383d6ad3d3270f90833f85d7 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 04:03:26 -0800 Subject: [PATCH 062/130] change in listenere --- lib/Listeners/UserConfigChangedListener.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/Listeners/UserConfigChangedListener.php b/lib/Listeners/UserConfigChangedListener.php index 00e8c77..fda89d0 100644 --- a/lib/Listeners/UserConfigChangedListener.php +++ b/lib/Listeners/UserConfigChangedListener.php @@ -22,11 +22,10 @@ class UserConfigChangedListener implements IEventListener { // return; // } - $feature = $event->getFeature(); - $user = $event->getUser(); - $username = $user->getUID(); + $key = $event->getKey(); + $user = $event->getUserId(); - \OC::$server->getLogger()->error(">>>>>>>> username:: " . $username); - \OC::$server->getLogger()->error(">>>>>>>> feature:: " . $feature); + \OC::$server->getLogger()->error(">>>>>>>> user:: " . $user); + \OC::$server->getLogger()->error(">>>>>>>> key:: " . $key); } } -- GitLab From b8a0fbdc49fe1e8dbb91e101bf42d651511bde22 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 04:04:59 -0800 Subject: [PATCH 063/130] listenre --- lib/Listeners/UserConfigChangedListener.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Listeners/UserConfigChangedListener.php b/lib/Listeners/UserConfigChangedListener.php index fda89d0..b3c046e 100644 --- a/lib/Listeners/UserConfigChangedListener.php +++ b/lib/Listeners/UserConfigChangedListener.php @@ -7,6 +7,7 @@ namespace OCA\EmailRecovery\Listeners; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\ILogger; +use OCP\User\Events\UserConfigChangedEvent; class UserConfigChangedListener implements IEventListener { private $logger; @@ -18,9 +19,9 @@ class UserConfigChangedListener implements IEventListener { public function handle(Event $event): void { \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserConfigChangedListener"); // \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserConfigChangedListener"); - // if (!($event instanceof UserConfigChangedEvent)) { - // return; - // } + if (!($event instanceof UserConfigChangedEvent)) { + return; + } $key = $event->getKey(); $user = $event->getUserId(); -- GitLab From 0adccd0e712332315738aea8fd9f5ac0fe3d1c2f Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 04:15:54 -0800 Subject: [PATCH 064/130] added verificationemail in listenere --- lib/Listeners/UserConfigChangedListener.php | 16 +++++++++++----- lib/Service/RecoveryEmailService.php | 1 - 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/Listeners/UserConfigChangedListener.php b/lib/Listeners/UserConfigChangedListener.php index b3c046e..f6dac81 100644 --- a/lib/Listeners/UserConfigChangedListener.php +++ b/lib/Listeners/UserConfigChangedListener.php @@ -8,25 +8,31 @@ use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\ILogger; use OCP\User\Events\UserConfigChangedEvent; +use OCA\EmailRecovery\Service\RecoveryEmailService; class UserConfigChangedListener implements IEventListener { private $logger; + private $recoveryEmailService; - public function __construct(ILogger $logger) { + public function __construct(ILogger $logger, RecoveryEmailService $recoveryEmailService) { $this->logger = $logger; + $this->recoveryEmailService = $recoveryEmailService; } public function handle(Event $event): void { \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserConfigChangedListener"); - // \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserConfigChangedListener"); if (!($event instanceof UserConfigChangedEvent)) { return; } $key = $event->getKey(); $user = $event->getUserId(); - - \OC::$server->getLogger()->error(">>>>>>>> user:: " . $user); - \OC::$server->getLogger()->error(">>>>>>>> key:: " . $key); + $newRecoveryEmail = $event->getValue(); + if ($key === 'recovery-email') { + \OC::$server->getLogger()->error(">>>>>>>> user:: " . $user); + \OC::$server->getLogger()->error(">>>>>>>> key:: " . $key); + \OC::$server->getLogger()->error(">>>>>>>> newRecoveryEmail:: " . $newRecoveryEmail); + $this->recoveryEmailService->sendVerificationEmail($user, $newRecoveryEmail); + } } } diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 5a0394d..f7ee0a3 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -102,7 +102,6 @@ class RecoveryEmailService { $this->updateRecoveryEmailAtLDAPServer($username, $recoveryEmail); } $this->config->setUserValue($username, $this->appName, 'recovery-email', $recoveryEmail); - $this->sendVerificationEmail($username, $recoveryEmail); } -- GitLab From 4c4d86c6a075c7ee98538f525118b5219d0cb6e4 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 04:17:59 -0800 Subject: [PATCH 065/130] remove unncessary function --- lib/Service/RecoveryEmailService.php | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index f7ee0a3..642445d 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -190,25 +190,4 @@ class RecoveryEmailService { return $token; } - /** - * Special-treat list items and strip empty lines - * - * @param IEMailTemplate $template - * @param string $message - * - * @return void - */ - public function setMailBody(IEMailTemplate $template, string $message): void { - $lines = explode("\n", $message); - $finalHtml = ""; - $finalText = ""; - foreach ($lines as $line) { - if (trim($line) === '') { - continue; - } - $finalHtml .= "

" . $line . "

"; - $finalText .= $line; - } - $template->addBodyText($finalHtml, $finalText); - } } -- GitLab From c0b69d9abf8d7f98292570ba034b4320455ce52d Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 04:19:31 -0800 Subject: [PATCH 066/130] remove logger code --- lib/Listeners/UserConfigChangedListener.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/Listeners/UserConfigChangedListener.php b/lib/Listeners/UserConfigChangedListener.php index f6dac81..7fdcf87 100644 --- a/lib/Listeners/UserConfigChangedListener.php +++ b/lib/Listeners/UserConfigChangedListener.php @@ -20,18 +20,12 @@ class UserConfigChangedListener implements IEventListener { } public function handle(Event $event): void { - \OC::$server->getLogger()->error(">>>>>>>> Handle event in UserConfigChangedListener"); if (!($event instanceof UserConfigChangedEvent)) { return; } - - $key = $event->getKey(); - $user = $event->getUserId(); - $newRecoveryEmail = $event->getValue(); - if ($key === 'recovery-email') { - \OC::$server->getLogger()->error(">>>>>>>> user:: " . $user); - \OC::$server->getLogger()->error(">>>>>>>> key:: " . $key); - \OC::$server->getLogger()->error(">>>>>>>> newRecoveryEmail:: " . $newRecoveryEmail); + if ($event->getKey() === 'recovery-email') { + $user = $event->getUserId(); + $newRecoveryEmail = $event->getValue(); $this->recoveryEmailService->sendVerificationEmail($user, $newRecoveryEmail); } } -- GitLab From 8103704c146c97fbade80d0fed170fee3bfcb632 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 04:24:25 -0800 Subject: [PATCH 067/130] change in application --- lib/AppInfo/Application.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 3e568ce..14ed4e0 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -27,7 +27,6 @@ declare(strict_types=1); namespace OCA\EmailRecovery\AppInfo; use OCP\AppFramework\App; -use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCA\EmailRecovery\Listeners\UserConfigChangedListener; @@ -41,12 +40,6 @@ class Application extends App implements IBootstrap { } public function register(IRegistrationContext $context): void { - // \OC::$server->getLogger()->error("I AM in register at emailrecovery app."); - $context->registerEventListener(UserConfigChangedEvent::class, UserConfigChangedListener::class); } - - public function boot(IBootContext $context): void { - // \OC::$server->getLogger()->error("I AM in boot at emailrecovery app."); - } } -- GitLab From a445cfb43d9a428955fe5ce600cb9d71b47a319d Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 04:26:26 -0800 Subject: [PATCH 068/130] renamed exception --- lib/Controller/EmailRecoveryController.php | 6 +++--- ...Exception.php => RecoveryEmailAlreadyFoundException.php} | 2 +- lib/Service/RecoveryEmailService.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename lib/Exception/{RecoveryEmailAlreadyFoundEmailException.php => RecoveryEmailAlreadyFoundException.php} (71%) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 4b71214..864e280 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -34,7 +34,7 @@ use OCP\AppFramework\Http\JSONResponse; use OCA\EmailRecovery\Service\RecoveryEmailService; use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; -use OCA\EmailRecovery\Exception\RecoveryEmailAlreadyFoundEmailException; +use OCA\EmailRecovery\Exception\RecoveryEmailAlreadyFoundException; use OCP\IUserManager; use OCP\Security\VerificationToken\IVerificationToken; use OCP\Security\VerificationToken\InvalidTokenException; @@ -155,7 +155,7 @@ class EmailRecoveryController extends Controller { $response->setStatus(400); $response->setData(['message' => $this->l->t('Error! User email address cannot be saved as recovery email address!')]); } - if ($e instanceof RecoveryEmailAlreadyFoundEmailException) { + if ($e instanceof RecoveryEmailAlreadyFoundException) { $response->setStatus(400); $response->setData(['message' => $this->l->t('Recovery email address is already taken.')]); } @@ -186,7 +186,7 @@ class EmailRecoveryController extends Controller { $response->setStatus(400); $response->setData(['message' => $this->l->t('Error! User email address cannot be saved as recovery email address!')]); } - if ($e instanceof RecoveryEmailAlreadyFoundEmailException) { + if ($e instanceof RecoveryEmailAlreadyFoundException) { $response->setStatus(400); $response->setData(['message' => $this->l->t('Recovery email address is already taken.')]); } diff --git a/lib/Exception/RecoveryEmailAlreadyFoundEmailException.php b/lib/Exception/RecoveryEmailAlreadyFoundException.php similarity index 71% rename from lib/Exception/RecoveryEmailAlreadyFoundEmailException.php rename to lib/Exception/RecoveryEmailAlreadyFoundException.php index 0406f77..67d5cbb 100644 --- a/lib/Exception/RecoveryEmailAlreadyFoundEmailException.php +++ b/lib/Exception/RecoveryEmailAlreadyFoundException.php @@ -4,7 +4,7 @@ namespace OCA\EmailRecovery\Exception; use Exception; -class RecoveryEmailAlreadyFoundEmailException extends Exception { +class RecoveryEmailAlreadyFoundException extends Exception { public function __construct($message = null, $code = 0) { parent::__construct($message, $code); } diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 642445d..459b0c5 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -10,7 +10,7 @@ use OCP\IConfig; use OCP\IUserManager; use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; -use OCA\EmailRecovery\Exception\RecoveryEmailAlreadyFoundEmailException; +use OCA\EmailRecovery\Exception\RecoveryEmailAlreadyFoundException; use OCA\EcloudAccounts\Service\LDAPConnectionService; use OCP\Mail\IEMailTemplate; use OCP\Mail\IMailer; @@ -82,7 +82,7 @@ class RecoveryEmailService { } if (!empty($recoveryEmail) && $this->checkRecoveryEmailAvailable($recoveryEmail)) { $this->logger->info("User ID $username's requested recovery email address is already taken"); - throw new RecoveryEmailAlreadyFoundEmailException(); + throw new RecoveryEmailAlreadyFoundException(); } return true; } -- GitLab From c93113d15e16247b7b6a29cf78a67bcc2fc52184 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 04:34:19 -0800 Subject: [PATCH 069/130] added boot --- lib/AppInfo/Application.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 14ed4e0..5296b1c 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -31,6 +31,7 @@ use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCA\EmailRecovery\Listeners\UserConfigChangedListener; use OCP\User\Events\UserConfigChangedEvent; +use OCP\AppFramework\Bootstrap\IBootContext; class Application extends App implements IBootstrap { public const APP_ID = 'email-recovery'; @@ -42,4 +43,6 @@ class Application extends App implements IBootstrap { public function register(IRegistrationContext $context): void { $context->registerEventListener(UserConfigChangedEvent::class, UserConfigChangedListener::class); } + public function boot(IBootContext $context): void { + } } -- GitLab From 5942d036950d5352a4102129c62a9c673ab26168 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 04:58:43 -0800 Subject: [PATCH 070/130] changes --- lib/Controller/EmailRecoveryController.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 864e280..6c97094 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -171,11 +171,9 @@ class EmailRecoveryController extends Controller { $userId = $this->userSession->getUser()->getUID(); $response = new JSONResponse(); try { - if ($this->recoveryEmailService->validateRecoveryEmail($userId, $recoveryEmail)) { - $this->recoveryEmailService->sendVerificationEmail($userId, $recoveryEmail); - $response->setStatus(200); - return $response; - } + $this->recoveryEmailService->sendVerificationEmail($userId, $recoveryEmail); + $response->setStatus(200); + return $response; } catch (Exception $e) { $response->setStatus(500); if ($e instanceof InvalidRecoveryEmailException) { -- GitLab From bedd0875395b21b2dacce822b7963726abf0c6bf Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 05:01:45 -0800 Subject: [PATCH 071/130] common code is added at other function --- lib/Controller/EmailRecoveryController.php | 60 ++++++++-------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 6c97094..6d9fca2 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -139,29 +139,8 @@ class EmailRecoveryController extends Controller { public function setRecoveryEmail(string $recoveryEmail) { $userId = $this->userSession->getUser()->getUID(); $response = new JSONResponse(); - try { - if ($this->recoveryEmailService->validateRecoveryEmail($userId, $recoveryEmail)) { - $this->recoveryEmailService->updateRecoveryEmail($userId, $recoveryEmail); - $response->setStatus(200); - return $response; - } - } catch (Exception $e) { - $response->setStatus(500); - if ($e instanceof InvalidRecoveryEmailException) { - $response->setStatus(400); - $response->setData(['message' => $this->l->t('Invalid Recovery Email')]); - } - if ($e instanceof SameRecoveryEmailAsEmailException) { - $response->setStatus(400); - $response->setData(['message' => $this->l->t('Error! User email address cannot be saved as recovery email address!')]); - } - if ($e instanceof RecoveryEmailAlreadyFoundException) { - $response->setStatus(400); - $response->setData(['message' => $this->l->t('Recovery email address is already taken.')]); - } - $this->logger->error("Error setting recovery email for user $userId" . $e->getMessage()); - return $response; - } + $this->handleRecoveryEmailLogic($recoveryEmail, $userId, $response); + return $response; } /** @@ -170,26 +149,31 @@ class EmailRecoveryController extends Controller { public function resendRecoveryEmail(string $recoveryEmail) { $userId = $this->userSession->getUser()->getUID(); $response = new JSONResponse(); + $this->handleRecoveryEmailLogic($recoveryEmail, $userId, $response); + return $response; + } + + private function handleRecoveryEmailLogic(string $recoveryEmail, int $userId, JSONResponse $response) { try { - $this->recoveryEmailService->sendVerificationEmail($userId, $recoveryEmail); - $response->setStatus(200); - return $response; + if ($this->recoveryEmailService->validateRecoveryEmail($userId, $recoveryEmail)) { + $this->recoveryEmailService->updateRecoveryEmail($userId, $recoveryEmail); + $response->setStatus(200); + } } catch (Exception $e) { $response->setStatus(500); - if ($e instanceof InvalidRecoveryEmailException) { - $response->setStatus(400); - $response->setData(['message' => $this->l->t('Invalid Recovery Email')]); - } - if ($e instanceof SameRecoveryEmailAsEmailException) { - $response->setStatus(400); - $response->setData(['message' => $this->l->t('Error! User email address cannot be saved as recovery email address!')]); - } - if ($e instanceof RecoveryEmailAlreadyFoundException) { - $response->setStatus(400); - $response->setData(['message' => $this->l->t('Recovery email address is already taken.')]); + $errorMessages = [ + InvalidRecoveryEmailException::class => 'Invalid Recovery Email', + SameRecoveryEmailAsEmailException::class => 'Error! User email address cannot be saved as recovery email address!', + RecoveryEmailAlreadyFoundException::class => 'Recovery email address is already taken.' + ]; + foreach ($errorMessages as $exceptionClass => $errorMessage) { + if ($e instanceof $exceptionClass) { + $response->setStatus(400); + $response->setData(['message' => $this->l->t($errorMessage)]); + break; + } } $this->logger->error("Error setting recovery email for user $userId" . $e->getMessage()); - return $response; } } } -- GitLab From 705583cda53d151ce3b345ba75061437bf4da28f Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 05:04:33 -0800 Subject: [PATCH 072/130] added condition at validate email --- lib/Service/RecoveryEmailService.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 459b0c5..0adb500 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -80,18 +80,21 @@ class RecoveryEmailService { $this->logger->info("User ID $username's requested recovery email is the same as email"); throw new SameRecoveryEmailAsEmailException(); } - if (!empty($recoveryEmail) && $this->checkRecoveryEmailAvailable($recoveryEmail)) { + if (!empty($recoveryEmail) && $this->checkRecoveryEmailAvailable($username, $recoveryEmail)) { $this->logger->info("User ID $username's requested recovery email address is already taken"); throw new RecoveryEmailAlreadyFoundException(); } return true; } - public function checkRecoveryEmailAvailable(string $recoveryEmail): bool { + public function checkRecoveryEmailAvailable(string $username, string $recoveryEmail): bool { $recoveryEmail = strtolower($recoveryEmail); - $users = $this->config->getUsersForUserValue('email-recovery', 'recovery-email', $recoveryEmail); - if (count($users)) { - return true; + $currentRecoveryEmail = $this->getRecoveryEmail($username); + if ($currentRecoveryEmail !== $recoveryEmail) { + $users = $this->config->getUsersForUserValue('email-recovery', 'recovery-email', $recoveryEmail); + if (count($users)) { + return true; + } } return false; } -- GitLab From 2fb8da36ff6e83c94c825bec97832420e6147fe6 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 05:07:56 -0800 Subject: [PATCH 073/130] added condition at validate email --- lib/Controller/EmailRecoveryController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 6d9fca2..d972332 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -153,7 +153,7 @@ class EmailRecoveryController extends Controller { return $response; } - private function handleRecoveryEmailLogic(string $recoveryEmail, int $userId, JSONResponse $response) { + private function handleRecoveryEmailLogic(string $recoveryEmail, string $userId, JSONResponse $response) { try { if ($this->recoveryEmailService->validateRecoveryEmail($userId, $recoveryEmail)) { $this->recoveryEmailService->updateRecoveryEmail($userId, $recoveryEmail); -- GitLab From ded75a6894f388271051fc5537403accfcd2d43c Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 6 Dec 2023 23:34:17 -0800 Subject: [PATCH 074/130] added verified value as bool --- lib/Controller/EmailRecoveryController.php | 2 +- lib/Service/RecoveryEmailService.php | 2 +- src/main.html | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index d972332..389afdb 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -108,7 +108,7 @@ class EmailRecoveryController extends Controller { $this->verificationToken->check($token, $user, $verificationKey, $email); $userValueKey = 'recovery-email-verified'; - $this->config->setUserValue($user->getUID(), $this->appName, $userValueKey, 'true'); + $this->config->setUserValue($user->getUID(), $this->appName, $userValueKey, true); $this->verificationToken->delete($token, $user, $verificationKey); diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 0adb500..a738af9 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -65,7 +65,7 @@ class RecoveryEmailService { } public function getRecoveryEmailVerificationStatus(string $username) : string { - return $this->config->getUserValue($username, $this->appName, 'recovery-email-verified', 'true'); + return $this->config->getUserValue($username, $this->appName, 'recovery-email-verified', true); } public function validateRecoveryEmail(string $username, string $recoveryEmail) : bool { diff --git a/src/main.html b/src/main.html index 0aef549..1a37228 100644 --- a/src/main.html +++ b/src/main.html @@ -13,7 +13,7 @@ v-model="recoveryEmail" :placeholder="placeholder" /> - +

- {{ t("email-recovery","Email address have been saved. An email has been sent to you for verification.") }} + {{ t("email-recovery","Please, check your inbox. An email has been sent to you for verification.") }}

Date: Thu, 7 Dec 2023 09:36:16 -0800 Subject: [PATCH 079/130] added translations --- l10n/en.js | 3 +-- l10n/en.json | 2 +- l10n/es.js | 1 - l10n/fr.js | 1 - l10n/fr.json | 1 - 5 files changed, 2 insertions(+), 6 deletions(-) diff --git a/l10n/en.js b/l10n/en.js index ff0c76f..02791b7 100644 --- a/l10n/en.js +++ b/l10n/en.js @@ -5,7 +5,7 @@ OC.L10N.register( "Changes saved": "Changes saved", "Error! User email address cannot be saved as recovery email address!": "Error! User email address cannot be saved as recovery email address!", "Change Recovery Email": "Change Recovery Email", - "Invalid Recovery Email!": "Invalid Recovery Email!", + "Invalid Recovery Email": "Invalid Recovery Email", "Please, check your inbox. An email has been sent to you for verification.": "Please, check your inbox. An email has been sent to you for verification.", "Resend Verification Email": "Resend Verification Email", "Recovery email is not verified.": "Recovery email is not verified.", @@ -18,7 +18,6 @@ OC.L10N.register( "Please note that this link will be valid for the next 30 minutes.": "Please note that this link will be valid for the next 30 minutes.", "If you did not initiate this change, please contact our support team immediately.": "If you did not initiate this change, please contact our support team immediately.", "Thank you for choosing %s.": "Thank you for choosing %s.", - "Invalid Recovery Email": "Invalid Recovery Email", "Recovery email address is already taken.": "Recovery email address is already taken.", "You verified recovery email successfully.": "You verified recovery email successfully.", "Could not verify recovery email because the token is expired": "Could not verify recovery email because the token is expired", diff --git a/l10n/en.json b/l10n/en.json index 2224709..2848d92 100644 --- a/l10n/en.json +++ b/l10n/en.json @@ -4,7 +4,7 @@ "Changes saved": "Changes saved", "Error! User email address cannot be saved as recovery email address!": "Error! User email address cannot be saved as recovery email address!", "Change Recovery Email": "Change Recovery Email", - "Invalid Recovery Email!": "Invalid Recovery Email!", + "Invalid Recovery Email": "Invalid Recovery Email", "Error setting recovery email": "Error setting recovery mail", "Please, check your inbox. An email has been sent to you for verification.": "Please, check your inbox. An email has been sent to you for verification.", "Resend Verification Email": "Resend Verification Email", diff --git a/l10n/es.js b/l10n/es.js index 48b2231..df574a1 100644 --- a/l10n/es.js +++ b/l10n/es.js @@ -20,7 +20,6 @@ OC.L10N.register( "Please note that this link will be valid for the next 30 minutes.": "Tenga en cuenta que este enlace será válido durante los próximos 30 minutos.", "If you did not initiate this change, please contact our support team immediately.": "Si no ha iniciado este cambio, póngase en contacto con nuestro equipo de asistencia inmediatamente.", "Thank you for choosing %s.": "Gracias por elegir %s.", - "Invalid Recovery Email": "Correo electrónico de recuperación no válido", "Recovery email address is already taken.": "La dirección de correo electrónico de recuperación ya está ocupada.", "You verified recovery email successfully.": "Ha verificado correctamente el correo electrónico de recuperación.", "Could not verify recovery email because the token is expired": "No se ha podido verificar el correo electrónico de recuperación porque el token ha caducado.", diff --git a/l10n/fr.js b/l10n/fr.js index fe5f33d..45f6419 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -20,7 +20,6 @@ OC.L10N.register( "Please note that this link will be valid for the next 30 minutes.": "Veuillez noter que ce lien est valable pour les 30 prochaines minutes.", "If you did not initiate this change, please contact our support team immediately.": "Si vous n'êtes pas à l'origine de ce changement, veuillez contacter immédiatement notre équipe d'assistance.", "Thank you for choosing %s.": "Merci d'avoir choisi %s.", - "Invalid Recovery Email": "Email de récupération invalide", "Recovery email address is already taken.": "L'adresse électronique de récupération est déjà prise.", "You verified recovery email successfully.": "Vous avez vérifié l'email de récupération avec succès.", "Could not verify recovery email because the token is expired": "Impossible de vérifier l'e-mail de récupération car le jeton a expiré.", diff --git a/l10n/fr.json b/l10n/fr.json index c443b22..2987ce9 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -18,7 +18,6 @@ "Please note that this link will be valid for the next 30 minutes.": "Veuillez noter que ce lien est valable pour les 30 prochaines minutes.", "If you did not initiate this change, please contact our support team immediately.": "Si vous n'êtes pas à l'origine de ce changement, veuillez contacter immédiatement notre équipe d'assistance.", "Thank you for choosing %s.": "Merci d'avoir choisi %s.", - "Invalid Recovery Email": "Email de récupération invalide", "Recovery email address is already taken.": "L'adresse électronique de récupération est déjà prise.", "You verified recovery email successfully.": "Vous avez vérifié l'email de récupération avec succès.", "Could not verify recovery email because the token is expired": "Impossible de vérifier l'e-mail de récupération car le jeton a expiré.", -- GitLab From 43c35e7edbdfaeb865bd1ec17343e4bfdac50dcf Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 7 Dec 2023 09:47:41 -0800 Subject: [PATCH 080/130] recovery email create token changes --- lib/Service/RecoveryEmailService.php | 38 +++++++++++++++++++++------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 81a7c79..200bc37 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -24,7 +24,7 @@ use OCP\Security\ICrypto; use OCP\Defaults; use OCP\BackgroundJob\IJobList; use OCA\EmailRecovery\AppInfo\Application; -use OC\Authentication\Token\TokenCleanupJob; +use OC\Security\VerificationToken\CleanupJob; use OCP\Security\VerificationToken\IVerificationToken; class RecoveryEmailService { @@ -147,7 +147,7 @@ class RecoveryEmailService { $token = $this->createToken($user, $recoveryEmailAddress); $key = $this->crypto->encrypt($recoveryEmailAddress); $link = $this->urlGenerator->linkToRouteAbsolute($this->appName .'.email_recovery.verify_recovery_email', ['userId' => $user->getUID(), 'token' => $token, 'key' => $key]); - $this->logger->error('EMAIL VERIFICATIN URL:: ' . $link); + $displayName = $user->getDisplayName(); $emailTemplate = $this->mailer->createEMailTemplate('recovery-email.confirmation', [ @@ -176,21 +176,41 @@ class RecoveryEmailService { return $emailTemplate; } private function createToken(IUser $user, string $recoveryEmail = ''): string { - $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); - $token = $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail); - + $subject = 'verifyRecoveryMail'; + $token = $this->secureRandom->generate( + 21, + ISecureRandom::CHAR_DIGITS. + ISecureRandom::CHAR_LOWER. + ISecureRandom::CHAR_UPPER + ); $tokenValue = $this->timeFactory->getTime() .':'. $token; $encryptedValue = $this->crypto->encrypt($tokenValue, $recoveryEmail . $this->config->getSystemValue('secret')); - $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-token', $encryptedValue); - $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-verified', 'false'); + $this->config->setUserValue($user->getUID(), Application::APP_ID, $subject, $encryptedValue); $jobArgs = json_encode([ 'userId' => $user->getUID(), - 'subject' => 'recovery-email-token', + 'subject' => $subject, 'pp' => $recoveryEmail, 'notBefore' => $this->timeFactory->getTime() + self::TOKEN_LIFETIME * 2, // multiply to provide a grace period ]); - $this->jobList->add(TokenCleanupJob::class, $jobArgs); + $this->jobList->add(CleanUpJob::class, $jobArgs); + $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-verified', 'false'); + return $token; + + // $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); + // $token = $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail); + + // $tokenValue = $this->timeFactory->getTime() .':'. $token; + // $encryptedValue = $this->crypto->encrypt($tokenValue, $recoveryEmail . $this->config->getSystemValue('secret')); + // $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-token', $encryptedValue); + // $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-verified', 'false'); + // $jobArgs = json_encode([ + // 'userId' => $user->getUID(), + // 'subject' => 'recovery-email-token', + // 'pp' => $recoveryEmail, + // 'notBefore' => $this->timeFactory->getTime() + self::TOKEN_LIFETIME * 2, // multiply to provide a grace period + // ]); + // $this->jobList->add(CleanUpJob::class, $jobArgs); } } -- GitLab From d2669034c26458a659548904415b20a4a0f10973 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 7 Dec 2023 09:48:12 -0800 Subject: [PATCH 081/130] removed unwanted comments --- lib/Service/RecoveryEmailService.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 200bc37..cc78db2 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -197,20 +197,5 @@ class RecoveryEmailService { $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-verified', 'false'); return $token; - - // $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); - // $token = $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail); - - // $tokenValue = $this->timeFactory->getTime() .':'. $token; - // $encryptedValue = $this->crypto->encrypt($tokenValue, $recoveryEmail . $this->config->getSystemValue('secret')); - // $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-token', $encryptedValue); - // $this->config->setUserValue($user->getUID(), Application::APP_ID, 'recovery-email-verified', 'false'); - // $jobArgs = json_encode([ - // 'userId' => $user->getUID(), - // 'subject' => 'recovery-email-token', - // 'pp' => $recoveryEmail, - // 'notBefore' => $this->timeFactory->getTime() + self::TOKEN_LIFETIME * 2, // multiply to provide a grace period - // ]); - // $this->jobList->add(CleanUpJob::class, $jobArgs); } } -- GitLab From 5e3c46ed5bf6ac63ab65f5e2165739ed982f5ba6 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 7 Dec 2023 10:08:16 -0800 Subject: [PATCH 082/130] it json --- l10n/it.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/l10n/it.json b/l10n/it.json index c5b2379..7319eff 100644 --- a/l10n/it.json +++ b/l10n/it.json @@ -7,6 +7,17 @@ "Change Recovery Email" : "Modifica dell'e-mail di recupero", "Recovery Email " : "Recupero e-mail ", "Changes saved" : "Modifiche salvate", - "Please, check your inbox. An email has been sent to you for verification.": "Controllare la posta in arrivo. Le è stata inviata un'e-mail di verifica." + "Please, check your inbox. An email has been sent to you for verification.": "Controllare la posta in arrivo. Le è stata inviata un'e-mail di verifica.", + "Hello %s": "Ciao %s", + "This is to inform you that the recovery email for your %s account has been successfully updated.": "Questo per informarvi che l'e-mail di recupero per il vostro account %s è stata aggiornata con successo.", + "To verify your new recovery email, please click on the following button.": "Per verificare la nuova e-mail di recupero, fare clic sul seguente pulsante.", + "Verify recovery email": "Verifica dell'e-mail di recupero", + "Please note that this link will be valid for the next 30 minutes.": "Si noti che questo link sarà valido per i prossimi 30 minuti.", + "If you did not initiate this change, please contact our support team immediately.": "Se non avete avviato questa modifica, contattate immediatamente il nostro team di assistenza.", + "Thank you for choosing %s.": "Grazie per aver scelto %s.", + "Recovery email address is already taken.": "L'indirizzo e-mail di recupero è già stato preso.", + "You verified recovery email successfully.": "L'e-mail di recupero è stata verificata con successo.", + "Could not verify recovery email because the token is expired": "Impossibile verificare l'email di recupero perché il token è scaduto", + "Could not verify recovery email because the token is invalid": "Impossibile verificare l'email di recupero perché il token non è valido" },"pluralForm" :"nplurals=2; plural=n != 1;" } \ No newline at end of file -- GitLab From f4ee38523b663037264bce616f22a8e2cb22c3a1 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 7 Dec 2023 10:25:31 -0800 Subject: [PATCH 083/130] resendRecoveryButton changes --- src/main.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.html b/src/main.html index 6321b45..74078b8 100644 --- a/src/main.html +++ b/src/main.html @@ -24,6 +24,7 @@ />

- {{ t("email-recovery","Please, check your inbox. An email has been sent to you for verification.") }} + {{ t("email-recovery","Please check your inbox. An email has been sent to you for verification.") }}

{{ t( "email-recovery", errorKey ) }} -- GitLab From f51f3159e559ae249b049e5cf132a6c942a3fb19 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 13 Dec 2023 11:26:41 -0800 Subject: [PATCH 112/130] isRecoveryEmailTaken --- lib/Service/RecoveryEmailService.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 9b7c473..ccb2cfd 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -83,14 +83,14 @@ class RecoveryEmailService { $this->logger->info("User ID $username's requested recovery email is the same as email"); throw new SameRecoveryEmailAsEmailException(); } - if (!empty($recoveryEmail) && $this->checkRecoveryEmailAvailable($username, $recoveryEmail)) { + if (!empty($recoveryEmail) && $this->isRecoveryEmailTaken($username, $recoveryEmail)) { $this->logger->info("User ID $username's requested recovery email address is already taken"); throw new RecoveryEmailAlreadyFoundException(); } return true; } - public function checkRecoveryEmailAvailable(string $username, string $recoveryEmail): bool { + public function isRecoveryEmailTaken(string $username, string $recoveryEmail): bool { $recoveryEmail = strtolower($recoveryEmail); $currentRecoveryEmail = $this->getRecoveryEmail($username); if ($currentRecoveryEmail !== $recoveryEmail) { -- GitLab From e3f0d4be0b5a409579ff6f64d962b0cf618f93c8 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 13 Dec 2023 11:30:11 -0800 Subject: [PATCH 113/130] removed unncessary --- lib/Service/RecoveryEmailService.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index ccb2cfd..19c0407 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -16,13 +16,10 @@ use OCP\Mail\IEMailTemplate; use OCP\Mail\IMailer; use OCP\Util; use OCP\IUser; -use OCP\Security\ISecureRandom; use OCP\L10N\IFactory; -use OCP\AppFramework\Utility\ITimeFactory; use OCP\IURLGenerator; use OCP\Security\ICrypto; use OCP\Defaults; -use OCP\BackgroundJob\IJobList; use OCP\Security\VerificationToken\IVerificationToken; class RecoveryEmailService { @@ -39,20 +36,17 @@ class RecoveryEmailService { private IVerificationToken $verificationToken; protected const TOKEN_LIFETIME = 60 * 30; // 30 minutes - public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, ISecureRandom $secureRandom, IFactory $l10nFactory, ITimeFactory $timeFactory, ICrypto $crypto, IURLGenerator $urlGenerator, Defaults $themingDefaults, IJobList $jobList, IVerificationToken $verificationToken) { + public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, IFactory $l10nFactory, ICrypto $crypto, IURLGenerator $urlGenerator, Defaults $themingDefaults, IVerificationToken $verificationToken) { $this->logger = $logger; $this->config = $config; $this->appName = $appName; $this->LDAPConnectionService = $LDAPConnectionService; $this->userManager = $userManager; $this->mailer = $mailer; - $this->secureRandom = $secureRandom; $this->l10nFactory = $l10nFactory; - $this->timeFactory = $timeFactory; $this->crypto = $crypto; $this->urlGenerator = $urlGenerator; $this->themingDefaults = $themingDefaults; - $this->jobList = $jobList; $this->verificationToken = $verificationToken; } public function setRecoveryEmail(string $username, string $value = '') : void { -- GitLab From 34a062b453cec14656e59c1e87cb5dec113e166a Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 13 Dec 2023 11:41:37 -0800 Subject: [PATCH 114/130] refactored code in controller --- lib/Controller/EmailRecoveryController.php | 15 +++++---------- lib/Service/RecoveryEmailService.php | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index d21873e..320ea79 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -102,17 +102,12 @@ class EmailRecoveryController extends Controller { $user = $this->userManager->get($userId); $verificationKey = 'verifyRecoveryMail' . $ref; - //check verification token - $this->verificationToken->check($token, $user, $verificationKey, $email); + + $this->recoveryEmailService->performRecoveryEmailVerification($token, $user, $verificationKey, $email); - $newRecoveryEmailAddress = $this->recoveryEmailService->getUnverifiedRecoveryEmail($userId); - if ($newRecoveryEmailAddress != '') { - //set recovery email - $this->recoveryEmailService->setRecoveryEmail($user->getUID(), $newRecoveryEmailAddress); - $this->recoveryEmailService->deleteRecoveryEmailAppUserValue($user->getUID()); - } - //delete verification token - $this->verificationToken->delete($token, $user, $verificationKey); + $this->recoveryEmailService->makeRecoveryEmailVerified($userId); + + $this->recoveryEmailService->deleteVerificationToken($token, $user, $verificationKey); $responseParams = [ 'title' => $this->l->t('You verified recovery email successfully.'), diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 19c0407..2c76868 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -184,4 +184,22 @@ class RecoveryEmailService { $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); return $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail, self::TOKEN_LIFETIME); } + + public function decryptEmailAndGenerateRef(string $key): string { + $email = $this->crypto->decrypt($key); + return substr(hash('sha256', $email), 0, 8); + } + public function performRecoveryEmailVerification(string $token, IUser $user, string $verificationKey, string $email): void { + $this->verificationToken->check($token, $user, $verificationKey, $email); + } + public function deleteVerificationToken(string $token, IUser $user, string $verificationKey): void { + $this->verificationToken->delete($token, $user, $verificationKey); + } + public function makeRecoveryEmailVerified(string $userId): void { + $newRecoveryEmailAddress = $this->getUnverifiedRecoveryEmail($userId); + if ($newRecoveryEmailAddress !== '') { + $this->setRecoveryEmail($userId, $newRecoveryEmailAddress); + $this->deleteRecoveryEmailAppUserValue($userId); + } + } } -- GitLab From e92a06cc5d5008963f8e3064a6b6c49a77aa7119 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 13 Dec 2023 12:24:30 -0800 Subject: [PATCH 115/130] added disabled condition --- src/App.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.vue b/src/App.vue index fb7acf6..0b0570a 100644 --- a/src/App.vue +++ b/src/App.vue @@ -25,7 +25,7 @@ export default { }, computed: { isButtonDisabled() { - return this.recoveryEmail === loadState('email-recovery', 'recoveryEmail') || this.recoveryEmail.trim() === '' + return this.recoveryEmail === loadState('email-recovery', 'unverifiedRecoveryEmail') || this.recoveryEmail === loadState('email-recovery', 'recoveryEmail') || this.recoveryEmail.trim() === '' }, }, methods: { -- GitLab From 124f4bfe3b806fc6b38a8f5c89e8420017168199 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 13 Dec 2023 14:27:27 -0800 Subject: [PATCH 116/130] chagne to expire token --- lib/Controller/EmailRecoveryController.php | 6 +++--- lib/Service/RecoveryEmailService.php | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 320ea79..343776a 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -94,15 +94,15 @@ class EmailRecoveryController extends Controller { * @PublicPage * @NoCSRFRequired */ - public function verifyRecoveryEmail(string $token, string $userId, string $key): TemplateResponse { + public function verifyRecoveryEmail(string $token, string $userId): TemplateResponse { try { //decrypt email - $email = $this->crypto->decrypt($key); + $email = $this->recoveryEmailService->getUnverifiedRecoveryEmail($userId); $ref = substr(hash('sha256', $email), 0, 8); $user = $this->userManager->get($userId); $verificationKey = 'verifyRecoveryMail' . $ref; - + $this->recoveryEmailService->performRecoveryEmailVerification($token, $user, $verificationKey, $email); $this->recoveryEmailService->makeRecoveryEmailVerified($userId); diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 2c76868..bea7316 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -182,6 +182,7 @@ class RecoveryEmailService { } private function createToken(IUser $user, string $recoveryEmail = ''): string { $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); + $this->config->deleteUserValue($user->getUID(), 'core', 'verifyRecoveryMail' . $ref); return $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail, self::TOKEN_LIFETIME); } -- GitLab From 99936ece68b8b44b6dc40d868a22dae560114d8e Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 13 Dec 2023 14:29:33 -0800 Subject: [PATCH 117/130] chagne to expire token #2 --- lib/Service/RecoveryEmailService.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index bea7316..925f9d8 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -18,7 +18,6 @@ use OCP\Util; use OCP\IUser; use OCP\L10N\IFactory; use OCP\IURLGenerator; -use OCP\Security\ICrypto; use OCP\Defaults; use OCP\Security\VerificationToken\IVerificationToken; @@ -30,13 +29,12 @@ class RecoveryEmailService { private IUserManager $userManager; private IMailer $mailer; private IFactory $l10nFactory; - private ICrypto $crypto; private IURLGenerator $urlGenerator; private Defaults $themingDefaults; private IVerificationToken $verificationToken; protected const TOKEN_LIFETIME = 60 * 30; // 30 minutes - public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, IFactory $l10nFactory, ICrypto $crypto, IURLGenerator $urlGenerator, Defaults $themingDefaults, IVerificationToken $verificationToken) { + public function __construct(string $appName, ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService, IUserManager $userManager, IMailer $mailer, IFactory $l10nFactory, IURLGenerator $urlGenerator, Defaults $themingDefaults, IVerificationToken $verificationToken) { $this->logger = $logger; $this->config = $config; $this->appName = $appName; @@ -44,7 +42,6 @@ class RecoveryEmailService { $this->userManager = $userManager; $this->mailer = $mailer; $this->l10nFactory = $l10nFactory; - $this->crypto = $crypto; $this->urlGenerator = $urlGenerator; $this->themingDefaults = $themingDefaults; $this->verificationToken = $verificationToken; @@ -64,7 +61,6 @@ class RecoveryEmailService { public function deleteRecoveryEmailAppUserValue(string $username) : void { $this->config->deleteUserValue($username, $this->appName, 'unverified-recovery-email'); } - public function validateRecoveryEmail(string $username, string $recoveryEmail) : bool { $user = $this->userManager->get($username); $email = $user->getEMailAddress(); @@ -150,8 +146,7 @@ class RecoveryEmailService { $l10n = $this->l10nFactory->get('settings', $lang); $token = $this->createToken($user, $recoveryEmailAddress); - $key = $this->crypto->encrypt($recoveryEmailAddress); - $link = $this->urlGenerator->linkToRouteAbsolute($this->appName .'.email_recovery.verify_recovery_email', ['userId' => $user->getUID(), 'token' => $token, 'key' => $key]); + $link = $this->urlGenerator->linkToRouteAbsolute($this->appName .'.email_recovery.verify_recovery_email', ['userId' => $user->getUID(), 'token' => $token]); $this->logger->error('EMAIL URL LINK: ' . $link); $displayName = $user->getDisplayName(); @@ -182,14 +177,11 @@ class RecoveryEmailService { } private function createToken(IUser $user, string $recoveryEmail = ''): string { $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); + + // removing past tokens $this->config->deleteUserValue($user->getUID(), 'core', 'verifyRecoveryMail' . $ref); return $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail, self::TOKEN_LIFETIME); } - - public function decryptEmailAndGenerateRef(string $key): string { - $email = $this->crypto->decrypt($key); - return substr(hash('sha256', $email), 0, 8); - } public function performRecoveryEmailVerification(string $token, IUser $user, string $verificationKey, string $email): void { $this->verificationToken->check($token, $user, $verificationKey, $email); } -- GitLab From 955d1a9b63fe50930e01fabb9b8397472844f7a2 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 13 Dec 2023 14:31:22 -0800 Subject: [PATCH 118/130] added condition to disable button --- src/App.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.vue b/src/App.vue index 0b0570a..897d404 100644 --- a/src/App.vue +++ b/src/App.vue @@ -25,7 +25,7 @@ export default { }, computed: { isButtonDisabled() { - return this.recoveryEmail === loadState('email-recovery', 'unverifiedRecoveryEmail') || this.recoveryEmail === loadState('email-recovery', 'recoveryEmail') || this.recoveryEmail.trim() === '' + return this.recoveryEmail === this.unverifiedRecoveryEmail || this.recoveryEmail === loadState('email-recovery', 'recoveryEmail') || this.recoveryEmail.trim() === '' }, }, methods: { -- GitLab From e114fe99948227b98a6d585e4f68b53abeea7747 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Wed, 13 Dec 2023 14:39:46 -0800 Subject: [PATCH 119/130] token and route changes --- appinfo/routes.php | 2 +- lib/Service/RecoveryEmailService.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 0cf6162..e37b59f 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -30,7 +30,7 @@ return [ 'verb' => 'OPTIONS', 'requirements' => ['path' => '.+']], ['name' => 'email_recovery_api#show', 'url' => '/api/recovery-email/{id}', 'verb' => 'GET'], ['name' => 'email_recovery_api#update', 'url' => '/api/recovery-email/{id}', 'verb' => 'PUT'], - ['name' => 'email_recovery#verify_recovery_email', 'url' => '/recovery-email/verify', 'verb' => 'GET'], + ['name' => 'email_recovery#verify_recovery_email', 'url' => '/recovery-email/verify/{token}/{userId}', 'verb' => 'GET'], ['name' => 'email_recovery#resend_recovery_email', 'url' => '/resend_recovery_email', 'verb' => 'POST'], ] diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 925f9d8..4576c5f 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -146,7 +146,7 @@ class RecoveryEmailService { $l10n = $this->l10nFactory->get('settings', $lang); $token = $this->createToken($user, $recoveryEmailAddress); - $link = $this->urlGenerator->linkToRouteAbsolute($this->appName .'.email_recovery.verify_recovery_email', ['userId' => $user->getUID(), 'token' => $token]); + $link = $this->urlGenerator->linkToRouteAbsolute($this->appName .'.email_recovery.verify_recovery_email', ['token' => $token,'userId' => $user->getUID()]); $this->logger->error('EMAIL URL LINK: ' . $link); $displayName = $user->getDisplayName(); -- GitLab From 9358c324bb0db3196da27655b22a66c4f1120dc8 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 14 Dec 2023 23:11:14 -0800 Subject: [PATCH 120/130] removed forech loop --- lib/Controller/EmailRecoveryController.php | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 343776a..94f85a8 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -158,19 +158,21 @@ class EmailRecoveryController extends Controller { } } catch (Exception $e) { $response->setStatus(500); - $errorMessages = [ - InvalidRecoveryEmailException::class => $this->l->t('Invalid Recovery Email'), - SameRecoveryEmailAsEmailException::class => $this->l->t('Error! User email address cannot be saved as recovery email address!'), - RecoveryEmailAlreadyFoundException::class => $this->l->t('Recovery email address is already taken.') - ]; - foreach ($errorMessages as $exceptionClass => $errorMessage) { - if ($e instanceof $exceptionClass) { - $response->setStatus(400); - $response->setData(['message' => $this->l->t($errorMessage)]); - break; - } + if ($e instanceof InvalidRecoveryEmailException) { + $response->setStatus(400); + $this->l->t('Invalid Recovery Email'); + $response->setData(['message' => 'Invalid Recovery Email']); + } + if ($e instanceof SameRecoveryEmailAsEmailException) { + $response->setStatus(400); + $this->l->t('Error! User email address cannot be saved as recovery email address!'); + $response->setData(['message' => 'Error! User email address cannot be saved as recovery email address!']); + } + if ($e instanceof RecoveryEmailAlreadyFoundException) { + $response->setStatus(400); + $this->l->t('Recovery email address is already taken.'); + $response->setData(['message' => 'Recovery email address is already taken.']); } - $this->logger->error("Error setting recovery email for user $userId" . $e->getMessage()); } } } -- GitLab From 2b8346e112d0bc6388d183de1344e444a84d60ab Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 14 Dec 2023 23:18:56 -0800 Subject: [PATCH 121/130] equality condition added --- lib/Service/RecoveryEmailService.php | 30 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 4576c5f..405d665 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -58,7 +58,7 @@ class RecoveryEmailService { public function getUnverifiedRecoveryEmail(string $username) : string { return $this->config->getUserValue($username, $this->appName, 'unverified-recovery-email', ''); } - public function deleteRecoveryEmailAppUserValue(string $username) : void { + public function deleteUnverifiedRecoveryEmail(string $username) : void { $this->config->deleteUserValue($username, $this->appName, 'unverified-recovery-email'); } public function validateRecoveryEmail(string $username, string $recoveryEmail) : bool { @@ -82,20 +82,24 @@ class RecoveryEmailService { public function isRecoveryEmailTaken(string $username, string $recoveryEmail): bool { $recoveryEmail = strtolower($recoveryEmail); + $currentRecoveryEmail = $this->getRecoveryEmail($username); - if ($currentRecoveryEmail !== $recoveryEmail) { - $users = $this->config->getUsersForUserValue('email-recovery', 'recovery-email', $recoveryEmail); - if (count($users)) { - return true; - } + $currentUnverifiedRecoveryEmail = $this->getUnverifiedRecoveryEmail($username); + + if ($currentRecoveryEmail === $recoveryEmail || $currentUnverifiedRecoveryEmail === $recoveryEmail) { + return false; } - $currentunVerifiedRecoveryEmail = $this->getUnverifiedRecoveryEmail($username); - if ($currentunVerifiedRecoveryEmail !== $recoveryEmail) { - $users = $this->config->getUsersForUserValue('email-recovery', 'unverified-recovery-email', $recoveryEmail); - if (count($users)) { - return true; - } + + $usersWithEmailRecovery = $this->config->getUsersForUserValue('email-recovery', 'recovery-email', $recoveryEmail); + if (count($usersWithEmailRecovery)) { + return true; } + + $usersWithUnverifiedRecovery = $this->config->getUsersForUserValue('email-recovery', 'unverified-recovery-email', $recoveryEmail); + if (count($usersWithUnverifiedRecovery)) { + return true; + } + return false; } @@ -192,7 +196,7 @@ class RecoveryEmailService { $newRecoveryEmailAddress = $this->getUnverifiedRecoveryEmail($userId); if ($newRecoveryEmailAddress !== '') { $this->setRecoveryEmail($userId, $newRecoveryEmailAddress); - $this->deleteRecoveryEmailAppUserValue($userId); + $this->deleteUnverifiedRecoveryEmail($userId); } } } -- GitLab From d44bb73f8af180f3b99ab62e315ae6766f7fbf47 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 14 Dec 2023 23:20:05 -0800 Subject: [PATCH 122/130] generateVerificationEmailTemplate renamed --- lib/Service/RecoveryEmailService.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 405d665..0bd8570 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -127,7 +127,7 @@ class RecoveryEmailService { public function sendVerificationEmail(string $uid, string $recoveryEmailAddress) : void { try { $user = $this->userManager->get($uid); - $emailTemplate = $this->generateTemplate($user, $recoveryEmailAddress); + $emailTemplate = $this->generateVerificationEmailTemplate($user, $recoveryEmailAddress); $email = $this->mailer->createMessage(); $email->useTemplate($emailTemplate); @@ -143,7 +143,7 @@ class RecoveryEmailService { * @param string $recoveryEmailAddress * @return IEMailTemplate */ - public function generateTemplate(IUser $user, string $recoveryEmailAddress) { + public function generateVerificationEmailTemplate(IUser $user, string $recoveryEmailAddress) { $userId = $user->getUID(); $lang = $this->config->getUserValue($userId, 'core', 'lang', null); -- GitLab From 3031a3e7126bb74860886859f13b7dd9e7ea0e01 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 14 Dec 2023 23:27:11 -0800 Subject: [PATCH 123/130] true,false change --- lib/Controller/EmailRecoveryController.php | 2 +- lib/Service/RecoveryEmailService.php | 2 +- lib/Settings/RecoveryEmailSettings.php | 2 +- src/App.vue | 4 ++-- src/main.html | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 94f85a8..380eab6 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -103,7 +103,7 @@ class EmailRecoveryController extends Controller { $user = $this->userManager->get($userId); $verificationKey = 'verifyRecoveryMail' . $ref; - $this->recoveryEmailService->performRecoveryEmailVerification($token, $user, $verificationKey, $email); + $this->recoveryEmailService->verifyToken($token, $user, $verificationKey, $email); $this->recoveryEmailService->makeRecoveryEmailVerified($userId); diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index 0bd8570..b583741 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -186,7 +186,7 @@ class RecoveryEmailService { $this->config->deleteUserValue($user->getUID(), 'core', 'verifyRecoveryMail' . $ref); return $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail, self::TOKEN_LIFETIME); } - public function performRecoveryEmailVerification(string $token, IUser $user, string $verificationKey, string $email): void { + public function verifyToken(string $token, IUser $user, string $verificationKey, string $email): void { $this->verificationToken->check($token, $user, $verificationKey, $email); } public function deleteVerificationToken(string $token, IUser $user, string $verificationKey): void { diff --git a/lib/Settings/RecoveryEmailSettings.php b/lib/Settings/RecoveryEmailSettings.php index 120e2c1..d509046 100644 --- a/lib/Settings/RecoveryEmailSettings.php +++ b/lib/Settings/RecoveryEmailSettings.php @@ -49,7 +49,7 @@ class RecoveryEmailSettings implements ISettings { $username = $this->userSession->getUser()->getUID(); $recoveryEmail = $this->recoveryEmailService->getRecoveryEmail($username); $unverifiedRecoveryEmail = $this->recoveryEmailService->getUnverifiedRecoveryEmail($username); - $recoveryEmailVerificationStatus = $recoveryEmail != '' ? 'true' : 'false'; + $recoveryEmailVerificationStatus = $recoveryEmail != '' ? true : false; $this->initialState->provideInitialState('recoveryEmail', $recoveryEmail); $this->initialState->provideInitialState('recoveryEmailVerificationStatus', $recoveryEmailVerificationStatus); diff --git a/src/App.vue b/src/App.vue index 897d404..3e93e3f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -42,7 +42,7 @@ export default { } ) .then(response => { - this.recoveryEmailVerificationStatus = 'false' + this.recoveryEmailVerificationStatus = false this.showConfirmation = true this.unverifiedRecoveryEmail = this.recoveryEmail setTimeout(function() { @@ -71,7 +71,7 @@ export default { } ) .then(response => { - this.recoveryEmailVerificationStatus = 'false' + this.recoveryEmailVerificationStatus = false this.showConfirmation = true setTimeout(function() { this.showConfirmation = false diff --git a/src/main.html b/src/main.html index 0f3c37c..7e1690c 100644 --- a/src/main.html +++ b/src/main.html @@ -10,7 +10,7 @@ v-model="recoveryEmail" :placeholder="placeholder" /> - + -- GitLab From f0d3af6f6795d863560ad92b89f402812bca49c5 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Thu, 14 Dec 2023 23:50:44 -0800 Subject: [PATCH 124/130] added check --- lib/Controller/EmailRecoveryController.php | 19 ++++++++++++------- lib/Listeners/UserConfigChangedListener.php | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 380eab6..9fab9c7 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -144,8 +144,16 @@ class EmailRecoveryController extends Controller { * @NoAdminRequired */ public function resendRecoveryEmail(string $recoveryEmail) { - $userId = $this->userSession->getUser()->getUID(); $response = new JSONResponse(); + $response->setStatus(200); + + $userId = $this->userSession->getUser()->getUID(); + $currentRecoveryEmail = $this->recoveryEmailService->getRecoveryEmail($userId); + if ($currentRecoveryEmail === $recoveryEmail) { + $response->setStatus(400); + $response->setData(['message' => $this->l->t('Recovery email is verified.')]); + return $response; + } $this->recoveryEmailService->sendVerificationEmail($userId, $recoveryEmail); return $response; } @@ -160,18 +168,15 @@ class EmailRecoveryController extends Controller { $response->setStatus(500); if ($e instanceof InvalidRecoveryEmailException) { $response->setStatus(400); - $this->l->t('Invalid Recovery Email'); - $response->setData(['message' => 'Invalid Recovery Email']); + $response->setData(['message' => $this->l->t('Invalid Recovery Email')]); } if ($e instanceof SameRecoveryEmailAsEmailException) { $response->setStatus(400); - $this->l->t('Error! User email address cannot be saved as recovery email address!'); - $response->setData(['message' => 'Error! User email address cannot be saved as recovery email address!']); + $response->setData(['message' => $this->l->t('Error! User email address cannot be saved as recovery email address!')]); } if ($e instanceof RecoveryEmailAlreadyFoundException) { $response->setStatus(400); - $this->l->t('Recovery email address is already taken.'); - $response->setData(['message' => 'Recovery email address is already taken.']); + $response->setData(['message' => $this->l->t('Recovery email address is already taken.')]); } } } diff --git a/lib/Listeners/UserConfigChangedListener.php b/lib/Listeners/UserConfigChangedListener.php index 773226a..bdf6e75 100644 --- a/lib/Listeners/UserConfigChangedListener.php +++ b/lib/Listeners/UserConfigChangedListener.php @@ -26,8 +26,8 @@ class UserConfigChangedListener implements IEventListener { if ($event->getKey() === 'unverified-recovery-email') { $user = $event->getUserId(); $newRecoveryEmail = $event->getValue(); - $this->recoveryEmailService->sendVerificationEmail($user, $newRecoveryEmail); $this->recoveryEmailService->setRecoveryEmail($user, ''); + $this->recoveryEmailService->sendVerificationEmail($user, $newRecoveryEmail); } } } -- GitLab From 89365c8452b51048acc8c24c7f3c6591e0612569 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 15 Dec 2023 00:00:49 -0800 Subject: [PATCH 125/130] change in condition --- src/App.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/App.vue b/src/App.vue index 3e93e3f..3e59cb8 100644 --- a/src/App.vue +++ b/src/App.vue @@ -82,6 +82,10 @@ export default { this.errorKey = 'Error sending recovery verification email' if (err.response && err.response.data.message) { this.errorKey = err.response.data.message + if (err.response.status === 400) { + this.errorKey = '' + this.recoveryEmailVerificationStatus = true + } } this.showError = true }) -- GitLab From 4c7c80df59aa4bf58d4ccc34e1554467110a009c Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 15 Dec 2023 00:05:09 -0800 Subject: [PATCH 126/130] change in condition --- src/App.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/App.vue b/src/App.vue index 3e59cb8..84bd7fb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -50,7 +50,6 @@ export default { }, 3000) }) .catch(err => { - console.error(err) this.errorKey = 'Error setting recovery email' if (err.response && err.response.data.message) { this.errorKey = err.response.data.message @@ -78,7 +77,6 @@ export default { }, 3000) }) .catch(err => { - console.error(err) this.errorKey = 'Error sending recovery verification email' if (err.response && err.response.data.message) { this.errorKey = err.response.data.message -- GitLab From 5f214848ba56b5ec9332b89fb23b3173f55f4e41 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 15 Dec 2023 00:19:47 -0800 Subject: [PATCH 127/130] added condition at listener --- lib/Listeners/UserConfigChangedListener.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Listeners/UserConfigChangedListener.php b/lib/Listeners/UserConfigChangedListener.php index bdf6e75..bfce357 100644 --- a/lib/Listeners/UserConfigChangedListener.php +++ b/lib/Listeners/UserConfigChangedListener.php @@ -26,8 +26,10 @@ class UserConfigChangedListener implements IEventListener { if ($event->getKey() === 'unverified-recovery-email') { $user = $event->getUserId(); $newRecoveryEmail = $event->getValue(); - $this->recoveryEmailService->setRecoveryEmail($user, ''); - $this->recoveryEmailService->sendVerificationEmail($user, $newRecoveryEmail); + if ($newRecoveryEmail !== '') { + $this->recoveryEmailService->setRecoveryEmail($user, ''); + $this->recoveryEmailService->sendVerificationEmail($user, $newRecoveryEmail); + } } } } -- GitLab From 80af7fc53ca1dcc634c593da0095c11942d48fbc Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 15 Dec 2023 00:25:16 -0800 Subject: [PATCH 128/130] temprory removed deleteuservalue code --- lib/Service/RecoveryEmailService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index b583741..b933ab6 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -183,7 +183,7 @@ class RecoveryEmailService { $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); // removing past tokens - $this->config->deleteUserValue($user->getUID(), 'core', 'verifyRecoveryMail' . $ref); + // $this->config->deleteUserValue($user->getUID(), 'core', 'verifyRecoveryMail' . $ref); return $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail, self::TOKEN_LIFETIME); } public function verifyToken(string $token, IUser $user, string $verificationKey, string $email): void { -- GitLab From bcf5be404ebdf7947a86049f8d3e470c87fcd53d Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 15 Dec 2023 15:44:03 -0800 Subject: [PATCH 129/130] api in progress flag added --- lib/Service/RecoveryEmailService.php | 5 +---- src/App.vue | 9 ++++++++- src/main.html | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index b933ab6..b7a5028 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -180,10 +180,7 @@ class RecoveryEmailService { return $emailTemplate; } private function createToken(IUser $user, string $recoveryEmail = ''): string { - $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); - - // removing past tokens - // $this->config->deleteUserValue($user->getUID(), 'core', 'verifyRecoveryMail' . $ref); + $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); return $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail, self::TOKEN_LIFETIME); } public function verifyToken(string $token, IUser $user, string $verificationKey, string $email): void { diff --git a/src/App.vue b/src/App.vue index 84bd7fb..e2e340c 100644 --- a/src/App.vue +++ b/src/App.vue @@ -21,11 +21,12 @@ export default { placeholder: t('email-recovery', 'Recovery Email'), value: t('email-recovery', 'Change Recovery Email'), recoveryEmailVerificationStatus: loadState('email-recovery', 'recoveryEmailVerificationStatus'), + apiInProgress: false, } }, computed: { isButtonDisabled() { - return this.recoveryEmail === this.unverifiedRecoveryEmail || this.recoveryEmail === loadState('email-recovery', 'recoveryEmail') || this.recoveryEmail.trim() === '' + return this.recoveryEmail === this.unverifiedRecoveryEmail || this.recoveryEmail === loadState('email-recovery', 'recoveryEmail') || this.recoveryEmail.trim() === '' || this.apiInProgress }, }, methods: { @@ -33,6 +34,7 @@ export default { this.showConfirmation = false this.showError = false this.errorKey = '' + this.apiInProgress = true confirmPassword().then(() => { axios .post( @@ -55,6 +57,8 @@ export default { this.errorKey = err.response.data.message } this.showError = true + }).finally(() => { + this.apiInProgress = false }) }) }, @@ -62,6 +66,7 @@ export default { this.showConfirmation = false this.showError = false this.errorKey = '' + this.apiInProgress = true axios .post( generateUrl('/apps/email-recovery/resend_recovery_email'), @@ -86,6 +91,8 @@ export default { } } this.showError = true + }).finally(() => { + this.apiInProgress = false }) }, }, diff --git a/src/main.html b/src/main.html index 7e1690c..0b865e3 100644 --- a/src/main.html +++ b/src/main.html @@ -25,6 +25,7 @@ v-if="recoveryEmailVerificationStatus !== true" type="button" @click.prevent="resendVerificationEmail" + :disabled="apiInProgress" > {{ t("email-recovery", "Resend Verification Email") }} -- GitLab From 49af3f0c65f74c02771e6b9428635f0a782afb34 Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Fri, 15 Dec 2023 15:47:33 -0800 Subject: [PATCH 130/130] change --- lib/Service/RecoveryEmailService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Service/RecoveryEmailService.php b/lib/Service/RecoveryEmailService.php index b7a5028..31f3156 100644 --- a/lib/Service/RecoveryEmailService.php +++ b/lib/Service/RecoveryEmailService.php @@ -180,7 +180,7 @@ class RecoveryEmailService { return $emailTemplate; } private function createToken(IUser $user, string $recoveryEmail = ''): string { - $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); + $ref = \substr(hash('sha256', $recoveryEmail), 0, 8); return $this->verificationToken->create($user, 'verifyRecoveryMail' . $ref, $recoveryEmail, self::TOKEN_LIFETIME); } public function verifyToken(string $token, IUser $user, string $verificationKey, string $email): void { -- GitLab