Documentazione Applicazione "Bitwall" (Framework _main.6.2)
1. Architettura e Funzionamento Generale
L'applicazione è strutturata su un'architettura ibrida procedurale/OOP, tipica dei framework custom PHP consolidati nel tempo. È progettata per erogare un'interfaccia "Desktop-like" (Single Page Application o ibrida) caricando moduli all'interno di finestre modali e contesti dinamici.

1.1 Entry Points
Il traffico in ingresso è gestito principalmente da due file posti nella root della webapp (webapp/bitwall):

index.php: È il controller principale per le richieste sincrone e il caricamento iniziale dell'interfaccia. Gestisce l'inizializzazione della sessione, il caricamento dei file di configurazione (config.ini, _userdata.php), la connessione al database e definisce il layout della pagina.
aj_index.php: È l'endpoint per le chiamate asincrone (AJAX). Riceve un parametro $_SRV (Service) che agisce come switch per instradare la richiesta verso la funzione o l'inclusione corretta (es. uploadMedia, salvataggio dati, refresh di finestre).
1.2 Routing e Variabili di Stato
Il routing interno del framework non usa URL espliciti in stile REST, ma si affida a variabili in querystring/POST:

$sz o $sezione: Indica la "sezione" o l'app che si sta aprendo (es. user, admin, crm). Viene usata per determinare quali porzioni di codice includere e quale layout renderizzare.
$_SRV: Usata per i servizi in background e le chiamate AJAX.
1.3 Sistema a Moduli
L'applicazione carica i moduli in modo dinamico in base alla configurazione definita nel file config.ini (tramite l'array $_modulo['nome_modulo'] = 1). Nel file index.php, il sistema esegue un ciclo per includere automaticamente i file .function.php dei moduli attivati:

Cerca prima in _main.6.2/_inc/user/ (Cartella legacy con funzionalità legate agli account utente, librerie, calendari e profili).
Cerca poi in _main.6.2/_inc/modules/ (Nuova struttura modulare, in cui troviamo admin, users, crm, ecc.).
1.4 Livelli di Accesso (ACL)
Il file _main.6.2/_inc/config.php definisce costanti globali per i livelli utente, come $SADMINLEVEL (2048), $ADMINLEVEL (1024), $MAXUSERSLEVEL (4) e $USERSLEVEL (2). Questi valori numerici vengono usati nelle logiche di business per determinare quali "App" (finestre) o moduli un utente può istanziare.

2. Gestione del Database (db.class.php & dbmanager.php)
La connessione e l'interazione con il database sono gestite tramite un custom Data Access Layer (DAL) che astrae l'utilizzo di estensioni native.

2.1 Inizializzazione (dbmanager.php)
Il file dbmanager.php si occupa di creare le istanze globali del database che verranno utilizzate in tutto il ciclo di vita della pagina.

Legge i parametri di connessione ($a_dbparam) definiti nelle configurazioni (_userdata.php).
Istanzia la classe principale: $mydb (oggetto DB_MySqlType).
Prevede la creazione di istanze multiple (es. $dbDati, $mydbNW per i network, $mydbW per il sito web), permettendo all'applicazione di dialogare contemporaneamente con più database (Architettura Multi-DB).
2.2 La Classe DB_MySqlType
Il file _class/db.class.php contiene l'implementazione del driver per MySQL (estende una classe astratta base DB0). Usa internamente la libreria mysqli.

Caratteristiche Principali del Design Pattern:
È un oggetto "Stateful" (mantiene lo stato). Invece di restituire oggetti di tipo Result, le query modificano le proprietà interne dell'oggetto $mydb, che vengono poi lette dallo sviluppatore. Proprietà chiave:

