mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-02 22:57:33 -05:00 
			
		
		
		
	
						commit
						281bb47684
					
				@ -4,6 +4,7 @@ APP_KEY=base64:RR++yx2rJ9kdxbdh3+AmbHLDQu+Q76i++co9Y8ybbno=
 | 
			
		||||
APP_DEBUG=false
 | 
			
		||||
 | 
			
		||||
APP_URL=http://localhost
 | 
			
		||||
REACT_URL=http://localhost:3001
 | 
			
		||||
 | 
			
		||||
DB_CONNECTION=mysql
 | 
			
		||||
MULTI_DB_ENABLED=false
 | 
			
		||||
@ -33,8 +34,8 @@ MAIL_PORT=2525
 | 
			
		||||
MAIL_USERNAME=null
 | 
			
		||||
MAIL_PASSWORD=null
 | 
			
		||||
MAIL_ENCRYPTION=null
 | 
			
		||||
MAIL_FROM_ADDRESS='user@example.com'
 | 
			
		||||
MAIL_FROM_NAME='Self Hosted User'
 | 
			
		||||
MAIL_FROM_ADDRESS="user@example.com"
 | 
			
		||||
MAIL_FROM_NAME="Self Hosted User"
 | 
			
		||||
 | 
			
		||||
POSTMARK_API_TOKEN=
 | 
			
		||||
REQUIRE_HTTPS=false
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
5.6.13
 | 
			
		||||
5.6.14
 | 
			
		||||
@ -64,8 +64,6 @@ class ImportMigrations extends Command
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        $this->faker = Factory::create();
 | 
			
		||||
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -76,6 +74,8 @@ class ImportMigrations extends Command
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        $this->faker = Factory::create();
 | 
			
		||||
 | 
			
		||||
        $this->buildCache();
 | 
			
		||||
 | 
			
		||||
        $path = $this->option('path') ?? public_path('storage/migrations/import');
 | 
			
		||||
 | 
			
		||||
@ -93,17 +93,6 @@ class MobileLocalization extends Command
 | 
			
		||||
                $text = str_replace(['<i>', '</i>'], '', $text);
 | 
			
		||||
                $text = str_replace(['<strong>', '</strong>'], '', $text);
 | 
			
		||||
 | 
			
		||||
//replace the three lines above with this
 | 
			
		||||
// if($language->locale == 'ar') {
 | 
			
		||||
//     $text = str_replace('\n', " ", $text);
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// $text = str_replace(['<strong>', '</strong>','<i>', '</i>','<b>', '</b>'], '', $text);
 | 
			
		||||
// $text = str_replace('"', "'", $text);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                echo "'$key': '$text',\n";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,10 +11,12 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Requests\Export\StoreExportRequest;
 | 
			
		||||
use App\Jobs\Company\CompanyExport;
 | 
			
		||||
use App\Utils\Traits\MakesHash;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
use Illuminate\Http\Response;
 | 
			
		||||
use App\Utils\Traits\MakesHash;
 | 
			
		||||
use App\Jobs\Company\CompanyExport;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
use App\Http\Requests\Export\StoreExportRequest;
 | 
			
		||||
 | 
			
		||||
class ExportController extends BaseController
 | 
			
		||||
{
 | 
			
		||||
@ -54,8 +56,12 @@ class ExportController extends BaseController
 | 
			
		||||
     */
 | 
			
		||||
    public function index(StoreExportRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        CompanyExport::dispatch(auth()->user()->getCompany(), auth()->user());
 | 
			
		||||
        $hash = Str::uuid();
 | 
			
		||||
        $url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]);
 | 
			
		||||
        Cache::put($hash, $url, now()->addHour());
 | 
			
		||||
 | 
			
		||||
        return response()->json(['message' => 'Processing'], 200);
 | 
			
		||||
        CompanyExport::dispatch(auth()->user()->getCompany(), auth()->user(), $hash);
 | 
			
		||||
 | 
			
		||||
        return response()->json(['message' => 'Processing', 'url' => $url], 200);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								app/Http/Controllers/ProtectedDownloadController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/Http/Controllers/ProtectedDownloadController.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use App\Jobs\Util\UnlinkFile;
 | 
			
		||||
use App\Exceptions\SystemError;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
use Illuminate\Support\Facades\Storage;
 | 
			
		||||
 | 
			
		||||
class ProtectedDownloadController extends BaseController
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    public function index(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        $hashed_path = Cache::pull($request->hash);
 | 
			
		||||
        
 | 
			
		||||
        if (!$hashed_path) {
 | 
			
		||||
            throw new SystemError('File no longer available', 404);
 | 
			
		||||
            abort(404, 'File no longer available');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        UnlinkFile::dispatch(config('filesystems.default'), $hashed_path)->delay(now()->addSeconds(10));
 | 
			
		||||
 | 
			
		||||
        return response()->streamDownload(function () use ($hashed_path) {
 | 
			
		||||
            echo Storage::get($hashed_path);
 | 
			
		||||
        }, basename($hashed_path), []);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -83,4 +83,5 @@ class PaymentReportController extends BaseController
 | 
			
		||||
            echo $csv;
 | 
			
		||||
        }, $this->filename, $headers);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,7 @@ use App\Http\Middleware\VerifyCsrfToken;
 | 
			
		||||
use App\Http\Middleware\ContactTokenAuth;
 | 
			
		||||
use Illuminate\Auth\Middleware\Authorize;
 | 
			
		||||
use App\Http\Middleware\SetDbByCompanyKey;
 | 
			
		||||
use App\Http\Middleware\ValidateSignature;
 | 
			
		||||
use App\Http\Middleware\PasswordProtection;
 | 
			
		||||
use App\Http\Middleware\ClientPortalEnabled;
 | 
			
		||||
use App\Http\Middleware\CheckClientExistence;
 | 
			
		||||
@ -49,16 +50,13 @@ use Illuminate\Http\Middleware\SetCacheHeaders;
 | 
			
		||||
use Illuminate\Session\Middleware\StartSession;
 | 
			
		||||
use App\Http\Middleware\CheckForMaintenanceMode;
 | 
			
		||||
use App\Http\Middleware\RedirectIfAuthenticated;
 | 
			
		||||
use Illuminate\Routing\Middleware\ThrottleRequests;
 | 
			
		||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
 | 
			
		||||
use Illuminate\Routing\Middleware\ValidateSignature;
 | 
			
		||||
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
 | 
			
		||||
use Illuminate\Routing\Middleware\SubstituteBindings;
 | 
			
		||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
 | 
			
		||||
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
 | 
			
		||||
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
 | 
			
		||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
 | 
			
		||||
use Illuminate\Routing\Middleware\ThrottleRequestsWithRedis;
 | 
			
		||||
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
 | 
			
		||||
 | 
			
		||||
class Kernel extends HttpKernel
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										49
									
								
								app/Http/Middleware/ValidateSignature.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/Http/Middleware/ValidateSignature.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Http\Middleware;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
