From fe5f50c78ea6f93877fec42350db53de86b93c33 Mon Sep 17 00:00:00 2001
From: "florian.azizian" <florian.azizian@maarch.org>
Date: Thu, 18 Mar 2021 10:45:01 +0100
Subject: [PATCH] FEAT #16626 TIME 1 Send email at user creation

---
 lang/fr.json                                  |  4 +++
 src/app/user/controllers/UserController.php   |  6 +++-
 src/app/user/models/UserModel.php             |  5 ++-
 .../controllers/AuthenticationController.php  | 32 +++++++++++++++++--
 src/core/models/AuthenticationModel.php       | 13 ++++++++
 5 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/lang/fr.json b/lang/fr.json
index f056039230..2adc354009 100755
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -79,6 +79,10 @@
 		"notificationForgotPasswordBody"     : "Bonjour,<br/>Vous avez demandé à réinitialiser le mot de passe de votre compte Maarch Parapheur.<br/>Pour modifier votre mot de passe, merci de bien vouloir cliquer sur le lien ci-dessous :<br/>",
 		"notificationForgotPasswordFooter"   : "<br/><br/>Si vous n'êtes pas à l'origine de cette demande, merci d'ignorer ce courriel.<br/>Pour toutes questions, merci de contacter l'administrateur technique de la solution.",
 		"notificationForgotPasswordSubject"  : "[Maarch Parapheur] Demande de réinitialisation de mot de passe",
+		"notificationNewAccountSubject"		 : "[Maarch Parapheur] Activer votre compte utilisateur",
+		"notificationNewAccountBody"		 : "Bienvenue,<br/><br/>Vous disposez maintenant d'un compte dans l'application Maarch Parapheur.<br/><br/>Pour vous connecter et définir votre mot de passe, merci de bien vouloir cliquer sur le lien ci-dessous :<br/><br/>",
+		"notificationNewAccountId"		 	 : "<br/><br/><b>Votre identifiant :</b>",
+		"notificationNewAccountFooter"		 : "<br/><br/>Ce message est envoyé automatiquement à la suite d'une action de l'administrateur.<br/>Merci de ne pas y répondre.<br/><br/>Pour toutes questions, merci de contacter l'administrateur technique de la solution.",
 		"notifications"                      : "Notifications",
 		"numberRequired"                     : "1 chiffre requis",
 		"onRange"                            : "le",
diff --git a/src/app/user/controllers/UserController.php b/src/app/user/controllers/UserController.php
index 03f2c975e5..f60ec2beda 100755
--- a/src/app/user/controllers/UserController.php
+++ b/src/app/user/controllers/UserController.php
@@ -163,6 +163,10 @@ class UserController
             'message'       => "{userAdded} : {$body['firstname']} {$body['lastname']}"
         ]);
 
+        if (empty($body['isRest'])) {
+            AuthenticationController::sendAccountActivationNotification(['userId' => $id, 'userEmail' => $body['email']]);
+        }
+
         return $response->withJson(['id' => $id]);
     }
 
@@ -581,7 +585,7 @@ class UserController
 
         $GLOBALS['id'] = $user['id'];
 
-        $resetToken = AuthenticationController::getResetJWT();
+        $resetToken = AuthenticationController::getResetJWT(['id' => $GLOBALS['id'], 'expirationTime' => 3600]);
         UserModel::update(['set' => ['reset_token' => $resetToken], 'where' => ['id = ?'], 'data' => [$user['id']]]);
 
         $user['preferences'] = json_decode($user['preferences'], true);
diff --git a/src/app/user/models/UserModel.php b/src/app/user/models/UserModel.php
index 19bca24fb1..87e245b07c 100755
--- a/src/app/user/models/UserModel.php
+++ b/src/app/user/models/UserModel.php
@@ -82,6 +82,9 @@ class UserModel
         ValidatorModel::notEmpty($args, ['login', 'email', 'firstname', 'lastname', 'picture']);
         ValidatorModel::stringType($args, ['login', 'email', 'firstname', 'lastname', 'picture', 'mode', 'signatureModes']);
 
