Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions backend/src/middleware/errorHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,16 @@ function formatErrorResponse(err, req) {
return response;
}

/**
* Attach request ID to error response
*/
export function attachRequestIdToError(err, req) {
if (!err.requestId) {
err.requestId = req.id || 'unknown';
}
return err;
}

/**
* Centralized error handling middleware
*/
Expand All @@ -223,6 +233,9 @@ export function errorHandler(err, req, res, next) {
return next(err);
}

// Attach request ID to error
attachRequestIdToError(err, req);

// Default error values
let statusCode = err.statusCode || 500;
let code = err.code || ErrorCodes.INTERNAL_ERROR;
Expand Down Expand Up @@ -327,4 +340,5 @@ export default {
createValidationError,
createStellarError,
generateRequestId,
attachRequestIdToError,
};
6 changes: 5 additions & 1 deletion backend/src/middleware/securityHeaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ export function helmetMiddleware() {
].filter(Boolean),
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'", "https://horizon.stellar.org", "https://horizon-testnet.stellar.org"],
connectSrc: [
"'self'",
"https://horizon.stellar.org",
"https://horizon-testnet.stellar.org",
],
fontSrc: ["'self'", "https:", "data:"],
objectSrc: ["'none'"],
mediaSrc: ["'self'"],
Expand Down
38 changes: 36 additions & 2 deletions backend/src/middleware/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,24 @@ export const rules = {
.isFloat({ gt: 0 })
.withMessage('Amount must be a positive number')
.isLength({ max: 20 })
.withMessage('Amount too long'),
.withMessage('Amount too long')
.custom((amount) => {
// Normalize to fixed-decimal string with max 7 decimal places
const parsed = parseFloat(amount);
if (isNaN(parsed)) throw new Error('Amount must be a valid number');

const normalized = parsed.toFixed(7);
const decimalPlaces = normalized.split('.')[1].replace(/0+$/, '').length;

if (decimalPlaces > 7) {
throw new Error('Amount cannot have more than 7 decimal places');
}
return true;
})
.customSanitizer((amount) => {
// Normalize to fixed-decimal string with max 7 decimal places
return parseFloat(amount).toFixed(7);
}),
body('assetCode')
.optional()
.trim()
Expand Down Expand Up @@ -209,7 +226,24 @@ export const rules = {
.isFloat({ gt: 0 })
.withMessage('Amount must be a positive number')
.isLength({ max: 20 })
.withMessage('Amount too long'),
.withMessage('Amount too long')
.custom((amount) => {
// Normalize to fixed-decimal string with max 7 decimal places
const parsed = parseFloat(amount);
if (isNaN(parsed)) throw new Error('Amount must be a valid number');

const normalized = parsed.toFixed(7);
const decimalPlaces = normalized.split('.')[1].replace(/0+$/, '').length;

if (decimalPlaces > 7) {
throw new Error('Amount cannot have more than 7 decimal places');
}
return true;
})
.customSanitizer((amount) => {
// Normalize to fixed-decimal string with max 7 decimal places
return parseFloat(amount).toFixed(7);
}),
body('assetCode')
.optional()
.trim()
Expand Down
Loading