[{"data":1,"prerenderedAt":1881},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fdocs\u002Fbot-detection":64,"navigation":191,"navLinks_footer":816,"\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation_page":829,"\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation_surround":1442,"\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation":1445},{"id":4,"extension":5,"links":6,"meta":61,"stem":62,"__hash__":63},"navigationMenu\u002Fnavigation.json","json",[7,52,57],{"nested":8,"label":9,"icon":10,"to":11,"children":12},true,"Docs","i-lucide-book-open","\u002Fdocs\u002Fgetting-started",[13,19,26,32,39,45],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},"Getting Started","i-lucide-rocket","An introduction to help you understand the core components.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fdocshub","Start Here",{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},"Auth H3 Client","i-lucide-key-round","\u002Fdocs\u002Fauth-h3client","Seamlessly enforce OAuth 2.0 authentication and session management integrated directly as the client of the IAM module.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth-h3client","Core",{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},"IAM","i-lucide-shield-check","\u002Fdocs\u002Fiam","Identity and Access Management featuring granular roles, permissions, and security policies.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fauth",{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},"Bot Detection","i-lucide-cpu","\u002Fdocs\u002Fbot-detection","Advanced behavioral analysis and request fingerprinting to stop malicious automated traffic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fbot-detector","Security",{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},"Shield Base","i-lucide-database-zap","\u002Fdocs\u002Fshield-base","CLI and programmatic toolkit for compiling offline-ready IP intelligence databases from BGP, GeoIP, Tor, FireHOL, and other public threat feeds.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Fshield-base-cli",{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},"Utils","i-lucide-wrench","\u002Fdocs\u002Futils","A standard library of highly optimized helpers for formatting, validation, and core logic.","https:\u002F\u002Fgithub.com\u002FSergo706\u002Futils","Library",{"nested":53,"label":54,"icon":55,"to":56},false,"Blog","i-lucide-pen-line","\u002Fblog",{"nested":53,"label":58,"icon":59,"to":60},"Website","lucide:app-window-mac","https:\u002F\u002Friavzon.com",{},"navigation","gkaQ0xRGxSLrLyM3kttLe0oBwkrR1EBjlepF8LSbwF8",[65],{"title":9,"path":66,"stem":67,"children":68,"page":53},"\u002Fdocs","docs",[69],{"title":70,"path":35,"stem":71,"children":72},"Bot Detector","docs\u002Fbot-detection\u002Findex",[73,74,77,81,85,106,180,183,187],{"title":70,"path":35,"stem":71},{"title":14,"path":75,"stem":76},"\u002Fdocs\u002Fbot-detection\u002Fgetting-started","docs\u002Fbot-detection\u002F00.getting-started",{"title":78,"path":79,"stem":80},"CLI","\u002Fdocs\u002Fbot-detection\u002Fcli","docs\u002Fbot-detection\u002F01.cli",{"title":82,"path":83,"stem":84},"Data Sources","\u002Fdocs\u002Fbot-detection\u002Fdata-sources","docs\u002Fbot-detection\u002F02.data-sources",{"title":86,"path":87,"stem":88,"children":89,"page":53},"Guides","\u002Fdocs\u002Fbot-detection\u002Fguides","docs\u002Fbot-detection\u002F03.guides",[90,94,98,102],{"title":91,"path":92,"stem":93},"Custom Checkers","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fcustom","docs\u002Fbot-detection\u002F03.guides\u002FCUSTOM",{"title":95,"path":96,"stem":97},"Scheduling Database Generation","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fgenerate","docs\u002Fbot-detection\u002F03.guides\u002FGENERATE",{"title":99,"path":100,"stem":101},"Logging","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Flogging","docs\u002Fbot-detection\u002F03.guides\u002FLOGGING",{"title":103,"path":104,"stem":105},"Score Modes and Reputation Healing","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fscore","docs\u002Fbot-detection\u002F03.guides\u002FSCORE",{"title":107,"path":108,"stem":109,"children":110},"Checkers","\u002Fdocs\u002Fbot-detection\u002Fcheckers","docs\u002Fbot-detection\u002F04.checkers\u002Findex",[111,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176],{"title":107,"path":108,"stem":109},{"title":113,"path":114,"stem":115},"IP Validation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fip-validation","docs\u002Fbot-detection\u002F04.checkers\u002F01.ip-validation",{"title":117,"path":118,"stem":119},"Good \u002F Bad Bot Verification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgood-bots","docs\u002Fbot-detection\u002F04.checkers\u002F02.good-bots",{"title":121,"path":122,"stem":123},"Browser & Device Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbrowser-device","docs\u002Fbot-detection\u002F04.checkers\u002F03.browser-device",{"title":125,"path":126,"stem":127},"Locale Map","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Flocale-map","docs\u002Fbot-detection\u002F04.checkers\u002F04.locale-map",{"title":129,"path":130,"stem":131},"Known Threats","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-threats","docs\u002Fbot-detection\u002F04.checkers\u002F05.known-threats",{"title":133,"path":134,"stem":135},"ASN Classification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fasn-classification","docs\u002Fbot-detection\u002F04.checkers\u002F06.asn-classification",{"title":137,"path":138,"stem":139},"Tor Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftor-analysis","docs\u002Fbot-detection\u002F04.checkers\u002F07.tor-analysis",{"title":141,"path":142,"stem":143},"Timezone Consistency","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftimezone-consistency","docs\u002Fbot-detection\u002F04.checkers\u002F08.timezone-consistency",{"title":145,"path":146,"stem":147},"Honeypot","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fhoneypot","docs\u002Fbot-detection\u002F04.checkers\u002F09.honeypot",{"title":149,"path":150,"stem":151},"Known Bad IPs","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ips","docs\u002Fbot-detection\u002F04.checkers\u002F10.known-bad-ips",{"title":153,"path":154,"stem":155},"Behavior Rate","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbehavior-rate","docs\u002Fbot-detection\u002F04.checkers\u002F11.behavior-rate",{"title":157,"path":158,"stem":159},"Proxy \u002F ISP \u002F Cookie","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fproxy-isp-cookies","docs\u002Fbot-detection\u002F04.checkers\u002F12.proxy-isp-cookies",{"title":161,"path":162,"stem":163},"Session Coherence","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fsession-coherence","docs\u002Fbot-detection\u002F04.checkers\u002F13.session-coherence",{"title":165,"path":166,"stem":167},"Velocity Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fvelocity-fingerprint","docs\u002Fbot-detection\u002F04.checkers\u002F14.velocity-fingerprint",{"title":169,"path":170,"stem":171},"UA & Header Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fua-header","docs\u002Fbot-detection\u002F04.checkers\u002F15.ua-header",{"title":173,"path":174,"stem":175},"Geolocation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation","docs\u002Fbot-detection\u002F04.checkers\u002F16.geolocation",{"title":177,"path":178,"stem":179},"Known Bad User-Agents","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ua","docs\u002Fbot-detection\u002F04.checkers\u002F17.known-bad-ua",{"title":38,"path":181,"stem":182},"\u002Fdocs\u002Fbot-detection\u002Fsecurity","docs\u002Fbot-detection\u002F04.security",{"title":184,"path":185,"stem":186},"API Reference","\u002Fdocs\u002Fbot-detection\u002Fapi","docs\u002Fbot-detection\u002F05.api",{"title":188,"path":189,"stem":190},"Configuration","\u002Fdocs\u002Fbot-detection\u002Fconfiguration","docs\u002Fbot-detection\u002F06.configuration",[192],{"title":9,"path":66,"stem":67,"children":193,"page":53},[194,338,373,378,556,623],{"title":20,"path":22,"stem":195,"children":196},"docs\u002Fauth-h3client\u002Findex",[197,198,207,243,269,291,294,314,317],{"title":20,"path":22,"stem":195},{"title":14,"path":199,"stem":200,"children":201},"\u002Fdocs\u002Fauth-h3client\u002Fgetting-started","docs\u002Fauth-h3client\u002F00.getting-started\u002Findex",[202,203],{"title":14,"path":199,"stem":200},{"title":204,"path":205,"stem":206},"Nuxt Module","\u002Fdocs\u002Fauth-h3client\u002Fgetting-started\u002Fnuxt","docs\u002Fauth-h3client\u002F00.getting-started\u002F00.nuxt",{"title":208,"path":209,"stem":210,"children":211},"Essentials","\u002Fdocs\u002Fauth-h3client\u002Fessentials","docs\u002Fauth-h3client\u002F01.essentials\u002Findex",[212,213,217,221,225,229,233,236,240],{"title":208,"path":209,"stem":210},{"title":214,"path":215,"stem":216},"Session Management","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession","docs\u002Fauth-h3client\u002F01.essentials\u002F00.session",{"title":218,"path":219,"stem":220},"Route Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Froute-protection","docs\u002Fauth-h3client\u002F01.essentials\u002F01.route-protection",{"title":222,"path":223,"stem":224},"CSRF Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcsrf","docs\u002Fauth-h3client\u002F01.essentials\u002F02.csrf",{"title":226,"path":227,"stem":228},"Auth Flows","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fauth-flows","docs\u002Fauth-h3client\u002F01.essentials\u002F03.auth-flows",{"title":230,"path":231,"stem":232},"OAuth and OIDC","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth","docs\u002Fauth-h3client\u002F01.essentials\u002F04.oauth",{"title":33,"path":234,"stem":235},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection","docs\u002Fauth-h3client\u002F01.essentials\u002F05.bot-detection",{"title":237,"path":238,"stem":239},"Cookies","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcookies","docs\u002Fauth-h3client\u002F01.essentials\u002F06.cookies",{"title":99,"path":241,"stem":242},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Flogging","docs\u002Fauth-h3client\u002F01.essentials\u002F07.logging",{"title":244,"path":245,"stem":246,"children":247},"MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa","docs\u002Fauth-h3client\u002F02.mfa\u002Findex",[248,249,253,257,261,265],{"title":244,"path":245,"stem":246},{"title":250,"path":251,"stem":252},"Built-in MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fbuilt-in-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F01.built-in-flow",{"title":254,"path":255,"stem":256},"Password Reset","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fpassword-reset","docs\u002Fauth-h3client\u002F02.mfa\u002F02.password-reset",{"title":258,"path":259,"stem":260},"Email Change","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Femail-change","docs\u002Fauth-h3client\u002F02.mfa\u002F03.email-change",{"title":262,"path":263,"stem":264},"Custom MFA Flow","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F04.custom-flow",{"title":266,"path":267,"stem":268},"Client-Side MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fclient-side","docs\u002Fauth-h3client\u002F02.mfa\u002F05.client-side",{"title":270,"path":271,"stem":272,"children":273},"Client-side","\u002Fdocs\u002Fauth-h3client\u002Fclient","docs\u002Fauth-h3client\u002F03.client\u002Findex",[274,275,279,283,287],{"title":270,"path":271,"stem":272},{"title":276,"path":277,"stem":278},"useAuthData","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-auth-data","docs\u002Fauth-h3client\u002F03.client\u002F00.use-auth-data",{"title":280,"path":281,"stem":282},"useMagicLink","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-magic-link","docs\u002Fauth-h3client\u002F03.client\u002F01.use-magic-link",{"title":284,"path":285,"stem":286},"executeRequest","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fexecute-request","docs\u002Fauth-h3client\u002F03.client\u002F02.execute-request",{"title":288,"path":289,"stem":290},"getCsrfToken","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fget-csrf-token","docs\u002Fauth-h3client\u002F03.client\u002F03.get-csrf-token",{"title":38,"path":292,"stem":293},"\u002Fdocs\u002Fauth-h3client\u002Fsecurity","docs\u002Fauth-h3client\u002F04.security",{"title":86,"path":295,"stem":296,"children":297,"page":53},"\u002Fdocs\u002Fauth-h3client\u002Fguides","docs\u002Fauth-h3client\u002F05.guides",[298,302,306,310],{"title":299,"path":300,"stem":301},"H3 and Nitro Setup","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fh3-nitro","docs\u002Fauth-h3client\u002F05.guides\u002F00.h3-nitro",{"title":303,"path":304,"stem":305},"HMAC Inter-service Auth","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fhmac","docs\u002Fauth-h3client\u002F05.guides\u002Fhmac",{"title":307,"path":308,"stem":309},"Image Upload","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fimage-upload","docs\u002Fauth-h3client\u002F05.guides\u002Fimage-upload",{"title":311,"path":312,"stem":313},"mTLS Configuration","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fmtls","docs\u002Fauth-h3client\u002F05.guides\u002Fmtls",{"title":188,"path":315,"stem":316},"\u002Fdocs\u002Fauth-h3client\u002Fconfiguration","docs\u002Fauth-h3client\u002F06.configuration",{"title":184,"path":318,"stem":319,"children":320},"\u002Fdocs\u002Fauth-h3client\u002Fapi","docs\u002Fauth-h3client\u002F07.api\u002Findex",[321,322,326,330,334],{"title":184,"path":318,"stem":319},{"title":323,"path":324,"stem":325},"Routes Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcontrollers","docs\u002Fauth-h3client\u002F07.api\u002F00.controllers",{"title":327,"path":328,"stem":329},"Middleware Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fmiddleware","docs\u002Fauth-h3client\u002F07.api\u002F01.middleware",{"title":331,"path":332,"stem":333},"Client-side Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcomposables","docs\u002Fauth-h3client\u002F07.api\u002F02.composables",{"title":335,"path":336,"stem":337},"Utilities","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Futilities","docs\u002Fauth-h3client\u002F07.api\u002F03.utilities",{"title":70,"path":35,"stem":71,"children":339},[340,341,342,343,344,350,370,371,372],{"title":70,"path":35,"stem":71},{"title":14,"path":75,"stem":76},{"title":78,"path":79,"stem":80},{"title":82,"path":83,"stem":84},{"title":86,"path":87,"stem":88,"children":345,"page":53},[346,347,348,349],{"title":91,"path":92,"stem":93},{"title":95,"path":96,"stem":97},{"title":99,"path":100,"stem":101},{"title":103,"path":104,"stem":105},{"title":107,"path":108,"stem":109,"children":351},[352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369],{"title":107,"path":108,"stem":109},{"title":113,"path":114,"stem":115},{"title":117,"path":118,"stem":119},{"title":121,"path":122,"stem":123},{"title":125,"path":126,"stem":127},{"title":129,"path":130,"stem":131},{"title":133,"path":134,"stem":135},{"title":137,"path":138,"stem":139},{"title":141,"path":142,"stem":143},{"title":145,"path":146,"stem":147},{"title":149,"path":150,"stem":151},{"title":153,"path":154,"stem":155},{"title":157,"path":158,"stem":159},{"title":161,"path":162,"stem":163},{"title":165,"path":166,"stem":167},{"title":169,"path":170,"stem":171},{"title":173,"path":174,"stem":175},{"title":177,"path":178,"stem":179},{"title":38,"path":181,"stem":182},{"title":184,"path":185,"stem":186},{"title":188,"path":189,"stem":190},{"title":374,"path":11,"stem":375,"children":376},"Introduction","docs\u002Fgetting-started\u002Findex",[377],{"title":374,"path":11,"stem":375},{"title":27,"path":29,"stem":379,"children":380},"docs\u002Fiam\u002Findex",[381,382,385,520,523,539,542],{"title":27,"path":29,"stem":379},{"title":14,"path":383,"stem":384},"\u002Fdocs\u002Fiam\u002Fgetting-started","docs\u002Fiam\u002F00.getting-started",{"title":208,"path":386,"stem":387,"children":388},"\u002Fdocs\u002Fiam\u002Fessentials","docs\u002Fiam\u002F01.essentials\u002Findex",[389,390,394,398,402,406,410,414,418,422,426,430,433,437,441,445,449,452,456,460,463,467,470],{"title":208,"path":386,"stem":387},{"title":391,"path":392,"stem":393},"Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens","docs\u002Fiam\u002F01.essentials\u002F00.tokens",{"title":395,"path":396,"stem":397},"Access Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Faccess-tokens","docs\u002Fiam\u002F01.essentials\u002F01.access-tokens",{"title":399,"path":400,"stem":401},"Refresh Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens","docs\u002Fiam\u002F01.essentials\u002F02.refresh-tokens",{"title":403,"path":404,"stem":405},"Anomaly Detection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies","docs\u002Fiam\u002F01.essentials\u002F03.anomalies",{"title":407,"path":408,"stem":409},"Signup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fsignup","docs\u002Fiam\u002F01.essentials\u002F04.signup",{"title":411,"path":412,"stem":413},"Login","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogin","docs\u002Fiam\u002F01.essentials\u002F05.login",{"title":415,"path":416,"stem":417},"Logout","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout","docs\u002Fiam\u002F01.essentials\u002F06.logout",{"title":419,"path":420,"stem":421},"OAuth","\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth","docs\u002Fiam\u002F01.essentials\u002F07.oauth",{"title":423,"path":424,"stem":425},"Magic Links","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmagic-links","docs\u002Fiam\u002F01.essentials\u002F08.magic-links",{"title":427,"path":428,"stem":429},"Emails","\u002Fdocs\u002Fiam\u002Fessentials\u002Femails","docs\u002Fiam\u002F01.essentials\u002F09.emails",{"title":244,"path":431,"stem":432},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fmfa","docs\u002Fiam\u002F01.essentials\u002F10.mfa",{"title":434,"path":435,"stem":436},"Fingerprinting","\u002Fdocs\u002Fiam\u002Fessentials\u002Ffingerprinting","docs\u002Fiam\u002F01.essentials\u002F11.fingerprinting",{"title":438,"path":439,"stem":440},"Backend for Frontend","\u002Fdocs\u002Fiam\u002Fessentials\u002Fbff","docs\u002Fiam\u002F01.essentials\u002F12.bff",{"title":442,"path":443,"stem":444},"HMAC Authentication","\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac","docs\u002Fiam\u002F01.essentials\u002F13.hmac",{"title":446,"path":447,"stem":448},"XSS Protection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fxss","docs\u002Fiam\u002F01.essentials\u002F14.xss",{"title":99,"path":450,"stem":451},"\u002Fdocs\u002Fiam\u002Fessentials\u002Flogging","docs\u002Fiam\u002F01.essentials\u002F15.logging",{"title":453,"path":454,"stem":455},"Rate Limiting","\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F16.rate-limiting",{"title":457,"path":458,"stem":459},"Database","\u002Fdocs\u002Fiam\u002Fessentials\u002Fdatabase","docs\u002Fiam\u002F01.essentials\u002F17.database",{"title":237,"path":461,"stem":462},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fcookies","docs\u002Fiam\u002F01.essentials\u002F18.cookies",{"title":464,"path":465,"stem":466},"Service Startup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice","docs\u002Fiam\u002F01.essentials\u002F19.service",{"title":254,"path":468,"stem":469},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fpassword-reset","docs\u002Fiam\u002F01.essentials\u002F20.password-reset",{"title":471,"path":472,"stem":473,"children":474},"API Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi","docs\u002Fiam\u002F01.essentials\u002F21.api\u002Findex",[475,476,480,484,514,517],{"title":471,"path":472,"stem":473},{"title":477,"path":478,"stem":479},"Creating Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fcreation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F00.creation",{"title":481,"path":482,"stem":483},"Verifying Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fverification","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F01.verification",{"title":485,"path":486,"stem":487,"children":488},"Manage Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002Findex",[489,490,494,498,502,506,510],{"title":485,"path":486,"stem":487},{"title":491,"path":492,"stem":493},"Privileges","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fprivilege","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F00.privilege",{"title":495,"path":496,"stem":497},"Revocation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frevocation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F01.revocation",{"title":499,"path":500,"stem":501},"Rotation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frotation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F02.rotation",{"title":503,"path":504,"stem":505},"IP Restriction","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fip-updates","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F03.ip-updates",{"title":507,"path":508,"stem":509},"Metadata","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fmetadata","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F04.metadata",{"title":511,"path":512,"stem":513},"Token Listing","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Flist","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F05.list",{"title":453,"path":515,"stem":516},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F03.rate-limiting",{"title":38,"path":518,"stem":519},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fsecurity","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F04.security",{"title":38,"path":521,"stem":522},"\u002Fdocs\u002Fiam\u002Fsecurity","docs\u002Fiam\u002F02.security",{"title":86,"path":524,"stem":525,"children":526,"page":53},"\u002Fdocs\u002Fiam\u002Fguides","docs\u002Fiam\u002F03.guides",[527,531,535],{"title":528,"path":529,"stem":530},"Deployment","\u002Fdocs\u002Fiam\u002Fguides\u002Fdeployment","docs\u002Fiam\u002F03.guides\u002Fdeployment",{"title":532,"path":533,"stem":534},"Operation Scripts","\u002Fdocs\u002Fiam\u002Fguides\u002Foperation-scripts","docs\u002Fiam\u002F03.guides\u002Foperation-scripts",{"title":536,"path":537,"stem":538},"Role-Based Access Control","\u002Fdocs\u002Fiam\u002Fguides\u002Frbac","docs\u002Fiam\u002F03.guides\u002Frbac",{"title":188,"path":540,"stem":541},"\u002Fdocs\u002Fiam\u002Fconfiguration","docs\u002Fiam\u002F04.configuration",{"title":543,"path":544,"stem":545,"children":546,"page":53},"Api","\u002Fdocs\u002Fiam\u002Fapi","docs\u002Fiam\u002F05.API",[547,550,553],{"title":184,"path":548,"stem":549},"\u002Fdocs\u002Fiam\u002Fapi\u002Fapi","docs\u002Fiam\u002F05.API\u002F00.api",{"title":327,"path":551,"stem":552},"\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares","docs\u002Fiam\u002F05.API\u002F02.middlewares",{"title":323,"path":554,"stem":555},"\u002Fdocs\u002Fiam\u002Fapi\u002Froutes","docs\u002Fiam\u002F05.API\u002F03.routes",{"title":40,"path":42,"stem":557,"children":558},"docs\u002Fshield-base\u002Findex",[559,560,563,567,608,612,616,620],{"title":40,"path":42,"stem":557},{"title":14,"path":561,"stem":562},"\u002Fdocs\u002Fshield-base\u002Fgetting-started","docs\u002Fshield-base\u002F00.getting-started",{"title":564,"path":565,"stem":566},"CLI Reference","\u002Fdocs\u002Fshield-base\u002Fcli","docs\u002Fshield-base\u002F01.cli",{"title":82,"path":568,"stem":569,"children":570},"\u002Fdocs\u002Fshield-base\u002Fdata-sources","docs\u002Fshield-base\u002F02.data-sources\u002Findex",[571,572,576,580,584,588,592,596,600,604],{"title":82,"path":568,"stem":569},{"title":573,"path":574,"stem":575},"BGP \u002F ASN","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fbgp","docs\u002Fshield-base\u002F02.data-sources\u002Fbgp",{"title":577,"path":578,"stem":579},"City Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcity","docs\u002Fshield-base\u002F02.data-sources\u002Fcity",{"title":581,"path":582,"stem":583},"Country Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcountry","docs\u002Fshield-base\u002F02.data-sources\u002Fcountry",{"title":585,"path":586,"stem":587},"Verified Crawlers","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcrawlers","docs\u002Fshield-base\u002F02.data-sources\u002Fcrawlers",{"title":589,"path":590,"stem":591},"Disposable Emails","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Femail","docs\u002Fshield-base\u002F02.data-sources\u002Femail",{"title":593,"path":594,"stem":595},"FireHOL Threat Intelligence","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ffirehol","docs\u002Fshield-base\u002F02.data-sources\u002Ffirehol",{"title":597,"path":598,"stem":599},"Proxy Detection","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fproxy","docs\u002Fshield-base\u002F02.data-sources\u002Fproxy",{"title":601,"path":602,"stem":603},"Tor Nodes","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ftor","docs\u002Fshield-base\u002F02.data-sources\u002Ftor",{"title":605,"path":606,"stem":607},"Suspicious User-Agents","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fuseragent","docs\u002Fshield-base\u002F02.data-sources\u002Fuseragent",{"title":609,"path":610,"stem":611},"Programmatic Usage","\u002Fdocs\u002Fshield-base\u002Fusage","docs\u002Fshield-base\u002F03.usage",{"title":613,"path":614,"stem":615},"Custom Data Sources","\u002Fdocs\u002Fshield-base\u002Fcustom-data-sources","docs\u002Fshield-base\u002F04.custom-data-sources",{"title":617,"path":618,"stem":619},"TypeScript Types","\u002Fdocs\u002Fshield-base\u002Ftypes","docs\u002Fshield-base\u002F05.types",{"title":184,"path":621,"stem":622},"\u002Fdocs\u002Fshield-base\u002Fapi","docs\u002Fshield-base\u002F06.api",{"title":335,"path":48,"stem":624,"children":625},"docs\u002Futils\u002Findex",[626,627,644,677,774],{"title":335,"path":48,"stem":624},{"title":628,"path":629,"stem":630,"children":631,"page":53},"Eslint","\u002Fdocs\u002Futils\u002Feslint","docs\u002Futils\u002Feslint",[632,636,640],{"title":633,"path":634,"stem":635},"React Config","\u002Fdocs\u002Futils\u002Feslint\u002Freact","docs\u002Futils\u002Feslint\u002Freact",{"title":637,"path":638,"stem":639},"TypeScript Config","\u002Fdocs\u002Futils\u002Feslint\u002Ftypescript","docs\u002Futils\u002Feslint\u002Ftypescript",{"title":641,"path":642,"stem":643},"Vue Config","\u002Fdocs\u002Futils\u002Feslint\u002Fvue","docs\u002Futils\u002Feslint\u002Fvue",{"title":645,"path":646,"stem":647,"children":648,"page":53},"Server","\u002Fdocs\u002Futils\u002Fserver","docs\u002Futils\u002Fserver",[649,653,657,661,665,669,673],{"title":650,"path":651,"stem":652},"Encryption","\u002Fdocs\u002Futils\u002Fserver\u002Fencryption","docs\u002Futils\u002Fserver\u002Fencryption",{"title":654,"path":655,"stem":656},"Path Resolver","\u002Fdocs\u002Futils\u002Fserver\u002Fpathresolver","docs\u002Futils\u002Fserver\u002FpathResolver",{"title":658,"path":659,"stem":660},"File Replacements","\u002Fdocs\u002Futils\u002Fserver\u002Freplace","docs\u002Futils\u002Fserver\u002Freplace",{"title":662,"path":663,"stem":664},"run","\u002Fdocs\u002Futils\u002Fserver\u002Frun","docs\u002Futils\u002Fserver\u002Frun",{"title":666,"path":667,"stem":668},"scheduleTask","\u002Fdocs\u002Futils\u002Fserver\u002Fscheduletask","docs\u002Futils\u002Fserver\u002FscheduleTask",{"title":670,"path":671,"stem":672},"spawnRun","\u002Fdocs\u002Futils\u002Fserver\u002Fspawnrun","docs\u002Futils\u002Fserver\u002FspawnRun",{"title":674,"path":675,"stem":676},"uploadCsv","\u002Fdocs\u002Futils\u002Fserver\u002Fuploadcsv","docs\u002Futils\u002Fserver\u002FuploadCsv",{"title":678,"path":679,"stem":680,"children":681,"page":53},"Shared","\u002Fdocs\u002Futils\u002Fshared","docs\u002Futils\u002Fshared",[682,686,690,694,698,702,706,710,714,718,722,726,730,734,738,742,746,750,754,758,762,766,770],{"title":683,"path":684,"stem":685},"BatchQueue","\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue","docs\u002Futils\u002Fshared\u002FbatchQueue",{"title":687,"path":688,"stem":689},"capitalize","\u002Fdocs\u002Futils\u002Fshared\u002Fcapitalize","docs\u002Futils\u002Fshared\u002Fcapitalize",{"title":691,"path":692,"stem":693},"chunkProcess","\u002Fdocs\u002Futils\u002Fshared\u002Fchunkprocess","docs\u002Futils\u002Fshared\u002FchunkProcess",{"title":695,"path":696,"stem":697},"cleanObject","\u002Fdocs\u002Futils\u002Fshared\u002Fcleanobject","docs\u002Futils\u002Fshared\u002FcleanObject",{"title":699,"path":700,"stem":701},"createConfigManager","\u002Fdocs\u002Futils\u002Fshared\u002Fconfigurationdefiner","docs\u002Futils\u002Fshared\u002FconfigurationDefiner",{"title":703,"path":704,"stem":705},"debounce","\u002Fdocs\u002Futils\u002Fshared\u002Fdebounce","docs\u002Futils\u002Fshared\u002Fdebounce",{"title":707,"path":708,"stem":709},"ensureArray","\u002Fdocs\u002Futils\u002Fshared\u002Fensurearray","docs\u002Futils\u002Fshared\u002FensureArray",{"title":711,"path":712,"stem":713},"fetchWithRetry","\u002Fdocs\u002Futils\u002Fshared\u002Ffetchwithretry","docs\u002Futils\u002Fshared\u002FfetchWithRetry",{"title":715,"path":716,"stem":717},"filterEmptyValues","\u002Fdocs\u002Futils\u002Fshared\u002Ffilteremptyvalues","docs\u002Futils\u002Fshared\u002FfilterEmptyValues",{"title":719,"path":720,"stem":721},"findStringsInObject","\u002Fdocs\u002Futils\u002Fshared\u002Ffindobjectvalues","docs\u002Futils\u002Fshared\u002FfindObjectValues",{"title":723,"path":724,"stem":725},"fisherYatesShuffle","\u002Fdocs\u002Futils\u002Fshared\u002Ffisheryatesshuffle","docs\u002Futils\u002Fshared\u002FfisherYatesShuffle",{"title":727,"path":728,"stem":729},"getRandomImage","\u002Fdocs\u002Futils\u002Fshared\u002Fgetrandomimage","docs\u002Futils\u002Fshared\u002FgetRandomImage",{"title":731,"path":732,"stem":733},"isObjectHasValues","\u002Fdocs\u002Futils\u002Fshared\u002Fisobjecthasvalues","docs\u002Futils\u002Fshared\u002FisObjectHasValues",{"title":735,"path":736,"stem":737},"isAsyncOrPromise","\u002Fdocs\u002Futils\u002Fshared\u002Fispromise","docs\u002Futils\u002Fshared\u002FisPromise",{"title":739,"path":740,"stem":741},"MiniCache","\u002Fdocs\u002Futils\u002Fshared\u002Fminicache","docs\u002Futils\u002Fshared\u002FminiCache",{"title":743,"path":744,"stem":745},"parseCookies","\u002Fdocs\u002Futils\u002Fshared\u002Fparserawcookies","docs\u002Futils\u002Fshared\u002FparseRawCookies",{"title":747,"path":748,"stem":749},"safeAction","\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker","docs\u002Futils\u002Fshared\u002FpromiseLocker",{"title":751,"path":752,"stem":753},"Random","\u002Fdocs\u002Futils\u002Fshared\u002Frandom","docs\u002Futils\u002Fshared\u002Frandom",{"title":755,"path":756,"stem":757},"range","\u002Fdocs\u002Futils\u002Fshared\u002Frange","docs\u002Futils\u002Fshared\u002Frange",{"title":759,"path":760,"stem":761},"rateLimiters","\u002Fdocs\u002Futils\u002Fshared\u002Fratelimiters","docs\u002Futils\u002Fshared\u002FrateLimiters",{"title":763,"path":764,"stem":765},"safeObjectMerge","\u002Fdocs\u002Futils\u002Fshared\u002Fsafemerge","docs\u002Futils\u002Fshared\u002FsafeMerge",{"title":767,"path":768,"stem":769},"textTruncation","\u002Fdocs\u002Futils\u002Fshared\u002Ftexttruncation","docs\u002Futils\u002Fshared\u002FtextTruncation",{"title":771,"path":772,"stem":773},"validateZodSchema","\u002Fdocs\u002Futils\u002Fshared\u002Fvalidatezodschema","docs\u002Futils\u002Fshared\u002FvalidateZodSchema",{"title":775,"path":776,"stem":777,"children":778},"Utility Types","\u002Fdocs\u002Futils\u002Ftypes","docs\u002Futils\u002Ftypes\u002Findex",[779,780,784,788,792,796,800,804,808,812],{"title":775,"path":776,"stem":777},{"title":781,"path":782,"stem":783},"Brand","\u002Fdocs\u002Futils\u002Ftypes\u002Fbrand","docs\u002Futils\u002Ftypes\u002FBrand",{"title":785,"path":786,"stem":787},"DeepPartial","\u002Fdocs\u002Futils\u002Ftypes\u002Fdeeppartial","docs\u002Futils\u002Ftypes\u002FDeepPartial",{"title":789,"path":790,"stem":791},"Merge","\u002Fdocs\u002Futils\u002Ftypes\u002Fmerge","docs\u002Futils\u002Ftypes\u002FMerge",{"title":793,"path":794,"stem":795},"NonNullable","\u002Fdocs\u002Futils\u002Ftypes\u002Fnonnullable","docs\u002Futils\u002Ftypes\u002FNonNullable",{"title":797,"path":798,"stem":799},"Prettify","\u002Fdocs\u002Futils\u002Ftypes\u002Fprettify","docs\u002Futils\u002Ftypes\u002FPrettify",{"title":801,"path":802,"stem":803},"PromiseType","\u002Fdocs\u002Futils\u002Ftypes\u002Fpromisetype","docs\u002Futils\u002Ftypes\u002FPromiseType",{"title":805,"path":806,"stem":807},"RequireKeys","\u002Fdocs\u002Futils\u002Ftypes\u002Frequirekeys","docs\u002Futils\u002Ftypes\u002FRequireKeys",{"title":809,"path":810,"stem":811},"StandardResponse","\u002Fdocs\u002Futils\u002Ftypes\u002Fstandardresponse","docs\u002Futils\u002Ftypes\u002FStandardResponse",{"title":813,"path":814,"stem":815},"ValueOf","\u002Fdocs\u002Futils\u002Ftypes\u002Fvalueof","docs\u002Futils\u002Ftypes\u002FValueOf",{"id":4,"extension":5,"links":817,"meta":828,"stem":62,"__hash__":63},[818,826,827],{"nested":8,"label":9,"icon":10,"to":11,"children":819},[820,821,822,823,824,825],{"label":14,"icon":15,"to":11,"description":16,"github":17,"badge":18},{"label":20,"icon":21,"to":22,"description":23,"github":24,"badge":25},{"label":27,"icon":28,"to":29,"description":30,"github":31,"badge":25},{"label":33,"icon":34,"to":35,"description":36,"github":37,"badge":38},{"label":40,"icon":41,"to":42,"description":43,"github":44,"badge":38},{"label":46,"icon":47,"to":48,"description":49,"github":50,"badge":51},{"nested":53,"label":54,"icon":55,"to":56},{"nested":53,"label":58,"icon":59,"to":60},{},{"id":830,"title":173,"body":831,"description":1434,"extension":1435,"icon":1436,"meta":1437,"module":1438,"navigation":8,"path":174,"rawbody":1439,"seo":1440,"stem":175,"__hash__":1441},"docs\u002Fdocs\u002Fbot-detection\u002F04.checkers\u002F16.geolocation.md",{"type":832,"value":833,"toc":1429},"minimark",[834,838,841,844,849,865,871,873,876,1172,1179,1267,1269,1273,1396,1398,1406,1425],[835,836,837],"p",{},"The geolocation checker evaluates the richness of the client IP's geolocation data and optionally enforces a country blocklist. Legitimate residential and business IPs resolve to complete geolocation records with all geographic fields populated. IPs from proxies, VPNs, and certain datacenter allocations often return records with many null fields.",[835,839,840],{},"This checker runs in the heavy phase. It reads geolocation data already resolved from the MMDB database.",[842,843],"hr",{},[845,846,848],"h2",{"id":847},"how-it-works","How It Works",[835,850,851,855,856,860,861,864],{},[852,853,854],"strong",{},"Country blocklist",": When ",[857,858,859],"code",{},"bannedCountries"," is non-empty, the checker compares the resolved ISO 3166-1 alpha-2 country code against the list. A match applies the full ",[857,862,863],{},"banScore"," to the visitor's total, triggering an immediate ban. This check runs first before any field validation.",[835,866,867,870],{},[852,868,869],{},"Missing geo fields",": The checker validates nine geolocation fields independently. Each missing or null field applies its own penalty. The fields are: country, region, latitude\u002Flongitude, district, city, timezone, subregion, phone code, and continent. A residential IP in a well-covered region typically has all fields populated. An IP behind a VPN or in a poorly covered allocation may be missing several.",[842,872],{},[845,874,188],{"id":875},"configuration",[877,878,884],"pre",{"className":879,"code":880,"filename":881,"language":882,"meta":883,"style":883},"language-ts shiki shiki-themes light-plus light-plus dracula","await defineConfiguration({\n  store: { main: { driver: 'sqlite', name: '.\u002Fbot-detector.db' } },\n  checkers: {\n    enableGeoChecks: {\n      enable: true,\n      bannedCountries: ['KP', 'CU'],  \u002F\u002F ISO 3166-1 alpha-2 codes\n      penalties: {\n        countryUnknown: 10,\n        regionUnknown: 10,\n        latLonUnknown: 10,\n        districtUnknown: 10,\n        cityUnknown: 10,\n        timezoneUnknown: 10,\n        subregionUnknown: 10,\n        phoneUnknown: 10,\n        continentUnknown: 10,\n      },\n    },\n  },\n})\n","server.ts","ts","",[857,885,886,903,958,969,979,994,1028,1038,1052,1064,1076,1088,1100,1112,1124,1136,1148,1154,1160,1166],{"__ignoreMap":883},[887,888,891,895,899],"span",{"class":889,"line":890},"line",1,[887,892,894],{"class":893},"sZ328","await",[887,896,898],{"class":897},"sHOzp"," defineConfiguration",[887,900,902],{"class":901},"sDd4n","({\n",[887,904,906,910,914,917,920,922,924,927,929,933,937,940,943,946,948,950,953,955],{"class":889,"line":905},2,[887,907,909],{"class":908},"sjsA6","  store",[887,911,913],{"class":912},"s34zl",":",[887,915,916],{"class":901}," { ",[887,918,919],{"class":908},"main",[887,921,913],{"class":912},[887,923,916],{"class":901},[887,925,926],{"class":908},"driver",[887,928,913],{"class":912},[887,930,932],{"class":931},"sFkSl"," '",[887,934,936],{"class":935},"sFB1V","sqlite",[887,938,939],{"class":931},"'",[887,941,942],{"class":901},", ",[887,944,945],{"class":908},"name",[887,947,913],{"class":912},[887,949,932],{"class":931},[887,951,952],{"class":935},".\u002Fbot-detector.db",[887,954,939],{"class":931},[887,956,957],{"class":901}," } },\n",[887,959,961,964,966],{"class":889,"line":960},3,[887,962,963],{"class":908},"  checkers",[887,965,913],{"class":912},[887,967,968],{"class":901}," {\n",[887,970,972,975,977],{"class":889,"line":971},4,[887,973,974],{"class":908},"    enableGeoChecks",[887,976,913],{"class":912},[887,978,968],{"class":901},[887,980,982,985,987,991],{"class":889,"line":981},5,[887,983,984],{"class":908},"      enable",[887,986,913],{"class":912},[887,988,990],{"class":989},"sjR7W"," true",[887,992,993],{"class":901},",\n",[887,995,997,1000,1002,1005,1007,1010,1012,1014,1016,1019,1021,1024],{"class":889,"line":996},6,[887,998,999],{"class":908},"      bannedCountries",[887,1001,913],{"class":912},[887,1003,1004],{"class":901}," [",[887,1006,939],{"class":931},[887,1008,1009],{"class":935},"KP",[887,1011,939],{"class":931},[887,1013,942],{"class":901},[887,1015,939],{"class":931},[887,1017,1018],{"class":935},"CU",[887,1020,939],{"class":931},[887,1022,1023],{"class":901},"],  ",[887,1025,1027],{"class":1026},"sghk6","\u002F\u002F ISO 3166-1 alpha-2 codes\n",[887,1029,1031,1034,1036],{"class":889,"line":1030},7,[887,1032,1033],{"class":908},"      penalties",[887,1035,913],{"class":912},[887,1037,968],{"class":901},[887,1039,1041,1044,1046,1050],{"class":889,"line":1040},8,[887,1042,1043],{"class":908},"        countryUnknown",[887,1045,913],{"class":912},[887,1047,1049],{"class":1048},"spgvN"," 10",[887,1051,993],{"class":901},[887,1053,1055,1058,1060,1062],{"class":889,"line":1054},9,[887,1056,1057],{"class":908},"        regionUnknown",[887,1059,913],{"class":912},[887,1061,1049],{"class":1048},[887,1063,993],{"class":901},[887,1065,1067,1070,1072,1074],{"class":889,"line":1066},10,[887,1068,1069],{"class":908},"        latLonUnknown",[887,1071,913],{"class":912},[887,1073,1049],{"class":1048},[887,1075,993],{"class":901},[887,1077,1079,1082,1084,1086],{"class":889,"line":1078},11,[887,1080,1081],{"class":908},"        districtUnknown",[887,1083,913],{"class":912},[887,1085,1049],{"class":1048},[887,1087,993],{"class":901},[887,1089,1091,1094,1096,1098],{"class":889,"line":1090},12,[887,1092,1093],{"class":908},"        cityUnknown",[887,1095,913],{"class":912},[887,1097,1049],{"class":1048},[887,1099,993],{"class":901},[887,1101,1103,1106,1108,1110],{"class":889,"line":1102},13,[887,1104,1105],{"class":908},"        timezoneUnknown",[887,1107,913],{"class":912},[887,1109,1049],{"class":1048},[887,1111,993],{"class":901},[887,1113,1115,1118,1120,1122],{"class":889,"line":1114},14,[887,1116,1117],{"class":908},"        subregionUnknown",[887,1119,913],{"class":912},[887,1121,1049],{"class":1048},[887,1123,993],{"class":901},[887,1125,1127,1130,1132,1134],{"class":889,"line":1126},15,[887,1128,1129],{"class":908},"        phoneUnknown",[887,1131,913],{"class":912},[887,1133,1049],{"class":1048},[887,1135,993],{"class":901},[887,1137,1139,1142,1144,1146],{"class":889,"line":1138},16,[887,1140,1141],{"class":908},"        continentUnknown",[887,1143,913],{"class":912},[887,1145,1049],{"class":1048},[887,1147,993],{"class":901},[887,1149,1151],{"class":889,"line":1150},17,[887,1152,1153],{"class":901},"      },\n",[887,1155,1157],{"class":889,"line":1156},18,[887,1158,1159],{"class":901},"    },\n",[887,1161,1163],{"class":889,"line":1162},19,[887,1164,1165],{"class":901},"  },\n",[887,1167,1169],{"class":889,"line":1168},20,[887,1170,1171],{"class":901},"})\n",[835,1173,1174,1175,1178],{},"All weights live inside the ",[857,1176,1177],{},"penalties: {}"," sub-object.",[1180,1181,1182,1193,1203,1211,1219,1227,1235,1243,1251,1259],"field-group",{},[1183,1184,1186],"field",{"name":859,"type":1185},"string[]",[835,1187,1188,1189,1192],{},"List of ISO 3166-1 alpha-2 country codes to block. Requests from these countries are banned immediately. Default: ",[857,1190,1191],{},"[]",".",[1183,1194,1197],{"name":1195,"type":1196},"countryUnknown","number",[835,1198,1199,1200,1192],{},"Penalty when the country field is missing from the geolocation record. Default: ",[857,1201,1202],{},"10",[1183,1204,1206],{"name":1205,"type":1196},"regionUnknown",[835,1207,1208,1209,1192],{},"Penalty when the region\u002Fstate field is missing. Default: ",[857,1210,1202],{},[1183,1212,1214],{"name":1213,"type":1196},"latLonUnknown",[835,1215,1216,1217,1192],{},"Penalty when the latitude and longitude are missing. Default: ",[857,1218,1202],{},[1183,1220,1222],{"name":1221,"type":1196},"districtUnknown",[835,1223,1224,1225,1192],{},"Penalty when the district field is missing. Default: ",[857,1226,1202],{},[1183,1228,1230],{"name":1229,"type":1196},"cityUnknown",[835,1231,1232,1233,1192],{},"Penalty when the city field is missing. Default: ",[857,1234,1202],{},[1183,1236,1238],{"name":1237,"type":1196},"timezoneUnknown",[835,1239,1240,1241,1192],{},"Penalty when the timezone field is missing. Default: ",[857,1242,1202],{},[1183,1244,1246],{"name":1245,"type":1196},"subregionUnknown",[835,1247,1248,1249,1192],{},"Penalty when the subregion field is missing. Default: ",[857,1250,1202],{},[1183,1252,1254],{"name":1253,"type":1196},"phoneUnknown",[835,1255,1256,1257,1192],{},"Penalty when the phone dialing code is missing. Default: ",[857,1258,1202],{},[1183,1260,1262],{"name":1261,"type":1196},"continentUnknown",[835,1263,1264,1265,1192],{},"Penalty when the continent field is missing. Default: ",[857,1266,1202],{},[842,1268],{},[845,1270,1272],{"id":1271},"reason-codes","Reason Codes",[1274,1275,1276,1289],"table",{},[1277,1278,1279],"thead",{},[1280,1281,1282,1286],"tr",{},[1283,1284,1285],"th",{},"Code",[1283,1287,1288],{},"Trigger",[1290,1291,1292,1306,1316,1326,1336,1346,1356,1366,1376,1386],"tbody",{},[1280,1293,1294,1300],{},[1295,1296,1297],"td",{},[857,1298,1299],{},"BANNED_COUNTRY",[1295,1301,1302,1303,1305],{},"The resolved country is in the ",[857,1304,859],{}," list.",[1280,1307,1308,1313],{},[1295,1309,1310],{},[857,1311,1312],{},"COUNTRY_UNKNOWN",[1295,1314,1315],{},"Country field is missing from the geolocation record.",[1280,1317,1318,1323],{},[1295,1319,1320],{},[857,1321,1322],{},"REGION_UNKNOWN",[1295,1324,1325],{},"Region field is missing.",[1280,1327,1328,1333],{},[1295,1329,1330],{},[857,1331,1332],{},"LAT_LON_UNKNOWN",[1295,1334,1335],{},"Latitude and longitude are missing.",[1280,1337,1338,1343],{},[1295,1339,1340],{},[857,1341,1342],{},"DISTRICT_UNKNOWN",[1295,1344,1345],{},"District field is missing.",[1280,1347,1348,1353],{},[1295,1349,1350],{},[857,1351,1352],{},"CITY_UNKNOWN",[1295,1354,1355],{},"City field is missing.",[1280,1357,1358,1363],{},[1295,1359,1360],{},[857,1361,1362],{},"TIMEZONE_UNKNOWN",[1295,1364,1365],{},"Timezone field is missing.",[1280,1367,1368,1373],{},[1295,1369,1370],{},[857,1371,1372],{},"SUBREGION_UNKNOWN",[1295,1374,1375],{},"Subregion field is missing.",[1280,1377,1378,1383],{},[1295,1379,1380],{},[857,1381,1382],{},"PHONE_UNKNOWN",[1295,1384,1385],{},"Phone dialing code is missing.",[1280,1387,1388,1393],{},[1295,1389,1390],{},[857,1391,1392],{},"CONTINENT_UNKNOWN",[1295,1394,1395],{},"Continent field is missing.",[842,1397],{},[1399,1400,1401],"warning",{},[835,1402,1403,1404,1192],{},"Country blocklisting bans the visitor immediately and applies to all IPs that resolve to the blocked country, including VPNs, Tor exit nodes, and residential users in that country. Confirm your legal and business requirements before adding countries to ",[857,1405,859],{},[1407,1408,1409],"note",{},[835,1410,1411,1412,1414,1415,1418,1419,1421,1422,1192],{},"Each missing geo field adds only ",[857,1413,1202],{}," points by default. The cumulative effect of many missing fields is what provides signal. A completely empty geolocation record (all nine fields null) contributes ",[857,1416,1417],{},"90"," points, close to the default ",[857,1420,863],{}," of ",[857,1423,1424],{},"100",[1426,1427,1428],"style",{},"html pre.shiki code .sZ328, html code.shiki .sZ328{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#FF79C6}html pre.shiki code .sHOzp, html code.shiki .sHOzp{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#50FA7B}html pre.shiki code .sDd4n, html code.shiki .sDd4n{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sjsA6, html code.shiki .sjsA6{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#F8F8F2}html pre.shiki code .s34zl, html code.shiki .s34zl{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#FF79C6}html pre.shiki code .sFkSl, html code.shiki .sFkSl{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#E9F284}html pre.shiki code .sFB1V, html code.shiki .sFB1V{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#F1FA8C}html pre.shiki code .sjR7W, html code.shiki .sjR7W{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#BD93F9}html pre.shiki code .sghk6, html code.shiki .sghk6{--shiki-light:#008000;--shiki-default:#008000;--shiki-dark:#6272A4}html pre.shiki code .spgvN, html code.shiki .spgvN{--shiki-light:#098658;--shiki-default:#098658;--shiki-dark:#BD93F9}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":883,"searchDepth":905,"depth":905,"links":1430},[1431,1432,1433],{"id":847,"depth":905,"text":848},{"id":875,"depth":905,"text":188},{"id":1271,"depth":905,"text":1272},"Blocks requests from banned countries and penalizes IPs with incomplete or missing geolocation data.","md","i-lucide-map-pin",{},null,"---\ntitle: Geolocation\ndescription: Blocks requests from banned countries and penalizes IPs with incomplete or missing geolocation data.\nicon: i-lucide-map-pin\n---\n\nThe geolocation checker evaluates the richness of the client IP's geolocation data and optionally enforces a country blocklist. Legitimate residential and business IPs resolve to complete geolocation records with all geographic fields populated. IPs from proxies, VPNs, and certain datacenter allocations often return records with many null fields.\n\nThis checker runs in the heavy phase. It reads geolocation data already resolved from the MMDB database.\n\n---\n\n## How It Works\n\n**Country blocklist**: When `bannedCountries` is non-empty, the checker compares the resolved ISO 3166-1 alpha-2 country code against the list. A match applies the full `banScore` to the visitor's total, triggering an immediate ban. This check runs first before any field validation.\n\n**Missing geo fields**: The checker validates nine geolocation fields independently. Each missing or null field applies its own penalty. The fields are: country, region, latitude\u002Flongitude, district, city, timezone, subregion, phone code, and continent. A residential IP in a well-covered region typically has all fields populated. An IP behind a VPN or in a poorly covered allocation may be missing several.\n\n---\n\n## Configuration\n\n```ts [server.ts]\nawait defineConfiguration({\n  store: { main: { driver: 'sqlite', name: '.\u002Fbot-detector.db' } },\n  checkers: {\n    enableGeoChecks: {\n      enable: true,\n      bannedCountries: ['KP', 'CU'],  \u002F\u002F ISO 3166-1 alpha-2 codes\n      penalties: {\n        countryUnknown: 10,\n        regionUnknown: 10,\n        latLonUnknown: 10,\n        districtUnknown: 10,\n        cityUnknown: 10,\n        timezoneUnknown: 10,\n        subregionUnknown: 10,\n        phoneUnknown: 10,\n        continentUnknown: 10,\n      },\n    },\n  },\n})\n```\n\nAll weights live inside the `penalties: {}` sub-object.\n\n::field-group\n::field{name=\"bannedCountries\" type=\"string[]\"}\nList of ISO 3166-1 alpha-2 country codes to block. Requests from these countries are banned immediately. Default: `[]`.\n::\n\n::field{name=\"countryUnknown\" type=\"number\"}\nPenalty when the country field is missing from the geolocation record. Default: `10`.\n::\n\n::field{name=\"regionUnknown\" type=\"number\"}\nPenalty when the region\u002Fstate field is missing. Default: `10`.\n::\n\n::field{name=\"latLonUnknown\" type=\"number\"}\nPenalty when the latitude and longitude are missing. Default: `10`.\n::\n\n::field{name=\"districtUnknown\" type=\"number\"}\nPenalty when the district field is missing. Default: `10`.\n::\n\n::field{name=\"cityUnknown\" type=\"number\"}\nPenalty when the city field is missing. Default: `10`.\n::\n\n::field{name=\"timezoneUnknown\" type=\"number\"}\nPenalty when the timezone field is missing. Default: `10`.\n::\n\n::field{name=\"subregionUnknown\" type=\"number\"}\nPenalty when the subregion field is missing. Default: `10`.\n::\n\n::field{name=\"phoneUnknown\" type=\"number\"}\nPenalty when the phone dialing code is missing. Default: `10`.\n::\n\n::field{name=\"continentUnknown\" type=\"number\"}\nPenalty when the continent field is missing. Default: `10`.\n::\n::\n\n---\n\n## Reason Codes\n\n| Code | Trigger |\n| --- | --- |\n| `BANNED_COUNTRY` | The resolved country is in the `bannedCountries` list. |\n| `COUNTRY_UNKNOWN` | Country field is missing from the geolocation record. |\n| `REGION_UNKNOWN` | Region field is missing. |\n| `LAT_LON_UNKNOWN` | Latitude and longitude are missing. |\n| `DISTRICT_UNKNOWN` | District field is missing. |\n| `CITY_UNKNOWN` | City field is missing. |\n| `TIMEZONE_UNKNOWN` | Timezone field is missing. |\n| `SUBREGION_UNKNOWN` | Subregion field is missing. |\n| `PHONE_UNKNOWN` | Phone dialing code is missing. |\n| `CONTINENT_UNKNOWN` | Continent field is missing. |\n\n---\n\n::warning\nCountry blocklisting bans the visitor immediately and applies to all IPs that resolve to the blocked country, including VPNs, Tor exit nodes, and residential users in that country. Confirm your legal and business requirements before adding countries to `bannedCountries`.\n::\n\n::note\nEach missing geo field adds only `10` points by default. The cumulative effect of many missing fields is what provides signal. A completely empty geolocation record (all nine fields null) contributes `90` points, close to the default `banScore` of `100`.\n::\n",{"title":173,"description":1434},"z-MfKjE6g8HkEN7rHpYToQlDkhrYiJEzSTzzAbQM5Uk",[1443,1444],{"title":169,"path":170,"stem":171,"children":-1},{"title":177,"path":178,"stem":179,"children":-1},{"id":830,"title":173,"body":1446,"description":1434,"extension":1435,"icon":1436,"meta":1879,"module":1438,"navigation":8,"path":174,"rawbody":1439,"seo":1880,"stem":175,"__hash__":1441},{"type":832,"value":1447,"toc":1874},[1448,1450,1452,1454,1456,1464,1468,1470,1472,1688,1692,1754,1756,1758,1852,1854,1860,1872],[835,1449,837],{},[835,1451,840],{},[842,1453],{},[845,1455,848],{"id":847},[835,1457,1458,855,1460,860,1462,864],{},[852,1459,854],{},[857,1461,859],{},[857,1463,863],{},[835,1465,1466,870],{},[852,1467,869],{},[842,1469],{},[845,1471,188],{"id":875},[877,1473,1474],{"className":879,"code":880,"filename":881,"language":882,"meta":883,"style":883},[857,1475,1476,1484,1522,1530,1538,1548,1574,1582,1592,1602,1612,1622,1632,1642,1652,1662,1672,1676,1680,1684],{"__ignoreMap":883},[887,1477,1478,1480,1482],{"class":889,"line":890},[887,1479,894],{"class":893},[887,1481,898],{"class":897},[887,1483,902],{"class":901},[887,1485,1486,1488,1490,1492,1494,1496,1498,1500,1502,1504,1506,1508,1510,1512,1514,1516,1518,1520],{"class":889,"line":905},[887,1487,909],{"class":908},[887,1489,913],{"class":912},[887,1491,916],{"class":901},[887,1493,919],{"class":908},[887,1495,913],{"class":912},[887,1497,916],{"class":901},[887,1499,926],{"class":908},[887,1501,913],{"class":912},[887,1503,932],{"class":931},[887,1505,936],{"class":935},[887,1507,939],{"class":931},[887,1509,942],{"class":901},[887,1511,945],{"class":908},[887,1513,913],{"class":912},[887,1515,932],{"class":931},[887,1517,952],{"class":935},[887,1519,939],{"class":931},[887,1521,957],{"class":901},[887,1523,1524,1526,1528],{"class":889,"line":960},[887,1525,963],{"class":908},[887,1527,913],{"class":912},[887,1529,968],{"class":901},[887,1531,1532,1534,1536],{"class":889,"line":971},[887,1533,974],{"class":908},[887,1535,913],{"class":912},[887,1537,968],{"class":901},[887,1539,1540,1542,1544,1546],{"class":889,"line":981},[887,1541,984],{"class":908},[887,1543,913],{"class":912},[887,1545,990],{"class":989},[887,1547,993],{"class":901},[887,1549,1550,1552,1554,1556,1558,1560,1562,1564,1566,1568,1570,1572],{"class":889,"line":996},[887,1551,999],{"class":908},[887,1553,913],{"class":912},[887,1555,1004],{"class":901},[887,1557,939],{"class":931},[887,1559,1009],{"class":935},[887,1561,939],{"class":931},[887,1563,942],{"class":901},[887,1565,939],{"class":931},[887,1567,1018],{"class":935},[887,1569,939],{"class":931},[887,1571,1023],{"class":901},[887,1573,1027],{"class":1026},[887,1575,1576,1578,1580],{"class":889,"line":1030},[887,1577,1033],{"class":908},[887,1579,913],{"class":912},[887,1581,968],{"class":901},[887,1583,1584,1586,1588,1590],{"class":889,"line":1040},[887,1585,1043],{"class":908},[887,1587,913],{"class":912},[887,1589,1049],{"class":1048},[887,1591,993],{"class":901},[887,1593,1594,1596,1598,1600],{"class":889,"line":1054},[887,1595,1057],{"class":908},[887,1597,913],{"class":912},[887,1599,1049],{"class":1048},[887,1601,993],{"class":901},[887,1603,1604,1606,1608,1610],{"class":889,"line":1066},[887,1605,1069],{"class":908},[887,1607,913],{"class":912},[887,1609,1049],{"class":1048},[887,1611,993],{"class":901},[887,1613,1614,1616,1618,1620],{"class":889,"line":1078},[887,1615,1081],{"class":908},[887,1617,913],{"class":912},[887,1619,1049],{"class":1048},[887,1621,993],{"class":901},[887,1623,1624,1626,1628,1630],{"class":889,"line":1090},[887,1625,1093],{"class":908},[887,1627,913],{"class":912},[887,1629,1049],{"class":1048},[887,1631,993],{"class":901},[887,1633,1634,1636,1638,1640],{"class":889,"line":1102},[887,1635,1105],{"class":908},[887,1637,913],{"class":912},[887,1639,1049],{"class":1048},[887,1641,993],{"class":901},[887,1643,1644,1646,1648,1650],{"class":889,"line":1114},[887,1645,1117],{"class":908},[887,1647,913],{"class":912},[887,1649,1049],{"class":1048},[887,1651,993],{"class":901},[887,1653,1654,1656,1658,1660],{"class":889,"line":1126},[887,1655,1129],{"class":908},[887,1657,913],{"class":912},[887,1659,1049],{"class":1048},[887,1661,993],{"class":901},[887,1663,1664,1666,1668,1670],{"class":889,"line":1138},[887,1665,1141],{"class":908},[887,1667,913],{"class":912},[887,1669,1049],{"class":1048},[887,1671,993],{"class":901},[887,1673,1674],{"class":889,"line":1150},[887,1675,1153],{"class":901},[887,1677,1678],{"class":889,"line":1156},[887,1679,1159],{"class":901},[887,1681,1682],{"class":889,"line":1162},[887,1683,1165],{"class":901},[887,1685,1686],{"class":889,"line":1168},[887,1687,1171],{"class":901},[835,1689,1174,1690,1178],{},[857,1691,1177],{},[1180,1693,1694,1700,1706,1712,1718,1724,1730,1736,1742,1748],{},[1183,1695,1696],{"name":859,"type":1185},[835,1697,1188,1698,1192],{},[857,1699,1191],{},[1183,1701,1702],{"name":1195,"type":1196},[835,1703,1199,1704,1192],{},[857,1705,1202],{},[1183,1707,1708],{"name":1205,"type":1196},[835,1709,1208,1710,1192],{},[857,1711,1202],{},[1183,1713,1714],{"name":1213,"type":1196},[835,1715,1216,1716,1192],{},[857,1717,1202],{},[1183,1719,1720],{"name":1221,"type":1196},[835,1721,1224,1722,1192],{},[857,1723,1202],{},[1183,1725,1726],{"name":1229,"type":1196},[835,1727,1232,1728,1192],{},[857,1729,1202],{},[1183,1731,1732],{"name":1237,"type":1196},[835,1733,1240,1734,1192],{},[857,1735,1202],{},[1183,1737,1738],{"name":1245,"type":1196},[835,1739,1248,1740,1192],{},[857,1741,1202],{},[1183,1743,1744],{"name":1253,"type":1196},[835,1745,1256,1746,1192],{},[857,1747,1202],{},[1183,1749,1750],{"name":1261,"type":1196},[835,1751,1264,1752,1192],{},[857,1753,1202],{},[842,1755],{},[845,1757,1272],{"id":1271},[1274,1759,1760,1768],{},[1277,1761,1762],{},[1280,1763,1764,1766],{},[1283,1765,1285],{},[1283,1767,1288],{},[1290,1769,1770,1780,1788,1796,1804,1812,1820,1828,1836,1844],{},[1280,1771,1772,1776],{},[1295,1773,1774],{},[857,1775,1299],{},[1295,1777,1302,1778,1305],{},[857,1779,859],{},[1280,1781,1782,1786],{},[1295,1783,1784],{},[857,1785,1312],{},[1295,1787,1315],{},[1280,1789,1790,1794],{},[1295,1791,1792],{},[857,1793,1322],{},[1295,1795,1325],{},[1280,1797,1798,1802],{},[1295,1799,1800],{},[857,1801,1332],{},[1295,1803,1335],{},[1280,1805,1806,1810],{},[1295,1807,1808],{},[857,1809,1342],{},[1295,1811,1345],{},[1280,1813,1814,1818],{},[1295,1815,1816],{},[857,1817,1352],{},[1295,1819,1355],{},[1280,1821,1822,1826],{},[1295,1823,1824],{},[857,1825,1362],{},[1295,1827,1365],{},[1280,1829,1830,1834],{},[1295,1831,1832],{},[857,1833,1372],{},[1295,1835,1375],{},[1280,1837,1838,1842],{},[1295,1839,1840],{},[857,1841,1382],{},[1295,1843,1385],{},[1280,1845,1846,1850],{},[1295,1847,1848],{},[857,1849,1392],{},[1295,1851,1395],{},[842,1853],{},[1399,1855,1856],{},[835,1857,1403,1858,1192],{},[857,1859,859],{},[1407,1861,1862],{},[835,1863,1411,1864,1414,1866,1418,1868,1421,1870,1192],{},[857,1865,1202],{},[857,1867,1417],{},[857,1869,863],{},[857,1871,1424],{},[1426,1873,1428],{},{"title":883,"searchDepth":905,"depth":905,"links":1875},[1876,1877,1878],{"id":847,"depth":905,"text":848},{"id":875,"depth":905,"text":188},{"id":1271,"depth":905,"text":1272},{},{"title":173,"description":1434},1780436277946]