fix: fixed erroneaus endpoints uses
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user