update
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
const { UsersAuth, UserProfile } = require('../models');
|
||||
const { UsersAuth, UserProfile, Role, Permission, UserAssignment, School, Class, Grade } = require('../models');
|
||||
const roleHelperService = require('../services/roleHelperService');
|
||||
const bcrypt = require('bcrypt');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const crypto = require('crypto');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
// JWT Secret - nên lưu trong environment variable
|
||||
const JWT_SECRET = process.env.JWT_SECRET || 'sena-secret-key-2026';
|
||||
@@ -12,7 +14,36 @@ const JWT_EXPIRES_IN = '24h';
|
||||
*/
|
||||
class AuthController {
|
||||
/**
|
||||
* Login - Xác thực người dùng
|
||||
* @swagger
|
||||
* /api/auth/login:
|
||||
* post:
|
||||
* tags: [Authentication]
|
||||
* summary: Đăng nhập vào hệ thống
|
||||
* description: Xác thực người dùng bằng username/email và password
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - username
|
||||
* - password
|
||||
* properties:
|
||||
* username:
|
||||
* type: string
|
||||
* example: student001
|
||||
* password:
|
||||
* type: string
|
||||
* format: password
|
||||
* example: password123
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Đăng nhập thành công
|
||||
* 401:
|
||||
* description: Username hoặc password không đúng
|
||||
* 403:
|
||||
* description: Tài khoản bị khóa
|
||||
*/
|
||||
async login(req, res, next) {
|
||||
try {
|
||||
@@ -25,7 +56,6 @@ class AuthController {
|
||||
message: 'Username và password là bắt buộc',
|
||||
});
|
||||
}
|
||||
|
||||
// Tìm user theo username hoặc email
|
||||
const user = await UsersAuth.findOne({
|
||||
where: {
|
||||
@@ -107,6 +137,9 @@ class AuthController {
|
||||
current_session_id: sessionId,
|
||||
});
|
||||
|
||||
// Load role và permissions bằng helper service
|
||||
const { roleInfo, permissions } = await roleHelperService.getUserRoleAndPermissions(user.id);
|
||||
|
||||
// Tạo JWT token
|
||||
const token = jwt.sign(
|
||||
{
|
||||
@@ -114,6 +147,7 @@ class AuthController {
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
sessionId: sessionId,
|
||||
roleCode: roleInfo?.role_code,
|
||||
},
|
||||
JWT_SECRET,
|
||||
{ expiresIn: JWT_EXPIRES_IN }
|
||||
@@ -130,6 +164,8 @@ class AuthController {
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
profile: user.profile,
|
||||
role: roleInfo,
|
||||
permissions: permissions,
|
||||
last_login: user.last_login,
|
||||
login_count: user.login_count,
|
||||
},
|
||||
@@ -141,7 +177,74 @@ class AuthController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register - Tạo tài khoản mới
|
||||
* @swagger
|
||||
* /api/auth/register:
|
||||
* post:
|
||||
* tags: [Authentication]
|
||||
* summary: Đăng ký tài khoản mới
|
||||
* description: Tạo tài khoản người dùng mới với username, email và password. Tự động tạo profile nếu có thông tin.
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - username
|
||||
* - email
|
||||
* - password
|
||||
* properties:
|
||||
* username:
|
||||
* type: string
|
||||
* minLength: 3
|
||||
* maxLength: 50
|
||||
* example: newuser123
|
||||
* email:
|
||||
* type: string
|
||||
* format: email
|
||||
* example: user@example.com
|
||||
* password:
|
||||
* type: string
|
||||
* format: password
|
||||
* minLength: 6
|
||||
* example: password123
|
||||
* full_name:
|
||||
* type: string
|
||||
* example: Nguyễn Văn A
|
||||
* phone:
|
||||
* type: string
|
||||
* example: "0901234567"
|
||||
* school_id:
|
||||
* type: string
|
||||
* format: uuid
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Đăng ký tài khoản thành công
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* success:
|
||||
* type: boolean
|
||||
* example: true
|
||||
* message:
|
||||
* type: string
|
||||
* example: Đăng ký tài khoản thành công
|
||||
* data:
|
||||
* type: object
|
||||
* properties:
|
||||
* id:
|
||||
* type: string
|
||||
* format: uuid
|
||||
* username:
|
||||
* type: string
|
||||
* email:
|
||||
* type: string
|
||||
* 400:
|
||||
* description: Thiếu thông tin bắt buộc
|
||||
* 409:
|
||||
* description: Username hoặc email đã tồn tại
|
||||
*/
|
||||
async register(req, res, next) {
|
||||
try {
|
||||
@@ -155,13 +258,10 @@ class AuthController {
|
||||
});
|
||||
}
|
||||
|
||||
// Kiểm tra username đã tồn tại
|
||||
// Check if user exists
|
||||
const existingUser = await UsersAuth.findOne({
|
||||
where: {
|
||||
[require('sequelize').Op.or]: [
|
||||
{ username },
|
||||
{ email },
|
||||
],
|
||||
[Op.or]: [{ username }, { email }],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -173,25 +273,23 @@ class AuthController {
|
||||
}
|
||||
|
||||
// Hash password
|
||||
const salt = crypto.randomBytes(16).toString('hex');
|
||||
const passwordHash = await bcrypt.hash(password + salt, 10);
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
|
||||
// Tạo user mới
|
||||
const newUser = await UsersAuth.create({
|
||||
// Create user auth
|
||||
const user = await UsersAuth.create({
|
||||
username,
|
||||
email,
|
||||
password_hash: passwordHash,
|
||||
salt,
|
||||
qr_secret: crypto.randomBytes(32).toString('hex'),
|
||||
password_hash: hashedPassword,
|
||||
status: 'active',
|
||||
});
|
||||
|
||||
// Tạo profile nếu có thông tin
|
||||
if (full_name || phone || school_id) {
|
||||
// Create user profile if we have additional info
|
||||
if (full_name || phone) {
|
||||
await UserProfile.create({
|
||||
user_id: newUser.id,
|
||||
full_name: full_name || username,
|
||||
phone,
|
||||
school_id,
|
||||
user_id: user.id,
|
||||
full_name: full_name || null,
|
||||
phone: phone || null,
|
||||
school_id: school_id || null,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -199,18 +297,31 @@ class AuthController {
|
||||
success: true,
|
||||
message: 'Đăng ký tài khoản thành công',
|
||||
data: {
|
||||
id: newUser.id,
|
||||
username: newUser.username,
|
||||
email: newUser.email,
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Register error:', error);
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify Token - Xác thực JWT token
|
||||
* @swagger
|
||||
* /api/auth/verify-token:
|
||||
* post:
|
||||
* tags: [Authentication]
|
||||
* summary: Xác thực JWT token
|
||||
* description: Kiểm tra tính hợp lệ của JWT token
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Token hợp lệ
|
||||
* 401:
|
||||
* description: Token không hợp lệ
|
||||
*/
|
||||
async verifyToken(req, res, next) {
|
||||
try {
|
||||
@@ -271,7 +382,19 @@ class AuthController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout - Đăng xuất
|
||||
* @swagger
|
||||
* /api/auth/logout:
|
||||
* post:
|
||||
* tags: [Authentication]
|
||||
* summary: Đăng xuất
|
||||
* description: Xóa session hiện tại
|
||||
* security:
|
||||
* - bearerAuth: []
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Đăng xuất thành công
|
||||
* 401:
|
||||
* description: Token không hợp lệ
|
||||
*/
|
||||
async logout(req, res, next) {
|
||||
try {
|
||||
@@ -332,9 +455,16 @@ class AuthController {
|
||||
});
|
||||
}
|
||||
|
||||
// Load role và permissions bằng helper service
|
||||
const { roleInfo, permissions } = await roleHelperService.getUserRoleAndPermissions(user.id);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: user,
|
||||
data: {
|
||||
...user.toJSON(),
|
||||
role: roleInfo,
|
||||
permissions: permissions,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
|
||||
@@ -348,4 +478,4 @@ class AuthController {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new AuthController();
|
||||
module.exports = new AuthController();
|
||||
Reference in New Issue
Block a user