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);
+
}