fix: fixed erroneaus endpoints uses

This commit is contained in:
Giuseppe Raffa
2026-04-21 20:33:12 +02:00
parent e43c330594
commit 5433529ffd
2 changed files with 107 additions and 22 deletions

View File

@@ -46,50 +46,59 @@ router.post('/register', async (req, res) => {
router.post('/login', async (req, res) => { router.post('/login', async (req, res) => {
const { username, password, redirect, _csrf } = req.body; const { username, password, redirect, _csrf } = req.body;
const loginRedirect = (errorKey, safeRedirect) => { console.log('[DEBUG ROUTES] POST /api/auth/login START - username:', username);
const params = new URLSearchParams({ error: errorKey });
if (safeRedirect) params.set('redirect', safeRedirect); const ERROR_RESPONSES = {
return res.redirect(`/login?${params.toString()}`); csrf: { success: false, error: 'csrf', message: 'Richiesta non valida, riprova' },
invalid_credentials: { success: false, error: 'invalid_credentials', message: 'Credenziali non valide' },
invalid_redirect: { success: false, error: 'invalid_redirect', message: 'Redirect non autorizzato' }
}; };
// Validazione CSRF (double-submit cookie) // Validazione CSRF (double-submit cookie)
const csrfCookie = req.cookies && req.cookies._csrf; const csrfCookie = req.cookies && req.cookies._csrf;
if (!_csrf || !csrfCookie || _csrf !== csrfCookie) { if (!_csrf || !csrfCookie || _csrf !== csrfCookie) {
return loginRedirect('csrf', ''); console.log('[DEBUG ROUTES] CSRF validation failed');
return res.status(400).json(ERROR_RESPONSES.csrf);
} }
// Validazione base // Validazione base
if (!username || !password || typeof username !== 'string' || typeof password !== 'string') { if (!username || !password || typeof username !== 'string' || typeof password !== 'string') {
return loginRedirect('invalid_credentials', redirect || ''); console.log('[DEBUG ROUTES] Invalid credentials format');
return res.status(400).json(ERROR_RESPONSES.invalid_credentials);
} }
// Limiti di lunghezza per prevenire abuse // Limiti di lunghezza per prevenire abuse
if (username.length > 50 || password.length > PASSWORD_MAX_LENGTH) { if (username.length > 50 || password.length > PASSWORD_MAX_LENGTH) {
return loginRedirect('invalid_credentials', redirect || ''); console.log('[DEBUG ROUTES] Input too long');
return res.status(400).json(ERROR_RESPONSES.invalid_credentials);
} }
// Validazione redirect URL per prevenire open redirect attacks // Validazione redirect URL per prevenire open redirect attacks
let safeRedirect = ''; let safeRedirect = CONSOLE_URL;
if (redirect && typeof redirect === 'string') { if (redirect && typeof redirect === 'string') {
try { try {
const redirectUrl = new URL(redirect); const redirectUrl = new URL(redirect);
const consoleUrl = new URL(CONSOLE_URL); const consoleUrl = new URL(CONSOLE_URL);
if (redirectUrl.hostname !== consoleUrl.hostname) { if (redirectUrl.hostname !== consoleUrl.hostname) {
return loginRedirect('invalid_redirect', ''); console.log('[DEBUG ROUTES] Invalid redirect hostname');
return res.status(400).json(ERROR_RESPONSES.invalid_redirect);
} }
safeRedirect = redirect; safeRedirect = redirect;
} catch { } catch {
// URL relativo o non valido — ignora il redirect // URL relativo o non valido — usa CONSOLE_URL di default
console.log('[DEBUG ROUTES] Redirect URL parse error, using default');
} }
} }
try { try {
console.log('[DEBUG ROUTES] POST /api/auth/login START - username:', username);\n const user = await auth.login(username, password);
const user = await auth.login(username, password);\n console.log('[DEBUG ROUTES] auth.login() success - user:', user); console.log('[DEBUG ROUTES] auth.login() success - user:', user);
const session = await auth.newSession(user.id, req.headers['user-agent'], req.ip);\n console.log('[DEBUG ROUTES] auth.newSession() success - session:', session); const session = await auth.newSession(user.id, req.headers['user-agent'], req.ip);
console.log('[DEBUG ROUTES] auth.newSession() success - session:', session);
const token = jwt.generateToken(user, session.id);\n console.log('[DEBUG ROUTES] jwt.generateToken() success'); const token = jwt.generateToken(user, session.id);
console.log('[DEBUG ROUTES] jwt.generateToken() success');
const cookieOptions = { const cookieOptions = {
httpOnly: true, httpOnly: true,
@@ -104,12 +113,16 @@ router.post('/login', async (req, res) => {
res.cookie('auth_token', token, cookieOptions); res.cookie('auth_token', token, cookieOptions);
res.clearCookie('_csrf'); res.clearCookie('_csrf');
console.log('[DEBUG ROUTES] cookies set - redirecting to:', safeRedirect || CONSOLE_URL); console.log('[DEBUG ROUTES] cookies set - returning response with redirect_url:', safeRedirect);
const destination = safeRedirect || CONSOLE_URL; return res.status(200).json({
res.redirect(destination); success: true,
redirect_url: safeRedirect,
message: 'Login effettuato con successo'
});
} catch (err) { } catch (err) {
console.error('[DEBUG ROUTES] Login FAILED:', err.message, err.code, err);\n return loginRedirect('invalid_credentials', safeRedirect); console.error('[DEBUG ROUTES] Login FAILED:', err.message, err.code);
return res.status(401).json(ERROR_RESPONSES.invalid_credentials);
} }
}); });

View File

@@ -17,11 +17,11 @@
</div> </div>
{% if error %} {% if error %}
<p class="error">{{ error }}</p> <p class="error" id="errorMessage">{{ error }}</p>
{% endif %} {% endif %}
<form action="/api/auth/login" method="post"> <form id="loginForm">
<input type="hidden" name="redirect" value="{{ redirect }}"> <input type="hidden" id="redirect" name="redirect" value="{{ redirect }}">
<input type="hidden" name="_csrf" value="{{ csrf_token }}"> <input type="hidden" name="_csrf" value="{{ csrf_token }}">
<div class="group"> <div class="group">
<label for="username">Username</label> <label for="username">Username</label>
@@ -32,10 +32,82 @@
<input type="password" id="password" name="password" required autocomplete="current-password"> <input type="password" id="password" name="password" required autocomplete="current-password">
</div> </div>
<button type="submit" class="prominent">Login</button> <button type="submit" class="prominent" id="submitBtn">Login</button>
</form> </form>
</div> </div>
</div> </div>
<script>
const form = document.getElementById('loginForm');
const submitBtn = document.getElementById('submitBtn');
const errorMessage = document.getElementById('errorMessage');
form.addEventListener('submit', async (e) => {
e.preventDefault();
submitBtn.disabled = true;
submitBtn.textContent = 'Accesso in corso...';
if (errorMessage) errorMessage.style.display = 'none';
const formData = new FormData(form);
try {
console.log('[LOGIN] Sending login request...');
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
body: JSON.stringify({
username: formData.get('username'),
password: formData.get('password'),
redirect: formData.get('redirect'),
_csrf: formData.get('_csrf')
})
});
const data = await response.json();
console.log('[LOGIN] Response:', data);
if (data.success) {
console.log('[LOGIN] Login successful, redirecting to:', data.redirect_url);
window.location.href = data.redirect_url;
} else {
console.log('[LOGIN] Login failed:', data.error);
const errorMsg = data.message || 'Errore durante il login';
if (errorMessage) {
errorMessage.textContent = errorMsg;
errorMessage.style.display = 'block';
} else {
alert(errorMsg);
}
submitBtn.disabled = false;
submitBtn.textContent = 'Login';
// Ricarica la pagina per ottenere un nuovo CSRF token
setTimeout(() => {
window.location.reload();
}, 2000);
}
} catch (err) {
console.error('[LOGIN] Error:', err);
const errorMsg = 'Errore di connessione. Riprova più tardi.';
if (errorMessage) {
errorMessage.textContent = errorMsg;
errorMessage.style.display = 'block';
} else {
alert(errorMsg);
}
submitBtn.disabled = false;
submitBtn.textContent = 'Login';
}
});
</script>
</body> </body>
</html> </html>