summaryrefslogtreecommitdiff
path: root/public/ajax.php
diff options
context:
space:
mode:
authorGeo Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2026-07-12 15:51:52 +0300
committerGeo Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2026-07-12 15:51:52 +0300
commit02608271bb2a9f3a65ed536984d306ee14b48e34 (patch)
tree3f23ec48a694ec014e845c4f70d9b5f1c065403c /public/ajax.php
downloadkalassa-master.tar.gz
kalassa-master.tar.bz2
kalassa-master.zip
initialize repository; add docker config; migrate configuration to new specsHEADmaster
Diffstat (limited to 'public/ajax.php')
-rw-r--r--public/ajax.php413
1 files changed, 413 insertions, 0 deletions
diff --git a/public/ajax.php b/public/ajax.php
new file mode 100644
index 0000000..4b9be96
--- /dev/null
+++ b/public/ajax.php
@@ -0,0 +1,413 @@
+<?php
+include("config/parametres.php");
+include("includes/sessions.php");
+include("includes/functions.php");
+
+
+## -- 01. User Management Functions ////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+ ## LOGIN ---------------------------------------------------------------------
+ //////////////////////////////////////////////////////////////////////////////
+
+ function try_login() {
+ // --- CASE ONE --- -- -- - - -
+ ## User is loged in already
+ if ( (isset($_SESSION['user_status'])) && ($_SESSION['user_status'] == 1) ) {
+ return array(
+ 'success' => true,
+ 'data' => common_session_data__('array')
+ );
+ }
+
+ // --- CASE TWO --- -- -- - - -
+ ## User POSTed credentials to authenticate
+ elseif ($_SERVER['REQUEST_METHOD'] == 'POST') { // if data posted, then ...
+
+ ## check if user made too many attempts; if so, add delay
+ // -------------------------------------------------------------------
+
+ if (!isset($_SESSION['login_attempts'])) {
+ $_SESSION['login_attempts'] = array();
+ $_SESSION['login_attempts'][] = time();
+ }
+ else { // Check login attempts
+ $TOTatts = sizeof($_SESSION['login_attempts']);
+
+ // DENY if too many deny and force user to try later
+ if (($TOTatts > 32) && (time()-$_SESSION['login_attempts'][$TOTatts - 1] < 600))
+ return array('success' => false, 'data' => "Can not check; please try again after 10 minutes.");
+ if (($TOTatts > 16) && (time()-$_SESSION['login_attempts'][$TOTatts - 1] < 300))
+ return array('success' => false, 'data' => "Can not check; please try again after 5 minutes.");
+ if (($TOTatts > 8) && (time()-$_SESSION['login_attempts'][$TOTatts - 1] < 55))
+ return array('success' => false, 'data' => "Can not check; please try after 1 minute.");
+ if (($TOTatts > 4) && (time()-$_SESSION['login_attempts'][$TOTatts - 1] < 25))
+ return array('success' => false, 'data' => "Can not check; please try after 30 seconds. Forgot your password? Contact the administrator!");
+
+ // if too many attempts but stil ok on timings
+ // remove the first 10 attempts
+ if ($TOTatts > 75) {
+ for ($ti = 0 ; $ti < 16 ; $ti++) array_shift($_SESSION['login_attempts']);
+ }
+
+ // if not gone already allow try to login; so log the attempt and continue
+ $_SESSION['login_attempts'][] = time();
+ }
+
+ ## validate posted data (email, password)
+ // -------------------------------------------------------------------
+
+ // POST sent
+ $post = array('user' => $_POST['user'], 'pass' => $_POST['pass']);
+ // validation rules
+ $rules = array('user' => FILTER_VALIDATE_EMAIL, 'pass' => true );
+ // sanitize input array
+ $input = filter_var_array($post, $rules);
+
+ // check if all valid and non empty; keep errors
+ $valid = true; // valid (bool)
+ $error = array(); // errors (array)
+ $nonEmpty = array('user', 'pass'); // required fields
+ foreach($input as $k => $v) {
+ if ($v === false) { // check not validated
+ $valid = false; $error[] = $k ." not validated";
+ }
+ if ( (($v =="") || ($v === false)) && (in_array($k, $nonEmpty)) ) { // check required non empty
+ $valid = false; $error[] = $k . " is required";
+ }
+ }
+ // echo "inp: "; print_r($input); echo "\nerr: "; print_r($error); die();
+
+ if (!$valid) { // if no valid data
+ return array('success' => false, 'data' => join(", ", $error)); // return error(s)
+ }
+
+
+ ## CHECK DATABASE FOR USER
+ // use prepare statements for security
+ // -------------------------------------------------------------------
+
+ // init database connection
+ $_dbc = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_DBMS);
+ if ($_dbc->connect_errno) {
+ $_cError = "Database connection failed; Please try in a few minutes. ";
+ if (TESTING) echo $_dbc->connect_error;
+ $_dbc->close(); die();
+ }
+ $_dbc->set_charset("utf8");
+
+ // prepare statemet
+ $_stm = $_dbc->prepare("SELECT user_id, `user`, salt, pass, role, realname, birthstamp FROM `users` WHERE `user` = ?");
+ $_stm->bind_param("s", $post['user']); // bind values
+ $_stm->execute(); // execute query
+ $_stm->store_result(); // store result
+
+ if ($_stm->num_rows == 1) { // only one user should exist
+ $_stm->bind_result($uid, $user, $salt, $pass, $role, $name, $birth); // bind result variables
+ $_stm->fetch(); // fetch FIRST record values
+ }
+ else { // return error(s)
+ return array('success' => false, 'data' => "More than one users? Please contact system administrator");
+ }
+
+ $_stm->close(); // close statement
+ $_dbc->close(); // close connection
+
+ ## decide if user is ok
+ // -------------------------------------------------------------------
+ if ( $pass == md5($post['user'].$salt.$post['pass']) ) { // User is validated and ok
+
+ session_unset(); // unset $_SESSION, and
+ session_destroy(); // destroy current session's data before continue;
+ session_start(); // then start a new session;
+ session_regenerate_id(); // get a new session id to mitigate session fixation
+ // setup his session data
+ $_SESSION['user_status'] = 1; // update session status
+ $_SESSION['sess_expire'] = time() + SESSION_TTL; // session will expire after SESS_TTL seconds
+ $_SESSION['sess_update'] = time() + SESSION_UPD; // session need to update agter SESS_UPD sec
+ // keep critical user info into session
+ $_SESSION['uid'] = $uid;
+ $_SESSION['name'] = $name;
+ $_SESSION['role'] = $role;
+ $_SESSION['email'] = $post['user'];
+ $_SESSION['birth'] = $birth;
+
+ return array('success' => true, 'data' => array('uid' => $uid, 'name' => $name, 'role' => $role) );
+ }
+ else { // user is not ok unset critical session variables
+
+ $_SESSION['user_status'] = 0;
+ if (isset($_SESSION['uid'])) unset($_SESSION['uid']);
+ if (isset($_SESSION['name'])) unset($_SESSION['name']);
+ if (isset($_SESSION['role'])) unset($_SESSION['role']);
+ if (isset($_SESSION['role'])) unset($_SESSION['role']);
+ // then return failed
+ return array('success' => false, 'data' => "Not valid user credentials.");
+ }
+
+ } // --- end CASE TWO
+
+ // --- CASE THREE --- -- -- - - -
+ ## credentials not send via POST
+ else return array('success' => false, 'data' => "Data not sent correctly");
+ }
+
+
+ ## LOGOUT --------------------------------------------------------------------
+ //////////////////////////////////////////////////////////////////////////////
+
+ function try_logout() {
+ session_unset(); // unset, and
+ session_destroy(); // destroy session data;
+ session_start(); // then start a new session
+ session_regenerate_id(); // get a new session id to mitigate session fixation
+
+ // remove cookies
+ if (isset($_COOKIE[MAIN_COOKIE])) unset($_COOKIE[MAIN_COOKIE]);
+ if (isset($_COOKIE[USER_COOKIE])) unset($_COOKIE[USER_COOKIE]);
+
+ return array('success' => true, 'data' => "User disconected!"); // no chance for the function to fail
+ }
+
+
+
+## -- 02. Items Catalog Management ////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+ ## ADD ITEM ------------------------------------------------------------------
+ //////////////////////////////////////////////////////////////////////////////
+
+ function add_item() {
+ if ((ROLE) && ($_SERVER['REQUEST_METHOD'] == 'POST')) {
+
+ // POST sent
+ $post = array(
+ 'ccode' => $_POST['ccode'],
+ 'summary' => $_POST['summary'],
+ 'condition' => $_POST['condition'],
+ 'decade' => $_POST['decade'],
+ 'operator' => $_SESSION['name'],
+ 'timestamp' => time(),
+ 'box' => $_POST['box'],
+ 'exhibition' => $_POST['exhibition'],
+ 'record' => serialize($_POST)
+ );
+ // VALIDATE RULES
+ $rules = array(
+ 'ccode' => true,
+ 'summary' => FILTER_SANITIZE_STRING,
+ 'condition' => array('filter' => FILTER_VALIDATE_REGEXP, "options" => array("regexp" => "/^[A-Za-z0-9,]+$/")),
+ 'decade' => FILTER_VALIDATE_INT,
+ 'operator' => true,
+ 'timestamp' => true,
+ 'box' => FILTER_SANITIZE_STRING,
+ 'exhibition' => FILTER_SANITIZE_STRING,
+ 'record' => true
+ );
+ // SANITIZE input array
+ $input = filter_var_array($post, $rules);
+
+ // CHECK if all VALID and NON EMPTY
+ // --- -- -- - - -
+ $valid = true; // valid flag
+ $error = array(); // errors array
+ $nonEmpty = array( // required fields
+ 'ccode','operator','timestamp'
+ );
+ foreach($input as $k => $v) {
+ // check not validated
+ if ($v === false) {
+ $valid = false;
+ $error[] = $k ." not validated";
+ }
+ // check empty from required
+ if ( (($v =="") || ($v === false)) && (in_array($k, $nonEmpty)) ) {
+ $valid = false;
+ $error[] = $k . " is required";
+ }
+ }
+
+ // next line is check (uncomment for checking)
+ // if (TESTING) { echo "\nses: "; print_r($_SESSION); echo "\npost:"; print_r($_POST); echo "\n, inp: "; print_r($input); echo "\nerr: "; print_r($error); die(); }
+
+ // IF VALID add item
+ // --- -- -- - - -
+ if ($valid) {
+
+ // init database connection
+ $_dbc = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_DBMS);
+ if ($_dbc->connect_errno) {
+ echo "Database connection failed; Please try in a few minutes.";
+ if (TESTING) echo $_dbc->connect_error;
+ $_dbc->close(); die();
+ }
+ $_dbc->set_charset("utf8");
+
+ $_stm = $_dbc->prepare("INSERT INTO items
+ (ccode, summary, `condition`, decade, operator, `timestamp`, `box`, exhibition, record)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
+ );
+ $_stm->bind_param("sssisdsss",
+ $post['ccode'], $post['summary'], $post['condition'], $post['decade'], $post['operator'], $post['timestamp'], $post['box'], $post['exhibition'], $post['record']
+ );
+ $_stm->execute();
+ $_newid = $_dbc->insert_id;
+ $_stm->close();
+
+ if ($_newid > 0) {
+
+ // update individual category table
+ // -------------------------------------------------------------------
+ $cc = parse_ccode($post['ccode']);
+ $_Table = 'tt_'. $cc->idx; // find table
+ // do the insert
+ $_stm2 = $_dbc->prepare("INSERT INTO {$_Table} ( id ) VALUES ( ? )");
+ $_stm2->bind_param("d", $_newid);
+ $_stm2->execute();
+ $_iid = $_dbc->insert_id; // get new index
+ $_stm2->close();
+
+
+ // update record with individual index
+ // -------------------------------------------------------------------
+ $identity = $post['ccode'] .'.'. $_iid;
+ // do the insert
+ $_upd = $_dbc->prepare("UPDATE items SET identity = ? WHERE id = ?");
+ $_upd->bind_param("sd", $identity, $_newid);
+ $_upd->execute();
+ $_upd->close();
+
+ return array('success' => true, 'data' => "Item added", id => $_newid );
+ }
+ else
+ return array('success' => false, 'data' => "Unknown database error. Please contact the administrator");
+ }
+ else
+ return array('success' => false, 'data' => implode(", ", $error));
+
+ }
+ else return array('success' => false, 'data' => "Operation Denied.");
+ }
+
+
+ ## UPDATE ITEM ---------------------------------------------------------------
+ //////////////////////////////////////////////////////////////////////////////
+
+ function update_item($id) {
+ if ((ROLE) && ($_SERVER['REQUEST_METHOD'] == 'POST')) {
+
+ // POST sent
+ // * CCODE : sent correctly but WILL NOT CHANGE; exclude it from UPDATE statement
+ // * OPERATOR, TIMESTAMP : not need to change
+ $post = array(
+ 'summary' => $_POST['summary'],
+ 'condition' => $_POST['condition'],
+ 'decade' => $_POST['decade'],
+ 'box' => $_POST['box'],
+ 'exhibition' => $_POST['exhibition'],
+ 'record' => serialize($_POST)
+ );
+ // VALIDATE RULES
+ $rules = array(
+ 'summary' => FILTER_SANITIZE_STRING,
+ 'condition' => array('filter' => FILTER_VALIDATE_REGEXP, "options" => array("regexp" => "/^[A-Za-z0-9,]+$/")),
+ 'decade' => FILTER_VALIDATE_INT,
+ 'box' => FILTER_SANITIZE_STRING,
+ 'exhibition' => FILTER_SANITIZE_STRING,
+ 'record' => true
+ );
+ // SANITIZE input array
+ $input = filter_var_array($post, $rules);
+
+ // CHECK if all VALID and NON EMPTY
+ // * ALL required fields ARE ALREADY SET; no need to check if empty
+ // --- -- -- - - -
+ $valid = true; // valid flag
+ $error = array(); // errors array
+ foreach($input as $k => $v) {
+ // check not validated
+ if ($v === false) {
+ $valid = false;
+ $error[] = $k ." not validated";
+ }
+ }
+
+ // next line is check (uncomment for checking)
+ // if (TESTING) { echo "\nses: "; print_r($_SESSION); echo "\npost:"; print_r($_POST); echo "\n, inp: "; print_r($input); echo "\nerr: "; print_r($error); die(); }
+
+ // IF VALID add item
+ // --- -- -- - - -
+ if ($valid) {
+
+ // init database connection
+ $_dbc = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_DBMS);
+ if ($_dbc->connect_errno) {
+ echo "Database connection failed; Please try in a few minutes.";
+ if (TESTING) echo $_dbc->connect_error;
+ $_dbc->close(); die();
+ }
+ $_dbc->set_charset("utf8");
+
+ $_stm = $_dbc->prepare("UPDATE items
+ SET summary = ?, `condition` = ?, decade = ?, `box` = ?, exhibition = ?, record = ?
+ WHERE id = ?"
+ );
+ $_stm->bind_param("ssisssd",
+ $post['summary'], $post['condition'], $post['decade'], $post['box'], $post['exhibition'], $post['record'], $id
+ );
+ $_stm->execute();
+ $_stm->close();
+
+ return array('success' => true, 'data' => "Item Updated", id => $_newid );
+
+ }
+ else
+ return array('success' => false, 'data' => implode(", ", $error));
+
+ }
+ else return array('success' => false, 'data' => "Operation Denied.");
+ }
+
+## -- 10. SWITCH THE requested CASES ///////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+// parse GET argument(s)
+$do = (isset($_GET['do'])) ? $_GET['do'] : "none";
+
+// switch the 'do' cases
+switch ($do) {
+
+ case 'login':
+ $reply = try_login();
+ echo json_encode($reply, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
+ break;
+
+ case 'logout':
+ $reply = try_logout();
+ echo json_encode($reply, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
+ break;
+
+ case 'additem':
+ $reply = add_item();
+ echo json_encode($reply, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
+ break;
+
+ case 'upditem':
+ if (isset($_GET['id']) && is_numeric($_GET['id']) && (($_GET['id'] != '0'))) {
+ $item_id = $_GET['id']; // id of photo to upload
+ $reply = update_item($item_id);
+ }
+ else {
+ $reply = array('success' => false, 'data' => "ID error");
+ }
+ echo json_encode($reply, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
+ break;
+
+
+ default:
+ // code...
+ break;
+}