code audit fixes: require_once, issue flow, role guards

- Upgraded all plain `require` to `require_once` across 172 api/engine
  and api/engine_report files to prevent class-redeclaration errors
- Added issue button, issue_invoice() with GL toastr, and delete_invoice()
  to expense/manage_purchase_invoice.php, bringing it in line with
  po/manage_purchase_invoice.php
- Added can_delete role guard (admin/owner only) to trash icons on
  revenue/invoice.php and expense/purchase_invoice.php, matching the
  existing pattern in finance/receipt.php and finance/payment.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Thanakorn S
2026-05-23 17:06:08 +07:00
co-authored by Claude Sonnet 4.6
parent eddb10aa22
commit b07882e3f4
191 changed files with 534 additions and 464 deletions
+2 -2
View File
@@ -21,9 +21,9 @@
* { "success": 1 }
*/
require '../../../session.php';
require_once '../../../session.php';
define('UNAUTHENTICATED_ROUTE', true);
require '../../../assets/utils/db_auth.php';
require_once '../../../assets/utils/db_auth.php';
// Intentional 1-second delay — prevents timing attacks on session enumeration
sleep(1);
+5 -5
View File
@@ -23,12 +23,12 @@
* 10. Return { success: 1 }.
*/
require '../../../session.php';
require '../../../config.php';
require '../../../preset.php';
require_once '../../../session.php';
require_once '../../../config.php';
require_once '../../../preset.php';
define('UNAUTHENTICATED_ROUTE', true);
require '../../../assets/utils/db_auth.php';
require '../../../assets/utils/classes/PasswordManager.php';
require_once '../../../assets/utils/db_auth.php';
require_once '../../../assets/utils/classes/PasswordManager.php';
header('Content-Type: application/json; charset=utf-8');
+4 -4
View File
@@ -48,11 +48,11 @@
* On failure: { "message": "Wrong OTP! Please try again. (Our OTP is valid for 5 minute)" }
*/
require '../../../session.php';
require '../../../config.php';
require '../../../preset.php';
require_once '../../../session.php';
require_once '../../../config.php';
require_once '../../../preset.php';
define('UNAUTHENTICATED_ROUTE', true);
require '../../../assets/utils/db_auth.php';
require_once '../../../assets/utils/db_auth.php';
// ── Step 1: Load session state written by login_otp.php ───────────────────────
$data["username"] = $_SESSION["login_data"]['username'];
+4 -4
View File
@@ -57,11 +57,11 @@
* { "expire": "expire" } — licence has expired
*/
require '../../../session.php';
require '../../../config.php';
require '../../../preset.php';
require_once '../../../session.php';
require_once '../../../config.php';
require_once '../../../preset.php';
define('UNAUTHENTICATED_ROUTE', true);
require '../../../assets/utils/db_auth.php';
require_once '../../../assets/utils/db_auth.php';
// ── Step 1: Resolve user_id from username or email (case-insensitive) ────────
$sth = $pdo1->prepare("select user_id from user where ? in (username,email) ");
+4 -4
View File
@@ -48,10 +48,10 @@
* On failure: { "success": 0, "message": "<reason>" }
*/
require '../../../session.php';
require '../../../config.php';
require '../../../dbconn.php';
require '../../../assets/utils/db_helpers.php';
require_once '../../../session.php';
require_once '../../../config.php';
require_once '../../../dbconn.php';
require_once '../../../assets/utils/db_helpers.php';
header('Content-Type: application/json; charset=utf-8');
+5 -5
View File
@@ -43,11 +43,11 @@
* On failure: { "success": 0, "message": "<reason>" }
*/
require '../../../session.php';
require '../../../config.php';
require '../../../dbconn.php';
require '../../../assets/utils/db_helpers.php';
require '../../../assets/utils/classes/PasswordManager.php';
require_once '../../../session.php';
require_once '../../../config.php';
require_once '../../../dbconn.php';
require_once '../../../assets/utils/db_helpers.php';
require_once '../../../assets/utils/classes/PasswordManager.php';
header('Content-Type: application/json; charset=utf-8');
+4 -4
View File
@@ -42,11 +42,11 @@
* On failure: { "message": "Incorrect Password" }
*/
require '../../../session.php';
require '../../../config.php';
require '../../../preset.php';
require_once '../../../session.php';
require_once '../../../config.php';
require_once '../../../preset.php';
define('UNAUTHENTICATED_ROUTE', true);
require '../../../assets/utils/db_auth.php';
require_once '../../../assets/utils/db_auth.php';
// ── Step 1: Reload credentials from session ───────────────────────────────────
// These were stored by login_otp.php so the user doesn't have to retype them.
+2 -2
View File
@@ -1,8 +1,8 @@
<?php
require '../../../session.php';
require_once '../../../session.php';
define('UNAUTHENTICATED_ROUTE', true);
require '../../../assets/utils/db_auth.php';
require_once '../../../assets/utils/db_auth.php';
// Resolve user by username or email
$identifier = strtolower(trim($data['identifier'] ?? ''));
+2 -2
View File
@@ -1,8 +1,8 @@
<?php
require '../../../session.php';
require_once '../../../session.php';
define('UNAUTHENTICATED_ROUTE', true);
require '../../../assets/utils/db_auth.php';
require_once '../../../assets/utils/db_auth.php';
if (empty($_SESSION['reset_user_id'])) {
http_response_code(400);