Merge pull request #9032 from turbo124/v5-develop

v5.7.60
This commit is contained in:
David Bomba 2023-12-11 22:44:40 +11:00 committed by GitHub
commit fe34ab41d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 239 additions and 133 deletions

View File

@ -1 +1 @@
5.7.59
5.7.60

View File

@ -12,7 +12,8 @@
namespace App\DataProviders;
class Domains {
class Domains
{
private static array $verify_domains = [
'0-00.usa.cc',

View File

@ -146,16 +146,26 @@ class InvoiceFilters extends QueryFilters
*/
public function upcoming(): Builder
{
return $this->builder->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT])
->whereNull('due_date')
return $this->builder->where(function ($query) {
$query->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT])
->where('is_deleted', 0)
->where('balance', '>', 0)
->where(function ($query) {
$query->whereNull('due_date')
->orWhere(function ($q) {
$q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0);
})
->orWhere(function ($q) {
$q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0);
})
->orderByRaw('ISNULL(due_date), due_date '. 'desc')
->orderByRaw('ISNULL(partial_due_date), partial_due_date '. 'desc');
->orWhere(function ($q) {
$q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0);
});
})
->orderByRaw('ISNULL(due_date), due_date ' . 'desc')
->orderByRaw('ISNULL(partial_due_date), partial_due_date ' . 'desc');
});
}
/**
@ -165,13 +175,18 @@ class InvoiceFilters extends QueryFilters
*/
public function overdue(): Builder
{
return $this->builder->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
return $this->builder->where(function ($query) {
$query->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
->where('is_deleted', 0)
->where('balance', '>', 0)
->where(function ($query) {
$query->where('due_date', '<', now())
->orWhere('partial_due_date', '<', now());
})
->orderBy('due_date', 'ASC');
});
}
/**

View File

@ -155,6 +155,7 @@ class PaymentController extends BaseController
$user = auth()->user();
$payment = PaymentFactory::create($user->company()->id, $user->id);
$payment->date = now()->addSeconds($user->company()->utc_offset())->format('Y-m-d');
return $this->itemResponse($payment);
}

View File

@ -30,6 +30,12 @@ class SubdomainController extends BaseController
return response()->json(['message' => ctrans('texts.subdomain_is_not_available')], 401);
}
if (!preg_match('/^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$/', request()->input('subdomain'))) {
return response()->json(['message' => ctrans('texts.subdomain_is_not_available')], 401);
}
return response()->json(['message' => 'Domain available'], 200);
}
}

View File

@ -21,6 +21,12 @@ use Twilio\Rest\Client;
class TwilioController extends BaseController
{
private array $invalid_codes = [
'+21',
'+17152567760',
];
public function __construct()
{
parent::__construct();
@ -38,6 +44,10 @@ class TwilioController extends BaseController
$account = $user->company()->account;
if(!$this->checkPhoneValidity($request->phone)) {
return response()->json(['message' => 'This phone number is not supported'], 400);
}
if (MultiDB::hasPhoneNumber($request->phone)) {
return response()->json(['message' => 'This phone number has already been verified with another account'], 400);
}
@ -65,6 +75,19 @@ class TwilioController extends BaseController
return response()->json(['message' => 'Code sent.'], 200);
}
private function checkPhoneValidity($phone)
{
foreach($this->invalid_codes as $code){
if(stripos($phone, $code) !== false) {
return false;
}
return true;
}
}
/**
* Show the form for creating a new resource.
*

View File

@ -60,7 +60,7 @@ class UpdateCreditRequest extends Request
$rules['file'] = $this->file_validation;
}
$rules['number'] = ['bail', 'sometimes', Rule::unique('credits')->where('company_id', $user->company()->id)->ignore($this->credit->id)];
$rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('credits')->where('company_id', $user->company()->id)->ignore($this->credit->id)];
$rules['client_id'] = ['bail', 'sometimes',Rule::in([$this->credit->client_id])];

View File

@ -37,7 +37,7 @@ class ImportRequest extends Request
'column_map' => 'required_with:hash|array',
'skip_header' => 'required_with:hash|boolean',
'files.*' => 'file|mimes:csv,txt',
'bank_integration_id' => 'bail|required_if:column_map,bank_transaction|min:2'
'bank_integration_id' => 'bail|required_with:column_map.bank_transaction|min:2'
];
}
}

View File

@ -59,9 +59,8 @@ class UpdateInvoiceRequest extends Request
$rules['id'] = new LockedInvoiceRule($this->invoice);
$rules['number'] = ['bail', 'sometimes', Rule::unique('invoices')->where('company_id', $user->company()->id)->ignore($this->invoice->id)];
$rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('invoices')->where('company_id', $user->company()->id)->ignore($this->invoice->id)];
$rules['is_amount_discount'] = ['boolean'];
$rules['client_id'] = ['bail', 'sometimes', Rule::in([$this->invoice->client_id])];
$rules['line_items'] = 'array';

View File

@ -48,7 +48,7 @@ class UpdatePurchaseOrderRequest extends Request
$rules = [];
$rules['number'] = ['bail', 'sometimes', Rule::unique('purchase_orders')->where('company_id', $user->company()->id)->ignore($this->purchase_order->id)];
$rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('purchase_orders')->where('company_id', $user->company()->id)->ignore($this->purchase_order->id)];
$rules['vendor_id'] = ['bail', 'sometimes', Rule::in([$this->purchase_order->vendor_id])];
$rules['line_items'] = 'array';

View File

@ -55,7 +55,7 @@ class UpdateQuoteRequest extends Request
}
$rules['number'] = ['bail', 'sometimes', Rule::unique('quotes')->where('company_id', $user->company()->id)->ignore($this->quote->id)];
$rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('quotes')->where('company_id', $user->company()->id)->ignore($this->quote->id)];
$rules['client_id'] = ['bail', 'sometimes', Rule::in([$this->quote->client_id])];
@ -73,6 +73,8 @@ class UpdateQuoteRequest extends Request
$input = $this->decodePrimaryKeys($input);
$input['id'] = $this->quote->id;
if (isset($input['line_items'])) {
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
}
@ -85,7 +87,6 @@ class UpdateQuoteRequest extends Request
$input['exchange_rate'] = 1;
}
$input['id'] = $this->quote->id;
$this->replace($input);
}

View File

@ -42,12 +42,12 @@ class StoreSchedulerRequest extends Request
'template' => 'bail|required|string',
'parameters' => 'bail|array',
'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()],
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom',
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom,all',
'parameters.start_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'],
'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'],
'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'],
'parameters.entity_id' => ['bail', 'sometimes', 'string'],
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,clients,client_contacts,credits,documents,expenses,invoices,invoice_items,quotes,quote_items,recurring_invoices,payments,products,tasks'],
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,activity,client,contact,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'],
'parameters.date_key' => ['bail','sometimes', 'string'],
'parameters.status' => ['bail','sometimes', 'string', 'in:all,draft,paid,unpaid,overdue'],
];
@ -67,6 +67,10 @@ class StoreSchedulerRequest extends Request
$input['frequency_id'] = 0;
}
if(isset($input['parameters']) && isset($input['parameters']['clients'])) {
$input['parameters']['clients'] = [];
}
$this->replace($input);
}
}

View File

@ -39,12 +39,12 @@ class UpdateSchedulerRequest extends Request
'template' => 'bail|required|string',
'parameters' => 'bail|array',
'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()],
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom',
'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom,all',
'parameters.start_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'],
'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'],
'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'],
'parameters.entity_id' => ['bail', 'sometimes', 'string'],
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report', 'in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,clients,client_contacts,credits,documents,expenses,invoices,invoice_items,quotes,quote_items,recurring_invoices,payments,products,tasks'],
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report', 'in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,client,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'],
'parameters.date_key' => ['bail','sometimes', 'string'],
];
@ -63,6 +63,10 @@ class UpdateSchedulerRequest extends Request
$input['frequency_id'] = 0;
}
if(isset($input['parameters']) && isset($input['parameters']['clients'])) {
$input['parameters']['clients'] = [];
}
$this->replace($input);

View File

@ -387,19 +387,19 @@ class CompanyExport implements ShouldQueue
})->all();
$this->export_data['bank_integrations'] = $this->company->bank_integrations()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration) {
$this->export_data['bank_integrations'] = $this->company->bank_integrations()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration) {
$bank_integration = $this->transformArrayOfKeys($bank_integration, ['account_id','company_id', 'user_id']);
return $bank_integration->makeVisible(['id','user_id','company_id','account_id']);
return $bank_integration->makeVisible(['id','user_id','company_id','account_id','hashed_id']);
})->all();
$this->export_data['bank_transactions'] = $this->company->bank_transactions()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction) {
$bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','category_id','ninja_category_id','vendor_id']);
$this->export_data['bank_transactions'] = $this->company->bank_transactions()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction) {
$bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','ninja_category_id','vendor_id']);
return $bank_transaction->makeVisible(['id','user_id','company_id']);
})->all();
$this->export_data['schedulers'] = $this->company->schedulers()->orderBy('id', 'ASC')->cursor()->map(function ($scheduler) {
$this->export_data['schedulers'] = $this->company->schedulers()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($scheduler) {
$scheduler = $this->transformArrayOfKeys($scheduler, ['company_id', 'user_id']);
return $scheduler->makeVisible(['id','user_id','company_id']);

View File

@ -63,14 +63,12 @@ use App\Utils\Ninja;
use App\Utils\TempFile;
use App\Utils\Traits\GeneratesCounter;
use App\Utils\Traits\MakesHash;
use function GuzzleHttp\json_encode;
use Illuminate\Bus\Queueable;
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\Cache;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use JsonMachine\JsonDecoder\ExtJsonDecoder;
@ -142,7 +140,6 @@ class CompanyImport implements ShouldQueue
'recurring_expenses',
'expenses',
'tasks',
'payments',
'company_ledger',
'designs',
'documents',
@ -569,7 +566,7 @@ class CompanyImport implements ShouldQueue
['expenses' => 'expense_id'],
['vendors' => 'vendor_id'],
['expense_categories' => 'ninja_category_id'],
['expense_categories' => 'category_id'],
// ['expense_categories' => 'category_id'],
['bank_integrations' => 'bank_integration_id']
],
'bank_transactions',
@ -1143,7 +1140,34 @@ class CompanyImport implements ShouldQueue
continue;
}
$storage_url = (object)$this->getObject('storage_url', true);
if (!Storage::exists($document->url) && is_string($storage_url)) {
$url = $storage_url . $document->url;
$file = @file_get_contents($url);
if ($file) {
try {
Storage::disk(config('filesystems.default'))->put($document->url, $file);
} catch(\Exception $e) {
nlog($e->getMessage());
nlog("I could not upload {$document->url}");
}
}
else
continue;
}
else
continue;
$new_document = new Document();
$new_document->disk = config('filesystems.default');
$new_document->user_id = $this->transformId('users', $document->user_id);
$new_document->assigned_user_id = $this->transformId('users', $document->assigned_user_id);
$new_document->company_id = $this->company->id;
@ -1169,26 +1193,6 @@ class CompanyImport implements ShouldQueue
$new_document->save(['timestamps' => false]);
$storage_url = (object)$this->getObject('storage_url', true);
if (!Storage::exists($new_document->url) && is_string($storage_url)) {
$url = $storage_url . $new_document->url;
$file = @file_get_contents($url);
if ($file) {
try {
Storage::disk(config('filesystems.default'))->put($new_document->url, $file);
$new_document->disk = config('filesystems.default');
$new_document->save();
} catch(\Exception $e) {
nlog($e->getMessage());
nlog("I could not upload {$new_document->url}");
$new_document->forceDelete();
}
}
}
}
return $this;
@ -1727,7 +1731,9 @@ class CompanyImport implements ShouldQueue
*/
private function transformId(string $resource, ?string $old): ?int
{
if (empty($old)) {
// WjnegYbwZ1 == 0 return null;
if (empty($old) || $old == 'WjnegYbwZ1') {
return null;
}
@ -1736,6 +1742,7 @@ class CompanyImport implements ShouldQueue
}
if (! array_key_exists($resource, $this->ids)) {
$this->sendImportMail("The Import failed due to missing data in the import file. Resource {$resource} not available.");
throw new \Exception("Resource {$resource} not available.");
@ -1744,16 +1751,12 @@ class CompanyImport implements ShouldQueue
if (! array_key_exists("{$old}", $this->ids[$resource])) {
// nlog($this->ids[$resource]);
nlog("searching for {$old} in {$resource}");
nlog("If we are missing a user - default to the company owner");
if ($resource == 'users') {
return $this->company_owner->id;
}
$this->sendImportMail("The Import failed due to missing data in the import file. Resource {$resource} not available.");
nlog($this->ids[$resource]);
$this->sendImportMail("The Import failed due to missing data in the import file. Key {$old} not found in {$resource}.");
throw new \Exception("Missing {$resource} key: {$old}");
}

View File

@ -105,7 +105,7 @@ class PaymentFailedMailer implements ShouldQueue
});
//add client payment failures here.
//
if ($this->client->contacts()->whereNotNull('email')->exists() && $this->payment_hash) {
$contact = $this->client->contacts()->whereNotNull('email')->first();

View File

@ -305,14 +305,20 @@ class ProcessPostmarkWebhook implements ShouldQueue
if($sl) {
$this->updateSystemLog($sl, $data);
if (config('ninja.notification.slack')) {
$this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja();
}
return;
}
(new SystemLogger($data, SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company))->handle();
if (config('ninja.notification.slack')) {
$this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja();
}
if (config('ninja.notification.slack')) {
$this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja();
}
}
private function discoverInvitation($message_id)