$NrRecord: Numero di righe estratte da una SELECT.
$NrAffected: Numero di righe modificate da un UPDATE/INSERT.
$LastInsertedId: L'ID generato dall'ultima INSERT.
$LastError: Contiene eventuali messaggi d'errore.
Metodi Fondamentali:
Connect() / PConnect() / RefreshConnect(): Gestiscono la connessione. Supportano connessioni persistenti (utili per limitare l'overhead nelle chiamate AJAX continue).
DoSelect($sql): Esegue una SELECT. Particolarità vitale: non restituisce un cursore, ma esegue un fetch completo riversando tutti i risultati in un array bidimensionale che viene restituito dalla funzione. L'array è accessibile via $risultato[riga][colonna].
ExecSql($sql) / DoQuery($sql): Usate per query di scrittura (INSERT, UPDATE, DELETE). Valorizzano $LastInsertedId e $NrAffected.
GetRow($indice): Permette di scorrere manualmente il recordset memorizzato.
Gestione Transazioni: Implementa i wrapper nativi BeginTransaction(), Commit(), Rollback().
Sicurezza: Offre i metodi Escape() e EscapeString() per fare il sanitize degli input stringa prima di passarli alle query (protezione da SQL Injection).
Backup($tipo, $fullfilename): Un metodo avanzato built-in capace di fare un dump completo della struttura e dei dati delle tabelle scrivendo l'output direttamente su un file .sql su disco.
2.3 Flusso tipico di interrogazione (Esempio teorico di utilizzo)
Un tipico ciclo di recupero dati in questa applicazione seguirà questo approccio:

Php

Apply
global $mydb;

// Esecuzione di una Query di lettura
$sql = "SELECT id, nome, email FROM utenti WHERE attivo = 1";
$recordset = $mydb->DoSelect($sql);

if ($mydb->NrRecord > 0) {
    // Il db ha trovato risultati. Iterazione sull'array restituito
    for ($i = 0; $i < $mydb->NrRecord; $i++) {
        $id_utente = $recordset[$i]['id']; // o $recordset[$i][0]
        $nome      = $recordset[$i]['nome'];
        // ... logica per popolare l'UI ...
    }
}

// Esecuzione di una Query di scrittura
$sql_insert = "INSERT INTO log (user_id, action) VALUES (".$mydb->Escape($id_utente).", 'login')";
$mydb->ExecSql($sql_insert);

if ($mydb->GetAffectedRows() > 0) {
    $nuovo_id_log = $mydb->GetLastId();
}
========================================================================
Relazione sulle Procedure di Login e Accounting
Analisi Comparativa: _main.6.2 vs _wsmain.2.1

1. Architettura Generale e Modello di Dati
1.1 _main.6.2 (Framework in esame)
La gestione dell'autenticazione è centralizzata nei file login.php (controller di routing dell'azione) e _class/login.class.php (business logic). L'architettura presenta una logica di login molto complessa e strutturata a stati multipli.

Usa una variabile di controllo (passata via GET/POST) chiamata $azionelogin per gestire una Macchina a Stati Finita (FSM) con almeno 12 stati (es. 0 = Non loggato, 1 = Step 1, 2 = Controllo PIN, 4 = Reset Password, 10 = Logout).
Il sistema è predisposto per un'autenticazione nativa a 2 fattori (2FA/2-Step) e differenzia nettamente tra diverse tipologie di attori (es. Utenti VS Operatori).
Archivio log e tracciamento: Registra in modo granulare ogni azione legata alla sessione scrivendo su tre diverse tabelle (tbl_utenti, tbl_accessi, tbl_log_sessions). Inserisce un ID di sessione univoco e timestamp aggiornati per tracciare il tempo effettivo di permanenza e l'ultimo click (per calcolare il timeout inattivo).
1.2 _wsmain.2.1 (Le Dashboard - Baseline di riferimento)
Questa versione successiva adotta un approccio molto più pulito e semplificato.

Il controller login.php non usa un mega-switch numerico ($azionelogin), ma si basa su azioni più leggibili e standardizzate (es. controllo $login booleano e $logout).
L'inizializzazione della sessione è delegata più strettamente ai meccanismi nativi del PHP (session_start()).
La OOP è stata snellita. La classe Login non richiede il passaggio forzato dell'ID di sessione ($mysessionid) nel costruttore, ma lo rende una proprietà configurabile. I nomi delle tabelle sono passati tramite array strutturati ($this->db->vtables['sec_user_table']) suggerendo una maggiore standardizzazione del layer di persistenza.
2. Gestione delle Sessioni e Sicurezza (Il Confronto)
Il punto nevralgico tra le due versioni risiede nella gestione della sicurezza e, specificatamente, nell'hashing delle password e nella generazione del token di sessione ($MSID).

