mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-02 22:57:33 -05:00 
			
		
		
		
	Merge pull request #8634 from turbo124/v5-develop
Fixes for protected downloads in Docker Containers
This commit is contained in:
		
						commit
						c3a43354b3
					
				@ -32,6 +32,8 @@ class MigrationController extends BaseController
 | 
			
		||||
{
 | 
			
		||||
    use DispatchesJobs;
 | 
			
		||||
 | 
			
		||||
    public bool $silent_migration = false;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
@ -260,6 +262,9 @@ class MigrationController extends BaseController
 | 
			
		||||
    {
 | 
			
		||||
        nlog('Starting Migration');
 | 
			
		||||
 | 
			
		||||
        if($request->has('silent_migration'))
 | 
			
		||||
            $this->silent_migration = true;
 | 
			
		||||
 | 
			
		||||
        if ($request->companies) {
 | 
			
		||||
            //handle Laravel 5.5 UniHTTP
 | 
			
		||||
            $companies = json_decode($request->companies, 1);
 | 
			
		||||
@ -312,6 +317,8 @@ class MigrationController extends BaseController
 | 
			
		||||
                    $nmo->company = $user->account->companies()->first();
 | 
			
		||||
                    $nmo->settings = $user->account->companies()->first()->settings;
 | 
			
		||||
                    $nmo->to_user = $user;
 | 
			
		||||
 | 
			
		||||
                    if(!$this->silent_migration)
 | 
			
		||||
                        NinjaMailerJob::dispatch($nmo, true);
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
@ -321,6 +328,8 @@ class MigrationController extends BaseController
 | 
			
		||||
                    $nmo->company = $user->account->companies()->first();
 | 
			
		||||
                    $nmo->settings = $user->account->companies()->first()->settings;
 | 
			
		||||
                    $nmo->to_user = $user;
 | 
			
		||||
 | 
			
		||||
                    if(!$this->silent_migration)
 | 
			
		||||
                        NinjaMailerJob::dispatch($nmo, true);
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
@ -341,6 +350,7 @@ class MigrationController extends BaseController
 | 
			
		||||
                    $nmo->settings = $user->account->companies()->first();
 | 
			
		||||
                    $nmo->to_user = $user;
 | 
			
		||||
 | 
			
		||||
                    if(!$this->silent_migration)
 | 
			
		||||
                        NinjaMailerJob::dispatch($nmo, true);
 | 
			
		||||
 | 
			
		||||
                    return response()->json([
 | 
			
		||||
@ -431,9 +441,9 @@ class MigrationController extends BaseController
 | 
			
		||||
                nlog($migration_file);
 | 
			
		||||
 | 
			
		||||
                if (Ninja::isHosted()) {
 | 
			
		||||
                    StartMigration::dispatch($migration_file, $user, $fresh_company)->onQueue('migration');
 | 
			
		||||
                    StartMigration::dispatch($migration_file, $user, $fresh_company, $this->silent_migration)->onQueue('migration');
 | 
			
		||||
                } else {
 | 
			
		||||
                    StartMigration::dispatch($migration_file, $user, $fresh_company);
 | 
			
		||||
                    StartMigration::dispatch($migration_file, $user, $fresh_company, $this->silent_migration);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -30,11 +30,7 @@ class ProtectedDownloadController extends BaseController
 | 
			
		||||
            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), []);
 | 
			
		||||
        return response()->download($hashed_path, basename($hashed_path), [])->deleteFileAfterSend(true);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ class BulkInvoiceJob implements ShouldQueue
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {   //only the reminder should mark the reminder sent field
 | 
			
		||||
        // $this->invoice->service()->touchReminder($this->reminder_template)->markSent()->save();
 | 
			
		||||
 | 
			
		||||
        $this->invoice->service()->markSent()->save();
 | 
			
		||||
 | 
			
		||||
        $this->invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) {
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ class CleanStaleInvoiceOrder implements ShouldQueue
 | 
			
		||||
            Invoice::query()
 | 
			
		||||
                   ->withTrashed()
 | 
			
		||||
                   ->where('status_id', Invoice::STATUS_SENT)
 | 
			
		||||
                   ->where('created_at', '<', now()->subHours(2))
 | 
			
		||||
                   ->whereBetween('created_at', [now()->subHours(1), now()->subMinutes(10)])
 | 
			
		||||
                   ->where('balance', '>', 0)
 | 
			
		||||
                   ->cursor()
 | 
			
		||||
                   ->each(function ($invoice){
 | 
			
		||||
@ -77,7 +77,7 @@ class CleanStaleInvoiceOrder implements ShouldQueue
 | 
			
		||||
            Invoice::query()
 | 
			
		||||
                    ->withTrashed()
 | 
			
		||||
                    ->where('is_proforma', 1)
 | 
			
		||||
                    ->where('created_at', '<', now()->subHour())
 | 
			
		||||
                    ->whereBetween('created_at', [now()->subHours(1), now()->subMinutes(10)])
 | 
			
		||||
                    ->cursor()
 | 
			
		||||
                    ->each(function ($invoice) use ($repo) {
 | 
			
		||||
                        $invoice->is_proforma = false;
 | 
			
		||||
 | 
			
		||||
@ -165,6 +165,8 @@ class Import implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
    public $timeout = 10000000;
 | 
			
		||||
 | 
			
		||||
    public $silent_migration;
 | 
			
		||||
 | 
			
		||||
    // public $backoff = 86430;
 | 
			
		||||
 | 
			
		||||
    //  public $maxExceptions = 2;
 | 
			
		||||
@ -176,12 +178,13 @@ class Import implements ShouldQueue
 | 
			
		||||
     * @param User $user
 | 
			
		||||
     * @param array $resources
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $file_path, Company $company, User $user, array $resources = [])
 | 
			
		||||
    public function __construct(string $file_path, Company $company, User $user, array $resources = [], $silent_migration = false)
 | 
			
		||||
    {
 | 
			
		||||
        $this->file_path = $file_path;
 | 
			
		||||
        $this->company = $company;
 | 
			
		||||
        $this->user = $user;
 | 
			
		||||
        $this->resources = $resources;
 | 
			
		||||
        $this->silent_migration = $silent_migration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function middleware()
 | 
			
		||||
@ -263,8 +266,9 @@ class Import implements ShouldQueue
 | 
			
		||||
            $t = app('translator');
 | 
			
		||||
            $t->replace(Ninja::transformTranslations($this->company->settings));
 | 
			
		||||
        
 | 
			
		||||
            Mail::to($this->user->email, $this->user->name())
 | 
			
		||||
                ->send(new MigrationCompleted($this->company->id, $this->company->db, implode("<br>", $check_data)));
 | 
			
		||||
            if(!$this->silent_migration)
 | 
			
		||||
                Mail::to($this->user->email, $this->user->name())->send(new MigrationCompleted($this->company->id, $this->company->db, implode("<br>", $check_data)));
 | 
			
		||||
 | 
			
		||||
        } catch(\Exception $e) {
 | 
			
		||||
            nlog($e->getMessage());
 | 
			
		||||
        }
 | 
			
		||||
@ -641,7 +645,6 @@ class Import implements ShouldQueue
 | 
			
		||||
            
 | 
			
		||||
            $user = $user_repository->save($modified, $this->fetchUser($resource['email']), true, true);
 | 
			
		||||
            $user->email_verified_at = now();
 | 
			
		||||
            // $user->confirmation_code = '';
 | 
			
		||||
 | 
			
		||||
            if ($modified['deleted_at']) {
 | 
			
		||||
                $user->deleted_at = now();
 | 
			
		||||
@ -1590,6 +1593,8 @@ class Import implements ShouldQueue
 | 
			
		||||
                $nmo->company = $this->company;
 | 
			
		||||
                $nmo->settings = $this->company->settings;
 | 
			
		||||
                $nmo->to_user = $this->user;
 | 
			
		||||
 | 
			
		||||
                if(!$this->silent_migration)
 | 
			
		||||
                    NinjaMailerJob::dispatch($nmo, true);
 | 
			
		||||
 | 
			
		||||
                $modified['gateway_key'] = 'd14dd26a47cecc30fdd65700bfb67b34';
 | 
			
		||||
 | 
			
		||||
@ -99,7 +99,6 @@ class ReminderJob implements ShouldQueue
 | 
			
		||||
                         $query->where('is_disabled', 0);
 | 
			
		||||
                     })
 | 
			
		||||
                     ->with('invitations')->chunk(50, function ($invoices) {
 | 
			
		||||
                         // if ($invoice->refresh() && $invoice->isPayable()) {
 | 
			
		||||
 | 
			
		||||
                         foreach ($invoices as $invoice) {
 | 
			
		||||
                             $this->sendReminderForInvoice($invoice);
 | 
			
		||||
 | 
			
		||||
@ -49,6 +49,8 @@ class StartMigration implements ShouldQueue
 | 
			
		||||
     */
 | 
			
		||||
    private $company;
 | 
			
		||||
 | 
			
		||||
    private $silent_migration;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new job instance.
 | 
			
		||||
     *
 | 
			
		||||
@ -60,11 +62,12 @@ class StartMigration implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
    public $timeout = 0;
 | 
			
		||||
 | 
			
		||||
    public function __construct($filepath, User $user, Company $company)
 | 
			
		||||
    public function __construct($filepath, User $user, Company $company, $silent_migration = false)
 | 
			
		||||
    {
 | 
			
		||||
        $this->filepath = $filepath;
 | 
			
		||||
        $this->user = $user;
 | 
			
		||||
        $this->company = $company;
 | 
			
		||||
        $this->silent_migration = $silent_migration;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -116,7 +119,7 @@ class StartMigration implements ShouldQueue
 | 
			
		||||
                throw new NonExistingMigrationFile('Migration file does not exist, or it is corrupted.');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            (new Import($file, $this->company, $this->user))->handle();
 | 
			
		||||
            (new Import($file, $this->company, $this->user, [], $this->silent_migration))->handle();
 | 
			
		||||
 | 
			
		||||
            Storage::deleteDirectory(public_path("storage/migrations/{$filename}"));
 | 
			
		||||
 | 
			
		||||
@ -138,6 +141,7 @@ class StartMigration implements ShouldQueue
 | 
			
		||||
                app('sentry')->captureException($e);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(!$this->silent_migration)
 | 
			
		||||
                Mail::to($this->user->email, $this->user->name())->send(new MigrationFailed($e, $this->company, $e->getMessage()));
 | 
			
		||||
 | 
			
		||||
            if (Ninja::isHosted()) {
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ class UserRepository extends BaseRepository
 | 
			
		||||
     * @param bool $unset_company_user
 | 
			
		||||
     * @return \App\Models\User user Object
 | 
			
		||||
     */
 | 
			
		||||
    public function save(array $data, User $user, $unset_company_user = false)
 | 
			
		||||
    public function save(array $data, User $user, $unset_company_user = false, $is_migrating = false)
 | 
			
		||||
    {
 | 
			
		||||
        $details = $data;
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,7 @@ class UserRepository extends BaseRepository
 | 
			
		||||
            $user->password = Hash::make($data['password']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (! $user->confirmation_code) {
 | 
			
		||||
        if (! $user->confirmation_code && !$is_migrating) {
 | 
			
		||||
            $user->confirmation_code = $this->createDbHash($company->db);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -190,7 +190,7 @@ class InstantPayment
 | 
			
		||||
 | 
			
		||||
        /* Schedule a job to check the gateway fees for this invoice*/
 | 
			
		||||
        if (Ninja::isHosted()) {
 | 
			
		||||
            CheckGatewayFee::dispatch($first_invoice->id, $client->company->db)->delay(600);
 | 
			
		||||
            CheckGatewayFee::dispatch($first_invoice->id, $client->company->db)->delay(800);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($gateway) {
 | 
			
		||||
 | 
			
		||||
@ -56,8 +56,35 @@ class Helpers
 | 
			
		||||
    public function formatCustomFieldValue($custom_fields, $field, $value, $entity = null): ?string
 | 
			
		||||
    {
 | 
			
		||||
        $custom_field = '';
 | 
			
		||||
        $quote_or_credit_field = false;
 | 
			
		||||
 | 
			
		||||
        if ($custom_fields && property_exists($custom_fields, $field)) {
 | 
			
		||||
        if($custom_fields && stripos($field, 'quote') !== false && property_exists($custom_fields, $field)) {
 | 
			
		||||
            $custom_field = $custom_fields->{$field};
 | 
			
		||||
            $custom_field_parts = explode('|', $custom_field);
 | 
			
		||||
 | 
			
		||||
            if (count($custom_field_parts) >= 2) {
 | 
			
		||||
                $custom_field = $custom_field_parts[1];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $quote_or_credit_field = true;
 | 
			
		||||
 | 
			
		||||
        }elseif($custom_fields && stripos($field, 'credit') !== false && property_exists($custom_fields, $field)) {
 | 
			
		||||
            $custom_field = $custom_fields->{$field};
 | 
			
		||||
            $custom_field_parts = explode('|', $custom_field);
 | 
			
		||||
 | 
			
		||||
            if (count($custom_field_parts) >= 2) {
 | 
			
		||||
                $custom_field = $custom_field_parts[1];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $quote_or_credit_field = true;
 | 
			
		||||
 | 
			
		||||
        }elseif($custom_fields && stripos($field, 'credit') !== false) {
 | 
			
		||||
            $field = str_replace("credit", "invoice", $field);
 | 
			
		||||
        }elseif($custom_fields && stripos($field, 'quote') !== false) {
 | 
			
		||||
            $field = str_replace("quote", "invoice", $field);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!$quote_or_credit_field && $custom_fields && property_exists($custom_fields, $field)) {
 | 
			
		||||
            $custom_field = $custom_fields->{$field};
 | 
			
		||||
            $custom_field_parts = explode('|', $custom_field);
 | 
			
		||||
 | 
			
		||||
@ -90,6 +117,17 @@ class Helpers
 | 
			
		||||
     */
 | 
			
		||||
    public function makeCustomField($custom_fields, $field): string
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        if ($custom_fields && property_exists($custom_fields, $field)) {
 | 
			
		||||
            $custom_field = $custom_fields->{$field};
 | 
			
		||||
 | 
			
		||||
            $custom_field_parts = explode('|', $custom_field);
 | 
			
		||||
 | 
			
		||||
            return $custom_field_parts[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $field = str_replace(["quote","credit"], ["invoice", "invoice"], $field);
 | 
			
		||||
 | 
			
		||||
        if ($custom_fields && property_exists($custom_fields, $field)) {
 | 
			
		||||
            $custom_field = $custom_fields->{$field};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -222,10 +222,10 @@ class HtmlEngine
 | 
			
		||||
            $data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_quote')];
 | 
			
		||||
            $data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.quote_date')];
 | 
			
		||||
 | 
			
		||||
            $data['$quote.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice1', $this->entity->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice1')];
 | 
			
		||||
            $data['$quote.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice2', $this->entity->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice2')];
 | 
			
		||||
            $data['$quote.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice3', $this->entity->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice3')];
 | 
			
		||||
            $data['$quote.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice4', $this->entity->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice4')];
 | 
			
		||||
            $data['$quote.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'quote1', $this->entity->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'quote1')];
 | 
			
		||||
            $data['$quote.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'quote2', $this->entity->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'quote2')];
 | 
			
		||||
            $data['$quote.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'quote3', $this->entity->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'quote3')];
 | 
			
		||||
            $data['$quote.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'quote4', $this->entity->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'quote4')];
 | 
			
		||||
 | 
			
		||||
            $data['$custom1'] = &$data['$quote.custom1'];
 | 
			
		||||
            $data['$custom2'] = &$data['$quote.custom2'];
 | 
			
		||||
@ -266,10 +266,10 @@ class HtmlEngine
 | 
			
		||||
            // $data['$view_link']          = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_credit')];
 | 
			
		||||
            $data['$date'] = ['value' => $this->translateDate($this->entity->date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.credit_date')];
 | 
			
		||||
 | 
			
		||||
            $data['$credit.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'credit1', $this->entity->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice1')];
 | 
			
		||||
            $data['$credit.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'credit2', $this->entity->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice2')];
 | 
			
		||||
            $data['$credit.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'credit3', $this->entity->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice3')];
 | 
			
		||||
            $data['$credit.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'credit4', $this->entity->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice4')];
 | 
			
		||||
            $data['$credit.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'credit1', $this->entity->custom_value1, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'credit1')];
 | 
			
		||||
            $data['$credit.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'credit2', $this->entity->custom_value2, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'credit2')];
 | 
			
		||||
            $data['$credit.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'credit3', $this->entity->custom_value3, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'credit3')];
 | 
			
		||||
            $data['$credit.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'credit4', $this->entity->custom_value4, $this->client) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'credit4')];
 | 
			
		||||
 | 
			
		||||
            $data['$custom1'] = &$data['$credit.custom1'];
 | 
			
		||||
            $data['$custom2'] = &$data['$credit.custom2'];
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user