diff --git a/api.php b/api.php index 61ffda2..a1991f9 100644 --- a/api.php +++ b/api.php @@ -16,6 +16,34 @@ require_once './assets/functions.php'; include './settings/settings.php'; include './settings/config.php'; +//------------------------------------------ +// Header security - enabled via config +//------------------------------------------ +if (header_security){ + header('Content-Type: application/json'); + + // Set strict security headers + header('X-Content-Type-Options: nosniff'); + header('X-Frame-Options: DENY'); + header('X-XSS-Protection: 1; mode=block'); + header('Content-Security-Policy: default-src \'none\''); + header('Access-Control-Allow-Origin: ' . $_ENV['ALLOWED_ORIGIN']); + header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); + header('Access-Control-Allow-Headers: Content-Type, Accept, Authorization'); + + // Validate Content-Type + if (!str_contains($_SERVER['CONTENT_TYPE'],'application/json')) { + http_response_code(400); + exit(json_encode(['error' => 'Invalid Content-Type'])); + } + + // Validate request size + if ($_SERVER['CONTENT_LENGTH'] > '5M') { + http_response_code(413); + exit(json_encode(['error' => 'Request too large'])); + } + } + //------------------------------------------ // Retrieve API version and Collection // api.php/(v)ersion/{get/post}/collection/ diff --git a/api/v2/get/products.php b/api/v2/get/products.php index 86b20cc..c195307 100644 --- a/api/v2/get/products.php +++ b/api/v2/get/products.php @@ -66,6 +66,10 @@ if(isset($criterias['totals']) && $criterias['totals'] ==''){ elseif (isset($criterias['list']) && $criterias['list'] =='') { //SQL for Paging $sql = 'SELECT * FROM products '.$whereclause.''; +} +elseif (isset($criterias['list']) && $criterias['list'] =='price'){ + //GET ALL PRODUCTS AND PRODUCT ATTRIBUTES FOR PRICING + $sql = '(SELECT rowID as product_id, productname as product_name FROM products where salesflag = 1 '.$whereclause.' ) UNION (SELECT attribute_id as product_id, item_name as product_name FROM `products_attributes_items` WHERE item_status = 1 '.$whereclause.' )'; } else { //SQL for Paging @@ -100,7 +104,7 @@ if(isset($criterias['totals']) && $criterias['totals']==''){ $messages = $stmt->fetch(); $messages = $messages[0]; } -elseif(isset($criterias['list']) && $criterias['list']==''){ +elseif(isset($criterias['list'])){ //Excute Query $stmt->execute(); //Get results diff --git a/api/v2/get/products_configurations.php b/api/v2/get/products_configurations.php new file mode 100644 index 0000000..51bf815 --- /dev/null +++ b/api/v2/get/products_configurations.php @@ -0,0 +1,142 @@ +soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';} + +//default whereclause +$whereclause = ''; + +switch ($permission) { + case '4': + $whereclause = ''; + break; + case '3': + $whereclause = ''; + break; + default: + $condition = '__salesid___'.$partner->salesid.'___soldto___'.substr($partner->soldto, 0, strpos($partner->soldto, "-")).$soldto_search; + $whereclause = 'WHERE accounthierarchy like "'.$condition.'"'; + break; +} + +//NEW ARRAY +$criterias = []; +$clause = ''; + +//Check for $_GET variables and build up clause +if(isset($get_content) && $get_content!=''){ + //GET VARIABLES FROM URL + $requests = explode("&", $get_content); + //Check for keys and values + foreach ($requests as $y){ + $v = explode("=", $y); + //INCLUDE VARIABLES IN ARRAY + $criterias[$v[0]] = $v[1]; + + if ($v[0] == 'page' || $v[0] =='p' || $v[0] =='totals' || $v[0] =='list' || $v[0] =='history'|| $v[0] =='success_msg'){ + //do nothing + } + elseif ($v[0] == 'search') { + //build up search + $clause .= ' AND productcode like :'.$v[0]; + } + else {//create clause + $clause .= ' AND '.$v[0].' = :'.$v[0]; + } + } + if ($whereclause == '' && $clause !=''){ + $whereclause = 'WHERE '.substr($clause, 4); + } else { + $whereclause .= $clause; + } +} + +//ENSURE PRODUCTROWID IS SEND +if (isset($criterias['productrowid']) && $criterias['productrowid'] != ''){ + + //CHECK IF ALLOWED TO CRUD VERSIONS + $sql = "SELECT * FROM products WHERE rowID = ? '.$whereclause.'"; + $stmt = $pdo->prepare($sql); + $stmt->execute([$criterias['productrowid']]); + $product_data = $stmt->fetch(); + $product_owner = ($product_data['rowID'])? 1 : 0; + + //IF PRODUCT IS OWNED THEN CRUD is ALLOWED + if ($product_owner === 1 ){ + + //Define Query + if(isset($criterias['totals']) && $criterias['totals'] ==''){ + //Request for total rows + $sql = 'SELECT count(*) as count FROM products_configurations '.$whereclause.''; + } + elseif (isset($criterias['list']) && $criterias['list'] =='') { + //SQL for Paging + $sql = 'SELECT * FROM products_configurations '.$whereclause.''; + } + else { + //SQL for Paging + $sql = 'SELECT * FROM products_configurations '.$whereclause.''; + } + + $stmt = $pdo->prepare($sql); + + //Bind to query + if (str_contains($whereclause, ':condition')){ + $stmt->bindValue('condition', $condition, PDO::PARAM_STR); + } + + if (!empty($criterias)){ + foreach ($criterias as $key => $value){ + $key_condition = ':'.$key; + if (str_contains($whereclause, $key_condition)){ + if ($key == 'search'){ + $search_value = '%'.$value.'%'; + $stmt->bindValue($key, $search_value, PDO::PARAM_STR); + } + else { + $stmt->bindValue($key, $value, PDO::PARAM_STR); + } + } + } + } + + //Add paging details + if(isset($criterias['totals']) && $criterias['totals']==''){ + $stmt->execute(); + $messages = $stmt->fetch(); + $messages = $messages[0]; + } + elseif(isset($criterias['list']) && $criterias['list']==''){ + //Excute Query + $stmt->execute(); + //Get results + $messages = $stmt->fetchAll(PDO::FETCH_ASSOC); + } + else { + //$current_page = isset($criterias['p']) && is_numeric($criterias['p']) ? (int)$criterias['p'] : 1; + //$stmt->bindValue('page', ($current_page - 1) * $page_rows_products, PDO::PARAM_INT); + //$stmt->bindValue('num_products', $page_rows_products, PDO::PARAM_INT); + + //Excute Query + $stmt->execute(); + //Get results + $messages = $stmt->fetchAll(PDO::FETCH_ASSOC); + } + //------------------------------------------ + //JSON_ENCODE + //------------------------------------------ + $messages = json_encode($messages, JSON_UNESCAPED_UNICODE); + + //Send results + echo $messages; + } +} +?> \ No newline at end of file diff --git a/api/v2/post/pricelists.php b/api/v2/post/pricelists.php index 93cf997..2bae067 100644 --- a/api/v2/post/pricelists.php +++ b/api/v2/post/pricelists.php @@ -85,7 +85,7 @@ if ($command == 'update' && isAllowed('pricelists_manage',$profile,$permission,' $stmt->execute($execute_input); } elseif ($command == 'insert' && isAllowed('pricelists_manage',$profile,$permission,'C') === 1){ - $sql = 'INSERT INTO pricelists('.$clause_insert.') VALUES ('.$input_insert.')'; + $sql = 'INSERT INTO pricelists ('.$clause_insert.') VALUES ('.$input_insert.')'; $stmt = $pdo->prepare($sql); $stmt->execute($execute_input); // Return ID diff --git a/api/v2/post/products_configurations.php b/api/v2/post/products_configurations.php new file mode 100644 index 0000000..b50bb20 --- /dev/null +++ b/api/v2/post/products_configurations.php @@ -0,0 +1,107 @@ +soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';} + +//default whereclause +$whereclause = ''; + +switch ($permission) { + case '4': + $whereclause = ''; + break; + case '3': + $whereclause = ''; + break; + default: + $condition = '__salesid___'.$partner->salesid.'___soldto___'.substr($partner->soldto, 0, strpos($partner->soldto, "-")).$soldto_search; + $whereclause = ' AND accounthierarchy like "'.$condition.'"'; + break; +} + +//ENSURE PRODUCTROWID IS SEND +if (isset($post_content['productrowid']) && $post_content['productrowid'] != ''){ + + //CHECK IF ALLOWED TO CRUD VERSIONS + $sql = "SELECT * FROM products WHERE rowID = ? '.$whereclause.'"; + $stmt = $pdo->prepare($sql); + $stmt->execute([$post_content['productrowid']]); + $product_data = $stmt->fetch(); + $product_owner = ($product_data['rowID'])? 1 : 0; + + //IF PRODUCT IS OWNED THEN CRUD is ALLOWED + if ($product_owner === 1 ){ + //SET PARAMETERS FOR QUERY + $id = $post_content['rowID'] ?? ''; //check for rowID + $command = ($id == '')? 'insert' : 'update'; //IF rowID = empty then INSERT + if (isset($post_content['delete'])){$command = 'delete';} //change command to delete + $date = date('Y-m-d H:i:s'); + + //CREATE EMPTY STRINGS + $clause = ''; + $clause_insert =''; + $input_insert = ''; + + if ($command == 'insert'){ + $post_content['createdby'] = $username; + } + if ($command == 'update'){ + $post_content['updatedby'] = $username; + } + + //CREAT NEW ARRAY AND MAP TO CLAUSE + if(isset($post_content) && $post_content!=''){ + foreach ($post_content as $key => $var){ + if ($key == 'submit' || $key == 'rowID'){ + //do nothing + } + else { + $criterias[$key] = $var; + $clause .= ' , '.$key.' = ?'; + $clause_insert .= ' , '.$key.''; + $input_insert .= ', ?'; // ? for each insert item + $execute_input[]= $var; // Build array for input + } + } + } + + //CLEAN UP INPUT + $clause = substr($clause, 2); //Clean clause - remove first comma + $clause_insert = substr($clause_insert, 2); //Clean clause - remove first comma + $input_insert = substr($input_insert, 1); //Clean clause - remove first comma + + //QUERY AND VERIFY ALLOWED + if ($command == 'update' && isAllowed('products_configurations',$profile,$permission,'U') === 1){ + $sql = 'UPDATE products_configurations SET '.$clause.' WHERE rowID = ? '.$whereclause.''; + $execute_input[] = $id; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); + } + elseif ($command == 'insert' && isAllowed('products_configurations',$profile,$permission,'C') === 1){ + $sql = 'INSERT INTO products_configurations ('.$clause_insert.') VALUES ('.$input_insert.')'; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); + } + elseif ($command == 'delete' && isAllowed('products_configurations',$profile,$permission,'D') === 1){ + $stmt = $pdo->prepare('DELETE FROM products_configurations WHERE rowID = ? '.$whereclause.''); + $stmt->execute([ $id ]); + + //Add deletion to changelog + changelog($dbname,'products_configurations',$id,'Delete','Delete',$username); + } else + { + //do nothing + } + } +} +?> \ No newline at end of file diff --git a/assets/functions.php b/assets/functions.php index 43fe851..0b99d13 100644 --- a/assets/functions.php +++ b/assets/functions.php @@ -2846,72 +2846,74 @@ function getLatestVersion($productcode,$token){ // +++++++++++++++++++++++++++++++++++++++++++++++++++++++ function getRelativeTime($timestamp) { - //GET TRANSLATION FILE - if(isset($_SESSION['country_code'])){ - $api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php'; - if (file_exists($api_file_language)){ - include $api_file_language; //Include the code - } - else { - include dirname(__FILE__,2).'/settings/translations/translations_US.php'; - } - } - else { - include dirname(__FILE__,2).'/settings/translations/translations_US.php'; - } - - // Ensure the timestamp is a valid integer - $timestamp = is_numeric($timestamp) ? $timestamp : strtotime($timestamp); - - // Get current timestamp and calculate difference - $now = time(); - $diff = $now - $timestamp; - - // Define time periods - $minute = 60; - $hour = $minute * 60; - $day = $hour * 24; - $week = $day * 7; - $month = $day * 30; - $year = $day * 365; - - // Handle future timestamps - if ($diff < 0) { - $diff = abs($diff); - $suffix = $time_from_now; - } else { - $suffix = $time_ago; - } - - // Determine the appropriate time description - if ($diff < $minute) { - return $time_just_now; - } elseif ($diff < $hour) { - $minutes = floor($diff / $minute); - return $minutes.(($minutes != 1) ? $time_minutes : $time_minute) . " $suffix"; - } elseif ($diff < $day) { - $hours = floor($diff / $hour); - return $hours.(($hours != 1) ? $time_hours : $time_hour) . " $suffix"; - } elseif ($diff < $week) { - $days = floor($diff / $day); - - // Special handling for today and yesterday - if ($days == 0) { - return $time_today; - } elseif ($days == 1) { - return $time_yesterday; + if (!empty($timestamp) || $timestamp != ""){ + //GET TRANSLATION FILE + if(isset($_SESSION['country_code'])){ + $api_file_language = dirname(__FILE__,2).'/settings/translations/translations_'.strtoupper($_SESSION['country_code']).'.php'; + if (file_exists($api_file_language)){ + include $api_file_language; //Include the code } - - return $days.(($days != 1)?$time_days:$time_day) . " $suffix"; - } elseif ($diff < $month) { - $weeks = floor($diff / $week); - return $weeks.(($weeks != 1)?$time_weeks:$time_week) . " $suffix"; - } elseif ($diff < $year) { - $months = floor($diff / $month); - return $months.(($months != 1)?$time_months:$time_month) . " $suffix"; - } else { - $years = floor($diff / $year); - return $years.(($years != 1)?$time_years:$time_year) . " $suffix"; + else { + include dirname(__FILE__,2).'/settings/translations/translations_US.php'; + } + } + else { + include dirname(__FILE__,2).'/settings/translations/translations_US.php'; + } + + // Ensure the timestamp is a valid integer + $timestamp = is_numeric($timestamp) ? $timestamp : strtotime($timestamp); + + // Get current timestamp and calculate difference + $now = time(); + $diff = $now - $timestamp; + + // Define time periods + $minute = 60; + $hour = $minute * 60; + $day = $hour * 24; + $week = $day * 7; + $month = $day * 30; + $year = $day * 365; + + // Handle future timestamps + if ($diff < 0) { + $diff = abs($diff); + $suffix = $time_from_now; + } else { + $suffix = $time_ago; + } + + // Determine the appropriate time description + if ($diff < $minute) { + return $time_just_now; + } elseif ($diff < $hour) { + $minutes = floor($diff / $minute); + return $minutes.(($minutes != 1) ? $time_minutes : $time_minute) . " $suffix"; + } elseif ($diff < $day) { + $hours = floor($diff / $hour); + return $hours.(($hours != 1) ? $time_hours : $time_hour) . " $suffix"; + } elseif ($diff < $week) { + $days = floor($diff / $day); + + // Special handling for today and yesterday + if ($days == 0) { + return $time_today; + } elseif ($days == 1) { + return $time_yesterday; + } + + return $days.(($days != 1)?$time_days:$time_day) . " $suffix"; + } elseif ($diff < $month) { + $weeks = floor($diff / $week); + return $weeks.(($weeks != 1)?$time_weeks:$time_week) . " $suffix"; + } elseif ($diff < $year) { + $months = floor($diff / $month); + return $months.(($months != 1)?$time_months:$time_month) . " $suffix"; + } else { + $years = floor($diff / $year); + return $years.(($years != 1)?$time_years:$time_year) . " $suffix"; + } } } diff --git a/pricelists.php b/pricelists.php index efe6b1c..26d68ec 100644 --- a/pricelists.php +++ b/pricelists.php @@ -60,8 +60,8 @@ $view = '
-

