@@ -47,10 +47,19 @@ router.post(
4747 const validEvents : any [ ] = [ ]
4848 const validationErrors : any [ ] = [ ]
4949
50+ // We use a LRU cache & a hash of the request IP + error message
51+ // to prevent sending multiple validation errors per user that can spam requests to Hydro
52+ const getValidationErrorHash = ( validateErrors : ErrorObject [ ] ) =>
53+ `${ req . ip } :${ ( validateErrors || [ ] )
54+ . map (
55+ ( error : ErrorObject ) => error . message + error . instancePath + JSON . stringify ( error . params ) ,
56+ )
57+ . join ( ':' ) } `
58+
5059 for ( const eventBody of eventsToProcess ) {
5160 try {
61+ // Skip event if it doesn't have a type or if the type is not in the allowed types
5262 if ( ! eventBody . type || ! allowedTypes . has ( eventBody . type ) ) {
53- validationErrors . push ( { event : eventBody , error : 'Invalid type' } )
5463 continue
5564 }
5665 const type : EventType = eventBody . type
@@ -71,18 +80,7 @@ router.post(
7180 }
7281 const validate = validators [ type ]
7382 if ( ! validate ( body ) ) {
74- validationErrors . push ( {
75- event : body ,
76- error : validate . errors || [ ] ,
77- } )
78- // This protects so we don't bother sending the same validation
79- // error, per user, more than once (per time interval).
80- // This helps if we're bombarded with junk bot traffic. So it
81- // protects our Hydro instance from being overloaded with things
82- // that aren't helping anybody.
83- const hash = `${ req . ip } :${ ( validate . errors || [ ] )
84- . map ( ( error : ErrorObject ) => error . message + error . instancePath )
85- . join ( ':' ) } `
83+ const hash = getValidationErrorHash ( validate . errors || [ ] )
8684 if ( ! sentValidationErrors . has ( hash ) ) {
8785 sentValidationErrors . set ( hash , true )
8886 formatErrors ( validate . errors || [ ] , body ) . map ( ( error ) => {
0 commit comments