refactor: reorganize auth routes by separating view and API endpoints. Added some layer security to the most private apis
This commit is contained in:
@@ -5,6 +5,10 @@ const jwt = require('../tools/jwt');
|
||||
const CONSOLE_URL = process.env.CONSOLE_URL || 'http://localhost:3004';
|
||||
const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN || undefined;
|
||||
|
||||
// Validazione input
|
||||
const USERNAME_REGEX = /^[a-zA-Z0-9_.\-]{3,50}$/;
|
||||
const PASSWORD_MIN_LENGTH = 8;
|
||||
const PASSWORD_MAX_LENGTH = 128;
|
||||
|
||||
router.post('/register', async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
@@ -13,21 +17,59 @@ router.post('/register', async (req, res) => {
|
||||
return res.status(400).json({ error: 'Username e password richiesti' });
|
||||
}
|
||||
|
||||
if (typeof username !== 'string' || typeof password !== 'string') {
|
||||
return res.status(400).json({ error: 'Formato dati non valido' });
|
||||
}
|
||||
|
||||
if (!USERNAME_REGEX.test(username)) {
|
||||
return res.status(400).json({
|
||||
error: 'Username non valido. 3-50 caratteri alfanumerici, underscore, punto o trattino.'
|
||||
});
|
||||
}
|
||||
|
||||
if (password.length < PASSWORD_MIN_LENGTH || password.length > PASSWORD_MAX_LENGTH) {
|
||||
return res.status(400).json({
|
||||
error: `Password deve essere tra ${PASSWORD_MIN_LENGTH} e ${PASSWORD_MAX_LENGTH} caratteri`
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await auth.register(username, password);
|
||||
res.status(201).end();
|
||||
} catch (err) {
|
||||
console.error('[AUTH] Register failed:', err.message);
|
||||
const status = err.message === 'User already exists' ? 409 : 500;
|
||||
res.status(status).json({ error: err.message });
|
||||
res.status(status).json({ error: err.message === 'User already exists' ? err.message : 'Errore interno' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
router.post('/login', async (req, res) => {
|
||||
const { username, password, redirect } = req.body;
|
||||
|
||||
// Validazione base
|
||||
if (!username || !password || typeof username !== 'string' || typeof password !== 'string') {
|
||||
return res.render('loginpage', { error: 'Credenziali non valide', redirect: redirect || '' });
|
||||
}
|
||||
|
||||
// Limiti di lunghezza per prevenire abuse
|
||||
if (username.length > 50 || password.length > PASSWORD_MAX_LENGTH) {
|
||||
return res.render('loginpage', { error: 'Credenziali non valide', redirect: redirect || '' });
|
||||
}
|
||||
|
||||
// Validazione redirect URL per prevenire open redirect attacks
|
||||
if (redirect && typeof redirect === 'string') {
|
||||
try {
|
||||
const redirectUrl = new URL(redirect);
|
||||
const consoleUrl = new URL(CONSOLE_URL);
|
||||
// Permetti redirect solo allo stesso dominio del CONSOLE_URL
|
||||
if (redirectUrl.hostname !== consoleUrl.hostname) {
|
||||
return res.render('loginpage', { error: 'Redirect non autorizzato', redirect: '' });
|
||||
}
|
||||
} catch {
|
||||
// URL relativo o non valido — ignora il redirect
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const user = await auth.login(username, password);
|
||||
const session = await auth.newSession(user.id, req.headers['user-agent'], req.ip);
|
||||
@@ -37,7 +79,7 @@ router.post('/login', async (req, res) => {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
sameSite: 'lax',
|
||||
maxAge: 7 * 24 * 60 * 60 * 1000 // 7 giorni
|
||||
maxAge: 7 * 24 * 60 * 60 * 1000
|
||||
};
|
||||
|
||||
if (COOKIE_DOMAIN) {
|
||||
@@ -46,11 +88,11 @@ router.post('/login', async (req, res) => {
|
||||
|
||||
res.cookie('auth_token', token, cookieOptions);
|
||||
|
||||
// Redirect alla pagina da cui l'utente e' arrivato, o alla console
|
||||
const destination = redirect || CONSOLE_URL;
|
||||
res.redirect(destination);
|
||||
} catch (err) {
|
||||
console.error('[AUTH] Login failed:', err.message, err.stack);
|
||||
console.error('[AUTH] Login failed:', err.message);
|
||||
// Mai rivelare se è l'utente o la password ad essere sbagliati
|
||||
res.render('loginpage', { error: 'Credenziali non valide', redirect: redirect || '' });
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user