'.($pricelists_h2 ?? '').' ('.$query_total.')

-

'.($pricelists_p ?? '').'

+

'.($pricelists_h2 ?? 'Pricelists').' ('.$query_total.')

+

'.($pricelists_p ?? 'Manage pricelists').'

'; @@ -95,7 +95,7 @@ $view .= ' '.($pricelists_rowID ?? 'rowID').' - th>'.($pricelists_status ?? 'status').' + '.($pricelists_status ?? 'status').' '.($pricelists_name ?? 'name').' '.$general_created.' '.$general_actions.' diff --git a/pricelists_manage.php b/pricelists_manage.php index 10e7043..9775ce9 100644 --- a/pricelists_manage.php +++ b/pricelists_manage.php @@ -15,9 +15,10 @@ $delete_allowed = isAllowed($page ,$_SESSION['profile'],$_SESSION['permission'], $create_allowed = isAllowed($page ,$_SESSION['profile'],$_SESSION['permission'],'C'); // Default input product values -$text_variable = [ +$pricelists = [ 'rowID' => '', - 'variable' => '', + 'status' => '', + 'name' => '', 'created' => '', 'createdby' => '', 'updated' => '', @@ -25,6 +26,7 @@ $text_variable = [ 'accounthierarchy' => '' ]; + if (isset($_GET['rowID'])) { //CALL TO API $api_url = '/v2/pricelists/rowID='.$_GET['rowID']; @@ -40,6 +42,14 @@ if (isset($_GET['rowID'])) { //Decode Payload if (!empty($pricelists_items)){$pricelists_items = json_decode($pricelists_items,true);}else{$pricelists_items = null;} + //GET PRODUCTS AND ATTRIBUTES + $api_url = '/v2/products/list=price'; + $responses = ioServer($api_url,''); + //Decode Payload + if (!empty($responses)){$products = json_decode($responses,true);}else{$products = null;} + + + if ($update_allowed === 1){ if (isset($_POST['submit'])) { @@ -57,7 +67,6 @@ if (isset($_GET['rowID'])) { } if (isset($_POST['add'])) { - //GET ALL POST DATA $payload = json_encode($_POST, JSON_UNESCAPED_UNICODE); //API call @@ -66,9 +75,8 @@ if (isset($_GET['rowID'])) { if ($responses === 'NOK'){ } else { - generateLanguageFile($_POST['language_key'],$_SESSION['userkey']); header('Location: index.php?page=pricelists_manage&rowID='.$_GET['rowID'].''); - exit; + exit; } } @@ -94,11 +102,6 @@ if (isset($_GET['rowID'])) { } } - if ($NOK_error == 0){ - //NO errors generatelanguagefile - generateLanguageFile($attr_language,$_SESSION['userkey']); - } - header('Location: index.php?page=pricelists_manage&rowID='.$_GET['rowID'].''); exit; } @@ -132,8 +135,8 @@ if (isset($_GET['rowID'])) { } else { //GET ROWID OF CREATED ITEM - $variable_rowID = json_decode($responses,true); - header('Location: index.php?page=pricelists_manage&rowID='.$variable_rowID['rowID'].''); + $pricelists_rowID = json_decode($responses,true); + header('Location: index.php?page=pricelists_manage&rowID='.$pricelists_rowID['rowID'].''); exit; } } @@ -161,7 +164,7 @@ if (isset($success_msg)){ $view .='
-

'.($text_variables_h2 ?? '').'

+

'.($pricelists_h2 ?? '').'

'.$button_cancel.' '; @@ -183,24 +186,45 @@ $view .= '
//Define Service and User enabled $view .= '
- - - - '; - -$view .= '
+ + +
+
+ + + +
+
+ + +
+
+ + +
+
+ + +
'; $view .= '
- + - + - + - +
'; $view .= ''; @@ -216,8 +240,11 @@ $view .= ' - - + + + + + @@ -229,23 +256,44 @@ $view .= ' $view .= ' - + '; } else { - foreach ($pricelists_items as $pricelists_item){ + foreach ($pricelists_items as $pricelist_item){ + $view .= ' - - - - + + + + + + - - + + '; } } + $view .= '
'.($text_variable_translation_languagekey ?? '').''.($text_variable_translation_translation ?? '').''.($pricelists_item_status ?? 'Status').''.($pricelists_item_product_id ?? 'Product ID').''.($pricelists_item_price ?? 'Price').''.($pricelists_item_rpp ?? 'RPP').''.($pricelists_item_price_modifier ?? 'Modifier').' '.$general_created.' '.$general_actions.'
'.($message_no_text_variables ?? '').''.($message_no_pricelists ?? 'There are no pricelist items').'
'.getRelativeTime($pricelists_item['created']).'
+ + + + + + '.getRelativeTime($pricelist_item['created']).'
@@ -259,15 +307,40 @@ $view .= ' const newRow = document.createElement(\'tr\'); newRow.innerHTML = ` - + + + + + + + + + + + + - + + `; tbody.appendChild(newRow); } - + '; + +$view .= '
'; diff --git a/product.php b/product.php index c53265a..b551c01 100644 --- a/product.php +++ b/product.php @@ -54,6 +54,11 @@ $product_software = ioServer($api_url,''); //Decode Payload if (!empty($product_software)){$product_software = decode_payload($product_software);}else{$product_software = null;} +//CALL TO API FOR Product_configuration +$api_url = '/v2/products_configurations/productrowid='.$_GET['rowID']; +$products_configurations = ioServer($api_url,''); +//Decode Payload +if (!empty($products_configurations)){$products_configurations = json_decode($products_configurations,true);}else{$products_configurations = null;} //------------------------------ //Variables @@ -157,7 +162,41 @@ $view .= '
'; +if ($responses->configurable == 1){ + $view .= '
+
+ '.($product_configuration ?? 'Product configuration').' + + +
'; + if (!empty($products_configurations)){ + $view .= ' +
+ + + + + + + + '; + foreach ($products_configurations as $product_config){ + + $view .= ' + + + '; + } + $view .= ' + +
'.($product_configuration_version ?? 'Config-version').''.$general_actions.'
+
+ '; + } +$view .= ' +
+'; +} $view .= '
@@ -173,6 +212,7 @@ $view .= '
'.$product_version_number.' '.$product_status.' '.$product_version_version.' + '.($product_version_config ?? 'Config').' '.$general_actions.' @@ -183,6 +223,7 @@ $view .= '
'.$version->rowID.' '.(($version->status == 1)? ''.$prod_status_1:''.$prod_status_0).' '.$version->version.' + '.(!empty($version->config) ? ($general_yes ?? 'Y') : ($general_no ?? 'N')).' '.$general_view.' '; } @@ -249,6 +290,11 @@ $view .= '
+ + + + + diff --git a/product_manage.php b/product_manage.php index 0360bfc..974a711 100644 --- a/product_manage.php +++ b/product_manage.php @@ -38,7 +38,8 @@ $product = [ 'build' => 1, 'partnerhierarchy' => '', 'sn' =>'', - 'healthindex' =>'' + 'healthindex' =>'', + 'configurable' =>'' ]; if (isset($_GET['id'])) { @@ -56,8 +57,10 @@ if (isset($_GET['id'])) { uploadProduct($_POST['productcode']); } if (isset($_POST['submit'])) { + //GET ALL POST DATA $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); + var_dump($data); //Secure data $payload = generate_payload($data); //API call @@ -65,8 +68,8 @@ if (isset($_GET['id'])) { if ($responses === 'NOK'){ } else { - header('Location: index.php?page=product&rowID='.$_GET['id'].'&success_msg=2'); - exit; + header('Location: index.php?page=product&rowID='.$_GET['id'].'&success_msg=2'); + exit; } } @@ -171,6 +174,11 @@ $view .= '
$view .= '
+ + '; +} +if ($update_allowed === 1){ + $view .= ''; +} + +$view .= '
'; + +$view .= ' + '; + +$view .= '
+
+ + + + + + '; + //VIEW FOR PRODUCT CONFIGURATION + if (isset($_GET['rowID']) && $_GET['rowID'] !=''){ + + $view .= ' + +
+ +
'.($product_configurable ?? 'Configurable').''.(($responses->configurable == 1)? $enabled : $disabled).'
'.$product_serialized.' '.(($responses->sn == 1)? $enabled : $disabled).'
+
'; + + } + + if (isset($_GET['rowID']) && $_GET['rowID'] !='' && !empty($products_configurations['measurement'])){ + $measurements = json_decode($products_configurations['measurement'],true); + + $view .= ' + +
+ + + + + + + + + + + + '; + foreach ($measurements as $name => $measurement){ + $view .=' + + + + + + + + '; + } + + + $view .= ' +
TestNAverageMedianSTdev
'.$name.''.$measurement['n'].''.$measurement['average'].''.$measurement['median'].''.$measurement['stdev'].'
+
'; + + } +$view .= ' + + +
+
'; + +$view .= '
+
+ + + + +
+
'; +$view .= ''; + +//Output +echo $view; +template_footer() +?> \ No newline at end of file diff --git a/products_versions.php b/products_versions.php index e0493eb..0d906da 100644 --- a/products_versions.php +++ b/products_versions.php @@ -18,7 +18,7 @@ $products_versions = [ 'productrowid' => '', 'status' => '', 'version' => '', - 'software' => '', + 'config' => '', 'created' => '', 'createdby' => $_SESSION['username'], 'measurement' => '', @@ -30,11 +30,11 @@ $productrowid = $_GET['productrowid'] ?? ''; if (isset($_GET['rowID'])) { // ID param exists, edit an existing product //CALL TO API - $api_url = '/v1/products_versions/rowID='.$_GET['rowID'].'&productrowid='.$productrowid; + $api_url = '/v2/products_versions/rowID='.$_GET['rowID'].'&productrowid='.$productrowid; $responses = ioServer($api_url,''); //Decode Payload - if (!empty($responses)){$responses = decode_payload($responses);}else{$responses = null;} + if (!empty($responses)){$responses = json_decode($responses,true);}else{$responses = null;} $products_versions = json_decode(json_encode($responses[0]), true); @@ -42,40 +42,10 @@ if (isset($_GET['rowID'])) { if ($update_allowed === 1){ if (isset($_POST['submit'])) { - //CHECK FOR FIRMWARE FILE - $firmware_file = $_FILES["fileToUpload"]["name"] ?? ''; - - if($firmware_file !='' || !empty($firmware_file)){ - - $extension = strtolower(pathinfo($firmware_file, PATHINFO_EXTENSION)); - $target_dir = dirname(__FILE__)."/firmware/"; - - if ($extension == 'hex'){ - //READ FILE - $contents = file_get_contents($_FILES["fileToUpload"]["tmp_name"]); - //firmwarename - $firmware_name = pathinfo($_FILES["fileToUpload"]["name"], PATHINFO_FILENAME); - //Filename - $input_file = $target_dir . $firmware_name.'.HEX'; - //store firmware file - file_put_contents($input_file, $contents); - - } else { - $target_file = $target_dir . $firmware_file; - move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file); - $firmware_name = $firmware_file; - } - - //Use firmwarefile name as software version - $_POST['software'] = $firmware_name; - } - //GET ALL POST DATA - $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); - //Secure data - $payload = generate_payload($data); + $payload = json_encode($_POST, JSON_UNESCAPED_UNICODE); //API call - $responses = ioServer('/v1/products_versions', $payload); + $responses = ioServer('/v2/products_versions', $payload); if ($responses === 'NOK'){ } else { @@ -89,11 +59,9 @@ if (isset($_GET['rowID'])) { if ($delete_allowed === 1){ if (isset($_POST['delete'])) { //GET ALL POST DATA - $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); - //Secure data - $payload = generate_payload($data); + $payload = json_encode($_POST, JSON_UNESCAPED_UNICODE); //API call - $responses = ioServer('/v1/products_versions', $payload); + $responses = ioServer('/v2/products_versions', $payload); if ($responses === 'NOK'){ } else { @@ -108,42 +76,12 @@ if (isset($_GET['rowID'])) { // Create a new product if (isset($_POST['submit']) && $create_allowed === 1) { - //CHECK FOR FIRMWARE FILE - $firmware_file = $_FILES["fileToUpload"]["name"] ?? ''; - - if($firmware_file !='' || !empty($firmware_file)){ - - $extension = strtolower(pathinfo($firmware_file, PATHINFO_EXTENSION)); - $target_dir = dirname(__FILE__)."/firmware/"; - - if ($extension == 'hex'){ - //READ FILE - $contents = file_get_contents($_FILES["fileToUpload"]["tmp_name"]); - //firmwarename - $firmware_name = pathinfo($_FILES["fileToUpload"]["name"], PATHINFO_FILENAME); - //Filename - $input_file = $target_dir . $firmware_name.'.HEX'; - //store firmware file - file_put_contents($input_file, $contents); - - $firmware_name = $firmware_name.'.HEX'; - - } else { - $target_file = $target_dir . $firmware_file; - move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file); - $firmware_name = $firmware_file; - } - - //Use firmwarefile name as software version - $_POST['software'] = $firmware_name; - } - //GET ALL POST DATA $data = json_encode($_POST , JSON_UNESCAPED_UNICODE); //Secure data $payload = generate_payload($data); //API call - $responses = ioServer('/v1/products_versions', $payload); + $responses = ioServer('/v2/products_versions', $payload); if ($responses === 'NOK'){ } @@ -189,7 +127,18 @@ $view .= '
'; - + //VIEW FOR PRODUCT CONFIGURATION + if (isset($_GET['rowID']) && $_GET['rowID'] !=''){ + + $view .= ' + +
+ + +
'; + + } + if (isset($_GET['rowID']) && $_GET['rowID'] !='' && !empty($products_versions['measurement'])){ $measurements = json_decode($products_versions['measurement'],true); diff --git a/security.php b/security.php new file mode 100644 index 0000000..b31aeac --- /dev/null +++ b/security.php @@ -0,0 +1,65 @@ + 'nosniff', + 'X-Frame-Options' => 'DENY', + 'X-XSS-Protection' => '1; mode=block', + 'Content-Security-Policy' => 'default-src \'none\'', + 'Access-Control-Allow-Origin' => null, // Will check if exists + 'Access-Control-Allow-Methods' => null, // Will check if exists + 'Access-Control-Allow-Headers' => null, // Will check if exists + 'Strict-Transport-Security' => null // Will check if exists + ]; + + // Check each expected header + echo "Security Headers Test Results:\n"; + echo "==============================\n\n"; + + foreach ($expectedHeaders as $header => $expectedValue) { + if (isset($headers[$header])) { + if ($expectedValue === null) { + echo "✅ {$header} is present: {$headers[$header]}\n"; + } elseif ($headers[$header] === $expectedValue) { + echo "✅ {$header} has correct value: {$headers[$header]}\n"; + } else { + echo "❌ {$header} has incorrect value. Expected: {$expectedValue}, Got: {$headers[$header]}\n"; + } + } else { + echo "❌ {$header} is missing\n"; + } + } + + // Check for HTTPS + $isHttps = strpos($url, 'https://') === 0; + echo $isHttps ? + "\n✅ HTTPS is enabled\n" : + "\n❌ HTTPS is not enabled - Security headers may not be effective!\n"; + + curl_close($ch); +} + +// Usage +testSecurityHeaders('https://dev.veliti.nl/api.php'); \ No newline at end of file diff --git a/settings/settingsmenu.php b/settings/settingsmenu.php index f3857e1..6236894 100644 --- a/settings/settingsmenu.php +++ b/settings/settingsmenu.php @@ -246,6 +246,13 @@ $page_rows_pricelists = 50;//pricelists //------------------------------------------ $supportedLanguages = ['US', 'NL', 'DE', 'ES','PT']; +//------------------------------------------ +// Pricing +//------------------------------------------ +$supportedCurrencies = ["0" =>"euro", "1"=>"dollar"]; + +$supportedModifiers = ["0" =>"subtract", "1"=>"add"]; + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++ // All individual views and APIs - Profile ++++++++++++++ // +++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/settings/settingsprofiles.php b/settings/settingsprofiles.php index 9a07ff2..d1e4650 100644 --- a/settings/settingsprofiles.php +++ b/settings/settingsprofiles.php @@ -6,7 +6,7 @@ define('superuser_profile','dashboard,profile,assets,equipments,equipment,equipm /*Admin*/ define('admin_profile','dashboard,profile,buildtool,sales,accounts,account,contracts,contract,contract_manage,cartests,cartest,cartest_manage,assets,equipments,equipment,equipment_healthindex,equipment_data,equipment_manage,equipment_manage_edit,equipments_mass_update,histories,history,history_manage,firmwaretool,rmas,rma,rma_manage,rma_history,rma_history_manage,buildtool,products,products_versions,products_software,product,product_manage,servicereports,servicereport,admin,partners,partner,users,user,user_manage,communications,communication,communication_send,marketing,reporting,report_build,report_contracts_billing,report_healthindex,changelog,application'); /*AdminPlus*/ -define('adminplus_profile','dashboard,profile,buildtool,sales,accounts,account,contracts,contract,contract_manage,billing,cartests,cartest,cartest_manage,assets,equipments,equipment,equipment_healthindex,equipment_data,equipment_manage,equipment_manage_edit,equipments_mass_update,histories,history,history_manage,firmwaretool,rmas,rma,rma_manage,rma_history,rma_history_manage,buildtool,products,products_versions,products_software,products_attributes,products_attributes_items,products_attributes_manage,product,product_manage,servicereports,servicereport,admin,partners,partner,users,user,user_manage,communications,communication,communication_send,marketing,reporting,report_build,report_contracts_billing,report_healthindex,report_usage,config,settings,logfile,changelog,language,translations,translations_details,translation_manage,media,media_manage,application,maintenance,profiles,vin'); +define('adminplus_profile','dashboard,profile,buildtool,sales,accounts,account,contracts,contract,contract_manage,billing,cartests,cartest,cartest_manage,assets,equipments,equipment,equipment_healthindex,equipment_data,equipment_manage,equipment_manage_edit,equipments_mass_update,histories,history,history_manage,firmwaretool,rmas,rma,rma_manage,rma_history,rma_history_manage,buildtool,products,products_versions,products_software,products_attributes,products_attributes_items,products_attributes_manage,products_configurations,product,product_manage,pricelists,pricelists_items,pricelists_manage,servicereports,servicereport,admin,partners,partner,users,user,user_manage,communications,communication,communication_send,marketing,reporting,report_build,report_contracts_billing,report_healthindex,report_usage,config,settings,logfile,changelog,language,translations,translations_details,translation_manage,media,media_manage,application,maintenance,profiles,vin'); /*Build*/ define('build','dashboard,profile,buildtool,firmwaretool,buildtool,products_software,application'); /*Distribution*/ diff --git a/settings/settingsviews.php b/settings/settingsviews.php index 6ca3958..2194ce7 100644 --- a/settings/settingsviews.php +++ b/settings/settingsviews.php @@ -41,11 +41,12 @@ $all_views = [ "products_attributes", "products_attributes_items", "products_attributes_manage", + "products_configurations", "product", "product_manage", "pricelists", + "pricelists_items", "pricelists_manage", - "product_manage", "servicereports", "servicereport", "admin",