mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Fixes for contact authentication + viewed entity notifications
This commit is contained in:
parent
d807d51f67
commit
2bc8146f7c
@ -15,12 +15,15 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ClientPortal\Contact\ContactPasswordResetRequest;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Account;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Utils\Ninja;
|
||||
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\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ContactForgotPasswordController extends Controller
|
||||
@ -80,19 +83,35 @@ class ContactForgotPasswordController extends Controller
|
||||
public function sendResetLinkEmail(ContactPasswordResetRequest $request)
|
||||
{
|
||||
|
||||
if(Ninja::isHosted() && $request->has('db'))
|
||||
MultiDB::setDb($request->input('db'));
|
||||
|
||||
// $user = MultiDB::hasContact($request->input('email'));
|
||||
if(Ninja::isHosted() && $request->has('company_key'))
|
||||
MultiDB::findAndSetDbByCompanyKey($request->input('company_key'));
|
||||
|
||||
$this->validateEmail($request);
|
||||
|
||||
// $user = MultiDB::hasContact($request->input('email'));
|
||||
$company = Company::where('company_key', $request->input('company_key'))->first();
|
||||
$contact = MultiDB::findContact(['company_id' => $company->id, 'email' => $request->input('email')]);
|
||||
|
||||
$response = false;
|
||||
|
||||
if($contact){
|
||||
|
||||
/* Update all instances of the client */
|
||||
$token = Str::random(60);
|
||||
ClientContact::where('email', $contact->email)->update(['token' => $token]);
|
||||
|
||||
$contact->sendPasswordResetNotification($token);
|
||||
$response = Password::RESET_LINK_SENT;
|
||||
}
|
||||
else
|
||||
return $this->sendResetLinkFailedResponse($request, Password::INVALID_USER);
|
||||
|
||||
// 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)
|
||||
);
|
||||
// $response = $this->broker()->sendResetLink(
|
||||
// $this->credentials($request)
|
||||
// );
|
||||
|
||||
if ($request->ajax()) {
|
||||
|
||||
|
@ -14,11 +14,15 @@ namespace App\Http\Controllers\Auth;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Account;
|
||||
use App\Models\ClientContact;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ContactResetPasswordController extends Controller
|
||||
@ -76,19 +80,28 @@ class ContactResetPasswordController extends Controller
|
||||
|
||||
public function reset(Request $request)
|
||||
{
|
||||
if($request->has('db'))
|
||||
MultiDB::setDb($request->input('db'));
|
||||
if($request->has('company_key'))
|
||||
MultiDB::findAndSetDbByCompanyKey($request->input('company_key'));
|
||||
|
||||
$request->validate($this->rules(), $this->validationErrorMessages());
|
||||
|
||||
// Here we will attempt to reset the user's password. If it is successful we
|
||||
// will update the password on an actual user model and persist it to the
|
||||
// database. Otherwise we will parse the error and return the response.
|
||||
$response = $this->broker()->reset(
|
||||
$this->credentials($request), function ($user, $password) {
|
||||
$this->resetPassword($user, $password);
|
||||
}
|
||||
);
|
||||
$user = ClientContact::where($request->only(['email','token']))->first();
|
||||
|
||||
if(!$user)
|
||||
return $this->sendResetFailedResponse($request, PASSWORD::INVALID_USER);
|
||||
|
||||
$hashed_password = Hash::make($request->input('password'));
|
||||
|
||||
ClientContact::where('email', $user->email)->update([
|
||||
'password' => $hashed_password,
|
||||
'remember_token' => Str::random(60)
|
||||
]);
|
||||
|
||||
event(new PasswordReset($user));
|
||||
|
||||
auth()->login($user, true);
|
||||
|
||||
$response = Password::PASSWORD_RESET;
|
||||
|
||||
// Added this because it collides the session between
|
||||
// client & main portal giving unlimited redirects.
|
||||
|
@ -2,10 +2,13 @@
|
||||
|
||||
namespace App\Http\Controllers\ClientPortal;
|
||||
|
||||
use App\Events\Credit\CreditWasViewed;
|
||||
use App\Events\Misc\InvitationWasViewed;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ClientPortal\Credits\ShowCreditRequest;
|
||||
use App\Http\Requests\ClientPortal\Credits\ShowCreditsRequest;
|
||||
use App\Models\Credit;
|
||||
use App\Utils\Ninja;
|
||||
|
||||
class CreditController extends Controller
|
||||
{
|
||||
@ -20,6 +23,16 @@ class CreditController extends Controller
|
||||
|
||||
$data = ['credit' => $credit];
|
||||
|
||||
$invitation = $credit->invitations()->where('client_contact_id', auth()->user()->id)->first();
|
||||
|
||||
if ($invitation && auth()->guard('contact') && ! request()->has('silent') && ! $invitation->viewed_date) {
|
||||
|
||||
$invitation->markViewed();
|
||||
|
||||
event(new InvitationWasViewed($credit, $invitation, $credit->company, Ninja::eventVars()));
|
||||
event(new CreditWasViewed($invitation, $invitation->company, Ninja::eventVars()));
|
||||
|
||||
}
|
||||
|
||||
if ($request->query('mode') === 'fullscreen') {
|
||||
return render('credits.show-fullscreen', $data);
|
||||
|
@ -11,11 +11,14 @@
|
||||
|
||||
namespace App\Http\Controllers\ClientPortal;
|
||||
|
||||
use App\Events\Invoice\InvoiceWasViewed;
|
||||
use App\Events\Misc\InvitationWasViewed;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ClientPortal\Invoices\ShowInvoicesRequest;
|
||||
use App\Http\Requests\ClientPortal\Invoices\ProcessInvoicesInBulkRequest;
|
||||
use App\Http\Requests\ClientPortal\Invoices\ShowInvoiceRequest;
|
||||
use App\Http\Requests\ClientPortal\Invoices\ShowInvoicesRequest;
|
||||
use App\Models\Invoice;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Number;
|
||||
use App\Utils\TempFile;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
@ -23,10 +26,10 @@ use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\View\View;
|
||||
use ZipStream\Option\Archive;
|
||||
use ZipStream\ZipStream;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class InvoiceController extends Controller
|
||||
{
|
||||
@ -56,6 +59,18 @@ class InvoiceController extends Controller
|
||||
|
||||
$invoice->service()->removeUnpaidGatewayFees()->save();
|
||||
|
||||
|
||||
$invitation = $invoice->invitations()->where('client_contact_id', auth()->user()->id)->first();
|
||||
|
||||
if ($invitation && auth()->guard('contact') && ! request()->has('silent') && ! $invitation->viewed_date) {
|
||||
|
||||
$invitation->markViewed();
|
||||
|
||||
event(new InvitationWasViewed($invoice, $invitation, $invoice->company, Ninja::eventVars()));
|
||||
event(new InvoiceWasViewed($invitation, $invitation->company, Ninja::eventVars()));
|
||||
|
||||
}
|
||||
|
||||
$data = [
|
||||
'invoice' => $invoice,
|
||||
];
|
||||
|
@ -12,22 +12,24 @@
|
||||
|
||||
namespace App\Http\Controllers\ClientPortal;
|
||||
|
||||
use App\Events\Misc\InvitationWasViewed;
|
||||
use App\Events\Quote\QuoteWasApproved;
|
||||
use App\Events\Quote\QuoteWasViewed;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ClientPortal\Quotes\ProcessQuotesInBulkRequest;
|
||||
use App\Http\Requests\ClientPortal\Quotes\ShowQuotesRequest;
|
||||
use App\Http\Requests\ClientPortal\Quotes\ShowQuoteRequest;
|
||||
use App\Http\Requests\ClientPortal\Quotes\ShowQuotesRequest;
|
||||
use App\Jobs\Invoice\InjectSignature;
|
||||
use App\Models\Quote;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\TempFile;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\View\View;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use ZipStream\Option\Archive;
|
||||
use ZipStream\ZipStream;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class QuoteController extends Controller
|
||||
{
|
||||
@ -56,6 +58,18 @@ class QuoteController extends Controller
|
||||
'quote' => $quote,
|
||||
];
|
||||
|
||||
|
||||
$invitation = $quote->invitations()->where('client_contact_id', auth()->user()->id)->first();
|
||||
|
||||
if ($invitation && auth()->guard('contact') && ! request()->has('silent') && ! $invitation->viewed_date) {
|
||||
|
||||
$invitation->markViewed();
|
||||
|
||||
event(new InvitationWasViewed($quote, $invitation, $quote->company, Ninja::eventVars()));
|
||||
event(new QuoteWasViewed($invitation, $invitation->company, Ninja::eventVars()));
|
||||
|
||||
}
|
||||
|
||||
if ($request->query('mode') === 'fullscreen') {
|
||||
return render('quotes.show-fullscreen', $data);
|
||||
}
|
||||
|
@ -174,6 +174,32 @@ class MultiDB
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return User|null
|
||||
*/
|
||||
public static function findContact(array $search) : ?ClientContact
|
||||
{
|
||||
if (! config('ninja.db.multi_db_enabled'))
|
||||
return ClientContact::where($search)->first();
|
||||
|
||||
$current_db = config('database.default');
|
||||
|
||||
foreach (self::$dbs as $db) {
|
||||
|
||||
$user = ClientContact::on($db)->where($search)->first();
|
||||
|
||||
if ($user) {
|
||||
self::setDb($db);
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
||||
self::setDB($current_db);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static function contactFindAndSetDb($token) :bool
|
||||
{
|
||||
$current_db = config('database.default');
|
||||
|
@ -191,6 +191,9 @@ class PaytracePaymentDriver extends BaseDriver
|
||||
|
||||
$auth_data = json_decode($response);
|
||||
|
||||
if(!property_exists($auth_data, 'access_token'))
|
||||
throw new \Exception('Error authenticating with PayTrace');
|
||||
|
||||
$headers = [];
|
||||
$headers[] = 'Content-type: application/json';
|
||||
$headers[] = 'Authorization: Bearer '.$auth_data->access_token;
|
||||
|
@ -53,7 +53,7 @@
|
||||
href="{{ route('client.password.request') }}">{{ trans('texts.forgot_password') }}</a>
|
||||
</div>
|
||||
@if(isset($company) && !is_null($company))
|
||||
<input type="hidden" name="db" value="{{$company->db}}">
|
||||
<input type="hidden" name="company_key" value="{{$company->company_key}}">
|
||||
@endif
|
||||
<input type="password" name="password" id="password"
|
||||
class="input"
|
||||
|
@ -34,7 +34,7 @@
|
||||
<div class="flex flex-col">
|
||||
<label for="email" class="input-label">{{ ctrans('texts.email_address') }}</label>
|
||||
@if($company && !is_null($company))
|
||||
<input type="hidden" name="db" value="{{$company->db}}">
|
||||
<input type="hidden" name="company_key" value="{{$company->company_key}}">
|
||||
@endif
|
||||
<input type="email" name="email" id="email"
|
||||
class="input"
|
||||
|
@ -33,8 +33,8 @@
|
||||
<form action="{{ route('client.password.update') }}" method="post" class="mt-6">
|
||||
@csrf
|
||||
<input type="hidden" name="token" value="{{ $token }}">
|
||||
@if($db)
|
||||
<input type="hidden" name="db" value="{{$db}}">
|
||||
@if($company)
|
||||
<input type="hidden" name="company_key" value="{{$company->company_key}}">
|
||||
@endif
|
||||
<div class="flex flex-col">
|
||||
<label for="email" class="input-label">{{ ctrans('texts.email_address') }}</label>
|
||||
|
Loading…
x
Reference in New Issue
Block a user