2.1 Generazione del Token di Sessione (MSID)
_main.6.2 (Vulnerabile / Legacy):


Apply
// Da webapp/bitwall/index.php
$mysessionid = time().filter_input(INPUT_SERVER, "USER_AGENT");
$mysessionid = md5($mysessionid);
Problema: La generazione dell'ID di sessione non è crittograficamente sicura. Si basa sul tempo e sull'User-Agent. Un attaccante che conosce il momento esatto in cui un utente ha fatto login e il suo browser può facilmente prevedere o falsificare l'MD5 generato, esponendo il sistema ad attacchi di Session Hijacking e Session Fixation.

_wsmain.2.1 (Best Practice Attuale):


Apply
// Da _wsmain.2.1/_inc/login.php
if (function_exists('random_bytes')) {
    $MSID = bin2hex(random_bytes(16)); // 32 hex chars
}
Miglioramento: Utilizza la funzione nativa random_bytes(), che attinge al generatore di numeri pseudo-casuali crittograficamente sicuro (CSPRNG) del sistema operativo. Questo rende la sessione virtualmente impossibile da indovinare. Appoggia l'identificativo correttamente su $_SESSION['MSID'].

2.2 Storage e Validazione delle Password
Il Codice Ibrido in _main.6.2:


Apply
// Da _main.6.2/_class/login.class.php
$md5Password = md5($_password);
// ...
if($storedPasswordHash == $_password || $storedPasswordHash == $md5Password) $usrValid = true;
else {
    if (password_verify($_password, $storedPasswordHash)) $usrValid = true;
}
Analisi: Questa implementazione è in una fase "transizionale". Mantiene la retrocompatibilità controllando sia password in chiaro che password in MD5 (considerato debole). Tuttavia, dimostra di essere stata aggiornata (patchata) perché include la moderna funzione password_verify() (usata con gli hash di tipo BCRYPT). Questo significa che i nuovi utenti sono protetti, ma quelli legacy che non hanno mai cambiato password hanno un livello di sicurezza inferiore.

