11import { Request , Response } from 'express' ;
2+ import rateLimit from 'express-rate-limit' ;
23import { inject } from 'inversify' ;
34import { controller , httpDelete , httpGet , httpPost , httpPut } from 'inversify-express-utils' ;
45import { v4 } from 'uuid' ;
@@ -30,6 +31,70 @@ async function validateOr400(schema: Schema<unknown>, data: unknown, res: Respon
3031 }
3132}
3233
34+ const createItemRateLimit = rateLimit ( {
35+ windowMs : 60 * 60 * 1000 ,
36+ max : 500 ,
37+ message : 'Too many item creations, please try again later.' ,
38+ standardHeaders : true ,
39+ legacyHeaders : false ,
40+ } ) ;
41+
42+ const updateItemRateLimit = rateLimit ( {
43+ windowMs : 60 * 60 * 1000 ,
44+ max : 1000 ,
45+ message : 'Too many item updates, please try again later.' ,
46+ standardHeaders : true ,
47+ legacyHeaders : false ,
48+ } ) ;
49+
50+ const deleteItemRateLimit = rateLimit ( {
51+ windowMs : 60 * 60 * 1000 ,
52+ max : 500 ,
53+ message : 'Too many item deletions, please try again later.' ,
54+ standardHeaders : true ,
55+ legacyHeaders : false ,
56+ } ) ;
57+
58+ const buyItemRateLimit = rateLimit ( {
59+ windowMs : 60 * 60 * 1000 ,
60+ max : 2000 ,
61+ message : 'Too many item purchases, please try again later.' ,
62+ standardHeaders : true ,
63+ legacyHeaders : false ,
64+ } ) ;
65+
66+ const sellItemRateLimit = rateLimit ( {
67+ windowMs : 60 * 60 * 1000 ,
68+ max : 2000 ,
69+ message : 'Too many item sales, please try again later.' ,
70+ standardHeaders : true ,
71+ legacyHeaders : false ,
72+ } ) ;
73+
74+ const consumeItemRateLimit = rateLimit ( {
75+ windowMs : 60 * 60 * 1000 ,
76+ max : 1000 ,
77+ message : 'Too many item consumptions, please try again later.' ,
78+ standardHeaders : true ,
79+ legacyHeaders : false ,
80+ } ) ;
81+
82+ const dropItemRateLimit = rateLimit ( {
83+ windowMs : 60 * 60 * 1000 ,
84+ max : 1000 ,
85+ message : 'Too many item drops, please try again later.' ,
86+ standardHeaders : true ,
87+ legacyHeaders : false ,
88+ } ) ;
89+
90+ const transferOwnershipRateLimit = rateLimit ( {
91+ windowMs : 60 * 60 * 1000 ,
92+ max : 500 ,
93+ message : 'Too many ownership transfers, please try again later.' ,
94+ standardHeaders : true ,
95+ legacyHeaders : false ,
96+ } ) ;
97+
3398@controller ( '/items' )
3499export class Items {
35100 constructor (
@@ -216,7 +281,7 @@ export class Items {
216281 example : 'POST /api/items/create {"name": "Apple", "description": "A fruit", "price": 100, "iconHash": "abc123", "showInStore": true}' ,
217282 requiresAuth : true ,
218283 } )
219- @httpPost ( '/create' , LoggedCheck . middleware )
284+ @httpPost ( '/create' , LoggedCheck . middleware , createItemRateLimit )
220285 public async createItem ( req : AuthenticatedRequest , res : Response ) {
221286 if ( ! ( await validateOr400 ( createItemValidator , req . body , res , 'Invalid item data' ) ) ) {
222287 await this . createLog ( req , 'items' , 400 ) ;
@@ -259,7 +324,7 @@ export class Items {
259324 example : 'PUT /api/items/update/123 {"name": "Apple", "description": "A fruit", "price": 100, "iconHash": "abc123", "showInStore": true}' ,
260325 requiresAuth : true ,
261326 } )
262- @httpPut ( '/update/:itemId' , OwnerCheck . middleware )
327+ @httpPut ( '/update/:itemId' , OwnerCheck . middleware , updateItemRateLimit )
263328 public async updateItem ( req : AuthenticatedRequestWithOwner , res : Response ) {
264329 if ( ! ( await validateOr400 ( itemIdParamValidator , req . params , res , 'Invalid itemId' ) ) ) {
265330 await this . createLog ( req , 'items' , 400 ) ;
@@ -305,7 +370,7 @@ export class Items {
305370 example : 'DELETE /api/items/delete/123' ,
306371 requiresAuth : true ,
307372 } )
308- @httpDelete ( '/delete/:itemId' , OwnerCheck . middleware )
373+ @httpDelete ( '/delete/:itemId' , OwnerCheck . middleware , deleteItemRateLimit )
309374 public async deleteItem ( req : AuthenticatedRequestWithOwner , res : Response ) {
310375 if ( ! ( await validateOr400 ( itemIdParamValidator , req . params , res , 'Invalid itemId' ) ) ) {
311376 await this . createLog ( req , 'items' , 400 ) ;
@@ -322,7 +387,7 @@ export class Items {
322387 }
323388 }
324389
325- @httpPost ( '/buy/:itemId' , LoggedCheck . middleware )
390+ @httpPost ( '/buy/:itemId' , LoggedCheck . middleware , buyItemRateLimit )
326391 public async buyItem ( req : AuthenticatedRequest , res : Response ) {
327392 const { itemId } = req . params ;
328393 const { amount } = req . body ;
@@ -362,7 +427,7 @@ export class Items {
362427 }
363428 }
364429
365- @httpPost ( '/sell/:itemId' , LoggedCheck . middleware )
430+ @httpPost ( '/sell/:itemId' , LoggedCheck . middleware , sellItemRateLimit )
366431 public async sellItem ( req : AuthenticatedRequest , res : Response ) {
367432 const { itemId } = req . params ;
368433 const { amount, purchasePrice, dataItemIndex } = req . body ;
@@ -418,7 +483,7 @@ export class Items {
418483 }
419484 }
420485
421- @httpPost ( '/consume/:itemId' , OwnerCheck . middleware )
486+ @httpPost ( '/consume/:itemId' , OwnerCheck . middleware , consumeItemRateLimit )
422487 public async consumeItem ( req : AuthenticatedRequestWithOwner , res : Response ) {
423488 const { itemId } = req . params ;
424489 const { amount, uniqueId, userId } = req . body ;
@@ -468,7 +533,7 @@ export class Items {
468533 }
469534 }
470535
471- @httpPost ( '/drop/:itemId' , LoggedCheck . middleware )
536+ @httpPost ( '/drop/:itemId' , LoggedCheck . middleware , dropItemRateLimit )
472537 public async dropItem ( req : AuthenticatedRequest , res : Response ) {
473538 const { itemId } = req . params ;
474539 const { amount, uniqueId, dataItemIndex } = req . body ;
@@ -513,7 +578,7 @@ export class Items {
513578 }
514579 }
515580
516- @httpPost ( '/transfer-ownership/:itemId' , OwnerCheck . middleware )
581+ @httpPost ( '/transfer-ownership/:itemId' , OwnerCheck . middleware , transferOwnershipRateLimit )
517582 public async transferOwnership ( req : AuthenticatedRequestWithOwner , res : Response ) {
518583 const { itemId } = req . params ;
519584 const { newOwnerId } = req . body ;
@@ -541,3 +606,5 @@ export class Items {
541606 }
542607 }
543608}
609+
610+
0 commit comments