diff options
| author | Geo Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2026-07-12 15:51:52 +0300 |
|---|---|---|
| committer | Geo Halkiadakis <gchalkiadakis@sklavenitis.co.gr> | 2026-07-12 15:51:52 +0300 |
| commit | 02608271bb2a9f3a65ed536984d306ee14b48e34 (patch) | |
| tree | 3f23ec48a694ec014e845c4f70d9b5f1c065403c /public/ajax.php | |
| download | kalassa-02608271bb2a9f3a65ed536984d306ee14b48e34.tar.gz kalassa-02608271bb2a9f3a65ed536984d306ee14b48e34.tar.bz2 kalassa-02608271bb2a9f3a65ed536984d306ee14b48e34.zip | |
Diffstat (limited to 'public/ajax.php')
| -rw-r--r-- | public/ajax.php | 413 |
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; +} |
