mirror of
https://github.com/whyour/qinglong.git
synced 2026-08-13 04:02:56 +08:00
Security improvements: Fix ownership checks, add password hashing with bcrypt
Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
This commit is contained in:
co-authored by
whyour
parent
f355b4e441
commit
b2b1777c6b
@@ -8,7 +8,7 @@ const route = Router();
|
||||
|
||||
// Middleware to check if user is admin
|
||||
const requireAdmin = (req: Request, res: Response, next: NextFunction) => {
|
||||
if (req.user && (req.user as any).role === UserRole.admin) {
|
||||
if (req.user && req.user.role === UserRole.admin) {
|
||||
return next();
|
||||
}
|
||||
return res.status(403).send({ code: 403, message: '需要管理员权限' });
|
||||
|
||||
@@ -46,7 +46,7 @@ export default class CronService {
|
||||
attributes: ['id', 'userId'],
|
||||
});
|
||||
const unauthorized = crons.filter(
|
||||
(cron) => cron.userId !== userId && cron.userId !== undefined
|
||||
(cron) => cron.userId !== undefined && cron.userId !== userId
|
||||
);
|
||||
if (unauthorized.length > 0) {
|
||||
throw new Error('无权限操作该定时任务');
|
||||
|
||||
@@ -36,7 +36,7 @@ export default class EnvService {
|
||||
attributes: ['id', 'userId'],
|
||||
});
|
||||
const unauthorized = envs.filter(
|
||||
(env) => env.userId !== userId && env.userId !== undefined
|
||||
(env) => env.userId !== undefined && env.userId !== userId
|
||||
);
|
||||
if (unauthorized.length > 0) {
|
||||
throw new Error('无权限操作该环境变量');
|
||||
|
||||
@@ -2,11 +2,21 @@ import { Service, Inject } from 'typedi';
|
||||
import winston from 'winston';
|
||||
import { User, UserModel, UserRole, UserStatus } from '../data/user';
|
||||
import { Op } from 'sequelize';
|
||||
import bcrypt from 'bcrypt';
|
||||
|
||||
@Service()
|
||||
export default class UserManagementService {
|
||||
constructor(@Inject('logger') private logger: winston.Logger) {}
|
||||
|
||||
private async hashPassword(password: string): Promise<string> {
|
||||
const saltRounds = 10;
|
||||
return bcrypt.hash(password, saltRounds);
|
||||
}
|
||||
|
||||
private async verifyPassword(password: string, hash: string): Promise<boolean> {
|
||||
return bcrypt.compare(password, hash);
|
||||
}
|
||||
|
||||
public async list(searchText?: string): Promise<User[]> {
|
||||
let query: any = {};
|
||||
if (searchText) {
|
||||
@@ -40,11 +50,15 @@ export default class UserManagementService {
|
||||
throw new Error('用户名已存在');
|
||||
}
|
||||
|
||||
if (payload.password === 'admin') {
|
||||
throw new Error('密码不能设置为admin');
|
||||
if (payload.password.length < 6) {
|
||||
throw new Error('密码长度至少为6位');
|
||||
}
|
||||
|
||||
const doc = await UserModel.create(payload);
|
||||
// Hash the password before storing
|
||||
const hashedPassword = await this.hashPassword(payload.password);
|
||||
const userWithHashedPassword = { ...payload, password: hashedPassword };
|
||||
|
||||
const doc = await UserModel.create(userWithHashedPassword);
|
||||
return doc.get({ plain: true });
|
||||
}
|
||||
|
||||
@@ -58,8 +72,8 @@ export default class UserManagementService {
|
||||
throw new Error('用户不存在');
|
||||
}
|
||||
|
||||
if (payload.password === 'admin') {
|
||||
throw new Error('密码不能设置为admin');
|
||||
if (payload.password && payload.password.length < 6) {
|
||||
throw new Error('密码长度至少为6位');
|
||||
}
|
||||
|
||||
// Check if username is being changed and if new username already exists
|
||||
@@ -70,7 +84,13 @@ export default class UserManagementService {
|
||||
}
|
||||
}
|
||||
|
||||
const [, [updated]] = await UserModel.update(payload, {
|
||||
// Hash the password if it's being updated
|
||||
const updatePayload = { ...payload };
|
||||
if (payload.password) {
|
||||
updatePayload.password = await this.hashPassword(payload.password);
|
||||
}
|
||||
|
||||
const [, [updated]] = await UserModel.update(updatePayload, {
|
||||
where: { id: payload.id },
|
||||
returning: true,
|
||||
});
|
||||
@@ -91,7 +111,8 @@ export default class UserManagementService {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (user.password !== password) {
|
||||
const isPasswordValid = await this.verifyPassword(password, user.password);
|
||||
if (!isPasswordValid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user