@@ -12,6 +12,7 @@ import {
12
12
getRequestURL ,
13
13
readFormData ,
14
14
getRequestIP ,
15
+ getRequestFingerprint ,
15
16
} from "../src" ;
16
17
17
18
describe ( "" , ( ) => {
@@ -187,6 +188,103 @@ describe("", () => {
187
188
} ) ;
188
189
} ) ;
189
190
191
+ describe ( "getRequestFingerprint" , ( ) => {
192
+ it ( "returns an hash" , async ( ) => {
193
+ app . use ( eventHandler ( ( event ) => getRequestFingerprint ( event ) ) ) ;
194
+
195
+ const req = request . get ( "/" ) ;
196
+
197
+ // sha1 is 40 chars long
198
+ expect ( ( await req ) . text ) . toHaveLength ( 40 ) ;
199
+
200
+ // and only uses hex chars
201
+ expect ( ( await req ) . text ) . toMatch ( / ^ [ \d A - F a - f ] + $ / ) ;
202
+ } ) ;
203
+
204
+ it ( "returns the same hash every time for same request" , async ( ) => {
205
+ app . use (
206
+ eventHandler ( ( event ) => getRequestFingerprint ( event , { hash : false } ) ) ,
207
+ ) ;
208
+
209
+ const req = request . get ( "/" ) ;
210
+ expect ( ( await req ) . text ) . toMatchInlineSnapshot ( '"::ffff:127.0.0.1"' ) ;
211
+ expect ( ( await req ) . text ) . toMatchInlineSnapshot ( '"::ffff:127.0.0.1"' ) ;
212
+ } ) ;
213
+
214
+ it ( "returns null when all detections impossible" , async ( ) => {
215
+ app . use (
216
+ eventHandler ( ( event ) =>
217
+ getRequestFingerprint ( event , { hash : false , ip : false } ) ,
218
+ ) ,
219
+ ) ;
220
+ const f1 = ( await request . get ( "/" ) ) . text ;
221
+ expect ( f1 ) . toBe ( "" ) ;
222
+ } ) ;
223
+
224
+ it ( "can use path/method" , async ( ) => {
225
+ app . use (
226
+ eventHandler ( ( event ) =>
227
+ getRequestFingerprint ( event , {
228
+ hash : false ,
229
+ ip : false ,
230
+ path : true ,
231
+ method : true ,
232
+ } ) ,
233
+ ) ,
234
+ ) ;
235
+
236
+ const req = request . post ( "/foo" ) ;
237
+
238
+ expect ( ( await req ) . text ) . toMatchInlineSnapshot ( '"POST|/foo"' ) ;
239
+ } ) ;
240
+
241
+ it ( "uses user agent when available" , async ( ) => {
242
+ app . use (
243
+ eventHandler ( ( event ) =>
244
+ getRequestFingerprint ( event , { hash : false , userAgent : true } ) ,
245
+ ) ,
246
+ ) ;
247
+
248
+ const req = request . get ( "/" ) ;
249
+ req . set ( "user-agent" , "test-user-agent" ) ;
250
+
251
+ expect ( ( await req ) . text ) . toMatchInlineSnapshot (
252
+ '"::ffff:127.0.0.1|test-user-agent"' ,
253
+ ) ;
254
+ } ) ;
255
+
256
+ it ( "uses x-forwarded-for ip when header set" , async ( ) => {
257
+ app . use (
258
+ eventHandler ( ( event ) =>
259
+ getRequestFingerprint ( event , { hash : false , xForwardedFor : true } ) ,
260
+ ) ,
261
+ ) ;
262
+
263
+ const req = request . get ( "/" ) ;
264
+ req . set ( "x-forwarded-for" , "x-forwarded-for" ) ;
265
+
266
+ expect ( ( await req ) . text ) . toMatchInlineSnapshot ( '"x-forwarded-for"' ) ;
267
+ } ) ;
268
+
269
+ it ( "uses the request ip when no x-forwarded-for header set" , async ( ) => {
270
+ app . use (
271
+ eventHandler ( ( event ) => getRequestFingerprint ( event , { hash : false } ) ) ,
272
+ ) ;
273
+
274
+ app . options . onRequest = ( e ) => {
275
+ Object . defineProperty ( e . node . req . socket , "remoteAddress" , {
276
+ get ( ) : any {
277
+ return "0.0.0.0" ;
278
+ } ,
279
+ } ) ;
280
+ } ;
281
+
282
+ const req = request . get ( "/" ) ;
283
+
284
+ expect ( ( await req ) . text ) . toMatchInlineSnapshot ( '"0.0.0.0"' ) ;
285
+ } ) ;
286
+ } ) ;
287
+
190
288
describe ( "assertMethod" , ( ) => {
191
289
it ( "only allow head and post" , async ( ) => {
192
290
app . use (
0 commit comments