Files
betterhuman/backend/dist/routes/auth.js
T

145 lines
5.0 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const bcryptjs_1 = __importDefault(require("bcryptjs"));
const zod_1 = require("zod");
const prisma_1 = __importDefault(require("../lib/prisma"));
const jwt_1 = require("../lib/jwt");
const auth_1 = require("../middleware/auth");
const validate_1 = require("../middleware/validate");
const router = (0, express_1.Router)();
const loginSchema = zod_1.z.object({
email: zod_1.z.string().email(),
password: zod_1.z.string().min(1),
});
// POST /auth/login
router.post('/login', (0, validate_1.validate)(loginSchema), async (req, res) => {
try {
const { email, password } = req.body;
const user = await prisma_1.default.user.findFirst({
where: { email, isActive: true },
include: { employee: true },
});
if (!user) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const valid = await bcryptjs_1.default.compare(password, user.passwordHash);
if (!valid) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const payload = {
id: user.id,
companyId: user.companyId,
role: user.role,
employeeId: user.employee?.id,
};
const accessToken = (0, jwt_1.signAccessToken)(payload);
const refreshToken = (0, jwt_1.signRefreshToken)(payload);
// Store refresh token
await prisma_1.default.refreshToken.create({
data: {
userId: user.id,
token: refreshToken,
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
},
});
// Update last login
await prisma_1.default.user.update({
where: { id: user.id },
data: { lastLoginAt: new Date() },
});
res.cookie('refreshToken', refreshToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 7 * 24 * 60 * 60 * 1000,
});
return res.json({
accessToken,
user: {
id: user.id,
email: user.email,
role: user.role,
companyId: user.companyId,
employeeId: user.employee?.id,
firstName: user.employee?.firstName,
lastName: user.employee?.lastName,
},
});
}
catch (err) {
console.error('Login error:', err);
return res.status(500).json({ error: 'Internal server error' });
}
});
// POST /auth/refresh
router.post('/refresh', async (req, res) => {
try {
const token = req.cookies?.refreshToken;
if (!token) {
return res.status(401).json({ error: 'No refresh token' });
}
const stored = await prisma_1.default.refreshToken.findUnique({ where: { token } });
if (!stored || stored.expiresAt < new Date()) {
return res.status(401).json({ error: 'Invalid refresh token' });
}
const payload = (0, jwt_1.verifyRefreshToken)(token);
const accessToken = (0, jwt_1.signAccessToken)({
id: payload.id,
companyId: payload.companyId,
role: payload.role,
employeeId: payload.employeeId,
});
return res.json({ accessToken });
}
catch (err) {
return res.status(401).json({ error: 'Invalid refresh token' });
}
});
// POST /auth/logout
router.post('/logout', async (req, res) => {
const token = req.cookies?.refreshToken;
if (token) {
await prisma_1.default.refreshToken.deleteMany({ where: { token } }).catch(() => { });
}
res.clearCookie('refreshToken');
return res.json({ message: 'Logged out' });
});
// GET /auth/me
router.get('/me', auth_1.requireAuth, async (req, res) => {
try {
const user = await prisma_1.default.user.findUnique({
where: { id: req.user.id },
include: {
employee: {
include: {
department: true,
position: true,
location: true,
manager: { select: { firstName: true, lastName: true } },
},
},
company: true,
},
});
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
return res.json({
id: user.id,
email: user.email,
role: user.role,
companyId: user.companyId,
company: user.company,
employee: user.employee,
});
}
catch (err) {
return res.status(500).json({ error: 'Internal server error' });
}
});
exports.default = router;
//# sourceMappingURL=auth.js.map