From b7df85b084e9aaecef29ff6712015194f96e0c22 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 26 Jan 2018 18:07:47 +0000 Subject: [PATCH] Security fix for invoice view. Also paid status handler for invoice view. --- WEB-INF/lib/ttInvoiceHelper.class.php | 20 ++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/invoice_view.tpl | 14 +++++++++ invoice_view.php | 44 ++++++++++++++++++++++++--- 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index c30776c0..9fa7e58c 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -80,8 +80,10 @@ class ttInvoiceHelper { // The getInvoiceByName looks up an invoice by name. static function getInvoiceByName($invoice_name) { + $mdb2 = getConnection(); global $user; + $sql = "select id from tt_invoices where team_id = $user->team_id and name = ".$mdb2->quote($invoice_name)." and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -121,6 +123,24 @@ class ttInvoiceHelper { return false; } + // markPaid marks invoice items as paid. + static function markPaid($invoice_id, $mark_paid = true) { + + global $user; + $mdb2 = getConnection(); + + $paid_status = $mark_paid ? 1 : 0; + $sql = "update tt_log set paid = $paid_status where invoice_id = $invoice_id and status = 1"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + $sql = "update tt_expense_items set paid = $paid_status where invoice_id = $invoice_id and status = 1"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) return false; + + return true; + } + // The getInvoiceItems retrieves tt_log items associated with the invoice. static function getInvoiceItems($invoice_id) { global $user; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 54394134..75517620 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.17.5.3792 | Copyright © Anuko | +  Anuko Time Tracker 1.17.6.3793 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/invoice_view.tpl b/WEB-INF/templates/invoice_view.tpl index ec8bb96e..9faa3bb2 100644 --- a/WEB-INF/templates/invoice_view.tpl +++ b/WEB-INF/templates/invoice_view.tpl @@ -67,6 +67,20 @@ {$total|escape}
+ + {$forms.invoiceForm.open} + {if $user->isPluginEnabled('ps')} + + + + +
+ + +
{$i18n.label.mark_paid}: {$forms.invoiceForm.mark_paid_action_options.control} {$forms.invoiceForm.btn_mark_paid.control}
+
+ {/if} + {$forms.invoiceForm.close} {/if} diff --git a/invoice_view.php b/invoice_view.php index e94c04b7..7661d9c9 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -30,6 +30,7 @@ require_once('initialize.php'); import('DateAndTime'); import('ttInvoiceHelper'); import('ttClientHelper'); +import('form.Form'); // Access check. if (!ttAccessCheck(right_view_invoices) || !$user->isPluginEnabled('iv')) { @@ -37,14 +38,21 @@ if (!ttAccessCheck(right_view_invoices) || !$user->isPluginEnabled('iv')) { exit(); } -$invoice_id = (int)$request->getParameter('id'); -$invoice = ttInvoiceHelper::getInvoice($invoice_id); +$cl_id = (int)$request->getParameter('id'); +$invoice = ttInvoiceHelper::getInvoice($cl_id); +// Temporary fix for invalid invoice id. TODO: implement properly and review security of other pages, +// where item id is passed (or posted) as parameter. +if (!$invoice) { + header('Location: access_denied.php'); + exit(); +} + $invoice_date = new DateAndTime(DB_DATEFORMAT, $invoice['date']); $client = ttClientHelper::getClient($invoice['client_id'], true); if (!$client) // In case client was deleted. $client = ttClientHelper::getDeletedClient($invoice['client_id']); -$invoice_items = ttInvoiceHelper::getInvoiceItems($invoice_id); +$invoice_items = ttInvoiceHelper::getInvoiceItems($cl_id); $tax_percent = $client['tax']; $subtotal = 0; @@ -77,7 +85,35 @@ if (MODE_PROJECTS == $user->tracking_mode) elseif (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) $colspan += 2; -$smarty->assign('invoice_id', $invoice_id); +$form = new Form('invoiceForm'); +// Hidden control for invoice id. +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); +// invoiceForm only contains controls for "Mark paid" block below invoice table. +if ($user->isPluginEnabled('ps')) { + $mark_paid_action_options = array('1'=>$i18n->getKey('dropdown.paid'),'2'=>$i18n->getKey('dropdown.not_paid')); + $form->addInput(array('type'=>'combobox', + 'name'=>'mark_paid_action_options', + 'data'=>$mark_paid_action_options, + 'value'=>$cl_mark_paid_action_option)); + $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->getKey('button.submit'))); +} + +if ($request->isPost()) { + if ($request->getParameter('btn_mark_paid')) { + // User clicked the "Mark paid" button to mark all invoice items either paid or not paid. + + // Determine user action. + $mark_paid = $request->getParameter('mark_paid_action_options') == 1 ? true : false; + ttInvoiceHelper::markPaid($cl_id, $mark_paid); + + // Re-display this form. + header('Location: invoice_view.php?id='.$cl_id); + exit(); + } +} + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('invoice_id', $cl_id); $smarty->assign('invoice_name', $invoice['name']); $smarty->assign('invoice_date', $invoice_date->toString($user->date_format)); $smarty->assign('client_name', $client['name']); -- 2.20.1