Pārlūkot izejas kodu

Added notifications on user create

Sergio Brighenti 5 gadi atpakaļ
vecāks
revīzija
38fdd263e8

+ 37 - 0
app/Controllers/UserController.php

@@ -3,6 +3,7 @@
 namespace App\Controllers;
 
 use App\Database\Queries\UserQuery;
+use App\Web\Mail;
 use App\Web\ValidationChecker;
 use League\Flysystem\FileNotFoundException;
 use Psr\Http\Message\ResponseInterface as Response;
@@ -64,10 +65,12 @@ class UserController extends Controller
      * @param  Response  $response
      *
      * @return Response
+     * @throws \Exception
      */
     public function store(Request $request, Response $response): Response
     {
         $validator = $this->getUserCreateValidator($request);
+        $hasPassword = $validator->removeRule('password.required');
 
         if ($validator->fails()) {
             return redirect($response, route('user.create'));
@@ -95,6 +98,40 @@ class UserController extends Controller
             $maxUserQuota
         );
 
+        if (param($request, 'send_notification') !== null) {
+            if ($hasPassword) {
+                $message = lang('mail.new_account_text_with_pw', [
+                    param($request, 'username'),
+                    $this->config['app_name'],
+                    $this->config['base_url'],
+                    param($request, 'username'),
+                    param($request, 'password'),
+                    route('login.show'),
+                ]);
+            } else {
+                $resetToken = bin2hex(random_bytes(16));
+
+                $this->database->query('UPDATE `users` SET `reset_token`=? WHERE `id` = ?', [
+                    $resetToken,
+                    $this->database->getPdo()->lastInsertId(),
+                ]);
+
+                $message = lang('mail.new_account_text_with_reset', [
+                    param($request, 'username'),
+                    $this->config['app_name'],
+                    $this->config['base_url'],
+                    route('recover.password', ['resetToken' => $resetToken]),
+                ]);
+            }
+
+            Mail::make()
+                ->from(platform_mail(), $this->config['app_name'])
+                ->to(param($request, 'email'))
+                ->subject(lang('mail.new_account', [$this->config['app_name']]))
+                ->message($message)
+                ->send();
+        }
+
         $this->session->alert(lang('user_created', [param($request, 'username')]), 'success');
         $this->logger->info('User '.$this->session->get('username').' created a new user.', [array_diff_key($request->getParsedBody(), array_flip(['password']))]);
 

+ 24 - 4
app/Database/Queries/UserQuery.php

@@ -71,7 +71,17 @@ class UserQuery
     }
 
 
-    public function create(string $email, string $username, string $password, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1, string $activateToken = null)
+    /**
+     * @param  string  $email
+     * @param  string  $username
+     * @param  string|null  $password
+     * @param  int  $isAdmin
+     * @param  int  $isActive
+     * @param  int  $maxUserQuota
+     * @param  string|null  $activateToken
+     * @return bool|\PDOStatement|string
+     */
+    public function create(string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1, string $activateToken = null)
     {
         do {
             $userCode = humanRandomString(5);
@@ -82,7 +92,7 @@ class UserQuery
         return $this->database->query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`, `max_disk_quota`, `activate_token`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', [
             $email,
             $username,
-            password_hash($password, PASSWORD_DEFAULT),
+            $password !== null ? password_hash($password, PASSWORD_DEFAULT) : null,
             $isAdmin,
             $isActive,
             $userCode,
@@ -92,10 +102,20 @@ class UserQuery
         ]);
     }
 
+    /**
+     * @param $id
+     * @param  string  $email
+     * @param  string  $username
+     * @param  string|null  $password
+     * @param  int  $isAdmin
+     * @param  int  $isActive
+     * @param  int  $maxUserQuota
+     * @return bool|\PDOStatement|string
+     */
     public function update($id, string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1)
     {
         if (!empty($password)) {
-            $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `password`=?, `is_admin`=?, `active`=?, `max_disk_quota`=? WHERE `id` = ?', [
+            return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `password`=?, `is_admin`=?, `active`=?, `max_disk_quota`=? WHERE `id` = ?', [
                 $email,
                 $username,
                 password_hash($password, PASSWORD_DEFAULT),
@@ -105,7 +125,7 @@ class UserQuery
                 $id,
             ]);
         } else {
-            $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `is_admin`=?, `active`=?, `max_disk_quota`=? WHERE `id` = ?', [
+            return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `is_admin`=?, `active`=?, `max_disk_quota`=? WHERE `id` = ?', [
                 $email,
                 $username,
                 $isAdmin,

+ 13 - 0
app/Web/ValidationChecker.php

@@ -51,4 +51,17 @@ class ValidationChecker
         }
         return false;
     }
+
+    /**
+     * @param  string  $key
+     * @return bool
+     */
+    public function removeRule(string $key)
+    {
+        $condition = $this->rules[$key];
+
+        unset($this->rules[$key]);
+
+        return $condition;
+    }
 }

+ 5 - 0
resources/lang/en.lang.php

@@ -146,4 +146,9 @@ return [
     'only_recaptcha_v3' => 'Only reCAPTCHA v3 is supported.',
     'recaptcha_site_key' => 'reCAPTCHA Site Key',
     'recaptcha_secret_key' => 'reCAPTCHA Secret Key',
+    'send_notification' => 'Send Mail Notification',
+    'mail.new_account' => '%s - New Account Creation',
+    'mail.new_account_text_with_reset' => "Hi %s!\na new account was created for you on %s (%s), click on the following link to set a password and activate it:\n\n%s",
+    'mail.new_account_text_with_pw' => "Hi %s!\na new account was created for you on %s (%s), with the following credentials:\n\nUsername: %s\nPassword: %s\n\nClick on the following link to go to the login page:\n%s",
+    'user_create_password' => 'If leaved empty, you might want to send a notification to the user email.',
 ];

+ 9 - 1
resources/templates/user/create.twig

@@ -27,7 +27,8 @@
                             <div class="form-group row">
                                 <label for="password" class="col-sm-2 col-form-label">{{ lang('password') }}</label>
                                 <div class="col-sm-10">
-                                    <input type="password" class="form-control" id="password" placeholder="{{ lang('password') }}" name="password" autocomplete="off" required>
+                                    <input type="password" class="form-control" id="password" placeholder="{{ lang('password') }}" name="password" autocomplete="off">
+                                    <small>{{ lang('user_create_password') }}</small>
                                 </div>
                             </div>
                             {% if quota_enabled == 'on' %}
@@ -51,6 +52,13 @@
                                     <input type="checkbox" name="is_active" data-toggle="toggle" data-off="{{ lang('no') }}" data-on="{{ lang('yes') }}" checked>
                                 </div>
                             </div>
+                            <hr>
+                            <div class="form-group row">
+                                <label for="send_notification" class="col-sm-2 col-form-label">{{ lang('send_notification') }}</label>
+                                <div class="col-sm-10">
+                                    <input type="checkbox" name="send_notification" data-toggle="toggle" data-onstyle="info" data-off="{{ lang('no') }}" data-on="{{ lang('yes') }}">
+                                </div>
+                            </div>
                             <div class="form-group row justify-content-md-end">
                                 <div class="col-sm-10">
                                     <button type="submit" class="btn btn-outline-success">