just-another-http-api 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.js +7 -2
- package/package.json +1 -1
- package/utils/preventDuplicateRequest.js +27 -0
package/api.js
CHANGED
|
@@ -8,6 +8,8 @@ const uploads = require ( './src/upload' );
|
|
|
8
8
|
const auth = require ( './src/auth' );
|
|
9
9
|
const cors = require ( './src/cors' );
|
|
10
10
|
|
|
11
|
+
const preventDuplicateRequests = require('./utils/preventDuplicateRequest');
|
|
12
|
+
|
|
11
13
|
let app;
|
|
12
14
|
|
|
13
15
|
module.exports = async ( config, _app = null ) => {
|
|
@@ -87,6 +89,9 @@ function registerEndpoint ( app, endpoint, globalConfig ) {
|
|
|
87
89
|
if ( handlerConfig?.cors !== undefined ) {
|
|
88
90
|
preHandlers.push ( cors.addCustomCors ( handlerConfig, globalConfig ) );
|
|
89
91
|
}
|
|
92
|
+
if ( method.toLowerCase() === 'post' && handlerConfig?.preventDuplicate ) {
|
|
93
|
+
preHandlers.push( preventDuplicateRequests );
|
|
94
|
+
}
|
|
90
95
|
|
|
91
96
|
const fastifyMethod = translateLegacyMethods ( method.toLowerCase () );
|
|
92
97
|
const handler = endpoint.handlers[ method ];
|
|
@@ -97,6 +102,7 @@ function registerEndpoint ( app, endpoint, globalConfig ) {
|
|
|
97
102
|
{
|
|
98
103
|
preHandler: preHandlers,
|
|
99
104
|
websocket: handlerConfig?.websocket || false,
|
|
105
|
+
bodyLimit: handlerConfig?.bodyLimit || undefined,
|
|
100
106
|
},
|
|
101
107
|
wrappedHandler
|
|
102
108
|
);
|
|
@@ -203,8 +209,7 @@ function handleSpecialResponseTypes ( reply, response, method, path ) {
|
|
|
203
209
|
}
|
|
204
210
|
|
|
205
211
|
function sendGenericResponse ( reply, response, method, path ) {
|
|
206
|
-
|
|
207
|
-
const data = response.json ?? response.body ?? response.response ?? response;
|
|
212
|
+
const data = response.json !== undefined ? response.json : response.body ?? response.response ?? response;
|
|
208
213
|
|
|
209
214
|
if ( data !== undefined ) {
|
|
210
215
|
reply.type ( 'application/json' ).code ( method === 'post' ? 201 : 200 ).send ( data );
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "just-another-http-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "A framework built on top of fastify aimed at removing the need for any network or server configuration. ",
|
|
5
5
|
"homepage": "https://github.com/OllieEdge/just-another-http-api#readme",
|
|
6
6
|
"repository": {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
const { redis } = require('eip-cloud-services');
|
|
3
|
+
|
|
4
|
+
const TIMEFRAME_TO_PREVENT_DUPLICATE_REQUEST_SECONDS = 5
|
|
5
|
+
|
|
6
|
+
const hash = (item) => {
|
|
7
|
+
return crypto.createHash('sha256').update(item).digest('hex');
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
module.exports = async ( req ) => {
|
|
11
|
+
const clientIP = req.ip;
|
|
12
|
+
const requestBodyHash = hash(JSON.stringify(req.body));
|
|
13
|
+
const finalhash = hash(requestBodyHash);
|
|
14
|
+
const cacheKey = `hashedRequests:${clientIP}:${finalhash}`;
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const existingRequest = await redis.get(cacheKey);
|
|
18
|
+
if (existingRequest) {
|
|
19
|
+
const error = new Error('Too many requests');
|
|
20
|
+
error.code = 429;
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
await redis.set(cacheKey, '1', TIMEFRAME_TO_PREVENT_DUPLICATE_REQUEST_SECONDS);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
throw err;
|
|
26
|
+
}
|
|
27
|
+
};
|