Refactor password reset for admin users

This commit is contained in:
David Bomba 2021-02-15 10:39:40 +11:00
parent 08e280e651
commit 120d2c21ab
9 changed files with 134 additions and 105 deletions

View File

@ -12,8 +12,10 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Libraries\MultiDB;
use Illuminate\Contracts\View\Factory;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Password;
use Illuminate\View\View;
@ -65,4 +67,31 @@ class ContactForgotPasswordController extends Controller
{
return Password::broker('contacts');
}
public function sendResetLinkEmail(Request $request)
{
//MultiDB::userFindAndSetDb($request->input('email'));
$user = MultiDB::hasContact(['email' => $request->input('email')]);
$this->validateEmail($request);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$response = $this->broker()->sendResetLink(
$this->credentials($request)
);
if ($request->ajax()) {
return $response == Password::RESET_LINK_SENT
? response()->json(['message' => 'Reset link sent to your email.', 'status' => true], 201)
: response()->json(['message' => 'Email not found', 'status' => false], 401);
}
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($request, $response)
: $this->sendResetLinkFailedResponse($request, $response);
}
}

View File

@ -12,6 +12,7 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Libraries\MultiDB;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
@ -103,6 +104,10 @@ class ForgotPasswordController extends Controller
*/
public function sendResetLinkEmail(Request $request)
{
//MultiDB::userFindAndSetDb($request->input('email'));
$user = MultiDB::hasUser(['email' => $request->input('email')]);
$this->validateEmail($request);
// We will send the password reset link to this user. Once we have attempted

View File

@ -142,6 +142,31 @@ class MultiDB
return null;
}
/**
* @param array $data
* @return User|null
*/
public static function hasContact(array $data) : ?ClientContact
{
if (! config('ninja.db.multi_db_enabled')) {
return ClientContact::where($data)->withTrashed()->first();
}
foreach (self::$dbs as $db) {
self::setDB($db);
$user = ClientContacts::where($data)->withTrashed()->first();
if ($user) {
return $user;
}
}
self::setDefaultDatabase();
return null;
}
public static function contactFindAndSetDb($token) :bool
{
foreach (self::$dbs as $db) {
@ -160,7 +185,7 @@ class MultiDB
public static function userFindAndSetDb($email) : bool
{
//multi-db active
//multi-db active
foreach (self::$dbs as $db) {
if (User::on($db)->where(['email' => $email])->get()->count() >= 1) { // if user already exists, validation will fail
return true;

View File

@ -0,0 +1,53 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Mail\Admin;
class ResetPasswordObject
{
public $user;
public $token;
public $company;
/**
*
*/
public function __construct($token, $user, $company)
{
$this->token = $token;
$this->user = $user;
$this->company = $company;
}
public function build()
{
$data = [
'title' => ctrans('texts.your_password_reset_link'),
'message' => ctrans('texts.reset_password'),
'url' => route('password.reset', ['token' => $this->token, 'email' => $this->user->email]),
'button' => ctrans('texts.reset'),
'signature' => $this->company->settings->email_signature,
'settings' => $this->company->settings,
'logo' => $this->company->present()->logo(),
];
$mail_obj = new \stdClass;
$mail_obj->subject = ctrans('texts.your_password_reset_link');
$mail_obj->data = $data;
$mail_obj->markdown = 'email.admin.generic';
$mail_obj->tag = $this->company->company_key;
return $mail_obj;
}
}

View File

@ -11,6 +11,10 @@
namespace App\Models;
use App\Jobs\Mail\NinjaMailer;
use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject;
use App\Mail\Admin\ResetPasswordObject;
use App\Models\Presenters\UserPresenter;
use App\Notifications\ResetPasswordNotification;
use App\Utils\Traits\MakesHash;
@ -371,6 +375,15 @@ class User extends Authenticatable implements MustVerifyEmail
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
$nmo = new NinjaMailerObject;
$nmo->mailable = new NinjaMailer( (new ResetPasswordObject($token, $this, $this->account->default_company))->build());
$nmo->to_user = $this;
$nmo->settings = $this->account->default_company->settings;
$nmo->company = $this->account->default_company;
NinjaMailerJob::dispatch($nmo);
//$this->notify(new ResetPasswordNotification($token));
}
}

View File

@ -1,73 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class GmailTestNotification extends Notification
{
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}

View File

@ -20,6 +20,7 @@ use Illuminate\Notifications\Notification;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
//@deprecated
class NewAccountCreated extends Notification
{
//use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
@ -50,7 +51,7 @@ class NewAccountCreated extends Notification
*/
public function via($notifiable)
{
return ['slack', 'mail'];
return ['slack'];
}
/**
@ -61,26 +62,6 @@ class NewAccountCreated extends Notification
*/
public function toMail($notifiable)
{
$user_name = $this->user->first_name.' '.$this->user->last_name;
$email = $this->user->email;
$ip = $this->user->ip;
$data = [
'title' => ctrans('texts.new_signup'),
'message' => ctrans('texts.new_signup_text', ['user' => $user_name, 'email' => $email, 'ip' => $ip]),
'url' => config('ninja.web_url'),
'button' => ctrans('texts.account_login'),
'signature' => $this->company->settings->email_signature,
'logo' => $this->company->present()->logo(),
'settings' => $this->company->settings,
];
return (new MailMessage)
->subject(ctrans('texts.new_signup'))
->withSwiftMessage(function ($message) {
$message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
})
->markdown('email.admin.generic', $data);
}
/**

View File

@ -6,6 +6,7 @@ use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
//@deprecated
class ResetPasswordNotification extends Notification
{
// use Queueable;
@ -30,7 +31,7 @@ class ResetPasswordNotification extends Notification
*/
public function via($notifiable)
{
return ['mail'];
return [];
}
/**

View File

@ -1,19 +1,14 @@
@component('email.template.master', ['design' => 'light', 'whitelabel' => false])
@slot('header')
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
@include('email.components.header', ['logo' => $logo])
@endslot
<p>You are receiving this email because we received a password reset request for your account.</p>
<p>{{ ctrans('texts.reset_password') }}</p>
<a href="{{ $link }}" target="_blank" class="button">
Reset Password
{{ ctrans('texts.reset') }}
</a>
<p>
If youre having trouble clicking the "Reset Password" button, copy and paste the URL below into your web
browser:
</p>
<a href="{{ $link }}">{{ $link }}</a>
@endcomponent