use Closure;
 | 
			
		||||
use Illuminate\Routing\Exceptions\InvalidSignatureException;
 | 
			
		||||
 | 
			
		||||
class ValidateSignature
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The names of the parameters that should be ignored.
 | 
			
		||||
     *
 | 
			
		||||
     * @var array<int, string>
 | 
			
		||||
     */
 | 
			
		||||
    protected $ignore = [
 | 
			
		||||
        'q'
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle an incoming request.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  \Illuminate\Http\Request  $request
 | 
			
		||||
     * @param  \Closure  $next
 | 
			
		||||
     * @param  string|null  $relative
 | 
			
		||||
     * @return \Illuminate\Http\Response
 | 
			
		||||
     *
 | 
			
		||||
     * @throws \Illuminate\Routing\Exceptions\InvalidSignatureException
 | 
			
		||||
     */
 | 
			
		||||
    public function handle($request, Closure $next, $relative = null)
 | 
			
		||||
    {
 | 
			
		||||
        $ignore = property_exists($this, 'except') ? $this->except : $this->ignore;
 | 
			
		||||
 | 
			
		||||
        if ($request->hasValidSignatureWhileIgnoring($ignore, $relative !== 'relative')) {
 | 
			
		||||
            return $next($request);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new InvalidSignatureException;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -11,39 +11,39 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Jobs\Company;
 | 
			
		||||
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerJob;
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerObject;
 | 
			
		||||
use App\Libraries\MultiDB;
 | 
			
		||||
use App\Mail\DownloadBackup;
 | 
			
		||||
use App\Models\Company;
 | 
			
		||||
use App\Models\CreditInvitation;
 | 
			
		||||
use App\Models\InvoiceInvitation;
 | 
			
		||||
use App\Models\PurchaseOrderInvitation;
 | 
			
		||||
use App\Models\QuoteInvitation;
 | 
			
		||||
use App\Models\RecurringInvoiceInvitation;
 | 
			
		||||
use App\Models\User;
 | 
			
		||||
use App\Models\VendorContact;
 | 
			
		||||
use App\Utils\Ninja;
 | 
			
		||||
use App\Utils\Traits\MakesHash;
 | 
			
		||||
use App\Models\Company;
 | 
			
		||||
use App\Libraries\MultiDB;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
use App\Mail\DownloadBackup;
 | 
			
		||||
use App\Jobs\Util\UnlinkFile;
 | 
			
		||||
use App\Models\VendorContact;
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use App\Models\QuoteInvitation;
 | 
			
		||||
use App\Utils\Traits\MakesHash;
 | 
			
		||||
use App\Models\CreditInvitation;
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerJob;
 | 
			
		||||
use App\Models\InvoiceInvitation;
 | 
			
		||||
use Illuminate\Support\Facades\App;
 | 
			
		||||
use App\Jobs\Mail\NinjaMailerObject;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
use App\Models\PurchaseOrderInvitation;
 | 
			
		||||
use Illuminate\Support\Facades\Storage;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use App\Models\RecurringInvoiceInvitation;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
use Illuminate\Support\Facades\App;
 | 
			
		||||
use Illuminate\Support\Facades\Storage;
 | 
			
		||||
 | 
			
		||||
class CompanyExport implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesHash;
 | 
			
		||||
 | 
			
		||||
    public $company;
 | 
			
		||||
 | 
			
		||||
    private $export_format;
 | 
			
		||||
    private $export_format = 'json';
 | 
			
		||||
 | 
			
		||||
    private $export_data = [];
 | 
			
		||||
 | 
			
		||||
    public $user;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new job instance.
 | 
			
		||||
@ -52,11 +52,8 @@ class CompanyExport implements ShouldQueue
 | 
			
		||||
     * @param User $user
 | 
			
		||||
     * @param string $custom_token_name
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Company $company, User $user, $export_format = 'json')
 | 
			
		||||
    public function __construct(public Company $company, private User $user, public string $hash)
 | 
			
		||||
    {
 | 
			
		||||
        $this->company = $company;
 | 
			
		||||
        $this->user = $user;
 | 
			
		||||
        $this->export_format = $export_format;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -467,6 +464,10 @@ class CompanyExport implements ShouldQueue
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $storage_file_path = Storage::disk(config('filesystems.default'))->url('backups/'.$file_name);
 | 
			
		||||
        $storage_path = Storage::disk(config('filesystems.default'))->path('backups/'.$file_name);
 | 
			
		||||
 | 
			
		||||
        $url = Cache::get($this->hash);
 | 
			
		||||
        Cache::put($this->hash, $storage_path, now()->addHour());
 | 
			
		||||
 | 
			
		||||
        App::forgetInstance('translator');
 | 
			
		||||
        $t = app('translator');
 | 
			
		||||
@ -475,13 +476,15 @@ class CompanyExport implements ShouldQueue
 | 
			
		||||
        $company_reference = Company::find($this->company->id);
 | 
			
		||||
 | 
			
		||||
        $nmo = new NinjaMailerObject;
 | 
			
		||||
        $nmo->mailable = new DownloadBackup($storage_file_path, $company_reference);
 | 
			
		||||
        $nmo->mailable = new DownloadBackup($url, $company_reference);
 | 
			
		||||
        $nmo->to_user = $this->user;
 | 
			
		||||
        $nmo->company = $company_reference;
 | 
			
		||||
        $nmo->settings = $this->company->settings;
 | 
			
		||||
        
 | 
			
		||||
        NinjaMailerJob::dispatch($nmo, true);
 | 
			
		||||
        
 | 
			
		||||
        UnlinkFile::dispatch(config('filesystems.default'), $storage_path)->delay(now()->addHours(1));
 | 
			
		||||
 | 
			
		||||
        if (Ninja::isHosted()) {
 | 
			
		||||
            sleep(3);
 | 
			
		||||
            unlink($zip_path);
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
 | 
			
		||||
 | 
			
		||||
class SendToAdmin implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
@ -59,4 +60,9 @@ class SendToAdmin implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        NinjaMailerJob::dispatch($nmo);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function middleware()
 | 
			
		||||
    {
 | 
			
		||||
        return [new WithoutOverlapping("report-{$this->company->company_key}")];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@
 | 
			
		||||
 | 
			
		||||
namespace App\PaymentDrivers\Square;
 | 
			
		||||
 | 
			
		||||
use App\Exceptions\PaymentFailed;
 | 
			
		||||
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
 | 
			
		||||
use App\Models\ClientGatewayToken;
 | 
			
		||||
use App\Models\GatewayType;
 | 
			
		||||
@ -113,18 +114,23 @@ class CreditCard implements MethodInterface
 | 
			
		||||
        $body->setLocationId($this->square_driver->company_gateway->getConfigField('locationId'));
 | 
			
		||||
        $body->setReferenceId(Str::random(16));
 | 
			
		||||
 | 
			
		||||
        if ($request->has('verificationToken') && $request->input('verificationToken')) {
 | 
			
		||||
            $body->setVerificationToken($request->input('verificationToken'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($request->shouldUseToken()) {
 | 
			
		||||
            $body->setCustomerId($cgt->gateway_customer_reference);
 | 
			
		||||
        }elseif ($request->has('verificationToken') && $request->input('verificationToken')) {
 | 
			
		||||
            $body->setVerificationToken($request->input('verificationToken'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /** @var ApiResponse */
 | 
			
		||||
        $response = $this->square_driver->square->getPaymentsApi()->createPayment($body);
 | 
			
		||||
 | 
			
		||||
        if ($response->isSuccess()) {
 | 
			
		||||
 | 
			
		||||
            $body = json_decode($response->getBody());
 | 
			
		||||
 | 
			
		||||
            if($request->store_card){
 | 
			
		||||
                $this->createCard($body->payment->id);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $this->processSuccessfulPayment($response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -161,6 +167,52 @@ class CreditCard implements MethodInterface
 | 
			
		||||
        return $this->square_driver->processUnsuccessfulTransaction($data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function createCard($source_id)
 | 
			
		||||
    {
 | 
			
		||||
        
 | 
			
		||||
        $square_card = new \Square\Models\Card();
 | 
			
		||||
        $square_card->setCustomerId($this->findOrCreateClient());
 | 
			
		||||
 | 
			
		||||
        $body = new \Square\Models\CreateCardRequest(uniqid("st", true), $source_id, $square_card);
 | 
			
		||||
        
 | 
			
		||||
        $api_response = $this->square_driver
 | 
			
		||||
                             ->init()
 | 
			
		||||
                             ->square
 | 
			
		||||
                             ->getCardsApi()
 | 
			
		||||
                             ->createCard($body);
 | 
			
		||||
 | 
			
		||||
        $body = json_decode($api_response->getBody());
 | 
			
		||||
 | 
			
		||||
        if ($api_response->isSuccess()) {
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                $payment_meta = new \stdClass;
 | 
			
		||||
                $payment_meta->exp_month = (string) $body->card->exp_month;
 | 
			
		||||
                $payment_meta->exp_year = (string) $body->card->exp_year;
 | 
			
		||||
                $payment_meta->brand = (string) $body->card->card_brand;
 | 
			
		||||
                $payment_meta->last4 = (string) $body->card->last_4;
 | 
			
		||||
                $payment_meta->type = GatewayType::CREDIT_CARD;
 | 
			
		||||
 | 
			
		||||
                $data = [
 | 
			
		||||
                    'payment_meta' => $payment_meta,
 | 
			
		||||
                    'token' => $body->card->id,
 | 
			
		||||
                    'payment_method_id' => GatewayType::CREDIT_CARD,
 | 
			
		||||
                ];
 | 
			
		||||
 | 
			
		||||
                $this->square_driver->storeGatewayToken($data, ['gateway_customer_reference' => $body->card->customer_id]);
 | 
			
		||||
 | 
			
		||||
            } catch (\Exception $e) {
 | 
			
		||||
                return $this->square_driver->processInternallyFailedPayment($this->square_driver, $e);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            throw new PaymentFailed($body->errors[0]->detail, 500);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function findOrCreateClient()
 | 
			
		||||
    {
 | 
			
		||||
        $email_address = new \Square\Models\CustomerTextFilter();
 | 
			
		||||
 | 
			
		||||
@ -113,13 +113,6 @@ class AppServiceProvider extends ServiceProvider
 | 
			
		||||
            return $this;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        /* Extension for custom mailers */
 | 
			
		||||
 | 
			
		||||
        /* Convenience helper for testing s*/
 | 
			
		||||
        ParallelTesting::setUpTestDatabase(function ($database, $token) {
 | 
			
		||||
            Artisan::call('db:seed');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function register(): void
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ class ClientPortalServiceProvider extends ServiceProvider
 | 
			
		||||
       app()->bind('customMessage', function () {
 | 
			
		||||
            return new CustomMessage();
 | 
			
		||||
        });
 | 
			
		||||
 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -26,6 +27,6 @@ class ClientPortalServiceProvider extends ServiceProvider
 | 
			
		||||
     */
 | 
			
		||||
    public function boot()
 | 
			
		||||
    {
 | 
			
		||||
        //
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,277 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Providers;
 | 
			
		||||
 | 
			
		||||
use App\Libraries\MultiDB;
 | 
			
		||||
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
 | 
			
		||||
use Illuminate\Contracts\Auth\UserProvider;
 | 
			
		||||
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
 | 
			
		||||
use Illuminate\Contracts\Support\Arrayable;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
use Illuminate\Support\Str;
 | 
			
		||||
 | 
			
		||||
class MultiDatabaseUserProvider implements UserProvider
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The hasher implementation.
 | 
			
		||||
     *
 | 
			
		||||
     * @var HasherContract
 | 
			
		||||
     */
 | 
			
		||||
    protected $hasher;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The Eloquent user model.
 | 
			
		||||
     *
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $model;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new database user provider.
 | 
			
		||||
     *
 | 
			
		||||
     * @param HasherContract $hasher
 | 
			
		||||
     * @param  string  $model
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(HasherContract $hasher, $model)
 | 
			
		||||
    {
 | 
			
		||||
        $this->model = $model;
 | 
			
		||||
        $this->hasher = $hasher;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieve a user by their unique identifier.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  mixed  $identifier
 | 
			
		||||
     * @return UserContract|null
 | 
			
		||||
     */
 | 
			
		||||
    public function retrieveById($identifier)
 | 
			
		||||
    {
 | 
			
		||||
        $this->setDefaultDatabase($identifier);
 | 
			
		||||
 | 
			
		||||
        $model = $this->createModel();
 | 
			
		||||
 | 
			
		||||
        return $model->newQuery()
 | 
			
		||||
            ->where($model->getAuthIdentifierName(), $identifier)
 | 
			
		||||
            ->first();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieve a user by their unique identifier and "remember me" token.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  mixed  $identifier
 | 
			
		||||
     * @param  string  $token
 | 
			
		||||
     * @return UserContract|null
 | 
			
		||||
     */
 | 
			
		||||
    public function retrieveByToken($identifier, $token)
 | 
			
		||||
    {
 | 
			
		||||
        $this->setDefaultDatabase($identifier, $token);
 | 
			
		||||
 | 
			
		||||
        $model = $this->createModel();
 | 
			
		||||
 | 
			
		||||
        $model = $model->where($model->getAuthIdentifierName(), $identifier)->first();
 | 
			
		||||
 | 
			
		||||
        if (! $model) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $rememberToken = $model->getRememberToken();
 | 
			
		||||
 | 
			
		||||
        return $rememberToken && hash_equals($rememberToken, $token) ? $model : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the "remember me" token for the given user in storage.
 | 
			
		||||
     *
 | 
			
		||||
     * @param UserContract|Model  $user
 | 
			
		||||
     * @param  string  $token
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function updateRememberToken(UserContract $user, $token)
 | 
			
		||||
    {
 | 
			
		||||
        $user->setRememberToken($token);
 | 
			
		||||
 | 
			
		||||
        $timestamps = $user->timestamps;
 | 
			
		||||
 | 
			
		||||
        $user->timestamps = false;
 | 
			
		||||
 | 
			
		||||
        $user->save();
 | 
			
		||||
 | 
			
		||||
        $user->timestamps = $timestamps;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieve a user by the given credentials.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  array  $credentials
 | 
			
		||||
     * @return UserContract|null
 | 
			
		||||
     */
 | 
			
		||||
    public function retrieveByCredentials(array $credentials)
 | 
			
		||||
    {
 | 
			
		||||
        if (empty($credentials) ||
 | 
			
		||||
           (count($credentials) === 1 &&
 | 
			
		||||
            array_key_exists('password', $credentials))) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->setDefaultDatabase(false, $credentials['email'], false);
 | 
			
		||||
 | 
			
		||||
        // First we will add each credential element to the query as a where clause.
 | 
			
		||||
        // Then we can execute the query and, if we found a user, return it in a
 | 
			
		||||
        // Eloquent User "model" that will be utilized by the Guard instances.
 | 
			
		||||
        $query = $this->createModel()->newQuery();
 | 
			
		||||
 | 
			
		||||
        foreach ($credentials as $key => $value) {
 | 
			
		||||
            if (Str::contains($key, 'password')) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (is_array($value) || $value instanceof Arrayable) {
 | 
			
		||||
                $query->whereIn($key, $value);
 | 
			
		||||
            } else {
 | 
			
		||||
                $query->where($key, $value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $query->first();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Validate a user against the given credentials.
 | 
			
		||||
     *
 | 
			
		||||
     * @param UserContract $user
 | 
			
		||||
     * @param  array  $credentials
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function validateCredentials(UserContract $user, array $credentials)
 | 
			
		||||
    {
 | 
			
		||||
        $plain = $credentials['password'];
 | 
			
		||||
 | 
			
		||||
        return $this->hasher->check($plain, $user->getAuthPassword());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new instance of the model.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Model
 | 
			
		||||
     */
 | 
			
		||||
    public function createModel()
 | 
			
		||||
    {
 | 
			
		||||
        $class = '\\'.ltrim($this->model, '\\');
 | 
			
		||||
 | 
			
		||||
        return new $class;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the hasher implementation.
 | 
			
		||||
     *
 | 
			
		||||
     * @return HasherContract
 | 
			
		||||
     */
 | 
			
		||||
    public function getHasher()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->hasher;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the hasher implementation.
 | 
			
		||||
     *
 | 
			
		||||
     * @param HasherContract $hasher
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setHasher(HasherContract $hasher)
 | 
			
		||||
    {
 | 
			
		||||
        $this->hasher = $hasher;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the name of the Eloquent user model.
 | 
			
		||||
     *
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getModel()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->model;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the name of the Eloquent user model.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  string  $model
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setModel($model)
 | 
			
		||||
    {
 | 
			
		||||
        $this->model = $model;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets correct database by variable.
 | 
			
		||||
     * @param bool $id
 | 
			
		||||
     * @param bool $email
 | 
			
		||||
     * @param bool $token
 | 
			
		||||
     */
 | 
			
		||||
    private function setDefaultDatabase($id = false, $email = false, $token = false) : void
 | 
			
		||||
    {
 | 
			
		||||
        foreach (MultiDB::getDbs() as $database) {
 | 
			
		||||
            $this->setDB($database);
 | 
			
		||||
 | 
			
		||||
            /** Make sure we hook into the correct guard class */
 | 
			
		||||
            $query = $this->conn->table((new $this->model)->getTable());
 | 
			
		||||
 | 
			
		||||
            if ($id) {
 | 
			
		||||
                $query->where('id', '=', $id);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($email) {
 | 
			
		||||
                $query->where('email', '=', $email);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $user = $query->get();
 | 
			
		||||
 | 
			
		||||
            if (count($user) >= 1) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $query = $this->conn->table('company_tokens');
 | 
			
		||||
 | 
			
		||||
            if ($token) {
 | 
			
		||||
                $query->whereRaw('BINARY `token`= ?', $token);
 | 
			
		||||
 | 
			
		||||
                $token = $query->get();
 | 
			
		||||
 | 
			
		||||
                if (count($token) >= 1) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the database at runtime.
 | 
			
		||||
     * @param $database
 | 
			
		||||
     */
 | 
			
		||||
    private function setDB($database)
 | 
			
		||||
    {
 | 
			
		||||
        /** Get the database name we want to switch to*/
 | 
			
		||||
        $db_name = config('database.connections.'.$database.'.database');
 | 
			
		||||
 | 
			
		||||
        /* This will set the default configuration for the request / session?*/
 | 
			
		||||
        config(['database.default' => $database]);
 | 
			
		||||
 | 
			
		||||
        /* Set the connection to complete the user authentication */
 | 
			
		||||
        $this->conn = app('db')->connection(config('database.connections.database.'.$database));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -20,7 +20,6 @@ use Illuminate\Cache\RateLimiting\Limit;
 | 
			
		||||
use Illuminate\Support\Facades\RateLimiter;
 | 
			
		||||
use App\Http\Middleware\ThrottleRequestsWithPredis;
 | 
			
		||||
use Illuminate\Routing\Middleware\ThrottleRequests;
 | 
			
		||||
use Illuminate\Routing\Middleware\ThrottleRequestsWithRedis;
 | 
			
		||||
use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException;
 | 
			
		||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -101,7 +101,6 @@
 | 
			
		||||
        "php": "^8.1",
 | 
			
		||||
        "barryvdh/laravel-debugbar": "^3.6",
 | 
			
		||||
        "barryvdh/laravel-ide-helper": "^2.13",
 | 
			
		||||
        "beyondcode/laravel-query-detector": "^1.6",
 | 
			
		||||
        "brianium/paratest": "^6.1",
 | 
			
		||||
        "fakerphp/faker": "^1.14",
 | 
			
		||||
        "filp/whoops": "^2.7",
 | 
			
		||||
@ -136,7 +135,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "extra": {
 | 
			
		||||
        "laravel": {
 | 
			
		||||
            "dont-discover": ["invoiceninja/inspector"]
 | 
			
		||||
            "dont-discover": []
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										84
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										84
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							@ -4,7 +4,7 @@
 | 
			
		||||
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
			
		||||
        "This file is @generated automatically"
 | 
			
		||||
    ],
 | 
			
		||||
    "content-hash": "5119232ad274b24801da947fcbd4f884",
 | 
			
		||||
    "content-hash": "135eec9ab7a1e8c0ab3820ff27cf1488",
 | 
			
		||||
    "packages": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "adrienrn/php-mimetyper",
 | 
			
		||||
@ -14410,16 +14410,16 @@
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "barryvdh/reflection-docblock",
 | 
			
		||||
            "version": "v2.1.0",
 | 
			
		||||
            "version": "v2.1.1",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/barryvdh/ReflectionDocBlock.git",
 | 
			
		||||
                "reference": "bf44b757feb8ba1734659029357646466ded673e"
 | 
			
		||||
                "reference": "e6811e927f0ecc37cc4deaa6627033150343e597"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/bf44b757feb8ba1734659029357646466ded673e",
 | 
			
		||||
                "reference": "bf44b757feb8ba1734659029357646466ded673e",
 | 
			
		||||
                "url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/e6811e927f0ecc37cc4deaa6627033150343e597",
 | 
			
		||||
                "reference": "e6811e927f0ecc37cc4deaa6627033150343e597",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
@ -14456,69 +14456,9 @@
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "support": {
 | 
			
		||||
                "source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.1.0"
 | 
			
		||||
                "source": "https://github.com/barryvdh/ReflectionDocBlock/tree/v2.1.1"
 | 
			
		||||
            },
 | 
			
		||||
            "time": "2022-10-31T15:35:43+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "beyondcode/laravel-query-detector",
 | 
			
		||||
            "version": "1.7.0",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/beyondcode/laravel-query-detector.git",
 | 
			
		||||
                "reference": "40c7e168fcf7eeb80d8e96f7922e05ab194269c8"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/beyondcode/laravel-query-detector/zipball/40c7e168fcf7eeb80d8e96f7922e05ab194269c8",
 | 
			
		||||
                "reference": "40c7e168fcf7eeb80d8e96f7922e05ab194269c8",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0|^10.0",
 | 
			
		||||
                "php": "^7.1 || ^8.0"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "laravel/legacy-factories": "^1.0",
 | 
			
		||||
                "orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0|^8.0",
 | 
			
		||||
                "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "extra": {
 | 
			
		||||
                "laravel": {
 | 
			
		||||
                    "providers": [
 | 
			
		||||
                        "BeyondCode\\QueryDetector\\QueryDetectorServiceProvider"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "BeyondCode\\QueryDetector\\": "src"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "MIT"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Marcel Pociot",
 | 
			
		||||
                    "email": "marcel@beyondco.de",
 | 
			
		||||
                    "homepage": "https://beyondcode.de",
 | 
			
		||||
                    "role": "Developer"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Laravel N+1 Query Detector",
 | 
			
		||||
            "homepage": "https://github.com/beyondcode/laravel-query-detector",
 | 
			
		||||
            "keywords": [
 | 
			
		||||
                "beyondcode",
 | 
			
		||||
                "laravel-query-detector"
 | 
			
		||||
            ],
 | 
			
		||||
            "support": {
 | 
			
		||||
                "issues": "https://github.com/beyondcode/laravel-query-detector/issues",
 | 
			
		||||
                "source": "https://github.com/beyondcode/laravel-query-detector/tree/1.7.0"
 | 
			
		||||
            },
 | 
			
		||||
            "time": "2023-02-15T10:37:22+00:00"
 | 
			
		||||
            "time": "2023-06-14T05:06:27+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "brianium/paratest",
 | 
			
		||||
@ -16339,16 +16279,16 @@
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "phpstan/phpstan",
 | 
			
		||||
            "version": "1.10.24",
 | 
			
		||||
            "version": "1.10.25",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/phpstan/phpstan.git",
 | 
			
		||||
                "reference": "360ecc90569e9a60c2954ee209ec04fa0d958e14"
 | 
			
		||||
                "reference": "578f4e70d117f9a90699324c555922800ac38d8c"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/360ecc90569e9a60c2954ee209ec04fa0d958e14",
 | 
			
		||||
                "reference": "360ecc90569e9a60c2954ee209ec04fa0d958e14",
 | 
			
		||||
                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/578f4e70d117f9a90699324c555922800ac38d8c",
 | 
			
		||||
                "reference": "578f4e70d117f9a90699324c555922800ac38d8c",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
@ -16397,7 +16337,7 @@
 | 
			
		||||
                    "type": "tidelift"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2023-07-05T12:32:13+00:00"
 | 
			
		||||
            "time": "2023-07-06T12:11:37+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "phpunit/php-code-coverage",
 | 
			
		||||
 | 
			
		||||
@ -15,8 +15,8 @@ return [
 | 
			
		||||
    'require_https' => env('REQUIRE_HTTPS', true),
 | 
			
		||||
    'app_url' => rtrim(env('APP_URL', ''), '/'),
 | 
			
		||||
    'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
 | 
			
		||||
    'app_version' => '5.6.13',
 | 
			
		||||
    'app_tag' => '5.6.13',
 | 
			
		||||
    'app_version' => '5.6.14',
 | 
			
		||||
    'app_tag' => '5.6.14',
 | 
			
		||||
    'minimum_client_version' => '5.0.16',
 | 
			
		||||
    'terms_version' => '1.0.1',
 | 
			
		||||
    'api_secret' => env('API_SECRET', ''),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										71
									
								
								public/js/clients/payments/square-credit-card.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								public/js/clients/payments/square-credit-card.js
									
									
									
									
										vendored
									
									
								
							@ -176,18 +176,15 @@ var SquareCreditCard = /*#__PURE__*/function () {
 | 
			
		||||
  }, {
 | 
			
		||||
    key: "handle",
 | 
			
		||||
    value: function () {
 | 
			
		||||
      var _handle = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
 | 
			
		||||
        var _document$getElementB,
 | 
			
		||||
          _this = this,
 | 
			
		||||
          _document$getElementB2,
 | 
			
		||||
          _document$getElementB3;
 | 
			
		||||
        var toggleWithToken, _document$getElementB4;
 | 
			
		||||
        return _regeneratorRuntime().wrap(function _callee6$(_context6) {
 | 
			
		||||
          while (1) switch (_context6.prev = _context6.next) {
 | 
			
		||||
      var _handle = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
 | 
			
		||||
        var _this = this;
 | 
			
		||||
        return _regeneratorRuntime().wrap(function _callee7$(_context7) {
 | 
			
		||||
          while (1) switch (_context7.prev = _context7.next) {
 | 
			
		||||
            case 0:
 | 
			
		||||
              _context6.next = 2;
 | 
			
		||||
              return this.init();
 | 
			
		||||
            case 2:
 | 
			
		||||
              document.getElementById('payment-list').classList.add('hidden');
 | 
			
		||||
              _context7.next = 3;
 | 
			
		||||
              return this.init().then(function () {
 | 
			
		||||
                var _document$getElementB, _document$getElementB2, _document$getElementB3, _document$getElementB4;
 | 
			
		||||
                (_document$getElementB = document.getElementById('authorize-card')) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.addEventListener('click', function (e) {
 | 
			
		||||
                  return _this.completePaymentWithoutToken(e);
 | 
			
		||||
                });
 | 
			
		||||
@ -199,20 +196,14 @@ var SquareCreditCard = /*#__PURE__*/function () {
 | 
			
		||||
                  return _this.completePaymentWithoutToken(e);
 | 
			
		||||
                });
 | 
			
		||||
                Array.from(document.getElementsByClassName('toggle-payment-with-token')).forEach(function (element) {
 | 
			
		||||
                return element.addEventListener('click', function (element) {
 | 
			
		||||
                  document.getElementById('card-container').classList.add('hidden');
 | 
			
		||||
                  document.getElementById('save-card--container').style.display = 'none';
 | 
			
		||||
                  document.querySelector('input[name=token]').value = element.target.dataset.token;
 | 
			
		||||
                });
 | 
			
		||||
              });
 | 
			
		||||
              (_document$getElementB3 = document.getElementById('toggle-payment-with-credit-card')) === null || _document$getElementB3 === void 0 ? void 0 : _document$getElementB3.addEventListener('click', /*#__PURE__*/function () {
 | 
			
		||||
                  return element.addEventListener('click', /*#__PURE__*/function () {
 | 
			
		||||
                    var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(element) {
 | 
			
		||||
                      return _regeneratorRuntime().wrap(function _callee5$(_context5) {
 | 
			
		||||
                        while (1) switch (_context5.prev = _context5.next) {
 | 
			
		||||
                          case 0:
 | 
			
		||||
                        document.getElementById('card-container').classList.remove('hidden');
 | 
			
		||||
                        document.getElementById('save-card--container').style.display = 'grid';
 | 
			
		||||
                        document.querySelector('input[name=token]').value = '';
 | 
			
		||||
                            document.getElementById('card-container').classList.add('hidden');
 | 
			
		||||
                            document.getElementById('save-card--container').style.display = 'none';
 | 
			
		||||
                            document.querySelector('input[name=token]').value = element.target.dataset.token;
 | 
			
		||||
                          case 3:
 | 
			
		||||
                          case "end":
 | 
			
		||||
                            return _context5.stop();
 | 
			
		||||
@ -223,15 +214,41 @@ var SquareCreditCard = /*#__PURE__*/function () {
 | 
			
		||||
                      return _ref.apply(this, arguments);
 | 
			
		||||
                    };
 | 
			
		||||
                  }());
 | 
			
		||||
              toggleWithToken = document.querySelector('.toggle-payment-with-token');
 | 
			
		||||
              if (!toggleWithToken) {
 | 
			
		||||
                (_document$getElementB4 = document.getElementById('toggle-payment-with-credit-card')) === null || _document$getElementB4 === void 0 ? void 0 : _document$getElementB4.click();
 | 
			
		||||
              }
 | 
			
		||||
            case 8:
 | 
			
		||||
                });
 | 
			
		||||
                (_document$getElementB3 = document.getElementById('toggle-payment-with-credit-card')) === null || _document$getElementB3 === void 0 ? void 0 : _document$getElementB3.addEventListener('click', /*#__PURE__*/function () {
 | 
			
		||||
                  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(element) {
 | 
			
		||||
                    return _regeneratorRuntime().wrap(function _callee6$(_context6) {
 | 
			
		||||
                      while (1) switch (_context6.prev = _context6.next) {
 | 
			
		||||
                        case 0:
 | 
			
		||||
                          document.getElementById('card-container').classList.remove('hidden');
 | 
			
		||||
                          document.getElementById('save-card--container').style.display = 'grid';
 | 
			
		||||
                          document.querySelector('input[name=token]').value = '';
 | 
			
		||||
                        case 3:
 | 
			
		||||
                        case "end":
 | 
			
		||||
                          return _context6.stop();
 | 
			
		||||
                      }
 | 
			
		||||
        }, _callee6, this);
 | 
			
		||||
                    }, _callee6);
 | 
			
		||||
                  }));
 | 
			
		||||
                  return function (_x5) {
 | 
			
		||||
                    return _ref2.apply(this, arguments);
 | 
			
		||||
                  };
 | 
			
		||||
                }());
 | 
			
		||||
 | 
			
		||||
                // let toggleWithToken = document.querySelector(
 | 
			
		||||
                //     '.toggle-payment-with-token'
 | 
			
		||||
                // );
 | 
			
		||||
 | 
			
		||||
                // if (!toggleWithToken) {
 | 
			
		||||
                document.getElementById('loader').classList.add('hidden');
 | 
			
		||||
                document.getElementById('payment-list').classList.remove('hidden');
 | 
			
		||||
                (_document$getElementB4 = document.getElementById('toggle-payment-with-credit-card')) === null || _document$getElementB4 === void 0 ? void 0 : _document$getElementB4.click();
 | 
			
		||||
                // }
 | 
			
		||||
              });
 | 
			
		||||
            case 3:
 | 
			
		||||
            case "end":
 | 
			
		||||
              return _context7.stop();
 | 
			
		||||
          }
 | 
			
		||||
        }, _callee7, this);
 | 
			
		||||
      }));
 | 
			
		||||
      function handle() {
 | 
			
		||||
        return _handle.apply(this, arguments);
 | 
			
		||||
 | 
			
		||||
@ -31,8 +31,6 @@ var StripeCreditCard = /*#__PURE__*/function () {
 | 
			
		||||
    key: "setupStripe",
 | 
			
		||||
    value: function setupStripe() {
 | 
			
		||||
      if (this.stripeConnect) {
 | 
			
		||||
        // this.stripe.stripeAccount = this.stripeConnect;
 | 
			
		||||
 | 
			
		||||
        this.stripe = Stripe(this.key, {
 | 
			
		||||
          stripeAccount: this.stripeConnect
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@
 | 
			
		||||
    "/js/clients/payments/checkout-credit-card.js": "/js/clients/payments/checkout-credit-card.js?id=a2168c43060a7de40da20b5fc599bcab",
 | 
			
		||||
    "/js/clients/quotes/action-selectors.js": "/js/clients/quotes/action-selectors.js?id=4158693089b29ee8e13cb7d9ce4480a9",
 | 
			
		||||
    "/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=4e596cec23cdd6487534e6ed5499d791",
 | 
			
		||||
    "/js/clients/payments/stripe-credit-card.js": "/js/clients/payments/stripe-credit-card.js?id=b483e14d15000c04edfe4c9c80fb97c9",
 | 
			
		||||
    "/js/clients/payments/stripe-credit-card.js": "/js/clients/payments/stripe-credit-card.js?id=bfa116c1df42c641bc7a3ff4fa8d50dd",
 | 
			
		||||
    "/js/setup/setup.js": "/js/setup/setup.js?id=086b9e114b0b9ee01f909d686f489162",
 | 
			
		||||
    "/js/clients/payments/card-js.min.js": "/js/clients/payments/card-js.min.js?id=cf50b5ba1fcd1d184bf0c10d710672c8",
 | 
			
		||||
    "/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=c9593b44d66f89874d13f99bc3e6ff33",
 | 
			
		||||
@ -30,7 +30,7 @@
 | 
			
		||||
    "/js/clients/payments/mollie-credit-card.js": "/js/clients/payments/mollie-credit-card.js?id=2f72b969507e6135b5c52a65522ab3ae",
 | 
			
		||||
    "/js/clients/payments/eway-credit-card.js": "/js/clients/payments/eway-credit-card.js?id=0d1c8957b02c5601b7d57c39740bff75",
 | 
			
		||||
    "/js/clients/payment_methods/braintree-ach.js": "/js/clients/payment_methods/braintree-ach.js?id=2f8e5af9ba5ce266d2ee49b084fbe291",
 | 
			
		||||
    "/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=dbd7a15777def575562153c984dee08a",
 | 
			
		||||
    "/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=a5e1407a161c3c72545d125dd1100571",
 | 
			
		||||
    "/js/clients/statements/view.js": "/js/clients/statements/view.js?id=bd92ab50acabf1cc5232912d53edc5e1",
 | 
			
		||||
    "/js/clients/payments/razorpay-aio.js": "/js/clients/payments/razorpay-aio.js?id=46e14d31acaf3adf58444a5de4b4122c",
 | 
			
		||||
    "/js/clients/payments/stripe-sepa.js": "/js/clients/payments/stripe-sepa.js?id=ef15c0865a29c3c17f2ad185cad0d28e",
 | 
			
		||||
 | 
			
		||||
@ -125,7 +125,10 @@ class SquareCreditCard {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async handle() {
 | 
			
		||||
        await this.init();
 | 
			
		||||
 | 
			
		||||
        document.getElementById('payment-list').classList.add('hidden');
 | 
			
		||||
 | 
			
		||||
        await this.init().then(() => {
 | 
			
		||||
 | 
			
		||||
        document
 | 
			
		||||
            .getElementById('authorize-card')
 | 
			
		||||
@ -146,7 +149,7 @@ class SquareCreditCard {
 | 
			
		||||
        Array.from(
 | 
			
		||||
            document.getElementsByClassName('toggle-payment-with-token')
 | 
			
		||||
        ).forEach((element) =>
 | 
			
		||||
            element.addEventListener('click', (element) => {
 | 
			
		||||
            element.addEventListener('click', async (element) => {
 | 
			
		||||
                document
 | 
			
		||||
                    .getElementById('card-container')
 | 
			
		||||
                    .classList.add('hidden');
 | 
			
		||||
@ -168,13 +171,17 @@ class SquareCreditCard {
 | 
			
		||||
                document.querySelector('input[name=token]').value = '';
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        let toggleWithToken = document.querySelector(
 | 
			
		||||
            '.toggle-payment-with-token'
 | 
			
		||||
        );
 | 
			
		||||
        // let toggleWithToken = document.querySelector(
 | 
			
		||||
        //     '.toggle-payment-with-token'
 | 
			
		||||
        // );
 | 
			
		||||
 | 
			
		||||
        if (!toggleWithToken) {
 | 
			
		||||
        // if (!toggleWithToken) {
 | 
			
		||||
            document.getElementById('loader').classList.add('hidden');
 | 
			
		||||
            document.getElementById('payment-list').classList.remove('hidden');
 | 
			
		||||
            document.getElementById('toggle-payment-with-credit-card')?.click();
 | 
			
		||||
        }
 | 
			
		||||
        // }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,6 @@ class StripeCreditCard {
 | 
			
		||||
    setupStripe() {
 | 
			
		||||
 | 
			
		||||
        if (this.stripeConnect){
 | 
			
		||||
           // this.stripe.stripeAccount = this.stripeConnect;
 | 
			
		||||
           
 | 
			
		||||
           this.stripe = Stripe(this.key, {
 | 
			
		||||
              stripeAccount: this.stripeConnect,
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
@extends('portal.ninja2020.layout.error')
 | 
			
		||||
 | 
			
		||||
@section('title', __($title) ?? 'Server Error')
 | 
			
		||||
@section('title', $title ?? 'Error')
 | 
			
		||||
@section('code', __($code) ?? '500')
 | 
			
		||||
@section('message', __($message) ?? 'System Error')
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,32 @@
 | 
			
		||||
    <meta name="square_contact" content="{{ json_encode($square_contact) }}">
 | 
			
		||||
    <meta name="amount" content="{{ $amount }}">
 | 
			
		||||
    <meta name="currencyCode" content="{{ $currencyCode }}">
 | 
			
		||||
   <style>
 | 
			
		||||
    .loader {
 | 
			
		||||
      border-top-color: #3498db;
 | 
			
		||||
      -webkit-animation: spinner 1.5s linear infinite;
 | 
			
		||||
      animation: spinner 1.5s linear infinite;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @-webkit-keyframes spinner {
 | 
			
		||||
      0% {
 | 
			
		||||
        -webkit-transform: rotate(0deg);
 | 
			
		||||
      }
 | 
			
		||||
      100% {
 | 
			
		||||
        -webkit-transform: rotate(360deg);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @keyframes spinner {
 | 
			
		||||
      0% {
 | 
			
		||||
        transform: rotate(0deg);
 | 
			
		||||
      }
 | 
			
		||||
      100% {
 | 
			
		||||
        transform: rotate(360deg);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   </style>
 | 
			
		||||
@endsection
 | 
			
		||||
 | 
			
		||||
@section('gateway_content')
 | 
			
		||||
@ -33,23 +58,41 @@
 | 
			
		||||
 | 
			
		||||
    @include('portal.ninja2020.gateways.includes.payment_details')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')])
 | 
			
		||||
        <div class="flex flex-col" id="loader">
 | 
			
		||||
            <div class="loader ease-linear rounded-full border-4 border-t-4 border-gray-200 h-12 w-12 mb-4"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <ul class="list-none hover:list-disc " id="payment-list">
 | 
			
		||||
        @if (count($tokens) > 0)
 | 
			
		||||
            @foreach ($tokens as $token)
 | 
			
		||||
            @foreach($tokens as $token)
 | 
			
		||||
            <li class="py-2 hover:text-blue hover:bg-blue-600">
 | 
			
		||||
                <label class="mr-4">
 | 
			
		||||
                    <input type="radio" data-token="{{ $token->token }}" name="payment-type"
 | 
			
		||||
                        class="form-radio cursor-pointer toggle-payment-with-token" />
 | 
			
		||||
                    <span class="ml-1 cursor-pointer">**** {{ $token->meta?->last4 }}</span>
 | 
			
		||||
                    <input
 | 
			
		||||
                        type="radio"
 | 
			
		||||
                        data-token="{{ $token->token }}"
 | 
			
		||||
                        name="payment-type"
 | 
			
		||||
                        class="form-check-input text-indigo-600 rounded-full cursor-pointer toggle-payment-with-token toggle-payment-with-token"
 | 
			
		||||
                        />
 | 
			
		||||
                    <span class="ml-1 cursor-pointer">**** {{ $token->meta?->last4 }} - {{ $token->meta?->exp_month ?? 'xx' }}/{{ $token->meta?->exp_year ?? 'xx' }}</span>
 | 
			
		||||
                </label>
 | 
			
		||||
            </li>
 | 
			
		||||
            @endforeach
 | 
			
		||||
        @endisset
 | 
			
		||||
 | 
			
		||||
            <li class="py-2 hover:text-blue hover:bg-blue-600">
 | 
			
		||||
                <label>
 | 
			
		||||
            <input type="radio" id="toggle-payment-with-credit-card" class="form-radio cursor-pointer" name="payment-type"
 | 
			
		||||
                checked />
 | 
			
		||||
                    <input
 | 
			
		||||
                        type="radio"
 | 
			
		||||
                        id="toggle-payment-with-credit-card"
 | 
			
		||||
                        class="form-check-input text-indigo-600 rounded-full cursor-pointer"
 | 
			
		||||
                        name="payment-type"
 | 
			
		||||
                        checked/>
 | 
			
		||||
                    <span class="ml-1 cursor-pointer">{{ __('texts.new_card') }}</span>
 | 
			
		||||
                </label>
 | 
			
		||||
            </li>    
 | 
			
		||||
        </ul>
 | 
			
		||||
        
 | 
			
		||||
    @endcomponent
 | 
			
		||||
 | 
			
		||||
    @include('portal.ninja2020.gateways.includes.save_card')
 | 
			
		||||
 | 
			
		||||
@ -101,6 +101,7 @@ use App\Http\Controllers\Support\Messages\SendingController;
 | 
			
		||||
use App\Http\Controllers\Reports\ClientSalesReportController;
 | 
			
		||||
use App\Http\Controllers\Reports\InvoiceItemReportController;
 | 
			
		||||
use App\Http\Controllers\PaymentNotificationWebhookController;
 | 
			
		||||
use App\Http\Controllers\ProtectedDownloadController;
 | 
			
		||||
use App\Http\Controllers\Reports\ProductSalesReportController;
 | 
			
		||||
use App\Http\Controllers\Reports\ClientBalanceReportController;
 | 
			
		||||
use App\Http\Controllers\Reports\ClientContactReportController;
 | 
			
		||||
@ -141,7 +142,6 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale']
 | 
			
		||||
    Route::get('activities', [ActivityController::class, 'index']);
 | 
			
		||||
    Route::get('activities/download_entity/{activity}', [ActivityController::class, 'downloadHistoricalEntity']);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Route::post('charts/totals', [ChartController::class, 'totals'])->name('chart.totals');
 | 
			
		||||
    Route::post('charts/chart_summary', [ChartController::class, 'chart_summary'])->name('chart.chart_summary');
 | 
			
		||||
 | 
			
		||||
@ -280,26 +280,26 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale']
 | 
			
		||||
    Route::post('recurring_quotes/bulk', [RecurringQuoteController::class, 'bulk'])->name('recurring_quotes.bulk');
 | 
			
		||||
    Route::put('recurring_quotes/{recurring_quote}/upload', [RecurringQuoteController::class, 'upload']);
 | 
			
		||||
 | 
			
		||||
    Route::post('refresh', [LoginController::class, 'refresh'])->middleware('throttle:refresh');
 | 
			
		||||
    Route::post('refresh', [LoginController::class, 'refresh'])->middleware('throttle:refr2sh');
 | 
			
		||||
 | 
			
		||||
    Route::post('reports/clients', ClientReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/activities', ActivityReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/client_contacts', ClientContactReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/contacts', ClientContactReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/credits', CreditReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/documents', DocumentReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/expenses', ExpenseReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/invoices', InvoiceReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/invoice_items', InvoiceItemReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/quotes', QuoteReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/quote_items', QuoteItemReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/recurring_invoices', RecurringInvoiceReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/payments', PaymentReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/products', ProductReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/product_sales', ProductSalesReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
    Route::post('reports/tasks', TaskReportController::class)->middleware('throttle:20,1');
 | 
			
		||||
 | 
			
		||||
    Route::post('reports/clients', ClientReportController::class);
 | 
			
		||||
    Route::post('reports/activities', ActivityReportController::class);
 | 
			
		||||
    Route::post('reports/client_contacts', ClientContactReportController::class);
 | 
			
		||||
    Route::post('reports/contacts', ClientContactReportController::class);
 | 
			
		||||
    Route::post('reports/credits', CreditReportController::class);
 | 
			
		||||
    Route::post('reports/documents', DocumentReportController::class);
 | 
			
		||||
    Route::post('reports/expenses', ExpenseReportController::class);
 | 
			
		||||
    Route::post('reports/invoices', InvoiceReportController::class);
 | 
			
		||||
    Route::post('reports/invoice_items', InvoiceItemReportController::class);
 | 
			
		||||
    Route::post('reports/quotes', QuoteReportController::class);
 | 
			
		||||
    Route::post('reports/quote_items', QuoteItemReportController::class);
 | 
			
		||||
    Route::post('reports/recurring_invoices', RecurringInvoiceReportController::class);
 | 
			
		||||
    Route::post('reports/payments', PaymentReportController::class);
 | 
			
		||||
    Route::post('reports/products', ProductReportController::class);
 | 
			
		||||
    Route::post('reports/product_sales', ProductSalesReportController::class);
 | 
			
		||||
    Route::post('reports/tasks', TaskReportController::class);
 | 
			
		||||
    Route::post('reports/profitloss', ProfitAndLossController::class);
 | 
			
		||||
    
 | 
			
		||||
    Route::post('reports/ar_detail_report', ARDetailReportController::class);
 | 
			
		||||
    Route::post('reports/ar_summary_report', ARSummaryReportController::class);
 | 
			
		||||
    Route::post('reports/client_balance_report', ClientBalanceReportController::class);
 | 
			
		||||
@ -402,4 +402,6 @@ Route::post('api/v1/yodlee/data_updates', [YodleeController::class, 'dataUpdates
 | 
			
		||||
Route::post('api/v1/yodlee/refresh_updates', [YodleeController::class, 'refreshUpdatesWebhook'])->middleware('throttle:100,1');
 | 
			
		||||
Route::post('api/v1/yodlee/balance', [YodleeController::class, 'balanceWebhook'])->middleware('throttle:100,1');
 | 
			
		||||
 | 
			
		||||
Route::get('api/v1/protected_download/{hash}', [ProtectedDownloadController::class, 'index'])->name('protected_download')->middleware('signed')->middleware('throttle:300,1');
 | 
			
		||||
 | 
			
		||||
Route::fallback([BaseController::class, 'notFound'])->middleware('throttle:404');
 | 
			
		||||
@ -12,7 +12,3 @@ use Illuminate\Foundation\Inspiring;
 | 
			
		||||
| simple approach to interacting with each command's IO methods.
 | 
			
		||||
|
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
Artisan::command('inspire', function () {
 | 
			
		||||
    $this->comment(Inspiring::quote());
 | 
			
		||||
})->describe('Display an inspiring quote');
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user