fix(auth): flexibilizar login por email/usuario, asegurar hash admin123 y corregir cookies sobre HTTP

This commit is contained in:
2026-09-23 14:59:46 -03:00
parent bddd382c96
commit b540015b7e
7 changed files with 47 additions and 20 deletions
+8 -4
View File
@@ -40,17 +40,20 @@ const app = express();
const port = process.env.PORT || 3000;
app.disable('x-powered-by');
app.set('trust proxy', 1);
// Blindaje HTTP con Helmet
// Blindaje HTTP con Helmet (compatible con despliegues directos por IP y proxies HTTPS)
app.use(helmet({
contentSecurityPolicy: false,
crossOriginEmbedderPolicy: false
crossOriginEmbedderPolicy: false,
crossOriginOpenerPolicy: false,
originAgentCluster: false
}));
// Rate Limiting para protección contra ataques de fuerza bruta y abuso
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 30,
max: 60,
message: 'Demasiados intentos de autenticación. Por favor intente nuevamente en 15 minutos.',
standardHeaders: true,
legacyHeaders: false
@@ -61,7 +64,8 @@ const generalLimiter = rateLimit({
standardHeaders: true,
legacyHeaders: false
});
app.use('/auth/login', authLimiter);
app.post('/auth/login', authLimiter);
app.post('/auth/moodle', authLimiter);
app.use('/api', generalLimiter);
// Configuración de middlewares
+11 -5
View File
@@ -2,6 +2,12 @@ const express = require('express');
const router = express.Router();
const apiClient = require('../services/apiClient');
const isSecureCookie = (req) => {
if (process.env.COOKIE_SECURE === 'true') return true;
if (process.env.COOKIE_SECURE === 'false') return false;
return Boolean(req.secure || req.protocol === 'https' || req.get('x-forwarded-proto') === 'https');
};
router.get('/login', async (req, res) => {
let providers = { local: true, google: false, moodle: false };
let google_client_id = '';
@@ -38,7 +44,7 @@ router.post('/login', async (req, res) => {
if (token) {
res.cookie('auth_token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
secure: isSecureCookie(req),
sameSite: 'lax',
maxAge: 24 * 60 * 60 * 1000 // 1 día
});
@@ -66,7 +72,7 @@ router.post('/moodle', async (req, res) => {
if (token) {
res.cookie('auth_token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
secure: isSecureCookie(req),
sameSite: 'lax',
maxAge: 24 * 60 * 60 * 1000
});
@@ -89,7 +95,7 @@ router.post('/google', async (req, res) => {
if (token) {
res.cookie('auth_token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
secure: isSecureCookie(req),
sameSite: 'lax',
maxAge: 24 * 60 * 60 * 1000
});
@@ -130,12 +136,12 @@ router.get('/impersonate/:id', requireAuth, async (req, res) => {
if (targetUser) {
res.cookie('impersonate_user_id', targetUserId.toString(), {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
secure: isSecureCookie(req),
sameSite: 'lax'
});
res.cookie('impersonate_user_data', JSON.stringify(targetUser), {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
secure: isSecureCookie(req),
sameSite: 'lax'
});
}
+7 -4
View File
@@ -270,17 +270,20 @@
});
}
// Demo login autofill buttons
// Demo login autofill & instant submit (1 Clic)
document.querySelectorAll('.demo-fill-btn').forEach(btn => {
btn.addEventListener('click', function() {
btn.addEventListener('click', function(e) {
e.preventDefault();
const email = this.getAttribute('data-email');
const usrField = document.getElementById('username');
const pwdField = document.getElementById('password');
const form = document.getElementById('localLoginForm');
if (usrField && pwdField) {
usrField.value = email;
pwdField.value = 'admin123';
usrField.classList.add('is-valid');
setTimeout(() => usrField.classList.remove('is-valid'), 1500);
if (form) {
form.submit();
}
}
});
});