Fixes for validation of webhooks

This commit is contained in:
David Bomba 2023-01-27 21:38:59 +11:00
parent c121971636
commit 0a696da9f5
5 changed files with 196 additions and 5 deletions

View File

@ -16,12 +16,14 @@ use App\Factory\CreditFactory;
use App\Factory\InvoiceFactory;
use App\Factory\QuoteFactory;
use App\Factory\RecurringInvoiceFactory;
use App\Http\Requests\Preview\DesignPreviewRequest;
use App\Http\Requests\Preview\PreviewInvoiceRequest;
use App\Jobs\Util\PreviewPdf;
use App\Libraries\MultiDB;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Credit;
use App\Models\GroupSetting;
use App\Models\Invoice;
use App\Models\InvoiceInvitation;
use App\Models\Quote;
@ -30,9 +32,9 @@ use App\Repositories\CreditRepository;
use App\Repositories\InvoiceRepository;
use App\Repositories\QuoteRepository;
use App\Repositories\RecurringInvoiceRepository;
use App\Services\PdfMaker\Design;
use App\Services\PdfMaker\Design as PdfDesignModel;
use App\Services\PdfMaker\Design as PdfMakerDesign;
use App\Services\PdfMaker\Design;
use App\Services\PdfMaker\PdfMaker;
use App\Utils\HostedPDF\NinjaPdf;
use App\Utils\HtmlEngine;
@ -173,6 +175,170 @@ class PreviewController extends BaseController
return $this->blankEntity();
}
public function design(DesignPreviewRequest $request)
{
$company = auth()->user()->company();
MultiDB::setDb($company->db);
if ($request->input('entity') == 'quote') {
$repo = new QuoteRepository();
$entity_obj = QuoteFactory::create($company->id, auth()->user()->id);
$class = Quote::class;
} elseif ($request->input('entity') == 'credit') {
$repo = new CreditRepository();
$entity_obj = CreditFactory::create($company->id, auth()->user()->id);
$class = Credit::class;
} elseif ($request->input('entity') == 'recurring_invoice') {
$repo = new RecurringInvoiceRepository();
$entity_obj = RecurringInvoiceFactory::create($company->id, auth()->user()->id);
$class = RecurringInvoice::class;
} else { //assume it is either an invoice or a null object
$repo = new InvoiceRepository();
$entity_obj = InvoiceFactory::create($company->id, auth()->user()->id);
$class = Invoice::class;
}
try {
DB::connection(config('database.default'))->beginTransaction();
if ($request->has('entity_id')) {
$entity_obj = $class::on(config('database.default'))
->with('client.company')
->where('id', $this->decodePrimaryKey($request->input('entity_id')))
->where('company_id', $company->id)
->withTrashed()
->first();
}
if($request->has('client_id')) {
$client = Client::withTrashed()->find($this->decodePrimaryKey($request->client_id));
if($request->settings_type == 'client'){
$client->settings = $request->settings;
$client->save();
}
}
if($request->has('group_id')) {
$group = GroupSetting::withTrashed()->find($this->decodePrimaryKey($request->group_id));
if($request->settings_type == 'group'){
$group->settings = $request->settings;
$group->save();
}
}
if($request->settings_type == 'company'){
$company->settings = $request->settings;
$company->save();
}
if($request->has('footer') && !$request->filled('footer') && $request->input('entity') == 'recurring_invoice')
$request->merge(['footer' => $company->settings->invoice_footer]);
if($request->has('terms') && !$request->filled('terms') && $request->input('entity') == 'recurring_invoice')
$request->merge(['terms' => $company->settings->invoice_terms]);
$entity_obj = $repo->save($request->all(), $entity_obj);
if (! $request->has('entity_id')) {
$entity_obj->service()->fillDefaults()->save();
}
App::forgetInstance('translator');
$t = app('translator');
App::setLocale($entity_obj->client->locale());
$t->replace(Ninja::transformTranslations($entity_obj->client->getMergedSettings()));
$html = new HtmlEngine($entity_obj->invitations()->first());
$design = \App\Models\Design::find($entity_obj->design_id);
/* Catch all in case migration doesn't pass back a valid design */
if (! $design) {
$design = \App\Models\Design::find(2);
}
if ($design->is_custom) {
$options = [
'custom_partials' => json_decode(json_encode($design->design), true),
];
$template = new PdfMakerDesign(PdfDesignModel::CUSTOM, $options);
} else {
$template = new PdfMakerDesign(strtolower($design->name));
}
$variables = $html->generateLabelsAndValues();
$state = [
'template' => $template->elements([
'client' => $entity_obj->client,
'entity' => $entity_obj,
'pdf_variables' => (array) $entity_obj->company->settings->pdf_variables,
'$product' => $design->design->product,
'variables' => $variables,
]),
'variables' => $variables,
'options' => [
'all_pages_header' => $entity_obj->client->getSetting('all_pages_header'),
'all_pages_footer' => $entity_obj->client->getSetting('all_pages_footer'),
],
'process_markdown' => $entity_obj->client->company->markdown_enabled,
];
$maker = new PdfMaker($state);
$maker
->design($template)
->build();
DB::connection(config('database.default'))->rollBack();
nlog($maker->getCompiledHTML());
if (request()->query('html') == 'true') {
nlog($maker->getCompiledHTML());
return $maker->getCompiledHTML();
}
}
catch(\Exception $e){
nlog($e->getMessage());
DB::connection(config('database.default'))->rollBack();
return;
}
//if phantom js...... inject here..
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
return (new Phantom)->convertHtmlToPdf($maker->getCompiledHTML(true));
}
if(config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja'){
$pdf = (new NinjaPdf())->build($maker->getCompiledHTML(true));
$numbered_pdf = $this->pageNumbering($pdf, auth()->user()->company());
$numbered_pdf = $this->pageNumbering($pdf, auth()->user()->company());
if ($numbered_pdf) {
$pdf = $numbered_pdf;
}
return $pdf;
}
$file_path = (new PreviewPdf($maker->getCompiledHTML(true), $company))->handle();
$response = Response::make($file_path, 200);
$response->header('Content-Type', 'application/pdf');
return $response;
}
public function live(PreviewInvoiceRequest $request)
{
$company = auth()->user()->company();

View File

@ -28,8 +28,10 @@ class StoreWebhookRequest extends Request
public function rules()
{
return [
'target_url' => 'required|url',
'event_id' => 'required',
'target_url' => 'bail|required|url',
'event_id' => 'bail|required',
'headers' => 'bail|sometimes|json',
'rest_method' => 'required|in:post,put'
];
}
@ -37,6 +39,9 @@ class StoreWebhookRequest extends Request
{
$input = $this->all();
if(isset($input['headers']) && count($input['headers']) == 0)
$input['headers'] = null;
$this->replace($input);
}
}