Il Paradigma _wsmain.2.1: (Benchè non analizzato a fondo qui, le versioni 2.x standardizzano solitamente l'uso esclusivo di password_hash() con algoritmo Bcrypt o Argon2i, abbandonando i fallback insicuri).

2.3 Single Sign-On (SSO) e Autenticazione Remota
Una particolarità interessante di _main.6.2 è la presenza di logica per l'autenticazione remota (controlloLogInRemoto). Se un utente inserisce lo username con un dominio (es. utente@altrodominio.com), il sistema usa cURL per inviare la richiesta di login in POST a un endpoint esterno remoto, leggendo poi la risposta. Se l'utente è validato remotamente, il sistema crea al volo un account locale (Shadow Account) se non esiste, copiandone anagrafica e permessi, effettuando di fatto un login automatico.

3. Gestione del Ruolo e Permessi (Accounting)
_main.6.2: Usa un sistema di calcolo del livello di autorizzazione basato su potenze di 2 (abs_level).

SADMINLEVEL = 2048
ADMINLEVEL = 1024
OPERLEVEL = 8 Viene effettuato un controllo severo (if($abs_level >= $USERADMIN_LEVEL)) immediatamente dopo l'inserimento della password, bloccando l'accounting e forzando l'esclusione di utenti normali verso l'ambiente di back-office, ancor prima di inizializzare la sessione.
Limitazione e Controllo accessi in _main.6.2: Dispone di una logica (checkLog_tabUtenti) che implementa un "Ping" (refresh) costante tramite chiamate AJAX. Se l'utente chiude brutalmente il browser, il sistema lo intercetta perché il campo data_refresh o logtime smette di aggiornarsi, e procedure cron (come destroy_LogID_tabUtenti) invalidano le sessioni vecchie. Implementa inoltre una logica per bloccare gli Accessi Multipli (accessomultiplo=0), non permettendo allo stesso account di fare login da due PC/Browser differenti contemporaneamente.

Conclusioni e Spunti per il Futuro (Nessuna modifica apportata)
Il framework _main.6.2 possiede logiche aziendali estremamente ricche, stratificate e robuste lato "business logic" (gestione logout inattivi, blocco accesso multiplo, autenticazione multi-dominio remota).

Dove _wsmain.2.1 risulta superiore e da cui _main.6.2 dovrebbe ereditare in futuro:

Generazione dell'ID Sessione: L'MD5 del timestamp visto nel file index.php della 6.2 è obsoleto. L'implementazione di random_bytes() vista in _wsmain.2.1 è la strada corretta per prevenire il furto di sessione.
Ordine del Codice: La 6.2 usa un lungo script procedurale (login.php) basato su switch numerici complessi, mentre la 2.1 incapsula meglio gli stati.
Gestione Password: La 6.2 mantiene un fallback per password in MD5 o in chiaro. Andrebbe pianificata una migrazione forzata degli hash nel database, obbligando gli utenti legacy ad aggiornare le credenziali, rimuovendo così il codice di fallback ($storedPasswordHash == $md5Password).

======================================================================
APPENDICE: Evoluzione e Fix di Sicurezza Applicati in _main.6.3
A partire dalle criticità rilevate nell'architettura originale (_main.6.2), nella versione _main.6.3 sono stati applicati i seguenti interventi diretti per allineare l'autenticazione agli standard di sicurezza moderni:

1. Messa in Sicurezza dell'ID Sessione (MSID)
Problema Risolto: L'uso di MD5 e timestamp (User-Agent) rendeva l'ID di sessione prevedibile e vulnerabile a Session Hijacking.
Intervento: In webapp/bitwall/index.php, la generazione di $MSID è stata riscritta utilizzando il generatore crittografico nativo di PHP random_bytes(16).
Persistenza: L'app ora sfrutta la sessione nativa PHP ($_SESSION['MSID']) per conservare il token. Questo elimina la stringente necessità di dover passare l'MSID in chiaro tramite querystring GET/POST in ogni singola richiesta (a meno di chiamate asincrone specifiche che non lo recuperano).
2. Auto-Upgrade Silenzioso delle Password (BCRYPT)
Problema Risolto: Le password venivano storicizzate in testo in chiaro o hashiate con l'algoritmo debole MD5.
Intervento: In _main.6.3/_class/login.class.php è stata introdotta una logica di "Auto-Upgrade". Quando un utente accede con una password legacy valida (in chiaro o MD5), il sistema autorizza l'accesso ma parallelamente sovrascrive il record nel database hashiando la password con l'algoritmo sicuro BCRYPT (tramite password_hash()). Include anche il supporto per il rehashing automatico in caso i parametri di costo di bcrypt vengano aumentati dal server.
3. Semplificazione della "Macchina a Stati" FSM del Login
Intervento: È stata effettuata un'operazione di refactoring sul file _main.6.3/_inc/login.php.
Sono stati rimossi gli stati legacy complessi (es: $azionelogin == 2, 4, 6, 7, 8) che gestivano flussi obsoleti per il PIN di sicurezza ("2-step") e cambi di password intermedi non più utilizzati. L'obiettivo è ricostruire la MFA/2FA con standard moderni (es. TOTP o OTP via Email/SMS) quando si renderà necessaria in futuro, mantenendo intanto il controller pulito.
4. Hardening del Flusso di Logout
Intervento: Nello stato $azionelogin == 10 (Logout) all'interno di _main.6.3/_inc/login.php, oltre alla pulizia dei dati su DB (_sessionvars), è stata aggiunta la distruzione crittograficamente sicura della sessione PHP nativa in memoria.
Azione: Viene svuotato l'array $_SESSION, viene inviato un cookie di annullamento (setcookie) per invalidare il PHPSESSID sul browser, e viene chiamata session_destroy().