diff --git a/appinfo/info.xml b/appinfo/info.xml index 6076c77bd586b1e6fc26c126e1ff6279a24813c4..f8ef2cec6bfebdedb4cc784537f2c79324613138 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Email Recovery Email Recovery App - 4.0.0 + 4.0.1 agpl MURENA SAS EmailRecovery diff --git a/l10n/de.js b/l10n/de.js index 8de0a5729f938ea053c5b8cbc6783bdb9b820f33..1147ba5aa226b7c646dd07ce57f059d431e0f5c4 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -8,6 +8,10 @@ OC.L10N.register( "Recovery Email" : "Wiederherstellungs-E-Mail", "Change Recovery Email" : "Wiederherstellungs-E-Mail ändern", "Recovery Email " : "Wiederherstellungs-E-Mail ", - "Changes saved" : "Änderungen gespeichert" + "Changes saved" : "Änderungen gespeichert", + "You cannot set an email address with a Murena domain as recovery email address.": "Sie können keine E-Mail-Adresse mit einer Murena-Domäne als Wiederherstellungs-E-Mail-Adresse festlegen.", + "Recovery email is not verified.": "Die Wiederherstellungs-E-Mail wird nicht überprüft.", + "Recovery email address is already taken.": "Die E-Mail-Adresse für die Wiederherstellung ist bereits vergeben.", + "Resend Verification Email": "Verifizierungs-E-Mail erneut senden" }, "nplurals=2; plural=n != 1;"); diff --git a/l10n/de.json b/l10n/de.json index 44b96899966b6fef1b91df9bc9b508a385f1183f..516d4dd4644e15561bbe21718fc92baecc32363d 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -6,6 +6,10 @@ "Recovery Email" : "Wiederherstellungs-E-Mail", "Change Recovery Email" : "Wiederherstellungs-E-Mail ändern", "Recovery Email " : "Wiederherstellungs-E-Mail ", - "Changes saved" : "Änderungen gespeichert" + "Changes saved" : "Änderungen gespeichert", + "You cannot set an email address with a Murena domain as recovery email address.": "Sie können keine E-Mail-Adresse mit einer Murena-Domäne als Wiederherstellungs-E-Mail-Adresse festlegen.", + "Recovery email is not verified.": "Die Wiederherstellungs-E-Mail wird nicht überprüft.", + "Recovery email address is already taken.": "Die E-Mail-Adresse für die Wiederherstellung ist bereits vergeben.", + "Resend Verification Email": "Verifizierungs-E-Mail erneut senden" },"pluralForm" :"nplurals=2; plural=n != 1;" } \ No newline at end of file diff --git a/l10n/de_DE.js b/l10n/de_DE.js index 8de0a5729f938ea053c5b8cbc6783bdb9b820f33..1147ba5aa226b7c646dd07ce57f059d431e0f5c4 100644 --- a/l10n/de_DE.js +++ b/l10n/de_DE.js @@ -8,6 +8,10 @@ OC.L10N.register( "Recovery Email" : "Wiederherstellungs-E-Mail", "Change Recovery Email" : "Wiederherstellungs-E-Mail ändern", "Recovery Email " : "Wiederherstellungs-E-Mail ", - "Changes saved" : "Änderungen gespeichert" + "Changes saved" : "Änderungen gespeichert", + "You cannot set an email address with a Murena domain as recovery email address.": "Sie können keine E-Mail-Adresse mit einer Murena-Domäne als Wiederherstellungs-E-Mail-Adresse festlegen.", + "Recovery email is not verified.": "Die Wiederherstellungs-E-Mail wird nicht überprüft.", + "Recovery email address is already taken.": "Die E-Mail-Adresse für die Wiederherstellung ist bereits vergeben.", + "Resend Verification Email": "Verifizierungs-E-Mail erneut senden" }, "nplurals=2; plural=n != 1;"); diff --git a/l10n/de_DE.json b/l10n/de_DE.json index 44b96899966b6fef1b91df9bc9b508a385f1183f..516d4dd4644e15561bbe21718fc92baecc32363d 100644 --- a/l10n/de_DE.json +++ b/l10n/de_DE.json @@ -6,6 +6,10 @@ "Recovery Email" : "Wiederherstellungs-E-Mail", "Change Recovery Email" : "Wiederherstellungs-E-Mail ändern", "Recovery Email " : "Wiederherstellungs-E-Mail ", - "Changes saved" : "Änderungen gespeichert" + "Changes saved" : "Änderungen gespeichert", + "You cannot set an email address with a Murena domain as recovery email address.": "Sie können keine E-Mail-Adresse mit einer Murena-Domäne als Wiederherstellungs-E-Mail-Adresse festlegen.", + "Recovery email is not verified.": "Die Wiederherstellungs-E-Mail wird nicht überprüft.", + "Recovery email address is already taken.": "Die E-Mail-Adresse für die Wiederherstellung ist bereits vergeben.", + "Resend Verification Email": "Verifizierungs-E-Mail erneut senden" },"pluralForm" :"nplurals=2; plural=n != 1;" } \ No newline at end of file diff --git a/l10n/en.js b/l10n/en.js index 55e2c6724d323bfd348c13d1a81f459ed41829bb..47938dc517512f757487b040b322369f71d1b330 100644 --- a/l10n/en.js +++ b/l10n/en.js @@ -24,6 +24,7 @@ OC.L10N.register( "Could not verify recovery email because the token is invalid": "Could not verify recovery email because the token is invalid", "Unverified recovery email:": "Unverified recovery email:", "Please set your recovery email address to use your email account without restrictions.": "Please set your recovery email address to use your email account without restrictions.", - "SET RECOVERY EMAIL NOW": "SET RECOVERY EMAIL NOW" + "SET RECOVERY EMAIL NOW": "SET RECOVERY EMAIL NOW", + "You cannot set an email address with a Murena domain as recovery email address.": "You cannot set an email address with a Murena domain as recovery email address." }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/en.json b/l10n/en.json index b4b133a2482651d840ec10401c21b5186fa63184..5701614ad8981307047070656092796d67d185ac 100644 --- a/l10n/en.json +++ b/l10n/en.json @@ -25,7 +25,8 @@ "Please set your recovery email address to use your email account without restrictions.": "Please set your recovery email address to use your email account without restrictions.", "SET RECOVERY EMAIL NOW": "SET RECOVERY EMAIL NOW", "20240101_weekly_reminder_subject": "**Action required: Set up your recovery email**", - "20240101_weekly_reminder_body": "Dear **{username}**,\n\nFor security reasons you need to set a recovery email address for your Murena Cloud account. As you haven't done so yet, the usage of your email address is restricted. Please set and validate a recovery email address to remove all usage restriction on your email address.\n\n[SET MY RECOVERY EMAIL ADDRESS](https://murena.io/settings/user/security#recovery-email-form)" + "20240101_weekly_reminder_body": "Dear **{username}**,\n\nFor security reasons you need to set a recovery email address for your Murena Cloud account. As you haven't done so yet, the usage of your email address is restricted. Please set and validate a recovery email address to remove all usage restriction on your email address.\n\n[SET MY RECOVERY EMAIL ADDRESS](https://murena.io/settings/user/security#recovery-email-form)", + "You cannot set an email address with a Murena domain as recovery email address.": "You cannot set an email address with a Murena domain as recovery email address." }, "pluralForm": "nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/l10n/es.js b/l10n/es.js index ac209fc4c44f3855deb49a57a5ff5fd6f37372d9..9ed8198ef27d36d3a66c0028b9db3e152576c673 100644 --- a/l10n/es.js +++ b/l10n/es.js @@ -8,6 +8,10 @@ OC.L10N.register( "Recovery Email" : "Correo electrónico de recuperación", "Change Recovery Email" : "Cambiar correo electrónico de recuperación", "Recovery Email " : "Correo electrónico de recuperación ", - "Changes saved" : "Cambios guardados" + "Changes saved" : "Cambios guardados", + "You cannot set an email address with a Murena domain as recovery email address.": "No puede establecer una dirección de correo electrónico con un dominio de Murena como dirección de correo electrónico de recuperación.", + "Recovery email is not verified.": "El correo electrónico de recuperación no está verificado.", + "Recovery email address is already taken.": "La dirección de correo electrónico de recuperación ya está ocupada.", + "Resend Verification Email": "Reenviar correo de verificación" }, "nplurals=2; plural=n != 1;"); diff --git a/l10n/es.json b/l10n/es.json index 2941d980e1ec0a987760fb719bc1c524ead67840..3e8fae389d1fc88b009e8d02ca188ace459e012e 100644 --- a/l10n/es.json +++ b/l10n/es.json @@ -6,6 +6,10 @@ "Recovery Email" : "Correo electrónico de recuperación", "Change Recovery Email" : "Cambiar correo electrónico de recuperación", "Recovery Email " : "Correo electrónico de recuperación ", - "Changes saved" : "Cambios guardados" + "Changes saved" : "Cambios guardados", + "You cannot set an email address with a Murena domain as recovery email address.": "No puede establecer una dirección de correo electrónico con un dominio de Murena como dirección de correo electrónico de recuperación.", + "Recovery email is not verified.": "El correo electrónico de recuperación no está verificado.", + "Recovery email address is already taken.": "La dirección de correo electrónico de recuperación ya está ocupada.", + "Resend Verification Email": "Reenviar correo de verificación" },"pluralForm" :"nplurals=2; plural=n != 1;" } \ No newline at end of file diff --git a/l10n/fr.js b/l10n/fr.js index 4e31d62e919c84cc4ef392de1e13abfbda763d29..809296d5d123604ed82efcc2fa1792646be022a6 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -8,6 +8,10 @@ OC.L10N.register( "Recovery Email" : "Courriel de récupération", "Change Recovery Email" : "Modifier le courriel de récupération", "Recovery Email " : "Courriel de récupération ", - "Changes saved" : "Changements enregistrés" + "Changes saved" : "Changements enregistrés", + "You cannot set an email address with a Murena domain as recovery email address.": "Vous ne pouvez pas définir une adresse électronique avec un domaine Murena comme adresse électronique de récupération.", + "Recovery email is not verified.": "L'email de récupération n'est pas vérifié.", + "Recovery email address is already taken.": "L'adresse électronique de récupération est déjà prise.", + "Resend Verification Email": "Renvoyer l'e-mail de vérification" }, "nplurals=2; plural=n > 1;"); diff --git a/l10n/fr.json b/l10n/fr.json index c422d423a95d837ac92750fb44ba8f12535c7b2c..2cbd8e1996155798a34b29ed763fd2719f468a75 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -6,6 +6,10 @@ "Recovery Email" : "Courriel de récupération", "Change Recovery Email" : "Modifier le courriel de récupération", "Recovery Email " : "Courriel de récupération ", - "Changes saved" : "Changements enregistrés" + "Changes saved" : "Changements enregistrés", + "You cannot set an email address with a Murena domain as recovery email address.": "Vous ne pouvez pas définir une adresse électronique avec un domaine Murena comme adresse électronique de récupération.", + "Recovery email is not verified.": "L'email de récupération n'est pas vérifié.", + "Recovery email address is already taken.": "L'adresse électronique de récupération est déjà prise.", + "Resend Verification Email": "Renvoyer l'e-mail de vérification" },"pluralForm" :"nplurals=2; plural=n > 1;" } \ No newline at end of file diff --git a/l10n/it.js b/l10n/it.js index 02879b77641a3cb2ec81456c1e3b887222b91270..2d849dba87e5cfaa10b55ae2c6139bd2a44e6c2c 100644 --- a/l10n/it.js +++ b/l10n/it.js @@ -8,6 +8,10 @@ OC.L10N.register( "Recovery Email" : "Recupero e-mail", "Change Recovery Email" : "Modifica dell'e-mail di recupero", "Recovery Email " : "Recupero e-mail ", - "Changes saved" : "Modifiche salvate" + "Changes saved" : "Modifiche salvate", + "You cannot set an email address with a Murena domain as recovery email address.": "Non è possibile impostare un indirizzo e-mail con un dominio Murena come indirizzo e-mail di recupero.", + "Recovery email is not verified.": "L'e-mail di recupero non è verificata.", + "Recovery email address is already taken.": "L'indirizzo e-mail di recupero è già stato preso.", + "Resend Verification Email": "Reinvio dell'e-mail di verifica" }, "nplurals=2; plural=n != 1;"); diff --git a/l10n/it.json b/l10n/it.json index 2edf4b746d90817e88c6cec212c056a9e2a6d688..12773362f09ffaf81e5c20a0d1a1e20d030a7f45 100644 --- a/l10n/it.json +++ b/l10n/it.json @@ -6,6 +6,10 @@ "Recovery Email" : "Recupero e-mail", "Change Recovery Email" : "Modifica dell'e-mail di recupero", "Recovery Email " : "Recupero e-mail ", - "Changes saved" : "Modifiche salvate" + "Changes saved" : "Modifiche salvate", + "You cannot set an email address with a Murena domain as recovery email address.": "Non è possibile impostare un indirizzo e-mail con un dominio Murena come indirizzo e-mail di recupero.", + "Recovery email is not verified.": "L'e-mail di recupero non è verificata.", + "Recovery email address is already taken.": "L'indirizzo e-mail di recupero è già stato preso.", + "Resend Verification Email": "Reinvio dell'e-mail di verifica" },"pluralForm" :"nplurals=2; plural=n != 1;" } \ No newline at end of file diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 9fab9c73c593ca33647f80aa65c29abb5a44359c..9a29776d98a7a09674f5542e79985040c6342388 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -24,23 +24,24 @@ namespace OCA\EmailRecovery\Controller; +use Exception; +use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; +use OCA\EmailRecovery\Exception\MurenaDomainDisallowedException; +use OCA\EmailRecovery\Exception\RecoveryEmailAlreadyFoundException; +use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; +use OCA\EmailRecovery\Service\RecoveryEmailService; use OCP\AppFramework\Controller; -use OCP\IRequest; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; +use OCP\IL10N; use OCP\ILogger; -use \OCP\IL10N; -use OCP\IUserSession; -use OCP\AppFramework\Http\JSONResponse; -use OCA\EmailRecovery\Service\RecoveryEmailService; -use OCA\EmailRecovery\Exception\InvalidRecoveryEmailException; -use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; -use OCA\EmailRecovery\Exception\RecoveryEmailAlreadyFoundException; +use OCP\IRequest; use OCP\IUserManager; -use OCP\Security\VerificationToken\IVerificationToken; -use OCP\Security\VerificationToken\InvalidTokenException; -use Exception; -use OCP\AppFramework\Http\TemplateResponse; +use OCP\IUserSession; use OCP\Security\ICrypto; +use OCP\Security\VerificationToken\InvalidTokenException; +use OCP\Security\VerificationToken\IVerificationToken; class EmailRecoveryController extends Controller { private IConfig $config; @@ -79,15 +80,15 @@ class EmailRecoveryController extends Controller { * @NoAdminRequired */ - public function getRecoveryEmail() { - $response = new JSONResponse(); - $userId = $this->userSession->getUser()->getUID(); - $recoveryEmail = $this->config->getUserValue($userId, $this->appName, 'recovery-email'); - $unverifiedRecoveryEmail = $this->config->getUserValue($userId, $this->appName, 'unverified-recovery-email'); - $data = array("recoveryEmail" => $recoveryEmail, "unverifiedRecoveryEmail" => $unverifiedRecoveryEmail); - $response->setData($data); - return $response; - } + public function getRecoveryEmail() { + $response = new JSONResponse(); + $userId = $this->userSession->getUser()->getUID(); + $recoveryEmail = $this->config->getUserValue($userId, $this->appName, 'recovery-email'); + $unverifiedRecoveryEmail = $this->config->getUserValue($userId, $this->appName, 'unverified-recovery-email'); + $data = ["recoveryEmail" => $recoveryEmail, "unverifiedRecoveryEmail" => $unverifiedRecoveryEmail]; + $response->setData($data); + return $response; + } /** * @NoAdminRequired @@ -143,41 +144,45 @@ class EmailRecoveryController extends Controller { /** * @NoAdminRequired */ - public function resendRecoveryEmail(string $recoveryEmail) { - $response = new JSONResponse(); - $response->setStatus(200); + public function resendRecoveryEmail(string $recoveryEmail) { + $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; - } + $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; + } - private function handleRecoveryEmailLogic(string $recoveryEmail, string $userId, JSONResponse $response) { - try { - 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.')]); - } - } - } + private function handleRecoveryEmailLogic(string $recoveryEmail, string $userId, JSONResponse $response) { + try { + 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.')]); + } + if ($e instanceof MurenaDomainDisallowedException) { + $response->setStatus(400); + $response->setData(['message' => $this->l->t('You cannot set an email address with a Murena domain as recovery email address.')]); + } + } + } } diff --git a/lib/Exception/MurenaDomainDisallowedException.php b/lib/Exception/MurenaDomainDisallowedException.php new file mode 100644 index 0000000000000000000000000000000000000000..6504d9ba99d30b4b8b24129b984dde694908ce06 --- /dev/null +++ b/lib/Exception/MurenaDomainDisallowedException.php @@ -0,0 +1,11 @@ +userManager->get($username); $email = $user->getEMailAddress(); - - if (!filter_var($recoveryEmail, FILTER_VALIDATE_EMAIL)) { - $this->logger->info("User $username's requested recovery email does not match email format"); - throw new InvalidRecoveryEmailException(); - } - if (strcmp($recoveryEmail, $email) === 0) { - $this->logger->info("User ID $username's requested recovery email is the same as email"); - throw new SameRecoveryEmailAsEmailException(); - } - if (!empty($recoveryEmail) && $this->isRecoveryEmailTaken($username, $recoveryEmail)) { - $this->logger->info("User ID $username's requested recovery email address is already taken"); - throw new RecoveryEmailAlreadyFoundException(); + if (!empty($recoveryEmail)) { + if (!filter_var($recoveryEmail, FILTER_VALIDATE_EMAIL)) { + $this->logger->info("User $username's requested recovery email does not match email format"); + throw new InvalidRecoveryEmailException(); + } + if (strcmp($recoveryEmail, $email) === 0) { + $this->logger->info("User ID $username's requested recovery email is the same as email"); + throw new SameRecoveryEmailAsEmailException(); + } + if ($this->isRecoveryEmailTaken($username, $recoveryEmail)) { + $this->logger->info("User ID $username's requested recovery email address is already taken"); + throw new RecoveryEmailAlreadyFoundException(); + } + if ($this->isRecoveryEmailDomainDisallowed($recoveryEmail)) { + $this->logger->info("User ID $username's requested recovery email address is disallowed."); + throw new MurenaDomainDisallowedException(); + } } return true; } + public function isRecoveryEmailDomainDisallowed(string $recoveryEmail): bool { + $recoveryEmail = strtolower($recoveryEmail); + $emailParts = explode('@', $recoveryEmail); + $domain = $emailParts[1] ?? ''; + $legacyDomain = $this->config->getSystemValue('legacy_domain', ''); + + $mainDomain = $this->config->getSystemValue('main_domain', ''); + + $restrictedDomains = [$legacyDomain, $mainDomain]; + + return in_array($domain, $restrictedDomains); + } public function isRecoveryEmailTaken(string $username, string $recoveryEmail): bool { $recoveryEmail = strtolower($recoveryEmail);