diff --git a/stellar-payment-platform/package-lock.json b/stellar-payment-platform/package-lock.json index 62f2312..ad6816e 100644 --- a/stellar-payment-platform/package-lock.json +++ b/stellar-payment-platform/package-lock.json @@ -19,6 +19,8 @@ "cors": "^2.8.5", "dotenv": "^17.4.2", "express": "^4.21.2", + "express-rate-limit": "^7.5.1", + "express-validator": "^7.3.2", "express-rate-limit": "^7.5.0", "generic-pool": "^3.9.0", "node-cache": "^5.1.2", diff --git a/stellar-payment-platform/package.json b/stellar-payment-platform/package.json index fbcf619..3e6b7e2 100644 --- a/stellar-payment-platform/package.json +++ b/stellar-payment-platform/package.json @@ -31,6 +31,8 @@ "cors": "^2.8.5", "dotenv": "^17.4.2", "express": "^4.21.2", + "express-rate-limit": "^7.5.1", + "express-validator": "^7.3.2", "express-rate-limit": "^7.5.0", "generic-pool": "^3.9.0", "node-cache": "^5.1.2", diff --git a/stellar-payment-platform/server.js b/stellar-payment-platform/server.js index 3dd2afc..c253d30 100644 --- a/stellar-payment-platform/server.js +++ b/stellar-payment-platform/server.js @@ -181,7 +181,6 @@ const limiter = rateLimit({ }); app.use(cors(corsOptions)); -app.use(limiter); app.use(express.json({ limit: '10kb' })); const isPrimitive = (v) => v === null || v === undefined || typeof v !== 'object'; @@ -317,6 +316,15 @@ app.get('/metrics', async (req, res) => { } }); +app.get('/federation', limiter, etagCache, async (req, res, next) => { + const { q, type } = req.query; + const queryValue = typeof q === 'string' ? q.trim() : ''; + + if (!queryValue) { + const error = new Error("Missing 'q' parameter"); + error.statusCode = 400; + return next(error); + } app.get('/federation', etagCache, validateSchema({ query: federationQuerySchema }), async (req, res, next) => { const { q: queryValue, type } = req.query; @@ -480,6 +488,28 @@ const verifyFreighterRegistrationSignature = ({ * - Validates that provided signature(s) meet minimum threshold * - Ensures authorization requirements are satisfied */ +app.post('/register', limiter, idempotencyMiddleware(redisClient), async (req, res, next) => { + if (!req.is('application/json')) { + return res.status(415).json({ error: "Unsupported Media Type. Please send application/json" }); + } + + // Run express-validator chains manually + for (const validator of registerValidator) { + await validator.run(req); + } + + // Check for validation errors + const errors = validationResult(req); + if (!errors.isEmpty()) { + return res.status(422).json({ + success: false, + errors: errors.array().map(err => ({ + field: err.path, + message: err.msg, + })), + }); + } + app.post('/register', idempotencyMiddleware(redisClient), requireJson, validateSchema({ body: registerBodySchema }), async (req, res, next) => { // registerBodySchema has already guaranteed that username is a trimmed // 3-20 character alphanumeric string and address is a non-empty trimmed