Fix login endpoint leaking sensitive user fields

Use select clause instead of spreading full user object to prevent
resetToken, resetTokenExpiry, and other internal fields from being
returned in the login response.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
delta-lynx-89e8
2026-02-22 12:40:09 -08:00
parent d09c998d51
commit e72f3133c0

View File

@@ -53,19 +53,19 @@ router.post('/login', validate(loginSchema), async (req, res, next) => {
try {
const { email, password } = req.body;
const user = await prisma.user.findUnique({ where: { email } });
if (!user) throw new AppError(401, 'Invalid email or password');
if (!user.isActive) throw new AppError(403, 'Account is disabled');
const fullUser = await prisma.user.findUnique({ where: { email } });
if (!fullUser) throw new AppError(401, 'Invalid email or password');
if (!fullUser.isActive) throw new AppError(403, 'Account is disabled');
const valid = await comparePassword(password, user.passwordHash);
const valid = await comparePassword(password, fullUser.passwordHash);
if (!valid) throw new AppError(401, 'Invalid email or password');
const accessToken = generateAccessToken(user.id);
const refreshToken = generateRefreshToken(user.id);
const accessToken = generateAccessToken(fullUser.id);
const refreshToken = generateRefreshToken(fullUser.id);
await prisma.session.create({
data: {
userId: user.id,
userId: fullUser.id,
refreshToken,
userAgent: req.headers['user-agent'] || null,
ipAddress: req.ip || null,
@@ -80,8 +80,11 @@ router.post('/login', validate(loginSchema), async (req, res, next) => {
maxAge: 7 * 24 * 60 * 60 * 1000,
});
const { passwordHash: _, ...userData } = user;
res.json({ user: userData, accessToken });
const user = await prisma.user.findUnique({
where: { id: fullUser.id },
select: { id: true, email: true, fullName: true, nickname: true, avatar: true, phone: true, location: true, bio: true, rating: true, showEmail: true, showPhone: true, showLocation: true, createdAt: true },
});
res.json({ user, accessToken });
} catch (error) {
next(error);
}