View File

@ -27,13 +27,16 @@ class UpdateWebhookRequest extends Request
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
return auth()->user()->can('edit', $this->webhook);
}
public function rules()
{
return [
'target_url' => 'url',
'target_url' => 'bail|required|url',
'event_id' => 'bail|required',
'rest_method' => 'required|in:post,put',
'headers' => 'bail|sometimes|json',
];
}
@ -41,6 +44,9 @@ class UpdateWebhookRequest extends Request
{
$input = $this->all();
if(isset($input['headers']) && count($input['headers']) == 0)
$input['headers'] = null;
$this->replace($input);
}
}

View File

@ -11,9 +11,22 @@
namespace App\Policies;
use App\Models\User;
/**
* Class WebhookPolicy.
*/
class WebhookPolicy extends EntityPolicy
{
/**
* Checks if the user has create permissions.
*
* @param User $user
* @return bool
*/
public function create(User $user) : bool
{
return $user->isAdmin();
}
}

View File

@ -228,6 +228,7 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale
Route::post('preview', [PreviewController::class, 'show'])->name('preview.show');
Route::post('live_preview', [PreviewController::class, 'live'])->name('preview.live');
Route::post('live_design', [PreviewController::class, 'design'])->name('preview.design');
Route::post('preview/purchase_order', [PreviewPurchaseOrderController::class, 'show'])->name('preview_purchase_order.show');
Route::post('live_preview/purchase_order', [PreviewPurchaseOrderController::class, 'live'])->name('preview_purchase_order.live');