const query = require('../storage/database').query; const track = require('../tools/tracking') const { v4: uuid } = require('uuid'); const security = require('../tools/security') /** * Registra un nuovo utente */ async function register(username, password) { const userExists = await query('SELECT id FROM users WHERE username = $1', [username]); if (userExists.rows.length > 0) { throw new Error('User already exists'); } const hashedPassword = await security.hashPassword(password); const id = uuid(); await query('INSERT INTO users (id, username, password_hash) VALUES ($1, $2, $3)', [id, username, hashedPassword]); return { success: true, user: { id, username } }; } /** * Esegue il login di un utente */ async function login(username, password) { const result = await query('SELECT id, username, password_hash, created_at FROM users WHERE username = $1', [username]); if (result.rows.length === 0) { throw new Error('No user matched') } const user = result.rows[0]; const isValid = await security.verifyPassword(password, user.password_hash); if (!isValid) { throw new Error('Password mismatch') } return { id: user.id, username: user.username, created: user.created_at } } /** * Esegue il logout di un utente * */ async function logout(sessionID) { if (!sessionID) { throw new Error('no sessio id passed'); } const result = await query('UPDATE sessions SET is_revoked = TRUE WHERE id = $1', [sessionID]); return result.rowCount > 0; } /** * Crea una nuova sessione per un utente che ha appaena eseguito il login */ async function newSession(userId, userAgent, ip) { const id = uuid(); const sessionCode = security.generateSessionCode(); const metadata = track.getBasicMetadata(userAgent); await query( `INSERT INTO sessions (id, user_id, session_code, encoded_username, ip_address, user_agent, browser, os, device_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, [id, userId, sessionCode, '', ip, userAgent, metadata.browser, metadata.os, metadata.device_type] ); return { id, sessionCode }; } /** * Valida una sessione tramite il suo UUID */ async function validateSession(sessionId) { if (!sessionId || typeof sessionId !== 'string') { throw new Error('Invalid session ID'); } const result = await query( 'SELECT s.id, u.is_active FROM sessions s JOIN users u ON s.user_id = u.id WHERE s.id = $1 AND s.is_revoked = FALSE', [sessionId] ); if (result.rows.length === 0) { throw new Error('Session not found or revoked'); } if (!result.rows[0].is_active) { throw new Error('User account is not active'); } } module.exports = { register, login, logout, newSession, validateSession }