Skip to content

Commit 1a042b0

Browse files
committed
feat: aggiunta impostazione per disabilitare il controllo della sessione singola per utente
1 parent 29c7a5b commit 1a042b0

2 files changed

Lines changed: 41 additions & 28 deletions

File tree

src/AuthOSM.php

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -141,26 +141,32 @@ public function attempt($username, $password, $force = false)
141141

142142
if (!empty($user)) {
143143

144-
// Verifica se l'utente è già connesso (ha un token di sessione attivo)
144+
// Controllo sessione singola: se l'impostazione "Abilita controllo sessione singola" è attiva,
145+
// verifica se l'utente è già connesso (ha un token di sessione attivo) e blocca il login multiplo.
146+
// Il reset del token avviene sempre per evitare conflitti con checkSessionToken().
145147
if (!empty($user['session_token'])) {
146-
// Verifica se ci sono operazioni recenti per l'utente (sessione attiva)
147-
$user_model = User::find($user['id']);
148-
$is_online = $user_model ? $user_model->isOnline() : 0;
148+
$single_session_enabled = setting('Abilita controllo sessione singola');
149149

150-
// Se ci sono operazioni recenti, la sessione è ancora attiva -> blocca il login
151-
if ($is_online == 1) {
152-
$status = 'already_logged_in';
153-
$this->current_status = $status;
150+
if ($single_session_enabled) {
151+
// Verifica se ci sono operazioni recenti per l'utente (sessione attiva)
152+
$user_model = User::find($user['id']);
153+
$is_online = $user_model ? $user_model->isOnline() : 0;
154154

155-
// Log del tentativo
156-
$log['stato'] = self::getStatus()[$status]['code'];
157-
$log['user_agent'] = Filter::getPurifier()->purify($_SERVER['HTTP_USER_AGENT']);
158-
$database->insert('zz_logs', $log);
155+
// Se ci sono operazioni recenti, la sessione è ancora attiva -> blocca il login
156+
if ($is_online == 1) {
157+
$status = 'already_logged_in';
158+
$this->current_status = $status;
159159

160-
return false;
160+
// Log del tentativo
161+
$log['stato'] = self::getStatus()[$status]['code'];
162+
$log['user_agent'] = Filter::getPurifier()->purify($_SERVER['HTTP_USER_AGENT']);
163+
$database->insert('zz_logs', $log);
164+
165+
return false;
166+
}
161167
}
162168

163-
// Se non ci sono operazioni recenti, la sessione è scaduta -> resetta il token e permetti il login
169+
// Resetta il token precedente per permettere il nuovo login
164170
$database->update('zz_users', [
165171
'session_token' => null,
166172
], [
@@ -354,11 +360,11 @@ public function getFirstModule($first = null)
354360
if (!$this->isAdmin()) {
355361
$group = $this->getUser()['gruppo'];
356362

357-
$query .= ' AND `id` IN (SELECT `idmodule` FROM `zz_permissions` WHERE `idgruppo` = '.Group::where('nome', $group)->first()->id." AND `permessi` IN ('r', 'rw'))";
363+
$query .= ' AND `id` IN (SELECT `idmodule` FROM `zz_permissions` WHERE `idgruppo` = ' . Group::where('nome', $group)->first()->id . " AND `permessi` IN ('r', 'rw'))";
358364
}
359365

360366
$database = database();
361-
$results = $database->fetchArray($query." AND `options` != '' AND `options` != 'menu' AND `options` IS NOT NULL ORDER BY `order` ASC", $parameters);
367+
$results = $database->fetchArray($query . " AND `options` != '' AND `options` != 'menu' AND `options` IS NOT NULL ORDER BY `order` ASC", $parameters);
362368

363369
if (!empty($results)) {
364370
$module = null;
@@ -488,7 +494,7 @@ public static function getBruteTimeout()
488494

489495
$database = database();
490496

491-
$results = $database->fetchArray('SELECT TIME_TO_SEC(TIMEDIFF(DATE_ADD(created_at, INTERVAL '.self::$brute_options['timeout'].' SECOND), NOW())) AS diff FROM zz_logs WHERE ip = :ip AND stato = :state AND DATE_ADD(created_at, INTERVAL :timeout SECOND) >= NOW() ORDER BY created_at DESC LIMIT 1', [
497+
$results = $database->fetchArray('SELECT TIME_TO_SEC(TIMEDIFF(DATE_ADD(created_at, INTERVAL ' . self::$brute_options['timeout'] . ' SECOND), NOW())) AS diff FROM zz_logs WHERE ip = :ip AND stato = :state AND DATE_ADD(created_at, INTERVAL :timeout SECOND) >= NOW() ORDER BY created_at DESC LIMIT 1', [
492498
':ip' => get_client_ip(),
493499
':state' => self::getStatus()['failed']['code'],
494500
':timeout' => self::$brute_options['timeout'],
@@ -603,7 +609,7 @@ public function attemptOTPLogin($token, $otp_code)
603609
}
604610

605611
// Verifica token e OTP nel database
606-
$token_record = $database->fetchOne('SELECT * FROM `zz_otp_tokens` WHERE `token` = '.prepare($token).' AND `enabled` = 1');
612+
$token_record = $database->fetchOne('SELECT * FROM `zz_otp_tokens` WHERE `token` = ' . prepare($token) . ' AND `enabled` = 1');
607613

608614
if (empty($token_record)) {
609615
return [
@@ -705,13 +711,13 @@ public function attemptOTPLogin($token, $otp_code)
705711
}
706712

707713
// Pulisci l'OTP utilizzato
708-
$database->query('UPDATE `zz_otp_tokens` SET `last_otp` = "" WHERE `id` = '.prepare($token_record['id']));
714+
$database->query('UPDATE `zz_otp_tokens` SET `last_otp` = "" WHERE `id` = ' . prepare($token_record['id']));
709715

710716
// Pulisci le sessioni OTP
711-
unset($_SESSION['otp_last_sent_'.$token_record['id']]);
717+
unset($_SESSION['otp_last_sent_' . $token_record['id']]);
712718

713719
// Log del login
714-
$username = $utente ? $utente->username : 'token_'.$token_record['id'];
720+
$username = $utente ? $utente->username : 'token_' . $token_record['id'];
715721
$user_id = $utente ? $utente->id : null;
716722

717723
$database->insert('zz_logs', [
@@ -746,7 +752,7 @@ public function attemptTokenLogin($token)
746752
$database = database();
747753

748754
// Verifica token nel database
749-
$token_record = $database->fetchOne('SELECT * FROM `zz_otp_tokens` WHERE `token` = '.prepare($token).' AND `enabled` = 1');
755+
$token_record = $database->fetchOne('SELECT * FROM `zz_otp_tokens` WHERE `token` = ' . prepare($token) . ' AND `enabled` = 1');
750756

751757
if (empty($token_record)) {
752758
return [
@@ -841,7 +847,7 @@ public function attemptTokenLogin($token)
841847
}
842848

843849
// Log del login
844-
$username = $utente ? $utente->username : 'token_'.$token_record['id'];
850+
$username = $utente ? $utente->username : 'token_' . $token_record['id'];
845851
$user_id = $utente ? $utente->id : null;
846852

847853
$database->insert('zz_logs', [
@@ -965,7 +971,7 @@ public function identifyUser($user_id)
965971
$database = database();
966972

967973
try {
968-
$results = $database->fetchArray('SELECT `id`, `idanagrafica`, `username`, `session_token`, (SELECT `title` FROM `zz_groups` LEFT JOIN `zz_groups_lang` ON `zz_groups`.`id`=`zz_groups_lang`.`id_record` AND `zz_groups_lang`.`id_lang`='.prepare(Models\Locale::getDefault()->id).' WHERE `zz_groups`.`id` = `zz_users`.`idgruppo`) AS gruppo FROM `zz_users` WHERE `id` = :user_id AND `enabled` = 1 LIMIT 1', [
974+
$results = $database->fetchArray('SELECT `id`, `idanagrafica`, `username`, `session_token`, (SELECT `title` FROM `zz_groups` LEFT JOIN `zz_groups_lang` ON `zz_groups`.`id`=`zz_groups_lang`.`id_record` AND `zz_groups_lang`.`id_lang`=' . prepare(Models\Locale::getDefault()->id) . ' WHERE `zz_groups`.`id` = `zz_users`.`idgruppo`) AS gruppo FROM `zz_users` WHERE `id` = :user_id AND `enabled` = 1 LIMIT 1', [
969975
':user_id' => $user_id,
970976
]);
971977

@@ -1034,7 +1040,7 @@ protected function saveToSession()
10341040
$_SESSION['auth_token'] = $this->user->session_token;
10351041
}
10361042

1037-
$identifier = md5($_SESSION['id_utente'].$_SERVER['HTTP_USER_AGENT']);
1043+
$identifier = md5($_SESSION['id_utente'] . $_SERVER['HTTP_USER_AGENT']);
10381044
if ((empty($_SESSION['last_active']) || time() < $_SESSION['last_active'] + (60 * 60)) && (empty($_SESSION['identifier']) || $_SESSION['identifier'] == $identifier)) {
10391045
$_SESSION['last_active'] = time();
10401046
$_SESSION['identifier'] = $identifier;
@@ -1053,7 +1059,7 @@ protected function identifyByToken($token_record)
10531059
// Crea un utente virtuale per la sessione
10541060
$this->user = (object) [
10551061
'id' => 0,
1056-
'username' => 'token_'.$token_record['id'],
1062+
'username' => 'token_' . $token_record['id'],
10571063
'nome' => 'Token Access',
10581064
'cognome' => '',
10591065
'email' => '',
@@ -1092,7 +1098,7 @@ protected function isTokenStillValid()
10921098
$database = database();
10931099

10941100
// Recupera il token dal database per verificare lo stato attuale
1095-
$token_record = $database->fetchOne('SELECT * FROM `zz_otp_tokens` WHERE `id` = '.prepare($this->token_user['token_id']).' AND `enabled` = 1');
1101+
$token_record = $database->fetchOne('SELECT * FROM `zz_otp_tokens` WHERE `id` = ' . prepare($this->token_user['token_id']) . ' AND `enabled` = 1');
10961102

10971103
if (empty($token_record)) {
10981104
// Token non trovato o disabilitato
@@ -1196,7 +1202,7 @@ protected function refreshUser()
11961202
return false;
11971203
} catch (Exception $e) {
11981204
// In caso di errore, logga il problema e restituisci false
1199-
error_log('Errore durante il refresh dell\'utente: '.$e->getMessage());
1205+
error_log('Errore durante il refresh dell\'utente: ' . $e->getMessage());
12001206

12011207
return false;
12021208
}

update/2_11.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- Impostazione per abilitare/disabilitare il controllo sessione singola
2+
INSERT INTO `zz_settings` (`nome`, `valore`, `tipo`, `editable`, `sezione`) VALUES
3+
('Abilita controllo sessione singola', '1', 'boolean', 1, 'Sicurezza');
4+
5+
INSERT INTO `zz_settings_lang` (`id_lang`, `id_record`, `title`, `help`) VALUES
6+
(1, (SELECT MAX(`id`) FROM `zz_settings`), 'Abilita controllo sessione singola', 'Se abilitato, impedisce il login multiplo dello stesso utente da dispositivi diversi.'),
7+
(2, (SELECT MAX(`id`) FROM `zz_settings`), 'Enable single session control', 'If enabled, prevents multiple logins of the same user from different devices.');

0 commit comments

Comments
 (0)