polysignal_hackaton / backend /src /auth /auth.service.js
Cifo_Administrador
Fixes de bug de login y telegram
7493ff2
Raw
History Blame Contribute Delete
2.89 kB
/**
* 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.
* - logout({ jti, exp }) β†’ invalidar el token activo anadiendo su jti
* a la denylist en memoria hasta su expiracion original.
*
* Seguridad:
* - Mensaje generico en fallo de login ("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).
* - Logout invalida el jti del token; el cliente debe descartar el token.
*
* Devuelve:
* login β†’ { token: string, user: { id, email } }
* logout β†’ void
*/
import bcrypt from 'bcryptjs';
import { prisma } from '../utils/prisma.js';
import { HttpError } from '../utils/apiResponse.js';
import { signToken, addToDenylist } from './jwt.js';
const INVALID_CREDENTIALS = new HttpError(401, 'INVALID_CREDENTIALS', 'Email or password is incorrect');
function buildUserResponse(user) {
return {
id: user.id,
email: user.email,
telegramChatId: user.telegramChatId,
telegramBotToken: user.telegramBotToken,
telegramAlertsEnabled: user.telegramAlertsEnabled,
};
}
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: buildUserResponse(user),
};
};
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: buildUserResponse(user),
};
};
export const logout = ({ jti, exp }) => {
if (jti && exp) addToDenylist(jti, exp);
};
export const updateTelegram = async (userId, { telegramBotToken, telegramChatId, telegramAlertsEnabled }) => {
const data = {};
if (telegramBotToken !== undefined) data.telegramBotToken = telegramBotToken || null;
if (telegramChatId !== undefined) data.telegramChatId = telegramChatId || null;
if (telegramAlertsEnabled !== undefined) data.telegramAlertsEnabled = !!telegramAlertsEnabled;
const user = await prisma.user.update({
where: { id: userId },
data,
});
return { user: buildUserResponse(user) };
};