+        if (empty($args['password'])) {
+            $args['password'] = AuthenticationModel::generatePassword();
+        }
         $nextSequenceId = DatabaseModel::getNextSequenceValue(['sequenceId' => 'users_id_seq']);
 
         DatabaseModel::insert([
@@ -90,7 +93,7 @@ class UserModel
                 'id'                            => $nextSequenceId,
                 'login'                         => $args['login'],
                 'email'                         => $args['email'],
-                'password'                      => AuthenticationModel::getPasswordHash('maarch'),
+                'password'                      => $args['password'],
                 'firstname'                     => $args['firstname'],
                 'lastname'                      => $args['lastname'],
                 '"isRest"'                      => empty($args['isRest']) ? 'false' : 'true',
diff --git a/src/core/controllers/AuthenticationController.php b/src/core/controllers/AuthenticationController.php
index e2345441d1..65e0f8a941 100755
--- a/src/core/controllers/AuthenticationController.php
+++ b/src/core/controllers/AuthenticationController.php
@@ -15,11 +15,14 @@
 namespace SrcCore\controllers;
 
 use Configuration\models\ConfigurationModel;
+use Email\controllers\EmailController;
 use Firebase\JWT\JWT;
 use History\controllers\HistoryController;
 use Respect\Validation\Validator;
 use Slim\Http\Request;
 use Slim\Http\Response;
+use SrcCore\controllers\LanguageController;
+use SrcCore\controllers\UrlController;
 use SrcCore\models\AuthenticationModel;
 use SrcCore\models\CoreConfigModel;
 use SrcCore\models\PasswordModel;
@@ -299,12 +302,12 @@ class AuthenticationController
         return $jwt;
     }
 
-    public static function getResetJWT()
+    public static function getResetJWT($args = [])
     {
         $token = [
-            'exp'   => time() + 3600,
+            'exp'   => time() + $args['expirationTime'],
             'user'  => [
-                'id' => $GLOBALS['id']
+                'id' => $args['id']
             ],
             'connection' => ConfigurationModel::getConnection()
         ];
@@ -314,6 +317,29 @@ class AuthenticationController
         return $jwt;
     }
 
+    public static function sendAccountActivationNotification(array $args)
+    {
+        $resetToken = AuthenticationController::getResetJWT(['id' => $args['userId'], 'expirationTime' => 1209600]); // 14 days
+        UserModel::update(['set' => ['reset_token' => $resetToken], 'where' => ['id = ?'], 'data' => [$args['userId']]]);
+
+        $user = UserModel::getById(['select' => ['login'], 'id' => $args['userId']]);
+        $lang = LanguageController::get(['lang' => 'fr']);
+
+        $url = UrlController::getCoreUrl() . 'dist/update-password?token=' . $resetToken;
+        EmailController::createEmail([
+            'userId' => $args['userId'],
+            'data'   => [
+                'sender'     => 'Notification',
+                'recipients' => [$args['userEmail']],
+                'subject'    => $lang['notificationNewAccountSubject'],
+                'body'       => $lang['notificationNewAccountBody'] . $url . $lang['notificationNewAccountId'] . ' ' . $user['login'] . $lang['notificationNewAccountFooter'],
+                'isHtml'     => true
+            ]
+        ]);
+
+        return true;
+    }
+
     public static function isRouteAvailable(array $args)
     {
         ValidatorModel::notEmpty($args, ['userId', 'currentRoute']);
diff --git a/src/core/models/AuthenticationModel.php b/src/core/models/AuthenticationModel.php
index 97017ee2a6..8b96f7ccdf 100755
--- a/src/core/models/AuthenticationModel.php
+++ b/src/core/models/AuthenticationModel.php
@@ -68,4 +68,17 @@ class AuthenticationModel
 
         return $password;
     }
+
+    public static function generatePassword()
+    {
+        $length = rand(50, 70);
+        $chars = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcefghijklmnopqrstuvwxyz!@$%^*_=+,.?';
+        $count = mb_strlen($chars);
+        for ($i = 0, $password = ''; $i < $length; $i++) {
+            $index = rand(0, $count - 1);
+            $password .= mb_substr($chars, $index, 1);
+        }
+
+        return $password;
+    }
 }
-- 
GitLab