just-another-http-api 1.2.9 → 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 +10 -2
- package/package.json +2 -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 ) => {
|
|
@@ -36,6 +38,9 @@ async function createServer ( config ) {
|
|
|
36
38
|
if ( config.websocket?.enabled ){
|
|
37
39
|
app.register ( require ( '@fastify/websocket' ), config.websocket?.options );
|
|
38
40
|
}
|
|
41
|
+
if (config.cookies?.enabled) {
|
|
42
|
+
app.register ( require ( '@fastify/cookie' ), config.cookies );
|
|
43
|
+
}
|
|
39
44
|
await uploads.initialiseUploads ( app, config );
|
|
40
45
|
await caching.initialiseCaching ( app, config );
|
|
41
46
|
await auth.initialiseAuth ( app, config );
|
|
@@ -84,6 +89,9 @@ function registerEndpoint ( app, endpoint, globalConfig ) {
|
|
|
84
89
|
if ( handlerConfig?.cors !== undefined ) {
|
|
85
90
|
preHandlers.push ( cors.addCustomCors ( handlerConfig, globalConfig ) );
|
|
86
91
|
}
|
|
92
|
+
if ( method.toLowerCase() === 'post' && handlerConfig?.preventDuplicate ) {
|
|
93
|
+
preHandlers.push( preventDuplicateRequests );
|
|
94
|
+
}
|
|
87
95
|
|
|
88
96
|
const fastifyMethod = translateLegacyMethods ( method.toLowerCase () );
|
|
89
97
|
const handler = endpoint.handlers[ method ];
|
|
@@ -94,6 +102,7 @@ function registerEndpoint ( app, endpoint, globalConfig ) {
|
|
|
94
102
|
{
|
|
95
103
|
preHandler: preHandlers,
|
|
96
104
|
websocket: handlerConfig?.websocket || false,
|
|
105
|
+
bodyLimit: handlerConfig?.bodyLimit || undefined,
|
|
97
106
|
},
|
|
98
107
|
wrappedHandler
|
|
99
108
|
);
|
|
@@ -200,8 +209,7 @@ function handleSpecialResponseTypes ( reply, response, method, path ) {
|
|
|
200
209
|
}
|
|
201
210
|
|
|
202
211
|
function sendGenericResponse ( reply, response, method, path ) {
|
|
203
|
-
|
|
204
|
-
const data = response.json ?? response.body ?? response.response ?? response;
|
|
212
|
+
const data = response.json !== undefined ? response.json : response.body ?? response.response ?? response;
|
|
205
213
|
|
|
206
214
|
if ( data !== undefined ) {
|
|
207
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": {
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@aws-sdk/lib-storage": "^3.454.0",
|
|
29
29
|
"@fastify/caching": "^8.3.0",
|
|
30
|
+
"@fastify/cookie": "^9.4.0",
|
|
30
31
|
"@fastify/cors": "^8.4.1",
|
|
31
32
|
"@fastify/jwt": "^7.2.3",
|
|
32
33
|
"@fastify/redis": "^6.1.1",
|
|
@@ -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
|
+
};
|