View File

@ -307,8 +307,6 @@ class ReminderJob implements ShouldQueue
/**Refresh Invoice values*/
$invoice = $invoice->calc()->getInvoice();
// nlog('adjusting client balance and invoice balance by #'.$invoice->number.' '.($invoice->balance - $temp_invoice_balance));
// $invoice->client->service()->updateBalance($invoice->balance - $temp_invoice_balance);
$invoice->ledger()->updateInvoiceBalance($invoice->balance - $temp_invoice_balance, "Late Fee Adjustment for invoice {$invoice->number}");
$invoice->client->service()->calculateBalance();

View File

@ -113,6 +113,10 @@ class InstantBankPay implements MethodInterface
return $this->processSuccessfulPayment($payment);
}
if ($billing_request->status === 'submitted') {
return $this->processPendingPayment($payment);
}
return $this->processUnsuccessfulPayment($payment);
} catch (\Exception $exception) {
throw new PaymentFailed(
@ -125,7 +129,40 @@ class InstantBankPay implements MethodInterface
/**
* Handle pending payments for Instant Bank Transfer.
*
* @param ResourcesPayment $payment
* @param \GoCardlessPro\Resources\Payment $payment
* @param array $data
* @return RedirectResponse
*/
public function processPendingPayment(\GoCardlessPro\Resources\Payment $payment, array $data = [])
{
$data = [
'payment_method' => $payment->links->mandate,
'payment_type' => PaymentType::INSTANT_BANK_PAY,
'amount' => $this->go_cardless->payment_hash->data->amount_with_fee,
'transaction_reference' => $payment->id,
'gateway_type_id' => GatewayType::INSTANT_BANK_PAY,
];
$payment = $this->go_cardless->createPayment($data, Payment::STATUS_PENDING);
SystemLogger::dispatch(
['response' => $payment, 'data' => $data],
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_SUCCESS,
SystemLog::TYPE_GOCARDLESS,
$this->go_cardless->client,
$this->go_cardless->client->company,
);
return redirect()->route('client.payments.show', ['payment' => $this->go_cardless->encodePrimaryKey($payment->id)]);
}
/**
* Handle pending payments for Instant Bank Transfer.
*
* @param \GoCardlessPro\Resources\Payment $payment
* @param array $data
* @return RedirectResponse
*/
@ -163,12 +200,12 @@ class InstantBankPay implements MethodInterface
{
PaymentFailureMailer::dispatch($this->go_cardless->client, $payment->status, $this->go_cardless->client->company, $this->go_cardless->payment_hash->data->amount_with_fee);
PaymentFailureMailer::dispatch(
$this->go_cardless->client,
$payment,
$this->go_cardless->client->company,
$payment->amount
);
// PaymentFailureMailer::dispatch(
// $this->go_cardless->client,
// $payment,
// $this->go_cardless->client->company,
// $payment->amount
// );
$message = [
'server_response' => $payment,

View File

@ -165,7 +165,7 @@ class GoCardlessPaymentDriver extends BaseDriver
],
]);
if ($payment->status === 'pending_submission') {
if (in_array($payment->status, ['submitted', 'pending_submission'])) {
$this->confirmGatewayFee();
$data = [

View File

@ -70,7 +70,7 @@ class EmailReport
'report_keys' => []
];
if (count($this->scheduler->parameters['clients']) >= 1) {
if (isset($this->scheduler->parameters['clients']) && count($this->scheduler->parameters['clients']) >= 1) {
$data['clients'] = $this->transformKeys($this->scheduler->parameters['clients']);
}
@ -84,20 +84,20 @@ class EmailReport
'client_balance' => $export = (new ClientBalanceReport($this->scheduler->company, $data)),
'client_sales' => $export = (new ClientSalesReport($this->scheduler->company, $data)),
'user_sales' => $export = (new UserSalesReport($this->scheduler->company, $data)),
'clients' => $export = (new ClientExport($this->scheduler->company, $data)),
'client_contacts' => $export = (new ContactExport($this->scheduler->company, $data)),
'credits' => $export = (new CreditExport($this->scheduler->company, $data)),
'documents' => $export = (new DocumentExport($this->scheduler->company, $data)),
'expenses' => $export = (new ExpenseExport($this->scheduler->company, $data)),
'invoices' => $export = (new InvoiceExport($this->scheduler->company, $data)),
'invoice_items' => $export = (new InvoiceItemExport($this->scheduler->company, $data)),
'quotes' => $export = (new QuoteExport($this->scheduler->company, $data)),
'quote_items' => $export = (new QuoteItemExport($this->scheduler->company, $data)),
'recurring_invoices' => $export = (new RecurringInvoiceExport($this->scheduler->company, $data)),
'payments' => $export = (new PaymentExport($this->scheduler->company, $data)),
'products' => $export = (new ProductExport($this->scheduler->company, $data)),
'tasks' => $export = (new TaskExport($this->scheduler->company, $data)),
'profitloss' => $export = (new ProfitLoss($this->scheduler->company, $data)),
'client' => $export = (new ClientExport($this->scheduler->company, $data)),
'client_contact' => $export = (new ContactExport($this->scheduler->company, $data)),
'credit' => $export = (new CreditExport($this->scheduler->company, $data)),
'document' => $export = (new DocumentExport($this->scheduler->company, $data)),
'expense' => $export = (new ExpenseExport($this->scheduler->company, $data)),
'invoice' => $export = (new InvoiceExport($this->scheduler->company, $data)),
'invoice_item' => $export = (new InvoiceItemExport($this->scheduler->company, $data)),
'quote' => $export = (new QuoteExport($this->scheduler->company, $data)),
'quote_item' => $export = (new QuoteItemExport($this->scheduler->company, $data)),
'recurring_invoice' => $export = (new RecurringInvoiceExport($this->scheduler->company, $data)),
'payment' => $export = (new PaymentExport($this->scheduler->company, $data)),
'product' => $export = (new ProductExport($this->scheduler->company, $data)),
'task' => $export = (new TaskExport($this->scheduler->company, $data)),
default => $export = false,
};

86
composer.lock generated
View File

@ -485,16 +485,16 @@
},
{
"name": "aws/aws-sdk-php",
"version": "3.293.5",
"version": "3.293.7",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "f2002e52b382b45231da3f9552033f769acfebd8"
"reference": "3bf86ba8b9bbea2b298f89e6f5edc58de276690b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/f2002e52b382b45231da3f9552033f769acfebd8",
"reference": "f2002e52b382b45231da3f9552033f769acfebd8",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3bf86ba8b9bbea2b298f89e6f5edc58de276690b",
"reference": "3bf86ba8b9bbea2b298f89e6f5edc58de276690b",
"shasum": ""
},
"require": {
@ -574,9 +574,9 @@
"support": {
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
"issues": "https://github.com/aws/aws-sdk-php/issues",
"source": "https://github.com/aws/aws-sdk-php/tree/3.293.5"
"source": "https://github.com/aws/aws-sdk-php/tree/3.293.7"
},
"time": "2023-12-06T19:09:15+00:00"
"time": "2023-12-08T19:11:21+00:00"
},
{
"name": "bacon/bacon-qr-code",
@ -6576,16 +6576,16 @@
},
{
"name": "nesbot/carbon",
"version": "2.72.0",
"version": "2.72.1",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "a6885fcbad2ec4360b0e200ee0da7d9b7c90786b"
"reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/a6885fcbad2ec4360b0e200ee0da7d9b7c90786b",
"reference": "a6885fcbad2ec4360b0e200ee0da7d9b7c90786b",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/2b3b3db0a2d0556a177392ff1a3bf5608fa09f78",
"reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78",
"shasum": ""
},
"require": {
@ -6679,7 +6679,7 @@
"type": "tidelift"
}
],
"time": "2023-11-28T10:13:25+00:00"
"time": "2023-12-08T23:47:49+00:00"
},
{
"name": "nette/schema",
@ -6831,16 +6831,16 @@
},
{
"name": "nikic/php-parser",
"version": "v4.17.1",
"version": "v4.18.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
"shasum": ""
},
"require": {
@ -6881,9 +6881,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
"source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0"
},
"time": "2023-08-13T19:53:39+00:00"
"time": "2023-12-10T21:03:43+00:00"
},
{
"name": "nunomaduro/termwind",
@ -13841,23 +13841,23 @@
},
{
"name": "tijsverkoyen/css-to-inline-styles",
"version": "2.2.6",
"version": "v2.2.7",
"source": {
"type": "git",
"url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
"reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c"
"reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/c42125b83a4fa63b187fdf29f9c93cb7733da30c",
"reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c",
"url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/83ee6f38df0a63106a9e4536e3060458b74ccedb",
"reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"php": "^5.5 || ^7.0 || ^8.0",
"symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
"symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10"
@ -13888,9 +13888,9 @@
"homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
"support": {
"issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues",
"source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.6"
"source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.2.7"
},
"time": "2023-01-03T09:29:04+00:00"
"time": "2023-12-08T13:03:43+00:00"
},
{
"name": "turbo124/beacon",
@ -15263,16 +15263,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.40.2",
"version": "v3.41.1",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8"
"reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4344562a516b76afe8f2d64b2e52214c30d64ed8",
"reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/8b6ae8dcbaf23f09680643ab832a4a3a260265f6",
"reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6",
"shasum": ""
},
"require": {
@ -15302,8 +15302,6 @@
"php-cs-fixer/accessible-object": "^1.1",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4",
"phpspec/prophecy": "^1.17",
"phpspec/prophecy-phpunit": "^2.0",
"phpunit/phpunit": "^9.6",
"symfony/phpunit-bridge": "^6.3.8 || ^7.0",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
@ -15344,7 +15342,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.40.2"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.41.1"
},
"funding": [
{
@ -15352,7 +15350,7 @@
"type": "github"
}
],
"time": "2023-12-03T09:21:33+00:00"
"time": "2023-12-10T19:59:27+00:00"
},
{
"name": "hamcrest/hamcrest-php",
@ -15633,16 +15631,16 @@
},
{
"name": "mockery/mockery",
"version": "1.6.6",
"version": "1.6.7",
"source": {
"type": "git",
"url": "https://github.com/mockery/mockery.git",
"reference": "b8e0bb7d8c604046539c1115994632c74dcb361e"
"reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mockery/mockery/zipball/b8e0bb7d8c604046539c1115994632c74dcb361e",
"reference": "b8e0bb7d8c604046539c1115994632c74dcb361e",
"url": "https://api.github.com/repos/mockery/mockery/zipball/0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06",
"reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06",
"shasum": ""
},
"require": {
@ -15655,9 +15653,7 @@
},
"require-dev": {
"phpunit/phpunit": "^8.5 || ^9.6.10",
"psalm/plugin-phpunit": "^0.18.4",
"symplify/easy-coding-standard": "^11.5.0",
"vimeo/psalm": "^4.30"
"symplify/easy-coding-standard": "^12.0.8"
},
"type": "library",
"autoload": {
@ -15714,7 +15710,7 @@
"security": "https://github.com/mockery/mockery/security/advisories",
"source": "https://github.com/mockery/mockery"
},
"time": "2023-08-09T00:03:52+00:00"
"time": "2023-12-10T02:24:34+00:00"
},
{
"name": "myclabs/deep-copy",
@ -16071,16 +16067,16 @@
},
{
"name": "phpstan/phpstan",
"version": "1.10.47",
"version": "1.10.48",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39"
"reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/84dbb33b520ea28b6cf5676a3941f4bae1c1ff39",
"reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6",
"reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6",
"shasum": ""
},
"require": {
@ -16129,7 +16125,7 @@
"type": "tidelift"
}
],
"time": "2023-12-01T15:19:17+00:00"
"time": "2023-12-08T14:34:28+00:00"
},
{
"name": "phpunit/php-code-coverage",

View File

@ -17,8 +17,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => env('APP_VERSION', '5.7.59'),
'app_tag' => env('APP_TAG', '5.7.59'),
'app_version' => env('APP_VERSION', '5.7.60'),
'app_tag' => env('APP_TAG', '5.7.60'),
'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', false),

View File

@ -28,8 +28,20 @@ class DomainCheckTest extends TestCase
public function testDomainCheck()
{
$this->assertTrue(in_array('yopmail.com', Domains::getDomains()));
$this->assertFalse(in_array('invoiceninja.com', Domains::getDomains()));
$this->assertTrue(in_array('yopmail.com', \App\DataProviders\Domains::getDomains()));
$this->assertFalse(in_array('invoiceninja.com', \App\DataProviders\Domains::getDomains()));
}
public function testSubdomainValidation()
{
$this->assertFalse($this->checker('invoiceninja'));
$this->assertFalse($this->checker('hello'));
$this->assertTrue($this->checker('nasty.pasty'));
}
public function checker($subdomain)
{
return (!preg_match('/^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$/', $subdomain));
}
}