diff --git a/app/Controllers/Config.php b/app/Controllers/Config.php index 0f46ae023..df95fc82a 100644 --- a/app/Controllers/Config.php +++ b/app/Controllers/Config.php @@ -924,7 +924,9 @@ class Config extends Secure_Controller public function postSaveReceipt(): ResponseInterface { $batch_save_data = [ - 'receipt_template' => $this->request->getPost('receipt_template'), + 'receipt_template' => Sale_lib::isValidReceiptTemplate($this->request->getPost('receipt_template')) + ? $this->request->getPost('receipt_template') + : 'receipt_default', 'receipt_font_size' => $this->request->getPost('receipt_font_size', FILTER_SANITIZE_NUMBER_INT), 'print_delay_autoreturn' => $this->request->getPost('print_delay_autoreturn', FILTER_SANITIZE_NUMBER_INT), 'email_receipt_check_behaviour' => $this->request->getPost('email_receipt_check_behaviour'), diff --git a/app/Controllers/Sales.php b/app/Controllers/Sales.php index 81e263335..1d60d44bb 100644 --- a/app/Controllers/Sales.php +++ b/app/Controllers/Sales.php @@ -908,6 +908,14 @@ class Sales extends Secure_Controller return $this->_reload($data); } else { $data['barcode'] = $this->barcode_lib->generate_receipt_barcode($data['sale_id']); + + // Validate receipt template to prevent path traversal + $receipt_template = $this->config['receipt_template'] ?? ''; + if (!Sale_lib::isValidReceiptTemplate($receipt_template)) { + $receipt_template = 'receipt_default'; + } + $data['receipt_template_view'] = $receipt_template; + $this->sale_lib->clear_all(); return view('sales/receipt', $data); } @@ -1163,6 +1171,13 @@ class Sales extends Secure_Controller } $data['invoice_view'] = $invoice_type; + // Validate receipt template to prevent path traversal + $receipt_template = $this->config['receipt_template'] ?? ''; + if (!Sale_lib::isValidReceiptTemplate($receipt_template)) { + $receipt_template = 'receipt_default'; + } + $data['receipt_template_view'] = $receipt_template; + return $data; } diff --git a/app/Libraries/Sale_lib.php b/app/Libraries/Sale_lib.php index 44a79449d..58c9ce233 100644 --- a/app/Libraries/Sale_lib.php +++ b/app/Libraries/Sale_lib.php @@ -108,6 +108,11 @@ class Sale_lib 'custom_tax_invoice' ]; + private const ALLOWED_RECEIPT_TEMPLATES = [ + 'receipt_default', + 'receipt_short' + ]; + public function get_invoice_type_options(): array { $invoice_types = []; @@ -161,6 +166,11 @@ class Sale_lib return in_array($invoice_type, self::ALLOWED_INVOICE_TYPES, true); } + public static function isValidReceiptTemplate(string $receipt_template): bool + { + return in_array($receipt_template, self::ALLOWED_RECEIPT_TEMPLATES, true); + } + /** * @return array */ diff --git a/app/Models/Reports/Summary_sales_taxes.php b/app/Models/Reports/Summary_sales_taxes.php index a739bfe7d..5b4db1077 100644 --- a/app/Models/Reports/Summary_sales_taxes.php +++ b/app/Models/Reports/Summary_sales_taxes.php @@ -33,14 +33,16 @@ class Summary_sales_taxes extends Summary_report * @param object $builder * @return void */ - protected function _where(array $inputs, object &$builder): void // TODO: hungarian notation + protected function _where(array $inputs, object &$builder): void { $builder->where('sales.sale_status', COMPLETED); - if (empty($this->config['date_or_time_format'])) { // TODO: Duplicated code - $builder->where('DATE(sales.sale_time) BETWEEN ' . $this->db->escape($inputs['start_date']) . ' AND ' . $this->db->escape($inputs['end_date'])); + if (empty($this->config['date_or_time_format'])) { + $builder->where('DATE(sales.sale_time) >=', $inputs['start_date']); + $builder->where('DATE(sales.sale_time) <=', $inputs['end_date']); } else { - $builder->where('sales.sale_time BETWEEN ' . $this->db->escape(rawurldecode($inputs['start_date'])) . ' AND ' . $this->db->escape(rawurldecode($inputs['end_date']))); + $builder->where('sales.sale_time >=', $inputs['start_date']); + $builder->where('sales.sale_time <=', $inputs['end_date']); } } @@ -53,9 +55,11 @@ class Summary_sales_taxes extends Summary_report $builder = $this->db->table('sales_taxes'); if (empty($this->config['date_or_time_format'])) { - $builder->where('DATE(sale_time) BETWEEN ' . $inputs['start_date'] . ' AND ' . $inputs['end_date']); + $builder->where('DATE(sale_time) >=', $inputs['start_date']); + $builder->where('DATE(sale_time) <=', $inputs['end_date']); } else { - $builder->where('sale_time BETWEEN ' . $this->db->escape(rawurldecode($inputs['start_date'])) . ' AND ' . $this->db->escape(rawurldecode($inputs['end_date']))); + $builder->where('sale_time >=', $inputs['start_date']); + $builder->where('sale_time <=', $inputs['end_date']); } $builder->select('reporting_authority, jurisdiction_name, tax_category, tax_rate, SUM(sale_tax_amount) AS tax'); diff --git a/app/Views/sales/receipt.php b/app/Views/sales/receipt.php index cd168cb33..b27031eae 100644 --- a/app/Views/sales/receipt.php +++ b/app/Views/sales/receipt.php @@ -2,11 +2,14 @@ /** * @var int $sale_id_num * @var bool $print_after_sale + * @var string $receipt_template_view * @var array $config */ use App\Models\Employee; +$template = $receipt_template_view ?? 'receipt_default'; + ?> @@ -61,6 +64,6 @@ if (isset($error_message)) { - +