feat: enhance JSON serialization safety & add dxt upload limit (#230)

This commit is contained in:
samanhappy
2025-07-20 19:18:10 +08:00
committed by GitHub
parent 4388084704
commit 20fd355b87
49 changed files with 3068 additions and 378 deletions

View File

@@ -1,7 +1,16 @@
import { Request, Response } from 'express';
import jwt from 'jsonwebtoken';
import { validationResult } from 'express-validator';
import { findUserByUsername, verifyPassword, createUser, updateUserPassword } from '../models/User.js';
import {
findUserByUsername,
verifyPassword,
createUser,
updateUserPassword,
} from '../models/User.js';
import { getDataService } from '../services/services.js';
import { DataService } from '../services/dataService.js';
const dataService: DataService = getDataService();
// Default secret key - in production, use an environment variable
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-this';
@@ -21,7 +30,7 @@ export const login = async (req: Request, res: Response): Promise<void> => {
try {
// Find user by username
const user = findUserByUsername(username);
if (!user) {
res.status(401).json({ success: false, message: 'Invalid credentials' });
return;
@@ -29,7 +38,7 @@ export const login = async (req: Request, res: Response): Promise<void> => {
// Verify password
const isPasswordValid = await verifyPassword(password, user.password);
if (!isPasswordValid) {
res.status(401).json({ success: false, message: 'Invalid credentials' });
return;
@@ -39,26 +48,22 @@ export const login = async (req: Request, res: Response): Promise<void> => {
const payload = {
user: {
username: user.username,
isAdmin: user.isAdmin || false
}
isAdmin: user.isAdmin || false,
},
};
jwt.sign(
payload,
JWT_SECRET,
{ expiresIn: TOKEN_EXPIRY },
(err, token) => {
if (err) throw err;
res.json({
success: true,
token,
user: {
username: user.username,
isAdmin: user.isAdmin
}
});
}
);
jwt.sign(payload, JWT_SECRET, { expiresIn: TOKEN_EXPIRY }, (err, token) => {
if (err) throw err;
res.json({
success: true,
token,
user: {
username: user.username,
isAdmin: user.isAdmin,
permissions: dataService.getPermissions(user),
},
});
});
} catch (error) {
console.error('Login error:', error);
res.status(500).json({ success: false, message: 'Server error' });
@@ -79,7 +84,7 @@ export const register = async (req: Request, res: Response): Promise<void> => {
try {
// Create new user
const newUser = await createUser({ username, password, isAdmin });
if (!newUser) {
res.status(400).json({ success: false, message: 'User already exists' });
return;
@@ -89,26 +94,22 @@ export const register = async (req: Request, res: Response): Promise<void> => {
const payload = {
user: {
username: newUser.username,
isAdmin: newUser.isAdmin || false
}
isAdmin: newUser.isAdmin || false,
},
};
jwt.sign(
payload,
JWT_SECRET,
{ expiresIn: TOKEN_EXPIRY },
(err, token) => {
if (err) throw err;
res.json({
success: true,
token,
user: {
username: newUser.username,
isAdmin: newUser.isAdmin
}
});
}
);
jwt.sign(payload, JWT_SECRET, { expiresIn: TOKEN_EXPIRY }, (err, token) => {
if (err) throw err;
res.json({
success: true,
token,
user: {
username: newUser.username,
isAdmin: newUser.isAdmin,
permissions: dataService.getPermissions(newUser),
},
});
});
} catch (error) {
console.error('Registration error:', error);
res.status(500).json({ success: false, message: 'Server error' });
@@ -120,13 +121,14 @@ export const getCurrentUser = (req: Request, res: Response): void => {
try {
// User is already attached to request by auth middleware
const user = (req as any).user;
res.json({
success: true,
res.json({
success: true,
user: {
username: user.username,
isAdmin: user.isAdmin
}
isAdmin: user.isAdmin,
permissions: dataService.getPermissions(user),
},
});
} catch (error) {
console.error('Get current user error:', error);
@@ -149,7 +151,7 @@ export const changePassword = async (req: Request, res: Response): Promise<void>
try {
// Find user by username
const user = findUserByUsername(username);
if (!user) {
res.status(404).json({ success: false, message: 'User not found' });
return;
@@ -157,7 +159,7 @@ export const changePassword = async (req: Request, res: Response): Promise<void>
// Verify current password
const isPasswordValid = await verifyPassword(currentPassword, user.password);
if (!isPasswordValid) {
res.status(401).json({ success: false, message: 'Current password is incorrect' });
return;
@@ -165,7 +167,7 @@ export const changePassword = async (req: Request, res: Response): Promise<void>
// Update the password
const updated = await updateUserPassword(username, newPassword);
if (!updated) {
res.status(500).json({ success: false, message: 'Failed to update password' });
return;
@@ -176,4 +178,4 @@ export const changePassword = async (req: Request, res: Response): Promise<void>
console.error('Change password error:', error);
res.status(500).json({ success: false, message: 'Server error' });
}
};
};