Miglioramento dell'API

Aggiunta sezione di log per l'API e migliorata la gestione del login.
Aggiunto controllo contro attacchi brute-force nel login.
This commit is contained in:
Thomas Zilio 2017-09-04 10:24:44 +02:00
parent 343943aede
commit c7e88bcf5e
18 changed files with 187 additions and 87 deletions

View File

@ -5,8 +5,7 @@ function serverError()
$error = error_get_last(); $error = error_get_last();
if ($error['type'] == E_ERROR) { if ($error['type'] == E_ERROR) {
ob_end_clean(); ob_end_clean();
print_r($error); echo API::error('serverError');
die(API::error('serverError'));
} }
} }

View File

@ -2,9 +2,6 @@
include_once __DIR__.'/core.php'; include_once __DIR__.'/core.php';
$id_module = filter('id_module');
$id_record = filter('id_record');
$posizione = $id_module; $posizione = $id_module;
if (isset($id_record)) { if (isset($id_record)) {
$posizione .= ', '.$id_record; $posizione .= ', '.$id_record;
@ -12,13 +9,14 @@ if (isset($id_record)) {
$dbo->query('UPDATE zz_semaphores SET updated = NOW() WHERE id_utente = '.prepare($_SESSION['id_utente']).' AND posizione = '.prepare($posizione)); $dbo->query('UPDATE zz_semaphores SET updated = NOW() WHERE id_utente = '.prepare($_SESSION['id_utente']).' AND posizione = '.prepare($posizione));
$dbo->query('DELETE FROM zz_semaphores WHERE DATE_ADD(updated, INTERVAL '.(get_var('Timeout notifica di presenza (minuti)') * 2).' SECOND) <= NOW()'); $dbo->query('DELETE FROM zz_semaphores WHERE DATE_ADD(updated, INTERVAL '.(get_var('Timeout notifica di presenza (minuti)') * 2).' SECOND) <= NOW()');
$datas = $dbo->fetchArray('SELECT DISTINCT * FROM zz_semaphores INNER JOIN zz_users ON zz_semaphores.id_utente=zz_users.id_utente WHERE zz_semaphores.id_utente != '.prepare($_SESSION['id_utente']).' AND posizione = '.prepare($posizione));
$datas = $dbo->fetchArray('SELECT DISTINCT username FROM zz_semaphores INNER JOIN zz_users ON zz_semaphores.id_utente=zz_users.id WHERE zz_semaphores.id_utente != '.prepare($_SESSION['id_utente']).' AND posizione = '.prepare($posizione));
$result = []; $result = [];
if ($datas != null) {
foreach ($datas as $data) { foreach ($datas as $data) {
array_push($result, ['username' => $data['username']]); $result[] = [
} 'username' => $data['username'],
];
} }
echo json_encode($result); echo json_encode($result);

View File

@ -56,12 +56,13 @@ use Monolog\Handler\StreamHandler;
use Monolog\Handler\RotatingFileHandler; use Monolog\Handler\RotatingFileHandler;
$handlers = []; $handlers = [];
if (!API::isAPIRequest()) {
// File di log di base (logs/error.log) // File di log di base (logs/error.log)
$handlers[] = new StreamHandler(__DIR__.'/logs/error.log', Monolog\Logger::ERROR); $handlers[] = new StreamHandler(__DIR__.'/logs/error.log', Monolog\Logger::ERROR);
$handlers[] = new StreamHandler(__DIR__.'/logs/setup.log', Monolog\Logger::EMERGENCY); $handlers[] = new StreamHandler(__DIR__.'/logs/setup.log', Monolog\Logger::EMERGENCY);
// Impostazioni di debug // Impostazioni di debug
if (!empty($debug) && !API::isAPIRequest()) { if (!empty($debug)) {
// Ignoramento degli avvertimenti e delle informazioni relative alla deprecazione di componenti // Ignoramento degli avvertimenti e delle informazioni relative alla deprecazione di componenti
if (empty($strict)) { if (empty($strict)) {
error_reporting(E_ALL & ~E_NOTICE & ~E_USER_DEPRECATED); error_reporting(E_ALL & ~E_NOTICE & ~E_USER_DEPRECATED);
@ -85,12 +86,13 @@ if (!empty($debug) && !API::isAPIRequest()) {
$whoops->register(); $whoops->register();
} }
}
// Istanziamento della barra di debug
$debugbar = new DebugBar\StandardDebugBar();
$debugbar->addCollector(new DebugBar\Bridge\MonologCollector($logger));
} else { } else {
// Disabilita la segnalazione degli errori $handlers[] = new StreamHandler(__DIR__.'/logs/api.log', Monolog\Logger::ERROR);
}
// Disabilita la segnalazione degli errori (se il debug è disabilitato)
if (empty($debug)) {
error_reporting(0); error_reporting(0);
} }
@ -100,7 +102,7 @@ foreach ($handlers as $handler) {
$logger->pushHandler($handler->setFormatter($monologFormatter)); $logger->pushHandler($handler->setFormatter($monologFormatter));
} }
// Imposta Monolog come gestore degli errori (si sovrappone a Whoops) // Imposta Monolog come gestore degli errori
Monolog\ErrorHandler::register($logger); Monolog\ErrorHandler::register($logger);
// Istanziamento della gestione di date e numeri // Istanziamento della gestione di date e numeri
@ -117,6 +119,7 @@ $translator->addLocalePath($docroot.'/modules/*/locale');
$version = Update::getVersion(); $version = Update::getVersion();
$revision = Update::getRevision(); $revision = Update::getRevision();
// Inizializzazione della sessione
if (!API::isAPIRequest()) { if (!API::isAPIRequest()) {
session_set_cookie_params(0, $rootdir); session_set_cookie_params(0, $rootdir);
session_start(); session_start();
@ -207,7 +210,10 @@ if (!API::isAPIRequest()) {
} }
if ($continue) { if ($continue) {
if (!empty($debugbar)) { // Istanziamento della barra di debug
if (!empty($debug)) {
$debugbar = new DebugBar\StandardDebugBar();
$debugbar->addCollector(new DebugBar\Bridge\MonologCollector($logger));
$debugbar->addCollector(new DebugBar\DataCollector\PDO\PDOCollector($dbo->getPDO())); $debugbar->addCollector(new DebugBar\DataCollector\PDO\PDOCollector($dbo->getPDO()));
} }
@ -235,7 +241,7 @@ if (!API::isAPIRequest()) {
// Retrocompatibilità // Retrocompatibilità
$user_idanagrafica = $user['idanagrafica']; $user_idanagrafica = $user['idanagrafica'];
$rs = $dbo->fetchArray('SELECT * FROM `zz_modules` LEFT JOIN (SELECT `idmodule`, `permessi` FROM `zz_permissions` WHERE `idgruppo`=(SELECT `idgruppo` FROM `zz_users` WHERE `id_utente`='.prepare($_SESSION['id_utente']).')) AS `zz_permissions` ON `zz_modules`.`id`=`zz_permissions`.`idmodule` LEFT JOIN (SELECT `idmodule`, `clause` FROM `zz_group_module` WHERE `idgruppo`=(SELECT `idgruppo` FROM `zz_users` WHERE `id_utente`='.prepare($_SESSION['id_utente']).')) AS `zz_group_module` ON `zz_modules`.`id`=`zz_group_module`.`idmodule`'); $rs = $dbo->fetchArray('SELECT * FROM `zz_modules` LEFT JOIN (SELECT `idmodule`, `permessi` FROM `zz_permissions` WHERE `idgruppo`=(SELECT `idgruppo` FROM `zz_users` WHERE `id`='.prepare($_SESSION['id_utente']).')) AS `zz_permissions` ON `zz_modules`.`id`=`zz_permissions`.`idmodule` LEFT JOIN (SELECT `idmodule`, `clause` FROM `zz_group_module` WHERE `idgruppo`=(SELECT `idgruppo` FROM `zz_users` WHERE `id`='.prepare($_SESSION['id_utente']).')) AS `zz_group_module` ON `zz_modules`.`id`=`zz_group_module`.`idmodule`');
$modules_info = []; $modules_info = [];
for ($i = 0; $i < count($rs); ++$i) { for ($i = 0; $i < count($rs); ++$i) {
@ -260,8 +266,8 @@ if (!API::isAPIRequest()) {
// Istanziamento di HTMLHelper (retrocompatibilità) // Istanziamento di HTMLHelper (retrocompatibilità)
$html = new HTMLHelper(); $html = new HTMLHelper();
}
// Variabili GET e POST // Variabili GET e POST
$post = Filter::getPOST(); $post = Filter::getPOST();
$get = Filter::getGET(); $get = Filter::getGET();
}

View File

@ -91,6 +91,39 @@ if (str_contains($version, 'beta')) {
</div>'; </div>';
} }
// Controllo se è una beta e in caso mostro un warning
if (Auth::isBrute()) {
echo '
<div class="box box-danger box-center" id="brute">
<div class="box-header with-border text-center">
<h3 class="box-title">'._('Attenzione').'</h3>
</div>
<div class="box-body text-center">
<p>'._('Sono stati effettuati troppi tentativi di accesso consecutivi!').'</p>
<p>'._('Tempo rimanente (in secondi)').': <span id="brute-timeout">'.(Auth::getBruteTimeout() + 1).'</span></p>
</div>
</div>
<script>
$(document).ready(function(){
$(".login-box").fadeOut();
brute();
});
function brute() {
var value = parseFloat($("#brute-timeout").html()) - 1;
$("#brute-timeout").html(value);
if(value > 0){
setTimeout("brute()", 1000);
} else{
$("#brute").fadeOut();
$(".login-box").fadeIn();
}
}
</script>';
}
if (!empty($_SESSION['errors'])) { if (!empty($_SESSION['errors'])) {
echo ' echo '
<script> <script>

View File

@ -59,6 +59,8 @@ class API extends \Util\Singleton
*/ */
public function retrieve($request) public function retrieve($request)
{ {
$user = Auth::user();
$table = ''; $table = '';
$select = '*'; $select = '*';
@ -192,6 +194,8 @@ class API extends \Util\Singleton
*/ */
protected function fileRequest($request, $kind) protected function fileRequest($request, $kind)
{ {
$user = Auth::user();
$resources = self::getResources()[$kind]; $resources = self::getResources()[$kind];
$resource = $request['resource']; $resource = $request['resource'];

View File

@ -33,6 +33,12 @@ class Auth extends \Util\Singleton
'options' => [], 'options' => [],
]; ];
/** @var int Opzioni per la protezione contro attacchi brute-force */
protected static $brute = [
'attemps' => 3,
'timeout' => 180,
];
/** @var array Informazioni riguardanti l'utente autenticato */ /** @var array Informazioni riguardanti l'utente autenticato */
protected $infos; protected $infos;
/** @var string Nome del primo modulo su cui l'utente ha permessi di navigazione */ /** @var string Nome del primo modulo su cui l'utente ha permessi di navigazione */
@ -73,6 +79,10 @@ class Auth extends \Util\Singleton
{ {
session_regenerate_id(); session_regenerate_id();
if (self::isBrute()) {
return false;
}
$database = Database::getConnection(); $database = Database::getConnection();
$log = []; $log = [];
@ -80,7 +90,7 @@ class Auth extends \Util\Singleton
$log['ip'] = get_client_ip(); $log['ip'] = get_client_ip();
$log['stato'] = self::$status['failed']['code']; $log['stato'] = self::$status['failed']['code'];
$users = $database->fetchArray('SELECT id_utente, password, enabled FROM zz_users WHERE username = '.prepare($username).' LIMIT 1'); $users = $database->fetchArray('SELECT id AS id_utente, password, enabled FROM zz_users WHERE username = '.prepare($username).' LIMIT 1');
if (!empty($users)) { if (!empty($users)) {
$user = $users[0]; $user = $users[0];
@ -185,7 +195,7 @@ class Auth extends \Util\Singleton
$database = Database::getConnection(); $database = Database::getConnection();
try { try {
$results = $database->fetchArray('SELECT id_utente, idanagrafica, username, (SELECT nome FROM zz_groups WHERE id=idgruppo) AS gruppo FROM zz_users WHERE id_utente = '.prepare($user_id).' AND enabled = 1 LIMIT 1', false, ['session' => false]); $results = $database->fetchArray('SELECT id AS id_utente, idanagrafica, username, (SELECT nome FROM zz_groups WHERE id=idgruppo) AS gruppo FROM zz_users WHERE id = '.prepare($user_id).' AND enabled = 1 LIMIT 1', false, ['session' => false]);
if (!empty($results)) { if (!empty($results)) {
$results[0]['is_admin'] = ($results[0]['gruppo'] == 'Amministratori'); $results[0]['is_admin'] = ($results[0]['gruppo'] == 'Amministratori');
@ -349,4 +359,32 @@ class Auth extends \Util\Singleton
{ {
return self::getInstance()->getFirstModule(); return self::getInstance()->getFirstModule();
} }
/**
* Controlla se sono in corso molti tentativi di accesso (possibile brute-forcing).
*
* @return bool
*/
public static function isBrute()
{
$database = Database::getConnection();
$results = $database->fetchArray('SELECT COUNT(*) AS tot FROM zz_logs WHERE ip = '.prepare(get_client_ip()).' AND stato = '.prepare(self::getStatus()['failed']['code']).' AND DATE_ADD(created_at, INTERVAL '.self::$brute['timeout'].' SECOND) >= NOW()');
return $results[0]['tot'] > self::$brute['attemps'];
}
/**
* Restituisce il tempo di attesa rimanente per lo sblocco automatico dellla protezione contro attacchi brute-forc.
*
* @return int
*/
public static function getBruteTimeout()
{
$database = Database::getConnection();
$results = $database->fetchArray('SELECT TIME_TO_SEC(TIMEDIFF(DATE_ADD(created_at, INTERVAL '.self::$brute['timeout'].' SECOND), NOW())) AS diff FROM zz_logs WHERE ip = '.prepare(get_client_ip()).' AND stato = '.prepare(self::getStatus()['failed']['code']).' AND DATE_ADD(created_at, INTERVAL '.self::$brute['timeout'].' SECOND) >= NOW() ORDER BY created_at DESC LIMIT 1');
return intval($results[0]['diff']);
}
} }

View File

@ -38,7 +38,7 @@ class Modules
$user = Auth::user(); $user = Auth::user();
$results = $database->fetchArray('SELECT * FROM `zz_modules` LEFT JOIN (SELECT `idmodule`, `permessi` FROM `zz_permissions` WHERE `idgruppo` = (SELECT `idgruppo` FROM `zz_users` WHERE `id_utente` = '.prepare($user['id_utente']).')) AS `zz_permissions` ON `zz_modules`.`id`=`zz_permissions`.`idmodule` LEFT JOIN (SELECT `idmodule`, `clause`, `position` FROM `zz_group_module` WHERE `idgruppo` = (SELECT `idgruppo` FROM `zz_users` WHERE `id_utente` = '.prepare($user['id_utente']).') AND `enabled` = 1) AS `zz_group_module` ON `zz_modules`.`id`=`zz_group_module`.`idmodule`'); $results = $database->fetchArray('SELECT * FROM `zz_modules` LEFT JOIN (SELECT `idmodule`, `permessi` FROM `zz_permissions` WHERE `idgruppo` = (SELECT `idgruppo` FROM `zz_users` WHERE `id` = '.prepare($user['id_utente']).')) AS `zz_permissions` ON `zz_modules`.`id`=`zz_permissions`.`idmodule` LEFT JOIN (SELECT `idmodule`, `clause`, `position` FROM `zz_group_module` WHERE `idgruppo` = (SELECT `idgruppo` FROM `zz_users` WHERE `id` = '.prepare($user['id_utente']).') AND `enabled` = 1) AS `zz_group_module` ON `zz_modules`.`id`=`zz_group_module`.`idmodule`');
$modules = []; $modules = [];
$additionals = []; $additionals = [];
@ -210,7 +210,7 @@ class Modules
$user = Auth::user(); $user = Auth::user();
$datas = $database->fetchArray('SELECT * FROM `zz_views` WHERE `id_module`='.prepare($id).' AND `id` IN (SELECT `id_vista` FROM `zz_group_view` WHERE `id_gruppo`=(SELECT `idgruppo` FROM `zz_users` WHERE `id_utente`='.prepare($user['id_utente']).')) ORDER BY `order` ASC'); $datas = $database->fetchArray('SELECT * FROM `zz_views` WHERE `id_module`='.prepare($id).' AND `id` IN (SELECT `id_vista` FROM `zz_group_view` WHERE `id_gruppo`=(SELECT `idgruppo` FROM `zz_users` WHERE `id`='.prepare($user['id_utente']).')) ORDER BY `order` ASC');
if (!empty($datas)) { if (!empty($datas)) {
$select = ''; $select = '';

View File

@ -15,9 +15,6 @@ var isMobile = {
return navigator.userAgent.match(/IEMobile/i); return navigator.userAgent.match(/IEMobile/i);
}, },
any: function () { any: function () {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
},
complete: function () {
return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) || return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) ||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4))); /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4)));
} }
@ -164,7 +161,7 @@ $(document).ready(function () {
} }
}); });
if (isMobile.complete()) { if (isMobile.any()) {
$(".sidebar-menu").sortable("disable"); $(".sidebar-menu").sortable("disable");
} }
@ -178,7 +175,7 @@ $(document).ready(function () {
} }
// Nel caso la navigazione sia da mobile, disabilito il ritorno al punto precedente // Nel caso la navigazione sia da mobile, disabilito il ritorno al punto precedente
if (!isMobile.complete()) { if (!isMobile.any()) {
// Salvo lo scroll per riportare qui l'utente al reload // Salvo lo scroll per riportare qui l'utente al reload
$(window).on('scroll', function () { $(window).on('scroll', function () {
if (localStorage != undefined) { if (localStorage != undefined) {
@ -957,7 +954,7 @@ function start_inputmask() {
regex: "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$", regex: "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$",
}); });
if (isMobile.complete()) { if (isMobile.any()) {
$('.inputmask-decimal, .date-mask, .timestamp-mask').each(function () { $('.inputmask-decimal, .date-mask, .timestamp-mask').each(function () {
$(this).attr('type', 'tel'); $(this).attr('type', 'tel');
}); });

View File

@ -5,6 +5,16 @@ switch ($resource) {
// Inserisco l'anagrafica // Inserisco l'anagrafica
$dbo->update('an_anagrafiche', [ $dbo->update('an_anagrafiche', [
'ragione_sociale' => $request['data']['ragione_sociale'], 'ragione_sociale' => $request['data']['ragione_sociale'],
'piva' => $request['data']['piva'],
'codice_fiscale' => $request['data']['codice_fiscale'],
'indirizzo' => $request['data']['indirizzo'],
'citta' => $request['data']['citta'],
'provincia' => $request['data']['provincia'],
'id_nazione' => $request['data']['id_nazione'],
'telefono' => $request['data']['telefono'],
'fax' => $request['data']['fax'],
'cellulare' => $request['data']['cellulare'],
'email' => $request['data']['email'],
], ['idanagrafica' => $request['id']]); ], ['idanagrafica' => $request['id']]);
// Inserisco il rapporto dell'anagrafica (cliente, tecnico, ecc) // Inserisco il rapporto dell'anagrafica (cliente, tecnico, ecc)

View File

@ -3,7 +3,7 @@
include_once __DIR__.'/../../core.php'; include_once __DIR__.'/../../core.php';
// Prezzo modificabile solo se l'utente loggato è un tecnico (+ può vedere i prezzi) o se è amministratore // Prezzo modificabile solo se l'utente loggato è un tecnico (+ può vedere i prezzi) o se è amministratore
$rs = $dbo->fetchArray('SELECT nome FROM zz_groups WHERE id IN(SELECT idgruppo FROM zz_users WHERE id_utente='.prepare($_SESSION['id_utente']).')'); $rs = $dbo->fetchArray('SELECT nome FROM zz_groups WHERE id IN(SELECT idgruppo FROM zz_users WHERE id='.prepare($_SESSION['id_utente']).')');
for ($i = 0; $i < count($rs); ++$i) { for ($i = 0; $i < count($rs); ++$i) {
$gruppi[$i] = $rs[$i]['nome']; $gruppi[$i] = $rs[$i]['nome'];
} }

View File

@ -7,14 +7,14 @@ $id_utente = filter('id_utente');
switch (filter('op')) { switch (filter('op')) {
// Abilita utente // Abilita utente
case 'enable': case 'enable':
if ($dbo->query('UPDATE zz_users SET enabled=1 WHERE id_utente='.prepare($id_utente))) { if ($dbo->query('UPDATE zz_users SET enabled=1 WHERE id='.prepare($id_utente))) {
$_SESSION['infos'][] = _('Utente abilitato!'); $_SESSION['infos'][] = _('Utente abilitato!');
} }
break; break;
// Disabilita utente // Disabilita utente
case 'disable': case 'disable':
if ($dbo->query('UPDATE zz_users SET enabled=0 WHERE id_utente='.prepare($id_utente))) { if ($dbo->query('UPDATE zz_users SET enabled=0 WHERE id='.prepare($id_utente))) {
$_SESSION['infos'][] = _('Utente disabilitato!'); $_SESSION['infos'][] = _('Utente disabilitato!');
} }
break; break;
@ -34,7 +34,7 @@ switch (filter('op')) {
} elseif ($password != $password_rep) { } elseif ($password != $password_rep) {
$_SESSION['errors'][] = _('Le password non coincidono'); $_SESSION['errors'][] = _('Le password non coincidono');
} else { } else {
$dbo->query('UPDATE zz_users SET password='.prepare(Auth::hashPassword($password)).' WHERE id_utente='.prepare($id_utente)); $dbo->query('UPDATE zz_users SET password='.prepare(Auth::hashPassword($password)).' WHERE id='.prepare($id_utente));
$_SESSION['infos'][] = _('Password aggiornata!'); $_SESSION['infos'][] = _('Password aggiornata!');
} }
@ -42,13 +42,13 @@ switch (filter('op')) {
$username = filter('username'); $username = filter('username');
// Se ho modificato l'username, verifico che questo non sia già stato usato // Se ho modificato l'username, verifico che questo non sia già stato usato
$rs = $dbo->fetchArray('SELECT username FROM zz_users WHERE id_utente='.prepare($id_utente)); $rs = $dbo->fetchArray('SELECT username FROM zz_users WHERE id='.prepare($id_utente));
if ($rs[0]['username'] != $username) { if ($rs[0]['username'] != $username) {
$n = $dbo->fetchNum('SELECT id_utente FROM zz_users WHERE username='.prepare($username)); $n = $dbo->fetchNum('SELECT id FROM zz_users WHERE username='.prepare($username));
if ($n == 0) { if ($n == 0) {
$dbo->query('UPDATE zz_users SET username='.prepare($username).' WHERE id_utente='.prepare($id_utente)); $dbo->query('UPDATE zz_users SET username='.prepare($username).' WHERE id='.prepare($id_utente));
$_SESSION['infos'][] = _('Username aggiornato!'); $_SESSION['infos'][] = _('Username aggiornato!');
} else { } else {
@ -111,7 +111,7 @@ switch (filter('op')) {
// Elimina utente // Elimina utente
case 'delete': case 'delete':
if ($dbo->query('DELETE FROM zz_users WHERE id_utente='.prepare($id_utente))) { if ($dbo->query('DELETE FROM zz_users WHERE id='.prepare($id_utente))) {
$_SESSION['infos'][] = _('Utente eliminato!'); $_SESSION['infos'][] = _('Utente eliminato!');
} }
break; break;

View File

@ -17,9 +17,24 @@ switch ($resource) {
$token = $tokens[0]['token']; $token = $tokens[0]['token'];
} }
$results = $dbo->fetchArray('SELECT `ragione_sociale`, `codice`, `piva`, `codice_fiscale`, `indirizzo`, `citta`, `provincia`, (SELECT `nome` FROM `an_nazioni` WHERE `an_nazioni`.`id` = `an_anagrafiche`.`id_nazione`) AS nazione, `telefono`, `fax`, `indirizzo`, `citta`, `provincia`, `indirizzo`, `citta`, `an_anagrafiche`.`email` FROM `zz_users` LEFT JOIN `an_anagrafiche` ON `an_anagrafiche`.`idanagrafica` = `zz_users`.`idanagrafica` WHERE `id_utente` = '.prepare($user['id_utente']))[0]; $results = $dbo->fetchArray('SELECT `ragione_sociale`, `codice`, `piva`, `codice_fiscale`, `indirizzo`, `citta`, `provincia`, (SELECT `nome` FROM `an_nazioni` WHERE `an_nazioni`.`id` = `an_anagrafiche`.`id_nazione`) AS nazione, `telefono`, `fax`, `cellulare`, `an_anagrafiche`.`email` FROM `zz_users` LEFT JOIN `an_anagrafiche` ON `an_anagrafiche`.`idanagrafica` = `zz_users`.`idanagrafica` WHERE `id` = '.prepare($user['id_utente']))[0];
$results['token'] = $token; $results['token'] = $token;
} else {
$results = [
'status' => API::getStatus()['unauthorized']['code'],
];
if (Auth::isBrute()) {
$results['timeout'] = Auth::getBruteTimeout();
}
}
break;
case 'logout':
if (!empty($request['token']) && !empty($user)) {
$database->query('DELETE FROM `zz_tokens` WHERE `token` = '.prepare($request['token']).' AND `id_utente` = '.prepare($user['id_utente']));
} else { } else {
$results = [ $results = [
'status' => API::getStatus()['unauthorized']['code'], 'status' => API::getStatus()['unauthorized']['code'],

View File

@ -10,7 +10,7 @@ $id_utente = filter('id_utente');
if (!empty($id_utente)) { if (!empty($id_utente)) {
$value = 'change_pwd'; $value = 'change_pwd';
$rs = $dbo->fetchArray('SELECT username FROM zz_users WHERE id_utente='.prepare($id_utente)); $rs = $dbo->fetchArray('SELECT username FROM zz_users WHERE id='.prepare($id_utente));
$username = $rs[0]['username']; $username = $rs[0]['username'];
$message = _('Modifica'); $message = _('Modifica');
} else { } else {

View File

@ -6,10 +6,10 @@ include_once __DIR__.'/../../core.php';
$report = file_get_contents($docroot.'/templates/magazzino_inventario/magazzino_inventario.html'); $report = file_get_contents($docroot.'/templates/magazzino_inventario/magazzino_inventario.html');
$body = file_get_contents($docroot.'/templates/magazzino_inventario/magazzino_inventario_body.html'); $body = file_get_contents($docroot.'/templates/magazzino_inventario/magazzino_inventario_body.html');
$search_codice = $html->form('search_codice'); $search_codice = get('search_codice');
$search_descrizione = $html->form('search_descrizione'); $search_descrizione = get('search_descrizione');
$search_categoria = $html->form('search_categoria').' '.$html->form('search_subcategoria'); $search_categoria = get('search_categoria').' '.get('search_subcategoria');
$search_tipo = $html->form('search_tipo'); $search_tipo = get('search_tipo');
if ($search_tipo == '') { if ($search_tipo == '') {
$search_tipo = 'solo prodotti attivi'; $search_tipo = 'solo prodotti attivi';

View File

@ -2,7 +2,7 @@
include_once __DIR__.'/../../core.php'; include_once __DIR__.'/../../core.php';
$idconto = $html->form('idconto'); $idconto = get('idconto');
$module_name = 'Piano dei conti'; $module_name = 'Piano dei conti';
// carica report html // carica report html
@ -11,7 +11,7 @@ $body = file_get_contents($docroot.'/templates/partitario_mastrino/partitario_bo
include_once $docroot.'/templates/pdfgen_variables.php'; include_once $docroot.'/templates/pdfgen_variables.php';
// Calcolo il percorso piano dei conti // Calcolo il percorso piano dei conti
if ($html->form('lev') == '3') { if (get('lev') == '3') {
$rs = $dbo->fetchArray("SELECT idpianodeiconti2, CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti3 WHERE id=\"".$idconto.'"'); $rs = $dbo->fetchArray("SELECT idpianodeiconti2, CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti3 WHERE id=\"".$idconto.'"');
$percorso = $rs[0]['descrizione']; $percorso = $rs[0]['descrizione'];
$idpianodeiconti2 = $rs[0]['idpianodeiconti2']; $idpianodeiconti2 = $rs[0]['idpianodeiconti2'];
@ -24,7 +24,7 @@ if ($html->form('lev') == '3') {
($rs[0]['descrizione'] == '01 Patrimoniale') ? $descrizione = 'Stato patrimoniale' : $descrizione = 'Conto economico'; ($rs[0]['descrizione'] == '01 Patrimoniale') ? $descrizione = 'Stato patrimoniale' : $descrizione = 'Conto economico';
$percorso = $descrizione.'<br>&nbsp;&nbsp;'.$percorso; $percorso = $descrizione.'<br>&nbsp;&nbsp;'.$percorso;
} elseif ($html->form('lev') == '2') { } elseif (get('lev') == '2') {
$rs = $dbo->fetchArray("SELECT idpianodeiconti1, CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti2 WHERE id=\"".$idconto.'"'); $rs = $dbo->fetchArray("SELECT idpianodeiconti1, CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti2 WHERE id=\"".$idconto.'"');
$percorso = $rs[0]['descrizione'].'<br>&nbsp;&nbsp;&nbsp;&nbsp;'.$percorso; $percorso = $rs[0]['descrizione'].'<br>&nbsp;&nbsp;&nbsp;&nbsp;'.$percorso;
$idpianodeiconti1 = $rs[0]['idpianodeiconti1']; $idpianodeiconti1 = $rs[0]['idpianodeiconti1'];
@ -33,7 +33,7 @@ if ($html->form('lev') == '3') {
($rs[0]['descrizione'] == '01 Patrimoniale') ? $descrizione = 'Stato patrimoniale' : $descrizione = 'Conto economico'; ($rs[0]['descrizione'] == '01 Patrimoniale') ? $descrizione = 'Stato patrimoniale' : $descrizione = 'Conto economico';
$percorso = $descrizione.'<br>&nbsp;&nbsp;'.$percorso; $percorso = $descrizione.'<br>&nbsp;&nbsp;'.$percorso;
} elseif ($html->form('lev') == '1') { } elseif (get('lev') == '1') {
$rs = $dbo->fetchArray("SELECT CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti1 WHERE id=\"".$idconto.'"'); $rs = $dbo->fetchArray("SELECT CONCAT_WS(' ', numero, descrizione ) AS descrizione FROM co_pianodeiconti1 WHERE id=\"".$idconto.'"');
($rs[0]['descrizione'] == '01 Patrimoniale') ? $descrizione = 'Stato patrimoniale' : $descrizione = 'Conto economico'; ($rs[0]['descrizione'] == '01 Patrimoniale') ? $descrizione = 'Stato patrimoniale' : $descrizione = 'Conto economico';
@ -46,7 +46,7 @@ $body = str_replace('|period_start|', Translator::dateToLocale($_SESSION['period
$body = str_replace('|period_end|', Translator::dateToLocale($_SESSION['period_end']), $body); $body = str_replace('|period_end|', Translator::dateToLocale($_SESSION['period_end']), $body);
// Stampa da livello 3 // Stampa da livello 3
if ($html->form('lev') == '3') { if (get('lev') == '3') {
$body .= "<table style='table-layout:fixed; border-bottom:1px solid #777; border-right:1px solid #777; border-left:1px solid #777;' cellpadding='0' cellspacing='0'> $body .= "<table style='table-layout:fixed; border-bottom:1px solid #777; border-right:1px solid #777; border-left:1px solid #777;' cellpadding='0' cellspacing='0'>
<col width='80'><col width='452'><col width='80'><col width='80'> <col width='80'><col width='452'><col width='80'><col width='80'>
<tbody>\n"; <tbody>\n";
@ -101,7 +101,7 @@ if ($html->form('lev') == '3') {
} }
// Stampa da livello 2 // Stampa da livello 2
elseif ($html->form('lev') == '2') { elseif (get('lev') == '2') {
$body .= "<table style='table-layout:fixed; border-bottom:1px solid #777; border-right:1px solid #777; border-left:1px solid #777;' cellpadding='0' cellspacing='0'> $body .= "<table style='table-layout:fixed; border-bottom:1px solid #777; border-right:1px solid #777; border-left:1px solid #777;' cellpadding='0' cellspacing='0'>
<col width='80'><col width='452'><col width='80'><col width='80'> <col width='80'><col width='452'><col width='80'><col width='80'>
<tbody>\n"; <tbody>\n";
@ -155,7 +155,7 @@ elseif ($html->form('lev') == '2') {
} }
// Stampa completa bilancio // Stampa completa bilancio
elseif ($html->form('lev') == '1') { elseif (get('lev') == '1') {
$ricavi = 0; $ricavi = 0;
$costi = 0; $costi = 0;
$totale_attivita = 0; $totale_attivita = 0;

View File

@ -4,11 +4,11 @@ include_once __DIR__.'/../../core.php';
$module_name = 'Interventi'; $module_name = 'Interventi';
$id_module = $html->form('id_module'); $id_module = get('id_module');
$fields = []; $fields = [];
$select = '*'; $select = '*';
$datas = $dbo->fetchArray('SELECT * FROM zz_views WHERE id_module='.$id_module.' AND id IN (SELECT id_vista FROM zz_group_view WHERE id_gruppo=(SELECT idgruppo FROM zz_users WHERE id_utente='.$_SESSION['id_utente'].')) ORDER BY `order` ASC'); $datas = $dbo->fetchArray('SELECT * FROM zz_views WHERE id_module='.$id_module.' AND id IN (SELECT id_vista FROM zz_group_view WHERE id_gruppo=(SELECT idgruppo FROM zz_users WHERE id='.$_SESSION['id_utente'].')) ORDER BY `order` ASC');
if ($datas != null) { if ($datas != null) {
$select = ''; $select = '';
foreach ($datas as $data) { foreach ($datas as $data) {

View File

@ -13,10 +13,10 @@ include_once $docroot.'/templates/pdfgen_variables.php';
/* /*
Dati scadenzario Dati scadenzario
*/ */
if ($html->form('type') == 'clienti') { if (get('type') == 'clienti') {
$titolo = 'Scadenzario clienti'; $titolo = 'Scadenzario clienti';
$add_where = "AND an_tipianagrafiche.descrizione='Cliente'"; $add_where = "AND an_tipianagrafiche.descrizione='Cliente'";
} elseif ($html->form('type') == 'fornitori') { } elseif (get('type') == 'fornitori') {
$titolo = 'Scadenzario fornitori'; $titolo = 'Scadenzario fornitori';
$add_where = "AND an_tipianagrafiche.descrizione='Fornitore'"; $add_where = "AND an_tipianagrafiche.descrizione='Fornitore'";
} else { } else {

View File

@ -666,15 +666,15 @@ ALTER TABLE `zz_permissions` ADD FOREIGN KEY (`idmodule`) REFERENCES `zz_modules
ALTER TABLE `zz_plugins` ADD FOREIGN KEY (`idmodule_from`) REFERENCES `zz_modules`(`id`) ON DELETE CASCADE, ADD FOREIGN KEY (`idmodule_to`) REFERENCES `zz_modules`(`id`) ON DELETE CASCADE; ALTER TABLE `zz_plugins` ADD FOREIGN KEY (`idmodule_from`) REFERENCES `zz_modules`(`id`) ON DELETE CASCADE, ADD FOREIGN KEY (`idmodule_to`) REFERENCES `zz_modules`(`id`) ON DELETE CASCADE;
-- Aggiunta di chiavi esterne in zz_users -- Aggiunta di chiavi esterne in zz_users
ALTER TABLE `zz_users` CHANGE `idutente` `id_utente` int(11) NOT NULL AUTO_INCREMENT, ADD FOREIGN KEY (`idgruppo`) REFERENCES `zz_groups`(`id`) ON DELETE CASCADE; ALTER TABLE `zz_users` CHANGE `idutente` `id` int(11) NOT NULL AUTO_INCREMENT, ADD FOREIGN KEY (`idgruppo`) REFERENCES `zz_groups`(`id`) ON DELETE CASCADE;
-- Aggiunta di chiavi esterne in zz_logs -- Aggiunta di chiavi esterne in zz_logs
ALTER TABLE `zz_logs` DROP `password`, CHANGE `idutente` `id_utente` int(11), CHANGE `timestamp` `timestamp` datetime; ALTER TABLE `zz_logs` DROP `password`, CHANGE `idutente` `id_utente` int(11), CHANGE `timestamp` `timestamp` datetime;
UPDATE `zz_logs` SET `id_utente` = NULL WHERE `id_utente` = 0; UPDATE `zz_logs` SET `id_utente` = NULL WHERE `id_utente` = 0;
ALTER TABLE `zz_logs` ADD FOREIGN KEY (`id_utente`) REFERENCES `zz_users`(`id_utente`) ON DELETE CASCADE; ALTER TABLE `zz_logs` ADD FOREIGN KEY (`id_utente`) REFERENCES `zz_users`(`id`) ON DELETE CASCADE;
-- Aggiunta di chiavi esterne in zz_semaphores -- Aggiunta di chiavi esterne in zz_semaphores
ALTER TABLE `zz_semaphores` ADD FOREIGN KEY (`id_utente`) REFERENCES `zz_users`(`id_utente`) ON DELETE CASCADE; ALTER TABLE `zz_semaphores` ADD FOREIGN KEY (`id_utente`) REFERENCES `zz_users`(`id`) ON DELETE CASCADE;
-- Aggiunta della tabella per gestire le chiavi di accesso all'API -- Aggiunta della tabella per gestire le chiavi di accesso all'API
CREATE TABLE IF NOT EXISTS `zz_tokens` ( CREATE TABLE IF NOT EXISTS `zz_tokens` (
@ -684,7 +684,7 @@ CREATE TABLE IF NOT EXISTS `zz_tokens` (
`descrizione` varchar(255), `descrizione` varchar(255),
`enabled` boolean NOT NULL DEFAULT 1, `enabled` boolean NOT NULL DEFAULT 1,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
FOREIGN KEY (`id_utente`) REFERENCES `zz_users`(`id_utente`) ON DELETE CASCADE FOREIGN KEY (`id_utente`) REFERENCES `zz_users`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB; ) ENGINE=InnoDB;
-- Modifica di an_sedi per sostituire le nazioni con i corrispettivi nella tabella apposita -- Modifica di an_sedi per sostituire le nazioni con i corrispettivi nella tabella apposita