diff --git a/app/assets/js/custom.js b/app/assets/js/custom.js index c13bb34..25747f9 100644 --- a/app/assets/js/custom.js +++ b/app/assets/js/custom.js @@ -235,7 +235,12 @@ function ajax_request(options) { dataType: "json", // These two settings are only triggered when sending files processData: isSendingFiles ? false : true, - contentType: isSendingFiles ? false : "application/x-www-form-urlencoded; charset=UTF-8" + contentType: isSendingFiles ? false : "application/x-www-form-urlencoded; charset=UTF-8", + // for CSRF validation + headers: { + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') + } + }) .then(function (res) { diff --git a/app/assets/utils/db_auth.php b/app/assets/utils/db_auth.php index 87ba99f..7b2e433 100644 --- a/app/assets/utils/db_auth.php +++ b/app/assets/utils/db_auth.php @@ -3,18 +3,94 @@ require_once __DIR__."/../../config.php"; require_once __DIR__."/../../dbconn.php"; + +/** + * Check PDO statement for errors + * Logs full error server-side, returns generic message to client + * + * @param PDOStatement $sth - The executed PDO statement + * @param array &$answer - Response array passed by reference + * @param array $options - Optional settings: + * 'message' => Custom client-facing error message + * 'log' => Custom server log label + * 'code' => HTTP response code (default: 500) + * 'before_exit' => Callback function before exit + * + * @example + * // Simple — use all defaults + * db_check($sth, $answer); + * + * @example + * // Custom client message + * db_check($sth, $answer, [ + * 'message' => "Contact not found." + * ]); + * + * @example + * // Custom log label + message + * db_check($sth, $answer, [ + * 'log' => "Failed to fetch contact", + * 'message' => "Could not load contact. Please try again." + * ]); + * + * @example + * // Custom HTTP status code + * db_check($sth, $answer, [ + * 'code' => 403, + * 'message' => "Access denied." + * ]); + * + * @example + * // Cleanup callback before exit + * db_check($sth, $answer, [ + * 'message' => "Upload failed.", + * 'before_exit' => function() use ($tmp_file) { + * if(file_exists($tmp_file)) unlink($tmp_file); + * } + * ]); + */ +function db_check($sth, &$answer, $options = []) { + if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { + + $trace = debug_backtrace()[0]; + + $log_message = $options['log'] ?? "DB Error"; + error_log($log_message . " in " . $trace['file'] . " line " . $trace['line'] . ": " . $sth->errorInfo()[2]); + + $answer["message"] = $options['message'] ?? "A server error occurred. Please try again."; + + http_response_code($options['code'] ?? 500); + + if(isset($options['before_exit'])) { + call_user_func($options['before_exit']); + } + + exit(json_encode($answer)); + } +} + + + if(!empty($_SESSION["login_company_id"])){ + // CSRF Validation — add right at the top of the logged-in block + if($_SERVER['REQUEST_METHOD'] === 'POST'){ + $csrf_token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? ''; + if(empty($csrf_token) || $csrf_token !== $_SESSION['csrf_token']){ + http_response_code(403); + exit(json_encode(["message" => "Invalid request"])); + } + } + // validate otp $sql = "SELECT `password` FROM user - WHERE user_id = {$_SESSION["login_user_id"]}"; + WHERE user_id = :company_id"; $sth = $pdo1->prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $_SESSION["login_user_id"] + ]); + db_check($sth, $answer); $password = $sth->fetchColumn(); /** Generate OTP */ function generateOTP($sercet_key, $time_step = 180, $length = 6){ @@ -35,13 +111,13 @@ if(!empty($_SESSION["login_company_id"])){ } // check company accessibily - $sql = "SELECT * FROM company_map_user WHERE company_id = {$_SESSION["login_company_id"]} and user_id = {$_SESSION["login_user_id"]}"; + $sql = "SELECT * FROM company_map_user WHERE company_id = :login_company_id and user_id = :login_user_id"; $sth = $pdo1->prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":login_company_id" => $_SESSION["login_company_id"], + ":login_user_id" => $_SESSION["login_user_id"] + ]); + db_check($sth, $answer); $map = $sth->fetchAll(PDO::FETCH_ASSOC); if( count($map)==0 ){ @@ -51,10 +127,6 @@ if(!empty($_SESSION["login_company_id"])){ } - - - - // set up ANSWER $answer = array("success"=>0, "message"=>""); @@ -86,10 +158,4 @@ if(!empty($_SESSION["login_company_id"])){ ); } - - -class db_auth{ - - -} ?> diff --git a/app/assets/utils/module/mailer.php b/app/assets/utils/module/mailer.php index 4a82fc0..2fe4a12 100644 --- a/app/assets/utils/module/mailer.php +++ b/app/assets/utils/module/mailer.php @@ -34,10 +34,12 @@ class mailer{ return $input["smtp"]; } - $sql = "SELECT * FROM smtp_setting WHERE company_id = '{$revise["company_id"]}'"; + $sql = "SELECT * FROM smtp_setting WHERE company_id = :company_id "; $sth = $this->pdo2->prepare("$sql"); - $sth->execute(); + $sth->execute([ + ":company_id" => $revise["company_id"] + ]); $res = $sth->fetch(PDO::FETCH_ASSOC); diff --git a/app/contact/api/engine/contact.php b/app/contact/api/engine/contact.php index 2853c86..63cb544 100644 --- a/app/contact/api/engine/contact.php +++ b/app/contact/api/engine/contact.php @@ -1,19 +1,17 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/contact/api/engine/contact_type.php b/app/contact/api/engine/contact_type.php index 51e5e61..97293b6 100644 --- a/app/contact/api/engine/contact_type.php +++ b/app/contact/api/engine/contact_type.php @@ -1,19 +1,17 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/contact/api/engine/manage_contact.php b/app/contact/api/engine/manage_contact.php index bff0e24..d57a7eb 100644 --- a/app/contact/api/engine/manage_contact.php +++ b/app/contact/api/engine/manage_contact.php @@ -1,7 +1,6 @@ $name) { if ($_FILES['contact_files']['error'][$key] === UPLOAD_ERR_OK) { - $tmp_name = $_FILES['contact_files']['tmp_name'][$key]; - $extension = pathinfo($name, PATHINFO_EXTENSION); - - // Assign a unique ID to prevent filename collisions on the server - $file_id = uniqid() . "_" . time() . "." . $extension; + $tmp_name = $_FILES['contact_files']['tmp_name'][$key]; + $file_size = $_FILES['contact_files']['size'][$key]; + $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION)); + + // Check 1: File size + if ($file_size > $max_size) { + error_log("Rejected oversized file: " . $name); + continue; + } + + // Check 2: Extension whitelist + if (!in_array($extension, $allowed_extensions)) { + error_log("Rejected extension: " . $name); + continue; + } + + // Check 3: Real MIME type (reads actual file bytes, not filename) + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mime = finfo_file($finfo, $tmp_name); + finfo_close($finfo); + + if (!in_array($mime, $allowed_mimes)) { + error_log("Rejected MIME type: " . $mime . " for file: " . $name); + continue; + } + + // Safe unique filename — no original extension trusted + $file_id = uniqid() . "_" . time() . "." . $extension; $destination = $target_dir . $file_id; if (move_uploaded_file($tmp_name, $destination)) { $uploaded_names[] = $file_id; - // Standard readable permission - chmod($destination, 0644); + chmod($destination, 0644); } else { error_log("Failed to move uploaded file: " . $name); } diff --git a/app/contact/api/engine/manage_contact_type.php b/app/contact/api/engine/manage_contact_type.php index df6eecb..7478244 100644 --- a/app/contact/api/engine/manage_contact_type.php +++ b/app/contact/api/engine/manage_contact_type.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); $target_dir = $include_url."uploads/contact/"; diff --git a/app/contact/api/engine/retrieve_contact_type.php b/app/contact/api/engine/retrieve_contact_type.php index 5af031f..47997fe 100644 --- a/app/contact/api/engine/retrieve_contact_type.php +++ b/app/contact/api/engine/retrieve_contact_type.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetch(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/ics/api/engine/product_search.php b/app/ics/api/engine/product_search.php index 99de560..a7884ef 100644 --- a/app/ics/api/engine/product_search.php +++ b/app/ics/api/engine/product_search.php @@ -1,22 +1,21 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":keyword" => '%'.$data["keyword"].'%' + ]); + db_check($sth, $answer); $result = $sth->fetchAll(PDO::FETCH_ASSOC); $answer["result"] = $result; diff --git a/app/ics/api/engine/retrieve_aisle.php b/app/ics/api/engine/retrieve_aisle.php index 35a256c..8fbee7c 100644 --- a/app/ics/api/engine/retrieve_aisle.php +++ b/app/ics/api/engine/retrieve_aisle.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $warehouse, + ":zone" => $data["zone"] + ]); + db_check($sth, $answer); $pre = $sth->fetchAll(PDO::FETCH_ASSOC); diff --git a/app/ics/api/engine/retrieve_rack.php b/app/ics/api/engine/retrieve_rack.php index 3fd09dd..6d6d9b9 100644 --- a/app/ics/api/engine/retrieve_rack.php +++ b/app/ics/api/engine/retrieve_rack.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $warehouse, + ":zone" => $data["zone"], + ":aisle" => $data["aisle"] + ]); + db_check($sth, $answer); $pre = $sth->fetchAll(PDO::FETCH_ASSOC); diff --git a/app/ics/api/engine/retrieve_zone.php b/app/ics/api/engine/retrieve_zone.php index 1600d27..23fdfd3 100644 --- a/app/ics/api/engine/retrieve_zone.php +++ b/app/ics/api/engine/retrieve_zone.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $warehouse + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/include_header.php b/app/include_header.php index 12eb3b9..4c9ba27 100644 --- a/app/include_header.php +++ b/app/include_header.php @@ -4,6 +4,7 @@ ThreeWMS + diff --git a/app/inventory/api/engine/manage_category.php b/app/inventory/api/engine/manage_category.php index fe1bb47..692a0f0 100644 --- a/app/inventory/api/engine/manage_category.php +++ b/app/inventory/api/engine/manage_category.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); + $row = $sth->fetch(PDO::FETCH_ASSOC); $table_log = json_decode($row['log'] ?? '[]', true); diff --git a/app/inventory/api/engine/manage_product.php b/app/inventory/api/engine/manage_product.php index 8411256..bc8a062 100644 --- a/app/inventory/api/engine/manage_product.php +++ b/app/inventory/api/engine/manage_product.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); + $row = $sth->fetch(PDO::FETCH_ASSOC); $table_log = json_decode($row['log'] ?? '[]', true); diff --git a/app/inventory/api/engine/manage_storage.php b/app/inventory/api/engine/manage_storage.php index 8799110..1460e2f 100644 --- a/app/inventory/api/engine/manage_storage.php +++ b/app/inventory/api/engine/manage_storage.php @@ -1,7 +1,6 @@ execute([ ':id' => $id, ]); -if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); -} +db_check($sth, $answer); + $row = $sth->fetch(PDO::FETCH_ASSOC); $table_log = json_decode($row['log'] ?? '[]', true); @@ -89,10 +86,7 @@ if ($id > 0) { ]); } -if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); -} +db_check($sth, $answer); $answer["success"] = 1; exit(json_encode($answer)); diff --git a/app/inventory/api/engine/manage_warehouse.php b/app/inventory/api/engine/manage_warehouse.php index 7a7fcf7..7caeb32 100644 --- a/app/inventory/api/engine/manage_warehouse.php +++ b/app/inventory/api/engine/manage_warehouse.php @@ -1,7 +1,6 @@ execute([ ':id' => $id, ]); -if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); -} +db_check($sth, $answer); + $row = $sth->fetch(PDO::FETCH_ASSOC); $table_log = json_decode($row['log'] ?? '[]', true); @@ -76,10 +73,7 @@ if ($id > 0) { } -if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); -} +db_check($sth, $answer); $answer["success"] = 1; exit(json_encode($answer)); diff --git a/app/inventory/api/engine/manager.php b/app/inventory/api/engine/manager.php index fc17034..c85d5ad 100644 --- a/app/inventory/api/engine/manager.php +++ b/app/inventory/api/engine/manager.php @@ -1,19 +1,14 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth = $pdo1->query($sql); + db_check($sth, $answer); $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/inventory/api/engine/product.php b/app/inventory/api/engine/product.php index 108f56c..9094c59 100644 --- a/app/inventory/api/engine/product.php +++ b/app/inventory/api/engine/product.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/inventory/api/engine/product_category.php b/app/inventory/api/engine/product_category.php index f054686..76ec232 100644 --- a/app/inventory/api/engine/product_category.php +++ b/app/inventory/api/engine/product_category.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/inventory/api/engine/remove_category.php b/app/inventory/api/engine/remove_category.php index c818ffc..12901f0 100644 --- a/app/inventory/api/engine/remove_category.php +++ b/app/inventory/api/engine/remove_category.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); $json = $sth->fetch(PDO::FETCH_ASSOC); $json = json_encode($json); @@ -26,25 +25,26 @@ // delete data $sql = "DELETE FROM md_product_category WHERE - company_id = {$company_id} and - id = {$id}"; + company_id = :company_id and + id = :id "; $sth = $pdo2->prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $id, + ":id" => $id + ]); + db_check($sth, $answer); // insert into archive - $sql = "INSERT INTO archive (`company_id`,`user_id`,`date`,`json`) VALUES ({$company_id},{$user_id},NOW(),'{$jsona}')"; + $sql = "INSERT INTO archive (`company_id`,`user_id`,`date`,`json`) VALUES (:company_id,:user_id,NOW(),:json)"; $sth = $pdo2->prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":user_id" => $user_id, + ":json" => $json + ]); + db_check($sth, $answer); diff --git a/app/inventory/api/engine/retrieve_category.php b/app/inventory/api/engine/retrieve_category.php index c7e11b7..b53b547 100644 --- a/app/inventory/api/engine/retrieve_category.php +++ b/app/inventory/api/engine/retrieve_category.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetch(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/inventory/api/engine/retrieve_product.php b/app/inventory/api/engine/retrieve_product.php index 4e0e548..019297b 100644 --- a/app/inventory/api/engine/retrieve_product.php +++ b/app/inventory/api/engine/retrieve_product.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetch(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/inventory/api/engine/retrieve_storage.php b/app/inventory/api/engine/retrieve_storage.php index ad41e0f..0f5e8a7 100644 --- a/app/inventory/api/engine/retrieve_storage.php +++ b/app/inventory/api/engine/retrieve_storage.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetch(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/inventory/api/engine/retrieve_warehouse.php b/app/inventory/api/engine/retrieve_warehouse.php index 2fdfb2b..50cfa55 100644 --- a/app/inventory/api/engine/retrieve_warehouse.php +++ b/app/inventory/api/engine/retrieve_warehouse.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetch(PDO::FETCH_ASSOC); $answer["success"] = 1; diff --git a/app/inventory/api/engine/storage.php b/app/inventory/api/engine/storage.php index 55e50ee..881063e 100644 --- a/app/inventory/api/engine/storage.php +++ b/app/inventory/api/engine/storage.php @@ -1,7 +1,6 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); diff --git a/app/inventory/api/engine/warehouse.php b/app/inventory/api/engine/warehouse.php index 8d7a675..d3c15aa 100644 --- a/app/inventory/api/engine/warehouse.php +++ b/app/inventory/api/engine/warehouse.php @@ -1,19 +1,17 @@ prepare($sql); - $sth->execute(); - if ($sth->errorInfo()[0] != "00000" && !empty($sth->errorInfo()[0])) { - $answer["message"] = (empty($sth->errorInfo()[2])) ? $sth->errorInfo()[0] : $sth->errorInfo()[2]; - exit(json_encode($answer)); - } + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); diff --git a/app/login/api/engine/back.php b/app/login/api/engine/back.php index aecae09..67f00a7 100644 --- a/app/login/api/engine/back.php +++ b/app/login/api/engine/back.php @@ -1,7 +1,6 @@ prepare("select * from user where user_id = :user_id limit 1;"); + $sth->execute([ + ":user_id" => $user_id + ]); + $temp = $sth->fetch(PDO::FETCH_ASSOC); /** * Validate OTP @@ -24,7 +30,7 @@ return str_pad(strval($otp), $length, '0', STR_PAD_LEFT); } - $otp = generateOTP($password); + $otp = generateOTP($temp["password"]); // time diff between $_SESSION["otpTime"] and now() in minutes $otp_time = isset($_SESSION['otpTime']) ? (int)$_SESSION['otpTime'] : 0; @@ -44,55 +50,20 @@ exit(json_encode($answer)); } - // get password - $sth = $pdo1->prepare("select * from user where user_id = {$user_id} limit 1;"); - $sth->execute(); - $temp = $sth->fetch(PDO::FETCH_ASSOC); + session_regenerate_id(true); // ← fixes session fixation + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); // ← CSRF token - if( strtolower($data["username"]) == "support" ){ - if( $data["password"] == strtolower(substr(md5("trcloud".date("Ymd")),0,4)) ){ - $support = true; - }else{ - $support = false; - } - }else{ - $support = false; - } - - /** - * validate password + /** + * Create login session */ - if((($password == $temp["password"]||$salt_password == $temp["password"]) && strtolower($data["username"]) != "support") || $support == true ){ + $_SESSION["login_status"] = 1; + $_SESSION["login_username"] = $temp["username"]; + $_SESSION["login_name"] = $temp["name"]; + $_SESSION["login_surname"] = $temp["surname"]; + $_SESSION["login_company_id"] = $temp["default_company"]; - // create user session - if( strtolower($data["username"]) == "support" ){ - $s = $pdo1->query("select *, 'info@trcloud.co' as email from user where username='support' limit 1;"); - $temp = $s->fetch(PDO::FETCH_ASSOC); - } - - /** - * Create login session - */ - $_SESSION["login_status"] = 1; - $_SESSION["login_username"] = $temp["username"]; - $_SESSION["login_name"] = $temp["name"]; - $_SESSION["login_surname"] = $temp["surname"]; - $_SESSION["login_company_id"] = $temp["default_company"]; - - $answer["success"] = 1; - $answer["message"] = "Login Complete!"; - exit(json_encode($answer)); - } - else - { - $answer["message"] = "Incorrect Password"; - setcookie("u", "", time()-1, "/"); - setcookie("h1", "", time()-1, "/"); - setcookie("h2", "", time()-1, "/"); - exit(json_encode($answer)); - } - - $answer["success"] = 1; + $answer["success"] = 1; + $answer["message"] = "Login Complete!"; exit(json_encode($answer)); ?> \ No newline at end of file diff --git a/app/login/api/engine/login_otp.php b/app/login/api/engine/login_otp.php index 5b31387..20ed03f 100644 --- a/app/login/api/engine/login_otp.php +++ b/app/login/api/engine/login_otp.php @@ -1,6 +1,7 @@ fetchColumn(); $username = strtolower($data["username"]); - $password = md5(trim(strtolower($data["password"]))); - $salt_password = md5($user_id."_".trim(strtolower($data["password"]))); // get password $sth = $pdo1->prepare("select password from user where username = ? or email = ? limit 1;"); $sth->execute(array($username,$username)); $temp = $sth->fetch(PDO::FETCH_ASSOC); - if( strtolower($data["username"]) == "support" ){ - if( $data["password"] == strtolower(substr(md5("trcloud".date("Ymd")),0,4)) ){ - $support = true; - }else{ - $support = false; - } - }else{ - $support = false; - } - /** * validate password */ - if((($password == $temp["password"]||$salt_password == $temp["password"]) && strtolower($data["username"]) != "support") || $support == true ){ + if(password_verify(trim($data["password"]), $temp["password"])) { // create user session if( strtolower($data["username"]) == "support" ){ @@ -150,7 +139,7 @@ return str_pad($result, 6, 'A', STR_PAD_LEFT); } - $otp = generateOTP($password); + $otp = generateOTP($temp["password"]); $reference_number = numberToLetters(generateOTP($otp)); diff --git a/app/login/api/engine/request_new_otp.php b/app/login/api/engine/request_new_otp.php index 3ce7d62..cf2dd05 100644 --- a/app/login/api/engine/request_new_otp.php +++ b/app/login/api/engine/request_new_otp.php @@ -1,37 +1,28 @@ prepare("select * from user where user_id = {$user_id} limit 1;"); - $sth->execute(); + // get password + $sth = $pdo1->prepare("select * from user where user_id = :user_id limit 1;"); + $sth->execute([ + ":user_id" => $user_id + ]); $temp = $sth->fetch(PDO::FETCH_ASSOC); // user email $user_email = $temp["email"]; - if( strtolower($data["username"]) == "support" ){ - if( $data["password"] == strtolower(substr(md5("trcloud".date("Ymd")),0,4)) ){ - $support = true; - }else{ - $support = false; - } - }else{ - $support = false; - } - - /** + /** * validate password */ - if((($password == $temp["password"]||$salt_password == $temp["password"]) && strtolower($data["username"]) != "support") || $support == true ){ + if(password_verify(trim($data["password"]), $temp["password"])) { /** * Generate OTP @@ -63,7 +54,7 @@ return str_pad($result, 6, 'A', STR_PAD_LEFT); } - $otp = generateOTP($password); + $otp = generateOTP($temp["password"]); $reference_number = numberToLetters(generateOTP($otp)); diff --git a/app/preset.php b/app/preset.php index 4691c53..bbc8e8c 100644 --- a/app/preset.php +++ b/app/preset.php @@ -3,20 +3,7 @@ //<><><><><><><><> MAIN TRCLOUD <><><><><><><><>// if(true){ $expire = "2027-01-01"; - // unique key - $pinkey = "wms"; - /** - * default smtp server - */ - $SMTP = []; - $SMTP['server'] = "smtp.gmail.com"; - $SMTP['username'] = "thanakorn.inbox@gmail.com"; - $SMTP['port'] = "587"; - $SMTP['password'] = "duuo vnad rdax hgpt"; - // password encoding - $method = "AES-256-CBC"; - $iv = "1234567890123456"; // Must be exactly 16 bytes - $SMTP['password'] = openssl_encrypt($SMTP['password'], $method, $pinkey, 0, $iv); + }