@@ -5,13 +5,15 @@ import { getContext } from "../../agent/Context";
55import { escapeHTML } from "../../helpers/escapeHTML" ;
66import { ipAllowedToAccessRoute } from "./ipAllowedToAccessRoute" ;
77
8+ const checkedBlocks = Symbol ( "__zen_checked_blocks__" ) ;
9+
810/**
911 * Inspects the IP address of the request:
1012 * - Whether the IP address is blocked by an IP blocklist (e.g. Geo restrictions)
1113 * - Whether the IP address is allowed to access the current route (e.g. Admin panel)
1214 */
1315export function checkIfRequestIsBlocked (
14- res : ServerResponse ,
16+ res : ServerResponse & { [ checkedBlocks ] ?: boolean } ,
1517 agent : Agent
1618) : boolean {
1719 if ( res . headersSent ) {
@@ -26,6 +28,14 @@ export function checkIfRequestIsBlocked(
2628 return false ;
2729 }
2830
31+ if ( res [ checkedBlocks ] ) {
32+ return false ;
33+ }
34+
35+ // We don't need to check again if the request has already been checked
36+ // Also ensures that the statistics are only counted once
37+ // res[checkedBlocklist] = true;
38+
2939 if ( ! ipAllowedToAccessRoute ( context , agent ) ) {
3040 res . statusCode = 403 ;
3141 res . setHeader ( "Content-Type" , "text/plain" ) ;
@@ -69,43 +79,37 @@ export function checkIfRequestIsBlocked(
6979 ? agent . getConfig ( ) . getBlockedIPAddresses ( context . remoteAddress )
7080 : [ ] ;
7181
72- if ( blockedIPs . length > 0 ) {
73- // The same IP address can be blocked by multiple lists
74- agent . getInspectionStatistics ( ) . onIPAddressMatches ( blockedIPs ) ;
82+ agent . getInspectionStatistics ( ) . onIPAddressMatches ( blockedIPs ) ;
83+ const blockingMatch = blockedIPs . find ( ( match ) => ! match . monitor ) ;
7584
76- const blockingMatch = blockedIPs . find ( ( match ) => ! match . monitor ) ;
77- if ( blockingMatch ) {
78- res . statusCode = 403 ;
79- res . setHeader ( "Content-Type" , "text/plain" ) ;
80-
81- let message = `Your IP address is blocked due to ${ escapeHTML ( blockingMatch . reason ) } .` ;
82- if ( context . remoteAddress ) {
83- message += ` (Your IP: ${ escapeHTML ( context . remoteAddress ) } )` ;
84- }
85+ if ( blockingMatch ) {
86+ res . statusCode = 403 ;
87+ res . setHeader ( "Content-Type" , "text/plain" ) ;
8588
86- res . end ( message ) ;
87- return true ;
89+ let message = `Your IP address is blocked due to ${ escapeHTML ( blockingMatch . reason ) } .` ;
90+ if ( context . remoteAddress ) {
91+ message += ` (Your IP: ${ escapeHTML ( context . remoteAddress ) } )` ;
8892 }
93+
94+ res . end ( message ) ;
95+ return true ;
8996 }
9097
9198 const blockedUserAgents =
9299 context . headers && typeof context . headers [ "user-agent" ] === "string"
93100 ? agent . getConfig ( ) . getBlockedUserAgents ( context . headers [ "user-agent" ] )
94101 : [ ] ;
95102
96- if ( blockedUserAgents . length > 0 ) {
97- // The same user agent can be blocked by multiple lists
98- agent . getInspectionStatistics ( ) . onUserAgentMatches ( blockedUserAgents ) ;
103+ agent . getInspectionStatistics ( ) . onUserAgentMatches ( blockedUserAgents ) ;
99104
100- if ( blockedUserAgents . find ( ( match ) => ! match . monitor ) ) {
101- res . statusCode = 403 ;
102- res . setHeader ( "Content-Type" , "text/plain" ) ;
105+ if ( blockedUserAgents . find ( ( match ) => ! match . monitor ) ) {
106+ res . statusCode = 403 ;
107+ res . setHeader ( "Content-Type" , "text/plain" ) ;
103108
104- res . end (
105- "You are not allowed to access this resource because you have been identified as a bot."
106- ) ;
107- return true ;
108- }
109+ res . end (
110+ "You are not allowed to access this resource because you have been identified as a bot."
111+ ) ;
112+ return true ;
109113 }
110114
111115 return false ;
0 commit comments