145 lines
5.0 KiB
JavaScript
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
|