File size: 1,779 Bytes
8f7dc55 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | /**
* Logica de negocio del modulo de autenticacion.
*
* Responsabilidades:
* - login({ email, password }) → buscar usuario, comparar hash con bcrypt,
* verificar que este activo (isActive) y firmar JWT.
*
* Seguridad:
* - Mensaje generico en fallo ("Email or password is incorrect")
* para no revelar si el email existe.
* - Bcrypt con salt rounds configurable (BCRYPT_ROUNDS, default 10).
* - JWT firmado con HS256 y expiracion (JWT_EXPIRES_IN).
*
* Devuelve:
* { token: string, user: { id, email } }
*/
import bcrypt from 'bcryptjs';
import { prisma } from '../utils/prisma.js';
import { HttpError } from '../utils/apiResponse.js';
import { signToken } from './jwt.js';
const INVALID_CREDENTIALS = new HttpError(401, 'INVALID_CREDENTIALS', 'Email or password is incorrect');
export const login = async ({ email, password }) => {
const user = await prisma.user.findUnique({ where: { email } });
if (!user || !user.isActive) throw INVALID_CREDENTIALS;
const passwordOk = await bcrypt.compare(password, user.passwordHash);
if (!passwordOk) throw INVALID_CREDENTIALS;
const token = signToken({ sub: user.id, email: user.email });
return {
token,
user: { id: user.id, email: user.email },
};
};
export const register = async ({ email, password }) => {
const existing = await prisma.user.findUnique({ where: { email } });
if (existing) {
throw new HttpError(409, 'EMAIL_EXISTS', 'Email already registered');
}
const passwordHash = await bcrypt.hash(password, 10);
const user = await prisma.user.create({
data: { email, passwordHash, isActive: true },
});
const token = signToken({ sub: user.id, email: user.email });
return {
token,
user: { id: user.id, email: user.email },
};
};
|