mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-11 05:32:39 +01:00
Merge pull request #7710 from turbo124/v5-stable
Fixes for payment emails
This commit is contained in:
commit
ca60e9635c
@ -12,6 +12,7 @@
|
||||
namespace App\Factory;
|
||||
|
||||
use App\Models\VendorContact;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class VendorContactFactory
|
||||
{
|
||||
@ -21,6 +22,7 @@ class VendorContactFactory
|
||||
$vendor_contact->first_name = '';
|
||||
$vendor_contact->user_id = $user_id;
|
||||
$vendor_contact->company_id = $company_id;
|
||||
$vendor_contact->contact_key = Str::random(40);
|
||||
$vendor_contact->id = 0;
|
||||
|
||||
return $vendor_contact;
|
||||
|
@ -119,7 +119,6 @@ class InvitationController extends Controller
|
||||
return redirect()->route('client.login');
|
||||
|
||||
} else {
|
||||
nlog("else - default - login contact");
|
||||
request()->session()->invalidate();
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||
}
|
||||
@ -195,7 +194,7 @@ class InvitationController extends Controller
|
||||
|
||||
$file_name = $invitation->{$entity}->numberFormatter().'.pdf';
|
||||
|
||||
$file = CreateRawPdf::dispatchNow($invitation, $invitation->company->db);
|
||||
$file = (new CreateRawPdf($invitation, $invitation->company->db))->handle();
|
||||
|
||||
$headers = ['Content-Type' => 'application/pdf'];
|
||||
|
||||
|
@ -613,7 +613,6 @@ class PaymentController extends BaseController
|
||||
// code...
|
||||
break;
|
||||
case 'email':
|
||||
//dispatch email to queue
|
||||
$payment->service()->sendEmail();
|
||||
|
||||
if (! $bulk) {
|
||||
|
@ -73,7 +73,6 @@ class InvitationController extends Controller
|
||||
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
||||
|
||||
} else {
|
||||
nlog("else - default - login contact");
|
||||
request()->session()->invalidate();
|
||||
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\VendorPortal;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\ViewComposers\PortalComposer;
|
||||
use App\Models\RecurringInvoice;
|
||||
use Auth;
|
||||
|
||||
class VendorContactHashLoginController extends Controller
|
||||
{
|
||||
/**
|
||||
* Logs a user into the client portal using their contact_key
|
||||
* @param string $contact_key The contact key
|
||||
* @return Auth|Redirect
|
||||
*/
|
||||
public function login(string $contact_key)
|
||||
{
|
||||
return redirect('/vendors/purchase_orders');
|
||||
}
|
||||
|
||||
public function magicLink(string $magic_link)
|
||||
{
|
||||
return redirect($this->setRedirectPath());
|
||||
}
|
||||
|
||||
public function errorPage()
|
||||
{
|
||||
return render('generic.error', ['title' => session()->get('title'), 'notification' => session()->get('notification')]);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -42,6 +42,7 @@ use App\Http\Middleware\TrimStrings;
|
||||
use App\Http\Middleware\TrustProxies;
|
||||
use App\Http\Middleware\UrlSetDb;
|
||||
use App\Http\Middleware\UserVerified;
|
||||
use App\Http\Middleware\VendorContactKeyLogin;
|
||||
use App\Http\Middleware\VendorLocale;
|
||||
use App\Http\Middleware\VerifyCsrfToken;
|
||||
use App\Http\Middleware\VerifyHash;
|
||||
@ -166,6 +167,7 @@ class Kernel extends HttpKernel
|
||||
'shop_token_auth' => ShopTokenAuth::class,
|
||||
'phantom_secret' => PhantomSecret::class,
|
||||
'contact_key_login' => ContactKeyLogin::class,
|
||||
'vendor_contact_key_login' => VendorContactKeyLogin::class,
|
||||
'check_client_existence' => CheckClientExistence::class,
|
||||
'user_verified' => UserVerified::class,
|
||||
'document_db' => SetDocumentDb::class,
|
||||
|
@ -50,7 +50,6 @@ class SetDomainNameDb
|
||||
];
|
||||
|
||||
if ($company = MultiDB::findAndSetDbByDomain($query)) {
|
||||
//$request->merge(['company_key' => $company->company_key]);
|
||||
session()->put('company_key', $company->company_key);
|
||||
} else {
|
||||
if ($request->json) {
|
||||
@ -68,7 +67,6 @@ class SetDomainNameDb
|
||||
];
|
||||
|
||||
if ($company = MultiDB::findAndSetDbByDomain($query)) {
|
||||
//$request->merge(['company_key' => $company->company_key]);
|
||||
session()->put('company_key', $company->company_key);
|
||||
} else {
|
||||
if ($request->json) {
|
||||
|
155
app/Http/Middleware/VendorContactKeyLogin.php
Normal file
155
app/Http/Middleware/VendorContactKeyLogin.php
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Http\ViewComposers\PortalComposer;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\VendorContact;
|
||||
use Auth;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class VendorContactKeyLogin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* Sets a contact LOGGED IN if an appropriate vendor_hash is provided as a query parameter
|
||||
* OR
|
||||
* If the contact_key is provided in the route
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (Auth::guard('vendor')->check()) {
|
||||
Auth::guard('vendor')->logout();
|
||||
$request->session()->invalidate();
|
||||
}
|
||||
|
||||
if ($request->segment(2) && $request->segment(2) == 'magic_link' && $request->segment(3)) {
|
||||
$payload = Cache::get($request->segment(3));
|
||||
|
||||
if (! $payload) {
|
||||
abort(403, 'Link expired.');
|
||||
}
|
||||
|
||||
$contact_email = $payload['email'];
|
||||
|
||||
if ($vendor_contact = VendorContact::where('email', $contact_email)->where('company_id', $payload['company_id'])->first()) {
|
||||
if (empty($vendor_contact->email)) {
|
||||
$vendor_contact->email = Str::random(15).'@example.com';
|
||||
}
|
||||
$vendor_contact->save();
|
||||
|
||||
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
||||
|
||||
if ($request->query('redirect') && ! empty($request->query('redirect'))) {
|
||||
return redirect()->to($request->query('redirect'));
|
||||
}
|
||||
|
||||
return redirect($this->setRedirectPath());
|
||||
}
|
||||
} elseif ($request->segment(3) && config('ninja.db.multi_db_enabled')) {
|
||||
if (MultiDB::findAndSetDbByContactKey($request->segment(3))) {
|
||||
if ($vendor_contact = VendorContact::where('contact_key', $request->segment(3))->first()) {
|
||||
if (empty($vendor_contact->email)) {
|
||||
$vendor_contact->email = Str::random(6).'@example.com';
|
||||
}
|
||||
$vendor_contact->save();
|
||||
|
||||
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
||||
|
||||
if ($request->query('next')) {
|
||||
return redirect()->to($request->query('next'));
|
||||
}
|
||||
|
||||
return redirect($this->setRedirectPath());
|
||||
}
|
||||
}
|
||||
} elseif ($request->segment(2) && $request->segment(2) == 'key_login' && $request->segment(3)) {
|
||||
if ($vendor_contact = VendorContact::where('contact_key', $request->segment(3))->first()) {
|
||||
if (empty($vendor_contact->email)) {
|
||||
$vendor_contact->email = Str::random(6).'@example.com';
|
||||
$vendor_contact->save();
|
||||
}
|
||||
|
||||
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
||||
|
||||
if ($request->query('next')) {
|
||||
return redirect($request->query('next'));
|
||||
}
|
||||
|
||||
return redirect($this->setRedirectPath());
|
||||
}
|
||||
} elseif ($request->has('vendor_hash') && config('ninja.db.multi_db_enabled')) {
|
||||
if (MultiDB::findAndSetDbByClientHash($request->input('vendor_hash'))) {
|
||||
if ($client = Vendor::where('vendor_hash', $request->input('vendor_hash'))->first()) {
|
||||
$primary_contact = $client->primary_contact()->first();
|
||||
|
||||
if (empty($primary_contact->email)) {
|
||||
$primary_contact->email = Str::random(6).'@example.com';
|
||||
}
|
||||
$primary_contact->save();
|
||||
|
||||
auth()->guard('vendor')->loginUsingId($primary_contact->id, true);
|
||||
|
||||
return redirect($this->setRedirectPath());
|
||||
}
|
||||
}
|
||||
} elseif ($request->has('vendor_hash')) {
|
||||
if ($client = Vendor::where('vendor_hash', $request->input('vendor_hash'))->first()) {
|
||||
$primary_contact = $client->primary_contact()->first();
|
||||
|
||||
if (empty($primary_contact->email)) {
|
||||
$primary_contact->email = Str::random(6).'@example.com';
|
||||
}
|
||||
$primary_contact->save();
|
||||
|
||||
auth()->guard('vendor')->loginUsingId($primary_contact->id, true);
|
||||
|
||||
return redirect($this->setRedirectPath());
|
||||
}
|
||||
} elseif ($request->segment(3)) {
|
||||
if ($vendor_contact = VendorContact::where('contact_key', $request->segment(3))->first()) {
|
||||
if (empty($vendor_contact->email)) {
|
||||
$vendor_contact->email = Str::random(6).'@example.com';
|
||||
$vendor_contact->save();
|
||||
}
|
||||
|
||||
auth()->guard('vendor')->loginUsingId($vendor_contact->id, true);
|
||||
|
||||
if ($request->query('next')) {
|
||||
return redirect($request->query('next'));
|
||||
}
|
||||
|
||||
return redirect($this->setRedirectPath());
|
||||
}
|
||||
}
|
||||
//28-02-2022 middleware should not allow this to progress as we should have redirected by this stage.
|
||||
abort(404, 'Unable to authenticate.');
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
private function setRedirectPath()
|
||||
{
|
||||
|
||||
return 'vendor/purchase_orders';
|
||||
|
||||
}
|
||||
}
|
@ -97,10 +97,6 @@ class UpdateClientRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (isset($input['group_settings_id'])) {
|
||||
$input['group_settings_id'] = $this->decodePrimaryKey($input['group_settings_id']);
|
||||
}
|
||||
|
||||
/* If the user removes the currency we must always set the default */
|
||||
if (array_key_exists('settings', $input) && ! array_key_exists('currency_id', $input['settings'])) {
|
||||
$input['settings']['currency_id'] = (string) auth()->user()->company()->settings->currency_id;
|
||||
|
@ -23,7 +23,8 @@ class BlackListRule implements Rule
|
||||
'candassociates.com',
|
||||
'vusra.com',
|
||||
'fourthgenet.com',
|
||||
'arxxwalls.com'
|
||||
'arxxwalls.com',
|
||||
'superhostforumla.com'
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -51,6 +51,9 @@ class Backup extends BaseModel
|
||||
{
|
||||
nlog('deleting => '.$this->filename);
|
||||
|
||||
if(!$this->filename)
|
||||
return;
|
||||
|
||||
try {
|
||||
Storage::disk(config('filesystems.default'))->delete($this->filename);
|
||||
} catch (\Exception $e) {
|
||||
|
@ -154,4 +154,13 @@ class VendorContact extends Authenticatable implements HasLocalePreference
|
||||
{
|
||||
return $this->hasMany(PurchaseOrderInvitation::class);
|
||||
}
|
||||
|
||||
public function getLoginLink()
|
||||
{
|
||||
|
||||
$domain = isset($this->company->portal_domain) ? $this->company->portal_domain : $this->company->domain();
|
||||
|
||||
return $domain.'/vendor/key_login/'.$this->contact_key;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use App\Models\Payment;
|
||||
use App\Models\PaymentType;
|
||||
use App\Models\SystemLog;
|
||||
use App\PaymentDrivers\StripePaymentDriver;
|
||||
use App\PaymentDrivers\Stripe\Jobs\UpdateCustomer;
|
||||
use Stripe\PaymentIntent;
|
||||
use Stripe\PaymentMethod;
|
||||
|
||||
@ -129,6 +130,8 @@ class CreditCard
|
||||
|
||||
public function processSuccessfulPayment()
|
||||
{
|
||||
UpdateCustomer::dispatch($this->stripe->company_gateway->company->company_key, $this->stripe->company_gateway->id, $this->stripe->client->id);
|
||||
|
||||
$stripe_method = $this->stripe->getStripePaymentMethod($this->stripe->payment_hash->data->server_response->payment_method);
|
||||
|
||||
$data = [
|
||||
|
92
app/PaymentDrivers/Stripe/Jobs/UpdateCustomer.php
Normal file
92
app/PaymentDrivers/Stripe/Jobs/UpdateCustomer.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers\Stripe\Jobs;
|
||||
|
||||
use App\Jobs\Mail\PaymentFailedMailer;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\PaymentType;
|
||||
use App\Models\SystemLog;
|
||||
use App\PaymentDrivers\Stripe\Utilities;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class UpdateCustomer implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Utilities;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
public $deleteWhenMissingModels = true;
|
||||
|
||||
public int $company_gateway_id;
|
||||
|
||||
public string $company_key;
|
||||
|
||||
private int $client_id;
|
||||
|
||||
public function __construct(string $company_key, int $company_gateway_id, int $client_id)
|
||||
{
|
||||
$this->company_key = $company_key;
|
||||
$this->company_gateway_id = $company_gateway_id;
|
||||
$this->client_id = $client_id;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
|
||||
MultiDB::findAndSetDbByCompanyKey($this->company_key);
|
||||
|
||||
$company = Company::where('company_key', $this->company_key)->first();
|
||||
|
||||
if($company->id !== config('ninja.ninja_default_company_id'))
|
||||
return;
|
||||
|
||||
$company_gateway = CompanyGateway::find($this->company_gateway_id);
|
||||
$client = Client::withTrashed()->find($this->client_id);
|
||||
|
||||
$stripe = $company_gateway->driver($client)->init();
|
||||
|
||||
$customer = $stripe->findOrCreateCustomer();
|
||||
//Else create a new record
|
||||
$data['name'] = $client->present()->name();
|
||||
$data['phone'] = substr($client->present()->phone(), 0, 20);
|
||||
|
||||
$data['address']['line1'] = $client->address1;
|
||||
$data['address']['line2'] = $client->address2;
|
||||
$data['address']['city'] = $client->city;
|
||||
$data['address']['postal_code'] = $client->postal_code;
|
||||
$data['address']['state'] = $client->state;
|
||||
$data['address']['country'] = $client->country ? $client->country->iso_3166_2 : '';
|
||||
|
||||
$data['shipping']['name'] = $client->present()->name();
|
||||
$data['shipping']['address']['line1'] = $client->shipping_address1;
|
||||
$data['shipping']['address']['line2'] = $client->shipping_address2;
|
||||
$data['shipping']['address']['city'] = $client->shipping_city;
|
||||
$data['shipping']['address']['postal_code'] = $client->shipping_postal_code;
|
||||
$data['shipping']['address']['state'] = $client->shipping_state;
|
||||
$data['shipping']['address']['country'] = $client->shipping_country ? $client->shipping_country->iso_3166_2 : '';
|
||||
|
||||
\Stripe\Customer::update($customer->id, $data, $stripe->stripe_connect_auth);
|
||||
|
||||
}
|
||||
}
|
@ -34,10 +34,10 @@ class SendEmail
|
||||
{
|
||||
$this->payment->load('company', 'client.contacts');
|
||||
|
||||
$this->payment->client->contacts->each(function ($contact) {
|
||||
if ($contact->email) {
|
||||
EmailPayment::dispatch($this->payment, $this->payment->company, $contact);
|
||||
}
|
||||
});
|
||||
$contact = $this->payment->client->contacts()->first();
|
||||
|
||||
if ($contact->email)
|
||||
EmailPayment::dispatch($this->payment, $this->payment->company, $contact);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ class VendorContactTransformer extends EntityTransformer
|
||||
'custom_value2' => $vendor->custom_value2 ?: '',
|
||||
'custom_value3' => $vendor->custom_value3 ?: '',
|
||||
'custom_value4' => $vendor->custom_value4 ?: '',
|
||||
'link' => $vendor->getLoginLink(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,11 @@ use App\Http\Controllers\VendorPortal\InvitationController;
|
||||
use App\Http\Controllers\VendorPortal\PurchaseOrderController;
|
||||
use App\Http\Controllers\VendorPortal\UploadController;
|
||||
use App\Http\Controllers\VendorPortal\VendorContactController;
|
||||
use App\Http\Controllers\VendorPortal\VendorContactHashLoginController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('vendors', [VendorContactLoginController::class, 'catch'])->name('vendor.catchall')->middleware(['domain_db', 'contact_account','vendor_locale']); //catch all
|
||||
Route::get('vendor/key_login/{contact_key}', [VendorContactHashLoginController::class, 'login'])->name('contact_login')->middleware(['domain_db','vendor_contact_key_login']);
|
||||
|
||||
Route::group(['middleware' => ['invite_db'], 'prefix' => 'vendor', 'as' => 'vendor.'], function () {
|
||||
/*Invitation catches*/
|
||||
|
Loading…
Reference in New Issue
Block a user