init Backend

This commit is contained in:
JakkrapartXD 2026-01-08 06:51:33 +00:00
parent 08a4e0d8fa
commit 924000b084
29 changed files with 10080 additions and 13 deletions

View file

@ -0,0 +1,152 @@
const bcrypt = require('bcrypt');
const prisma = require('../config/database');
const { generateAccessToken, generateRefreshToken } = require('../utils/jwt');
class AuthService {
/**
* Register a new user
* @param {Object} data - User registration data
* @returns {Promise<Object>} User and tokens
*/
async register({ username, email, password, role_id = 3 }) {
// Check if user exists
const existingUser = await prisma.user.findFirst({
where: {
OR: [{ username }, { email }],
},
});
if (existingUser) {
const field = existingUser.username === username ? 'username' : 'email';
throw Object.assign(new Error(`This ${field} is already taken`), {
statusCode: 409,
code: 'DUPLICATE_ENTRY',
});
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10);
// Create user
const user = await prisma.user.create({
data: {
username,
email,
password: hashedPassword,
role_id,
},
include: {
role: true,
},
});
// Generate tokens
const accessToken = generateAccessToken({
userId: user.id,
username: user.username,
role: user.role.code,
});
const refreshToken = generateRefreshToken({
userId: user.id,
});
// Remove password from response
delete user.password;
return {
user,
accessToken,
refreshToken,
};
}
/**
* Login user
* @param {Object} credentials - Login credentials
* @returns {Promise<Object>} User and tokens
*/
async login({ username, email, password }) {
// Find user
const user = await prisma.user.findFirst({
where: {
OR: [{ username }, { email }],
},
include: {
role: true,
},
});
if (!user) {
throw Object.assign(new Error('Invalid credentials'), {
statusCode: 401,
code: 'INVALID_CREDENTIALS',
});
}
// Check if user is active
if (!user.is_active) {
throw Object.assign(new Error('Account is inactive'), {
statusCode: 403,
code: 'ACCOUNT_INACTIVE',
});
}
// Verify password
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) {
throw Object.assign(new Error('Invalid credentials'), {
statusCode: 401,
code: 'INVALID_CREDENTIALS',
});
}
// Generate tokens
const accessToken = generateAccessToken({
userId: user.id,
username: user.username,
role: user.role.code,
});
const refreshToken = generateRefreshToken({
userId: user.id,
});
// Remove password from response
delete user.password;
return {
user,
accessToken,
refreshToken,
};
}
/**
* Get user profile
* @param {number} userId - User ID
* @returns {Promise<Object>} User profile
*/
async getProfile(userId) {
const user = await prisma.user.findUnique({
where: { id: userId },
include: {
role: true,
profile: true,
},
});
if (!user) {
throw Object.assign(new Error('User not found'), {
statusCode: 404,
code: 'NOT_FOUND',
});
}
delete user.password;
return user;
}
}
module.exports = new AuthService();