[{"data":1,"prerenderedAt":6908},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fdocs\u002Fiam":64,"navigation":257,"navLinks_footer":837,"\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares_page":850,"\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares_surround":4198,"\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares":4201},{"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":27,"path":29,"stem":70,"children":71},"docs\u002Fiam\u002Findex",[72,73,76,216,219,236,240],{"title":27,"path":29,"stem":70},{"title":14,"path":74,"stem":75},"\u002Fdocs\u002Fiam\u002Fgetting-started","docs\u002Fiam\u002F00.getting-started",{"title":77,"path":78,"stem":79,"children":80},"Essentials","\u002Fdocs\u002Fiam\u002Fessentials","docs\u002Fiam\u002F01.essentials\u002Findex",[81,82,86,90,94,98,102,106,110,114,118,122,126,130,134,138,142,146,150,154,158,162,166],{"title":77,"path":78,"stem":79},{"title":83,"path":84,"stem":85},"Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens","docs\u002Fiam\u002F01.essentials\u002F00.tokens",{"title":87,"path":88,"stem":89},"Access Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Faccess-tokens","docs\u002Fiam\u002F01.essentials\u002F01.access-tokens",{"title":91,"path":92,"stem":93},"Refresh Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens","docs\u002Fiam\u002F01.essentials\u002F02.refresh-tokens",{"title":95,"path":96,"stem":97},"Anomaly Detection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies","docs\u002Fiam\u002F01.essentials\u002F03.anomalies",{"title":99,"path":100,"stem":101},"Signup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fsignup","docs\u002Fiam\u002F01.essentials\u002F04.signup",{"title":103,"path":104,"stem":105},"Login","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogin","docs\u002Fiam\u002F01.essentials\u002F05.login",{"title":107,"path":108,"stem":109},"Logout","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout","docs\u002Fiam\u002F01.essentials\u002F06.logout",{"title":111,"path":112,"stem":113},"OAuth","\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth","docs\u002Fiam\u002F01.essentials\u002F07.oauth",{"title":115,"path":116,"stem":117},"Magic Links","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmagic-links","docs\u002Fiam\u002F01.essentials\u002F08.magic-links",{"title":119,"path":120,"stem":121},"Emails","\u002Fdocs\u002Fiam\u002Fessentials\u002Femails","docs\u002Fiam\u002F01.essentials\u002F09.emails",{"title":123,"path":124,"stem":125},"MFA","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmfa","docs\u002Fiam\u002F01.essentials\u002F10.mfa",{"title":127,"path":128,"stem":129},"Fingerprinting","\u002Fdocs\u002Fiam\u002Fessentials\u002Ffingerprinting","docs\u002Fiam\u002F01.essentials\u002F11.fingerprinting",{"title":131,"path":132,"stem":133},"Backend for Frontend","\u002Fdocs\u002Fiam\u002Fessentials\u002Fbff","docs\u002Fiam\u002F01.essentials\u002F12.bff",{"title":135,"path":136,"stem":137},"HMAC Authentication","\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac","docs\u002Fiam\u002F01.essentials\u002F13.hmac",{"title":139,"path":140,"stem":141},"XSS Protection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fxss","docs\u002Fiam\u002F01.essentials\u002F14.xss",{"title":143,"path":144,"stem":145},"Logging","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogging","docs\u002Fiam\u002F01.essentials\u002F15.logging",{"title":147,"path":148,"stem":149},"Rate Limiting","\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F16.rate-limiting",{"title":151,"path":152,"stem":153},"Database","\u002Fdocs\u002Fiam\u002Fessentials\u002Fdatabase","docs\u002Fiam\u002F01.essentials\u002F17.database",{"title":155,"path":156,"stem":157},"Cookies","\u002Fdocs\u002Fiam\u002Fessentials\u002Fcookies","docs\u002Fiam\u002F01.essentials\u002F18.cookies",{"title":159,"path":160,"stem":161},"Service Startup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice","docs\u002Fiam\u002F01.essentials\u002F19.service",{"title":163,"path":164,"stem":165},"Password Reset","\u002Fdocs\u002Fiam\u002Fessentials\u002Fpassword-reset","docs\u002Fiam\u002F01.essentials\u002F20.password-reset",{"title":167,"path":168,"stem":169,"children":170},"API Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi","docs\u002Fiam\u002F01.essentials\u002F21.api\u002Findex",[171,172,176,180,210,213],{"title":167,"path":168,"stem":169},{"title":173,"path":174,"stem":175},"Creating Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fcreation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F00.creation",{"title":177,"path":178,"stem":179},"Verifying Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fverification","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F01.verification",{"title":181,"path":182,"stem":183,"children":184},"Manage Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002Findex",[185,186,190,194,198,202,206],{"title":181,"path":182,"stem":183},{"title":187,"path":188,"stem":189},"Privileges","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fprivilege","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F00.privilege",{"title":191,"path":192,"stem":193},"Revocation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frevocation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F01.revocation",{"title":195,"path":196,"stem":197},"Rotation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frotation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F02.rotation",{"title":199,"path":200,"stem":201},"IP Restriction","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fip-updates","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F03.ip-updates",{"title":203,"path":204,"stem":205},"Metadata","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fmetadata","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F04.metadata",{"title":207,"path":208,"stem":209},"Token Listing","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Flist","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F05.list",{"title":147,"path":211,"stem":212},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F03.rate-limiting",{"title":38,"path":214,"stem":215},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fsecurity","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F04.security",{"title":38,"path":217,"stem":218},"\u002Fdocs\u002Fiam\u002Fsecurity","docs\u002Fiam\u002F02.security",{"title":220,"path":221,"stem":222,"children":223,"page":53},"Guides","\u002Fdocs\u002Fiam\u002Fguides","docs\u002Fiam\u002F03.guides",[224,228,232],{"title":225,"path":226,"stem":227},"Deployment","\u002Fdocs\u002Fiam\u002Fguides\u002Fdeployment","docs\u002Fiam\u002F03.guides\u002Fdeployment",{"title":229,"path":230,"stem":231},"Operation Scripts","\u002Fdocs\u002Fiam\u002Fguides\u002Foperation-scripts","docs\u002Fiam\u002F03.guides\u002Foperation-scripts",{"title":233,"path":234,"stem":235},"Role-Based Access Control","\u002Fdocs\u002Fiam\u002Fguides\u002Frbac","docs\u002Fiam\u002F03.guides\u002Frbac",{"title":237,"path":238,"stem":239},"Configuration","\u002Fdocs\u002Fiam\u002Fconfiguration","docs\u002Fiam\u002F04.configuration",{"title":241,"path":242,"stem":243,"children":244,"page":53},"Api","\u002Fdocs\u002Fiam\u002Fapi","docs\u002Fiam\u002F05.API",[245,249,253],{"title":246,"path":247,"stem":248},"API Reference","\u002Fdocs\u002Fiam\u002Fapi\u002Fapi","docs\u002Fiam\u002F05.API\u002F00.api",{"title":250,"path":251,"stem":252},"Middleware Reference","\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares","docs\u002Fiam\u002F05.API\u002F02.middlewares",{"title":254,"path":255,"stem":256},"Routes Reference","\u002Fdocs\u002Fiam\u002Fapi\u002Froutes","docs\u002Fiam\u002F05.API\u002F03.routes",[258],{"title":9,"path":66,"stem":67,"children":259,"page":53},[260,398,516,521,577,644],{"title":20,"path":22,"stem":261,"children":262},"docs\u002Fauth-h3client\u002Findex",[263,264,273,307,331,353,356,376,379],{"title":20,"path":22,"stem":261},{"title":14,"path":265,"stem":266,"children":267},"\u002Fdocs\u002Fauth-h3client\u002Fgetting-started","docs\u002Fauth-h3client\u002F00.getting-started\u002Findex",[268,269],{"title":14,"path":265,"stem":266},{"title":270,"path":271,"stem":272},"Nuxt Module","\u002Fdocs\u002Fauth-h3client\u002Fgetting-started\u002Fnuxt","docs\u002Fauth-h3client\u002F00.getting-started\u002F00.nuxt",{"title":77,"path":274,"stem":275,"children":276},"\u002Fdocs\u002Fauth-h3client\u002Fessentials","docs\u002Fauth-h3client\u002F01.essentials\u002Findex",[277,278,282,286,290,294,298,301,304],{"title":77,"path":274,"stem":275},{"title":279,"path":280,"stem":281},"Session Management","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession","docs\u002Fauth-h3client\u002F01.essentials\u002F00.session",{"title":283,"path":284,"stem":285},"Route Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Froute-protection","docs\u002Fauth-h3client\u002F01.essentials\u002F01.route-protection",{"title":287,"path":288,"stem":289},"CSRF Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcsrf","docs\u002Fauth-h3client\u002F01.essentials\u002F02.csrf",{"title":291,"path":292,"stem":293},"Auth Flows","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fauth-flows","docs\u002Fauth-h3client\u002F01.essentials\u002F03.auth-flows",{"title":295,"path":296,"stem":297},"OAuth and OIDC","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth","docs\u002Fauth-h3client\u002F01.essentials\u002F04.oauth",{"title":33,"path":299,"stem":300},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection","docs\u002Fauth-h3client\u002F01.essentials\u002F05.bot-detection",{"title":155,"path":302,"stem":303},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcookies","docs\u002Fauth-h3client\u002F01.essentials\u002F06.cookies",{"title":143,"path":305,"stem":306},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Flogging","docs\u002Fauth-h3client\u002F01.essentials\u002F07.logging",{"title":123,"path":308,"stem":309,"children":310},"\u002Fdocs\u002Fauth-h3client\u002Fmfa","docs\u002Fauth-h3client\u002F02.mfa\u002Findex",[311,312,316,319,323,327],{"title":123,"path":308,"stem":309},{"title":313,"path":314,"stem":315},"Built-in MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fbuilt-in-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F01.built-in-flow",{"title":163,"path":317,"stem":318},"\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fpassword-reset","docs\u002Fauth-h3client\u002F02.mfa\u002F02.password-reset",{"title":320,"path":321,"stem":322},"Email Change","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Femail-change","docs\u002Fauth-h3client\u002F02.mfa\u002F03.email-change",{"title":324,"path":325,"stem":326},"Custom MFA Flow","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F04.custom-flow",{"title":328,"path":329,"stem":330},"Client-Side MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fclient-side","docs\u002Fauth-h3client\u002F02.mfa\u002F05.client-side",{"title":332,"path":333,"stem":334,"children":335},"Client-side","\u002Fdocs\u002Fauth-h3client\u002Fclient","docs\u002Fauth-h3client\u002F03.client\u002Findex",[336,337,341,345,349],{"title":332,"path":333,"stem":334},{"title":338,"path":339,"stem":340},"useAuthData","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-auth-data","docs\u002Fauth-h3client\u002F03.client\u002F00.use-auth-data",{"title":342,"path":343,"stem":344},"useMagicLink","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-magic-link","docs\u002Fauth-h3client\u002F03.client\u002F01.use-magic-link",{"title":346,"path":347,"stem":348},"executeRequest","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fexecute-request","docs\u002Fauth-h3client\u002F03.client\u002F02.execute-request",{"title":350,"path":351,"stem":352},"getCsrfToken","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fget-csrf-token","docs\u002Fauth-h3client\u002F03.client\u002F03.get-csrf-token",{"title":38,"path":354,"stem":355},"\u002Fdocs\u002Fauth-h3client\u002Fsecurity","docs\u002Fauth-h3client\u002F04.security",{"title":220,"path":357,"stem":358,"children":359,"page":53},"\u002Fdocs\u002Fauth-h3client\u002Fguides","docs\u002Fauth-h3client\u002F05.guides",[360,364,368,372],{"title":361,"path":362,"stem":363},"H3 and Nitro Setup","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fh3-nitro","docs\u002Fauth-h3client\u002F05.guides\u002F00.h3-nitro",{"title":365,"path":366,"stem":367},"HMAC Inter-service Auth","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fhmac","docs\u002Fauth-h3client\u002F05.guides\u002Fhmac",{"title":369,"path":370,"stem":371},"Image Upload","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fimage-upload","docs\u002Fauth-h3client\u002F05.guides\u002Fimage-upload",{"title":373,"path":374,"stem":375},"mTLS Configuration","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fmtls","docs\u002Fauth-h3client\u002F05.guides\u002Fmtls",{"title":237,"path":377,"stem":378},"\u002Fdocs\u002Fauth-h3client\u002Fconfiguration","docs\u002Fauth-h3client\u002F06.configuration",{"title":246,"path":380,"stem":381,"children":382},"\u002Fdocs\u002Fauth-h3client\u002Fapi","docs\u002Fauth-h3client\u002F07.api\u002Findex",[383,384,387,390,394],{"title":246,"path":380,"stem":381},{"title":254,"path":385,"stem":386},"\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcontrollers","docs\u002Fauth-h3client\u002F07.api\u002F00.controllers",{"title":250,"path":388,"stem":389},"\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fmiddleware","docs\u002Fauth-h3client\u002F07.api\u002F01.middleware",{"title":391,"path":392,"stem":393},"Client-side Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcomposables","docs\u002Fauth-h3client\u002F07.api\u002F02.composables",{"title":395,"path":396,"stem":397},"Utilities","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Futilities","docs\u002Fauth-h3client\u002F07.api\u002F03.utilities",{"title":399,"path":35,"stem":400,"children":401},"Bot Detector","docs\u002Fbot-detection\u002Findex",[402,403,406,410,414,433,507,510,513],{"title":399,"path":35,"stem":400},{"title":14,"path":404,"stem":405},"\u002Fdocs\u002Fbot-detection\u002Fgetting-started","docs\u002Fbot-detection\u002F00.getting-started",{"title":407,"path":408,"stem":409},"CLI","\u002Fdocs\u002Fbot-detection\u002Fcli","docs\u002Fbot-detection\u002F01.cli",{"title":411,"path":412,"stem":413},"Data Sources","\u002Fdocs\u002Fbot-detection\u002Fdata-sources","docs\u002Fbot-detection\u002F02.data-sources",{"title":220,"path":415,"stem":416,"children":417,"page":53},"\u002Fdocs\u002Fbot-detection\u002Fguides","docs\u002Fbot-detection\u002F03.guides",[418,422,426,429],{"title":419,"path":420,"stem":421},"Custom Checkers","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fcustom","docs\u002Fbot-detection\u002F03.guides\u002FCUSTOM",{"title":423,"path":424,"stem":425},"Scheduling Database Generation","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fgenerate","docs\u002Fbot-detection\u002F03.guides\u002FGENERATE",{"title":143,"path":427,"stem":428},"\u002Fdocs\u002Fbot-detection\u002Fguides\u002Flogging","docs\u002Fbot-detection\u002F03.guides\u002FLOGGING",{"title":430,"path":431,"stem":432},"Score Modes and Reputation Healing","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fscore","docs\u002Fbot-detection\u002F03.guides\u002FSCORE",{"title":434,"path":435,"stem":436,"children":437},"Checkers","\u002Fdocs\u002Fbot-detection\u002Fcheckers","docs\u002Fbot-detection\u002F04.checkers\u002Findex",[438,439,443,447,451,455,459,463,467,471,475,479,483,487,491,495,499,503],{"title":434,"path":435,"stem":436},{"title":440,"path":441,"stem":442},"IP Validation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fip-validation","docs\u002Fbot-detection\u002F04.checkers\u002F01.ip-validation",{"title":444,"path":445,"stem":446},"Good \u002F Bad Bot Verification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgood-bots","docs\u002Fbot-detection\u002F04.checkers\u002F02.good-bots",{"title":448,"path":449,"stem":450},"Browser & Device Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbrowser-device","docs\u002Fbot-detection\u002F04.checkers\u002F03.browser-device",{"title":452,"path":453,"stem":454},"Locale Map","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Flocale-map","docs\u002Fbot-detection\u002F04.checkers\u002F04.locale-map",{"title":456,"path":457,"stem":458},"Known Threats","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-threats","docs\u002Fbot-detection\u002F04.checkers\u002F05.known-threats",{"title":460,"path":461,"stem":462},"ASN Classification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fasn-classification","docs\u002Fbot-detection\u002F04.checkers\u002F06.asn-classification",{"title":464,"path":465,"stem":466},"Tor Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftor-analysis","docs\u002Fbot-detection\u002F04.checkers\u002F07.tor-analysis",{"title":468,"path":469,"stem":470},"Timezone Consistency","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftimezone-consistency","docs\u002Fbot-detection\u002F04.checkers\u002F08.timezone-consistency",{"title":472,"path":473,"stem":474},"Honeypot","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fhoneypot","docs\u002Fbot-detection\u002F04.checkers\u002F09.honeypot",{"title":476,"path":477,"stem":478},"Known Bad IPs","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ips","docs\u002Fbot-detection\u002F04.checkers\u002F10.known-bad-ips",{"title":480,"path":481,"stem":482},"Behavior Rate","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbehavior-rate","docs\u002Fbot-detection\u002F04.checkers\u002F11.behavior-rate",{"title":484,"path":485,"stem":486},"Proxy \u002F ISP \u002F Cookie","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fproxy-isp-cookies","docs\u002Fbot-detection\u002F04.checkers\u002F12.proxy-isp-cookies",{"title":488,"path":489,"stem":490},"Session Coherence","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fsession-coherence","docs\u002Fbot-detection\u002F04.checkers\u002F13.session-coherence",{"title":492,"path":493,"stem":494},"Velocity Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fvelocity-fingerprint","docs\u002Fbot-detection\u002F04.checkers\u002F14.velocity-fingerprint",{"title":496,"path":497,"stem":498},"UA & Header Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fua-header","docs\u002Fbot-detection\u002F04.checkers\u002F15.ua-header",{"title":500,"path":501,"stem":502},"Geolocation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation","docs\u002Fbot-detection\u002F04.checkers\u002F16.geolocation",{"title":504,"path":505,"stem":506},"Known Bad User-Agents","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ua","docs\u002Fbot-detection\u002F04.checkers\u002F17.known-bad-ua",{"title":38,"path":508,"stem":509},"\u002Fdocs\u002Fbot-detection\u002Fsecurity","docs\u002Fbot-detection\u002F04.security",{"title":246,"path":511,"stem":512},"\u002Fdocs\u002Fbot-detection\u002Fapi","docs\u002Fbot-detection\u002F05.api",{"title":237,"path":514,"stem":515},"\u002Fdocs\u002Fbot-detection\u002Fconfiguration","docs\u002Fbot-detection\u002F06.configuration",{"title":517,"path":11,"stem":518,"children":519},"Introduction","docs\u002Fgetting-started\u002Findex",[520],{"title":517,"path":11,"stem":518},{"title":27,"path":29,"stem":70,"children":522},[523,524,525,565,566,571,572],{"title":27,"path":29,"stem":70},{"title":14,"path":74,"stem":75},{"title":77,"path":78,"stem":79,"children":526},[527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549],{"title":77,"path":78,"stem":79},{"title":83,"path":84,"stem":85},{"title":87,"path":88,"stem":89},{"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},{"title":111,"path":112,"stem":113},{"title":115,"path":116,"stem":117},{"title":119,"path":120,"stem":121},{"title":123,"path":124,"stem":125},{"title":127,"path":128,"stem":129},{"title":131,"path":132,"stem":133},{"title":135,"path":136,"stem":137},{"title":139,"path":140,"stem":141},{"title":143,"path":144,"stem":145},{"title":147,"path":148,"stem":149},{"title":151,"path":152,"stem":153},{"title":155,"path":156,"stem":157},{"title":159,"path":160,"stem":161},{"title":163,"path":164,"stem":165},{"title":167,"path":168,"stem":169,"children":550},[551,552,553,554,563,564],{"title":167,"path":168,"stem":169},{"title":173,"path":174,"stem":175},{"title":177,"path":178,"stem":179},{"title":181,"path":182,"stem":183,"children":555},[556,557,558,559,560,561,562],{"title":181,"path":182,"stem":183},{"title":187,"path":188,"stem":189},{"title":191,"path":192,"stem":193},{"title":195,"path":196,"stem":197},{"title":199,"path":200,"stem":201},{"title":203,"path":204,"stem":205},{"title":207,"path":208,"stem":209},{"title":147,"path":211,"stem":212},{"title":38,"path":214,"stem":215},{"title":38,"path":217,"stem":218},{"title":220,"path":221,"stem":222,"children":567,"page":53},[568,569,570],{"title":225,"path":226,"stem":227},{"title":229,"path":230,"stem":231},{"title":233,"path":234,"stem":235},{"title":237,"path":238,"stem":239},{"title":241,"path":242,"stem":243,"children":573,"page":53},[574,575,576],{"title":246,"path":247,"stem":248},{"title":250,"path":251,"stem":252},{"title":254,"path":255,"stem":256},{"title":40,"path":42,"stem":578,"children":579},"docs\u002Fshield-base\u002Findex",[580,581,584,588,629,633,637,641],{"title":40,"path":42,"stem":578},{"title":14,"path":582,"stem":583},"\u002Fdocs\u002Fshield-base\u002Fgetting-started","docs\u002Fshield-base\u002F00.getting-started",{"title":585,"path":586,"stem":587},"CLI Reference","\u002Fdocs\u002Fshield-base\u002Fcli","docs\u002Fshield-base\u002F01.cli",{"title":411,"path":589,"stem":590,"children":591},"\u002Fdocs\u002Fshield-base\u002Fdata-sources","docs\u002Fshield-base\u002F02.data-sources\u002Findex",[592,593,597,601,605,609,613,617,621,625],{"title":411,"path":589,"stem":590},{"title":594,"path":595,"stem":596},"BGP \u002F ASN","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fbgp","docs\u002Fshield-base\u002F02.data-sources\u002Fbgp",{"title":598,"path":599,"stem":600},"City Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcity","docs\u002Fshield-base\u002F02.data-sources\u002Fcity",{"title":602,"path":603,"stem":604},"Country Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcountry","docs\u002Fshield-base\u002F02.data-sources\u002Fcountry",{"title":606,"path":607,"stem":608},"Verified Crawlers","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcrawlers","docs\u002Fshield-base\u002F02.data-sources\u002Fcrawlers",{"title":610,"path":611,"stem":612},"Disposable Emails","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Femail","docs\u002Fshield-base\u002F02.data-sources\u002Femail",{"title":614,"path":615,"stem":616},"FireHOL Threat Intelligence","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ffirehol","docs\u002Fshield-base\u002F02.data-sources\u002Ffirehol",{"title":618,"path":619,"stem":620},"Proxy Detection","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fproxy","docs\u002Fshield-base\u002F02.data-sources\u002Fproxy",{"title":622,"path":623,"stem":624},"Tor Nodes","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ftor","docs\u002Fshield-base\u002F02.data-sources\u002Ftor",{"title":626,"path":627,"stem":628},"Suspicious User-Agents","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fuseragent","docs\u002Fshield-base\u002F02.data-sources\u002Fuseragent",{"title":630,"path":631,"stem":632},"Programmatic Usage","\u002Fdocs\u002Fshield-base\u002Fusage","docs\u002Fshield-base\u002F03.usage",{"title":634,"path":635,"stem":636},"Custom Data Sources","\u002Fdocs\u002Fshield-base\u002Fcustom-data-sources","docs\u002Fshield-base\u002F04.custom-data-sources",{"title":638,"path":639,"stem":640},"TypeScript Types","\u002Fdocs\u002Fshield-base\u002Ftypes","docs\u002Fshield-base\u002F05.types",{"title":246,"path":642,"stem":643},"\u002Fdocs\u002Fshield-base\u002Fapi","docs\u002Fshield-base\u002F06.api",{"title":395,"path":48,"stem":645,"children":646},"docs\u002Futils\u002Findex",[647,648,665,698,795],{"title":395,"path":48,"stem":645},{"title":649,"path":650,"stem":651,"children":652,"page":53},"Eslint","\u002Fdocs\u002Futils\u002Feslint","docs\u002Futils\u002Feslint",[653,657,661],{"title":654,"path":655,"stem":656},"React Config","\u002Fdocs\u002Futils\u002Feslint\u002Freact","docs\u002Futils\u002Feslint\u002Freact",{"title":658,"path":659,"stem":660},"TypeScript Config","\u002Fdocs\u002Futils\u002Feslint\u002Ftypescript","docs\u002Futils\u002Feslint\u002Ftypescript",{"title":662,"path":663,"stem":664},"Vue Config","\u002Fdocs\u002Futils\u002Feslint\u002Fvue","docs\u002Futils\u002Feslint\u002Fvue",{"title":666,"path":667,"stem":668,"children":669,"page":53},"Server","\u002Fdocs\u002Futils\u002Fserver","docs\u002Futils\u002Fserver",[670,674,678,682,686,690,694],{"title":671,"path":672,"stem":673},"Encryption","\u002Fdocs\u002Futils\u002Fserver\u002Fencryption","docs\u002Futils\u002Fserver\u002Fencryption",{"title":675,"path":676,"stem":677},"Path Resolver","\u002Fdocs\u002Futils\u002Fserver\u002Fpathresolver","docs\u002Futils\u002Fserver\u002FpathResolver",{"title":679,"path":680,"stem":681},"File Replacements","\u002Fdocs\u002Futils\u002Fserver\u002Freplace","docs\u002Futils\u002Fserver\u002Freplace",{"title":683,"path":684,"stem":685},"run","\u002Fdocs\u002Futils\u002Fserver\u002Frun","docs\u002Futils\u002Fserver\u002Frun",{"title":687,"path":688,"stem":689},"scheduleTask","\u002Fdocs\u002Futils\u002Fserver\u002Fscheduletask","docs\u002Futils\u002Fserver\u002FscheduleTask",{"title":691,"path":692,"stem":693},"spawnRun","\u002Fdocs\u002Futils\u002Fserver\u002Fspawnrun","docs\u002Futils\u002Fserver\u002FspawnRun",{"title":695,"path":696,"stem":697},"uploadCsv","\u002Fdocs\u002Futils\u002Fserver\u002Fuploadcsv","docs\u002Futils\u002Fserver\u002FuploadCsv",{"title":699,"path":700,"stem":701,"children":702,"page":53},"Shared","\u002Fdocs\u002Futils\u002Fshared","docs\u002Futils\u002Fshared",[703,707,711,715,719,723,727,731,735,739,743,747,751,755,759,763,767,771,775,779,783,787,791],{"title":704,"path":705,"stem":706},"BatchQueue","\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue","docs\u002Futils\u002Fshared\u002FbatchQueue",{"title":708,"path":709,"stem":710},"capitalize","\u002Fdocs\u002Futils\u002Fshared\u002Fcapitalize","docs\u002Futils\u002Fshared\u002Fcapitalize",{"title":712,"path":713,"stem":714},"chunkProcess","\u002Fdocs\u002Futils\u002Fshared\u002Fchunkprocess","docs\u002Futils\u002Fshared\u002FchunkProcess",{"title":716,"path":717,"stem":718},"cleanObject","\u002Fdocs\u002Futils\u002Fshared\u002Fcleanobject","docs\u002Futils\u002Fshared\u002FcleanObject",{"title":720,"path":721,"stem":722},"createConfigManager","\u002Fdocs\u002Futils\u002Fshared\u002Fconfigurationdefiner","docs\u002Futils\u002Fshared\u002FconfigurationDefiner",{"title":724,"path":725,"stem":726},"debounce","\u002Fdocs\u002Futils\u002Fshared\u002Fdebounce","docs\u002Futils\u002Fshared\u002Fdebounce",{"title":728,"path":729,"stem":730},"ensureArray","\u002Fdocs\u002Futils\u002Fshared\u002Fensurearray","docs\u002Futils\u002Fshared\u002FensureArray",{"title":732,"path":733,"stem":734},"fetchWithRetry","\u002Fdocs\u002Futils\u002Fshared\u002Ffetchwithretry","docs\u002Futils\u002Fshared\u002FfetchWithRetry",{"title":736,"path":737,"stem":738},"filterEmptyValues","\u002Fdocs\u002Futils\u002Fshared\u002Ffilteremptyvalues","docs\u002Futils\u002Fshared\u002FfilterEmptyValues",{"title":740,"path":741,"stem":742},"findStringsInObject","\u002Fdocs\u002Futils\u002Fshared\u002Ffindobjectvalues","docs\u002Futils\u002Fshared\u002FfindObjectValues",{"title":744,"path":745,"stem":746},"fisherYatesShuffle","\u002Fdocs\u002Futils\u002Fshared\u002Ffisheryatesshuffle","docs\u002Futils\u002Fshared\u002FfisherYatesShuffle",{"title":748,"path":749,"stem":750},"getRandomImage","\u002Fdocs\u002Futils\u002Fshared\u002Fgetrandomimage","docs\u002Futils\u002Fshared\u002FgetRandomImage",{"title":752,"path":753,"stem":754},"isObjectHasValues","\u002Fdocs\u002Futils\u002Fshared\u002Fisobjecthasvalues","docs\u002Futils\u002Fshared\u002FisObjectHasValues",{"title":756,"path":757,"stem":758},"isAsyncOrPromise","\u002Fdocs\u002Futils\u002Fshared\u002Fispromise","docs\u002Futils\u002Fshared\u002FisPromise",{"title":760,"path":761,"stem":762},"MiniCache","\u002Fdocs\u002Futils\u002Fshared\u002Fminicache","docs\u002Futils\u002Fshared\u002FminiCache",{"title":764,"path":765,"stem":766},"parseCookies","\u002Fdocs\u002Futils\u002Fshared\u002Fparserawcookies","docs\u002Futils\u002Fshared\u002FparseRawCookies",{"title":768,"path":769,"stem":770},"safeAction","\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker","docs\u002Futils\u002Fshared\u002FpromiseLocker",{"title":772,"path":773,"stem":774},"Random","\u002Fdocs\u002Futils\u002Fshared\u002Frandom","docs\u002Futils\u002Fshared\u002Frandom",{"title":776,"path":777,"stem":778},"range","\u002Fdocs\u002Futils\u002Fshared\u002Frange","docs\u002Futils\u002Fshared\u002Frange",{"title":780,"path":781,"stem":782},"rateLimiters","\u002Fdocs\u002Futils\u002Fshared\u002Fratelimiters","docs\u002Futils\u002Fshared\u002FrateLimiters",{"title":784,"path":785,"stem":786},"safeObjectMerge","\u002Fdocs\u002Futils\u002Fshared\u002Fsafemerge","docs\u002Futils\u002Fshared\u002FsafeMerge",{"title":788,"path":789,"stem":790},"textTruncation","\u002Fdocs\u002Futils\u002Fshared\u002Ftexttruncation","docs\u002Futils\u002Fshared\u002FtextTruncation",{"title":792,"path":793,"stem":794},"validateZodSchema","\u002Fdocs\u002Futils\u002Fshared\u002Fvalidatezodschema","docs\u002Futils\u002Fshared\u002FvalidateZodSchema",{"title":796,"path":797,"stem":798,"children":799},"Utility Types","\u002Fdocs\u002Futils\u002Ftypes","docs\u002Futils\u002Ftypes\u002Findex",[800,801,805,809,813,817,821,825,829,833],{"title":796,"path":797,"stem":798},{"title":802,"path":803,"stem":804},"Brand","\u002Fdocs\u002Futils\u002Ftypes\u002Fbrand","docs\u002Futils\u002Ftypes\u002FBrand",{"title":806,"path":807,"stem":808},"DeepPartial","\u002Fdocs\u002Futils\u002Ftypes\u002Fdeeppartial","docs\u002Futils\u002Ftypes\u002FDeepPartial",{"title":810,"path":811,"stem":812},"Merge","\u002Fdocs\u002Futils\u002Ftypes\u002Fmerge","docs\u002Futils\u002Ftypes\u002FMerge",{"title":814,"path":815,"stem":816},"NonNullable","\u002Fdocs\u002Futils\u002Ftypes\u002Fnonnullable","docs\u002Futils\u002Ftypes\u002FNonNullable",{"title":818,"path":819,"stem":820},"Prettify","\u002Fdocs\u002Futils\u002Ftypes\u002Fprettify","docs\u002Futils\u002Ftypes\u002FPrettify",{"title":822,"path":823,"stem":824},"PromiseType","\u002Fdocs\u002Futils\u002Ftypes\u002Fpromisetype","docs\u002Futils\u002Ftypes\u002FPromiseType",{"title":826,"path":827,"stem":828},"RequireKeys","\u002Fdocs\u002Futils\u002Ftypes\u002Frequirekeys","docs\u002Futils\u002Ftypes\u002FRequireKeys",{"title":830,"path":831,"stem":832},"StandardResponse","\u002Fdocs\u002Futils\u002Ftypes\u002Fstandardresponse","docs\u002Futils\u002Ftypes\u002FStandardResponse",{"title":834,"path":835,"stem":836},"ValueOf","\u002Fdocs\u002Futils\u002Ftypes\u002Fvalueof","docs\u002Futils\u002Ftypes\u002FValueOf",{"id":4,"extension":5,"links":838,"meta":849,"stem":62,"__hash__":63},[839,847,848],{"nested":8,"label":9,"icon":10,"to":11,"children":840},[841,842,843,844,845,846],{"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":851,"title":250,"body":852,"description":4190,"extension":4191,"icon":4192,"meta":4193,"module":4194,"navigation":8,"path":251,"rawbody":4195,"seo":4196,"stem":252,"__hash__":4197},"docs\u002Fdocs\u002Fiam\u002F05.API\u002F02.middlewares.md",{"type":853,"value":854,"toc":4154},"minimark",[855,872,885,900,903,908,914,921,932,938,979,984,1018,1023,1048,1053,1091,1100,1102,1108,1122,1126,1149,1153,1174,1178,1213,1227,1239,1241,1247,1253,1257,1280,1284,1316,1320,1340,1344,1367,1375,1377,1382,1391,1395,1418,1422,1495,1499,1565,1569,1630,1635,1646,1652,1672,1677,1751,1753,1759,1766,1770,1793,1797,1872,1876,1932,1940,1942,1946,1954,1959,1969,1974,2048,2058,2060,2065,2068,2072,2119,2127,2129,2135,2148,2152,2177,2185,2187,2193,2204,2209,2268,2273,2298,2303,2320,2324,2345,2351,2363,2365,2371,2379,2383,2406,2411,2446,2451,2465,2470,2532,2536,2559,2561,2565,2568,2574,2580,2584,2607,2611,2669,2674,2731,2737,2739,2745,2754,2758,2781,2785,2849,2853,2892,2897,2907,2909,2915,2925,2929,2952,2956,3011,3015,3063,3068,3110,3114,3153,3157,3162,3168,3170,3174,3179,3189,3193,3216,3220,3601,3606,3615,3620,3622,3626,3632,3638,3645,3650,3673,3681,3683,3689,3692,3697,3753,3758,3776,3780,3802,3810,3812,3815,3821,3838,3843,3896,3904,3906,3910,3913,3919,3934,3939,3973,3975,3981,3991,3993,3997,4003,4150],[856,857,858,859,863,864,867,868,871],"p",{},"Every middleware exported by ",[860,861,862],"code",{},"@riavzon\u002Fauth"," is documented here. Middleware functions follow the standard Express ",[860,865,866],{},"(req, res, next)"," signature unless noted otherwise. When using ",[860,869,870],{},"bootstrapApp()",", the global middleware stack is already wired in the correct order. You only need to apply route-level middleware when building custom routes.",[873,874,875],"warning",{},[856,876,877,878,881,882,884],{},"All middleware depends on a resolved configuration. Call ",[860,879,880],{},"configuration()"," or ",[860,883,870],{}," before mounting any of these functions.",[856,886,887,888,890,891,896,897,899],{},"For the full middleware stack order applied by ",[860,889,870],{},", see the ",[892,893,895],"a",{"href":894},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice#middleware-stack","Service"," page. For route-level middleware chains per endpoint, see the ",[892,898,254],{"href":255},".",[901,902],"hr",{},[904,905,907],"h2",{"id":906},"authentication-guards","Authentication Guards",[856,909,910,911,899],{},"These middleware functions enforce token presence and validity on protected routes. They don't verify the token contents themselves -- that responsibility belongs to ",[860,912,913],{},"protectRoute",[915,916,918],"h3",{"id":917},"requireaccesstoken",[860,919,920],{},"requireAccessToken",[856,922,923,924,927,928,931],{},"Extracts the Bearer token from the ",[860,925,926],{},"Authorization"," header and attaches it to ",[860,929,930],{},"req.token",". If the header is missing or malformed, the request is rejected immediately.",[856,933,934],{},[935,936,937],"strong",{},"Import",[939,940,945],"pre",{"className":941,"code":942,"language":943,"meta":944,"style":944},"language-ts shiki shiki-themes light-plus light-plus dracula","import { requireAccessToken } from '@riavzon\u002Fauth'\n","ts","",[860,946,947],{"__ignoreMap":944},[948,949,952,956,960,963,966,969,973,976],"span",{"class":950,"line":951},"line",1,[948,953,955],{"class":954},"sZ328","import",[948,957,959],{"class":958},"sDd4n"," { ",[948,961,920],{"class":962},"sjsA6",[948,964,965],{"class":958}," } ",[948,967,968],{"class":954},"from",[948,970,972],{"class":971},"sFkSl"," '",[948,974,862],{"class":975},"sFB1V",[948,977,978],{"class":971},"'\n",[856,980,981],{},[935,982,983],{},"Reads",[985,986,987,1000],"table",{},[988,989,990],"thead",{},[991,992,993,997],"tr",{},[994,995,996],"th",{},"Source",[994,998,999],{},"Value",[1001,1002,1003],"tbody",{},[991,1004,1005,1011],{},[1006,1007,1008,1010],"td",{},[860,1009,926],{}," header",[1006,1012,1013,1014,1017],{},"Must start with ",[860,1015,1016],{},"Bearer "," followed by the token string",[856,1019,1020],{},[935,1021,1022],{},"Sets",[985,1024,1025,1034],{},[988,1026,1027],{},[991,1028,1029,1032],{},[994,1030,1031],{},"Target",[994,1033,999],{},[1001,1035,1036],{},[991,1037,1038,1042],{},[1006,1039,1040],{},[860,1041,930],{},[1006,1043,1044,1045,1047],{},"The raw access token string (header value after ",[860,1046,1016],{},")",[856,1049,1050],{},[935,1051,1052],{},"Responses on failure",[985,1054,1055,1065],{},[988,1056,1057],{},[991,1058,1059,1062],{},[994,1060,1061],{},"Status",[994,1063,1064],{},"Body",[1001,1066,1067,1079],{},[991,1068,1069,1074],{},[1006,1070,1071],{},[860,1072,1073],{},"401",[1006,1075,1076],{},[860,1077,1078],{},"{ ok: false, error: 'Missing Bearer token' }",[991,1080,1081,1085],{},[1006,1082,1083],{},[860,1084,1073],{},[1006,1086,1087,1090],{},[860,1088,1089],{},"{ error: 'Access token missing' }"," (empty token after prefix)",[1092,1093,1094],"tip",{},[856,1095,1096,1097,1099],{},"This middleware only checks that a token is present. It does not verify the signature or decode the payload. Use ",[860,1098,913],{}," downstream for full verification.",[901,1101],{},[915,1103,1105],{"id":1104},"checkforactivemfa",[860,1106,1107],{},"checkForActiveMfa",[856,1109,1110,1111,1114,1115,1118,1119,1121],{},"Checks the anomaly cache for the current refresh token and short-circuits\nrequests that already have an unresolved MFA or re-login requirement. It hashes\n",[860,1112,1113],{},"req.cookies.session",", looks up that key in ",[860,1116,1117],{},"anomaliesCache()",", and returns the\ncached response before the request reaches ",[860,1120,913],{}," or a sensitive\ncontroller.",[856,1123,1124],{},[935,1125,937],{},[939,1127,1129],{"className":941,"code":1128,"language":943,"meta":944,"style":944},"import { checkForActiveMfa } from '@riavzon\u002Fauth'\n",[860,1130,1131],{"__ignoreMap":944},[948,1132,1133,1135,1137,1139,1141,1143,1145,1147],{"class":950,"line":951},[948,1134,955],{"class":954},[948,1136,959],{"class":958},[948,1138,1107],{"class":962},[948,1140,965],{"class":958},[948,1142,968],{"class":954},[948,1144,972],{"class":971},[948,1146,862],{"class":975},[948,1148,978],{"class":971},[856,1150,1151],{},[935,1152,983],{},[985,1154,1155,1163],{},[988,1156,1157],{},[991,1158,1159,1161],{},[994,1160,996],{},[994,1162,999],{},[1001,1164,1165],{},[991,1166,1167,1171],{},[1006,1168,1169],{},[860,1170,1113],{},[1006,1172,1173],{},"The refresh token cookie",[856,1175,1176],{},[935,1177,1052],{},[985,1179,1180,1188],{},[988,1181,1182],{},[991,1183,1184,1186],{},[994,1185,1061],{},[994,1187,1064],{},[1001,1189,1190,1202],{},[991,1191,1192,1197],{},[1006,1193,1194],{},[860,1195,1196],{},"202",[1006,1198,1199],{},[860,1200,1201],{},"{ mfa: true, message: 'A login link has been sent to your email.' }",[991,1203,1204,1208],{},[1006,1205,1206],{},[860,1207,1073],{},[1006,1209,1210],{},[860,1211,1212],{},"{ error: 'Re-login is required', message: cached.anomalyType }",[1214,1215,1216],"note",{},[856,1217,1218,1219,1222,1223,1226],{},"If the ",[860,1220,1221],{},"session"," cookie is missing, or if the cached anomaly is already\nresolved, this middleware calls ",[860,1224,1225],{},"next()"," and leaves the request untouched.",[1092,1228,1229],{},[856,1230,1231,1232,1235,1236,1238],{},"The built-in BFF, API management, custom MFA, and refresh-session routes place\nthis middleware after ",[860,1233,1234],{},"getFingerPrint"," and before ",[860,1237,913],{}," or the\ncontroller.",[901,1240],{},[915,1242,1244],{"id":1243},"requirerefreshtoken",[860,1245,1246],{},"requireRefreshToken",[856,1248,1249,1250,1252],{},"Checks that the ",[860,1251,1221],{}," cookie containing the refresh token is present. Rejects the request if the cookie is missing.",[856,1254,1255],{},[935,1256,937],{},[939,1258,1260],{"className":941,"code":1259,"language":943,"meta":944,"style":944},"import { requireRefreshToken } from '@riavzon\u002Fauth'\n",[860,1261,1262],{"__ignoreMap":944},[948,1263,1264,1266,1268,1270,1272,1274,1276,1278],{"class":950,"line":951},[948,1265,955],{"class":954},[948,1267,959],{"class":958},[948,1269,1246],{"class":962},[948,1271,965],{"class":958},[948,1273,968],{"class":954},[948,1275,972],{"class":971},[948,1277,862],{"class":975},[948,1279,978],{"class":971},[856,1281,1282],{},[935,1283,1052],{},[985,1285,1286,1294],{},[988,1287,1288],{},[991,1289,1290,1292],{},[994,1291,1061],{},[994,1293,1064],{},[1001,1295,1296,1306],{},[991,1297,1298,1302],{},[1006,1299,1300],{},[860,1301,1073],{},[1006,1303,1304],{},[860,1305,1212],{},[991,1307,1308,1312],{},[1006,1309,1310],{},[860,1311,1196],{},[1006,1313,1314],{},[860,1315,1201],{},[856,1317,1318],{},[935,1319,983],{},[985,1321,1322,1330],{},[988,1323,1324],{},[991,1325,1326,1328],{},[994,1327,996],{},[994,1329,999],{},[1001,1331,1332],{},[991,1333,1334,1338],{},[1006,1335,1336],{},[860,1337,1113],{},[1006,1339,1173],{},[856,1341,1342],{},[935,1343,1052],{},[985,1345,1346,1354],{},[988,1347,1348],{},[991,1349,1350,1352],{},[994,1351,1061],{},[994,1353,1064],{},[1001,1355,1356],{},[991,1357,1358,1362],{},[1006,1359,1360],{},[860,1361,1073],{},[1006,1363,1364],{},[860,1365,1366],{},"{ error: 'Refresh token missing' }",[1214,1368,1369],{},[856,1370,1371,1372,1374],{},"This middleware does not consume or verify the refresh token. Downstream handlers like ",[860,1373,913],{}," or the rotation controllers handle the actual verification.",[901,1376],{},[915,1378,1380],{"id":1379},"protectroute",[860,1381,913],{},[856,1383,1384,1385,1388,1389,899],{},"The primary authentication middleware. Verifies the access token signature, decodes the payload, runs the full ",[892,1386,1387],{"href":96},"anomaly detection"," pipeline against the session context, and enriches the request with the authenticated user's identity. If anomalies trigger MFA, the middleware sends the challenge email and responds with ",[860,1390,1196],{},[856,1392,1393],{},[935,1394,937],{},[939,1396,1398],{"className":941,"code":1397,"language":943,"meta":944,"style":944},"import { protectRoute } from '@riavzon\u002Fauth'\n",[860,1399,1400],{"__ignoreMap":944},[948,1401,1402,1404,1406,1408,1410,1412,1414,1416],{"class":950,"line":951},[948,1403,955],{"class":954},[948,1405,959],{"class":958},[948,1407,913],{"class":962},[948,1409,965],{"class":958},[948,1411,968],{"class":954},[948,1413,972],{"class":971},[948,1415,862],{"class":975},[948,1417,978],{"class":971},[856,1419,1420],{},[935,1421,983],{},[985,1423,1424,1432],{},[988,1425,1426],{},[991,1427,1428,1430],{},[994,1429,996],{},[994,1431,999],{},[1001,1433,1434,1445,1453,1463,1473,1485],{},[991,1435,1436,1440],{},[1006,1437,1438],{},[860,1439,930],{},[1006,1441,1442,1443,1047],{},"The raw access token (set by ",[860,1444,920],{},[991,1446,1447,1451],{},[1006,1448,1449],{},[860,1450,1113],{},[1006,1452,1173],{},[991,1454,1455,1460],{},[1006,1456,1457],{},[860,1458,1459],{},"req.cookies.canary_id",[1006,1461,1462],{},"The canary cookie for anomaly detection",[991,1464,1465,1470],{},[1006,1466,1467],{},[860,1468,1469],{},"req.ip",[1006,1471,1472],{},"Client IP address",[991,1474,1475,1480],{},[1006,1476,1477],{},[860,1478,1479],{},"req.fingerPrint",[1006,1481,1482,1483,1047],{},"Device fingerprint (set by ",[860,1484,1234],{},[991,1486,1487,1492],{},[1006,1488,1489,1010],{},[860,1490,1491],{},"User-Agent",[1006,1493,1494],{},"Browser and device identification",[856,1496,1497],{},[935,1498,1022],{},[985,1500,1501,1509],{},[988,1502,1503],{},[991,1504,1505,1507],{},[994,1506,1031],{},[994,1508,999],{},[1001,1510,1511,1521,1531,1545,1555],{},[991,1512,1513,1518],{},[1006,1514,1515],{},[860,1516,1517],{},"req.user.userId",[1006,1519,1520],{},"The authenticated user's numeric ID",[991,1522,1523,1528],{},[1006,1524,1525],{},[860,1526,1527],{},"req.user.visitor_id",[1006,1529,1530],{},"The visitor identifier string",[991,1532,1533,1538],{},[1006,1534,1535],{},[860,1536,1537],{},"req.user.accessTokenId",[1006,1539,1540,1541,1544],{},"The access token's ",[860,1542,1543],{},"jti"," claim (useful for rate limiter keying)",[991,1546,1547,1552],{},[1006,1548,1549],{},[860,1550,1551],{},"req.user.roles",[1006,1553,1554],{},"Array of role strings from the token payload",[991,1556,1557,1562],{},[1006,1558,1559],{},[860,1560,1561],{},"req.user.payload",[1006,1563,1564],{},"The full decoded JWT payload object",[856,1566,1567],{},[935,1568,1052],{},[985,1570,1571,1582],{},[988,1572,1573],{},[991,1574,1575,1577,1579],{},[994,1576,1061],{},[994,1578,1064],{},[994,1580,1581],{},"Meaning",[1001,1583,1584,1596,1617],{},[991,1585,1586,1590,1593],{},[1006,1587,1588],{},[860,1589,1196],{},[1006,1591,1592],{},"MFA challenge email sent",[1006,1594,1595],{},"Anomaly detection triggered adaptive MFA",[991,1597,1598,1602,1610],{},[1006,1599,1600],{},[860,1601,1073],{},[1006,1603,1604,881,1607],{},[860,1605,1606],{},"{ error: '...' }",[860,1608,1609],{},"{ error: '...', reason: '...' }",[1006,1611,1612,1613,1616],{},"Missing token, missing refresh cookies, malformed payload, verification failed, or re-login required (includes ",[860,1614,1615],{},"reason"," field with the anomaly description)",[991,1618,1619,1624,1627],{},[1006,1620,1621],{},[860,1622,1623],{},"500",[1006,1625,1626],{},"Internal error",[1006,1628,1629],{},"MFA dispatch failure or verification flow error",[856,1631,1632],{},[935,1633,1634],{},"Anomaly detection",[856,1636,1637,1638,1641,1642,1645],{},"The middleware calls ",[860,1639,1640],{},"strangeThings()"," internally, which runs nine checks including cookie binding, IP drift, user-agent drift, and geo anomalies. When anomalies are detected but the session is recoverable, the middleware automatically sends an MFA challenge email to the user and responds with ",[860,1643,1644],{},"202 Accepted",". The client must then complete the MFA flow before retrying the original request.",[856,1647,1648,1649,1651],{},"See the full ",[892,1650,95],{"href":96}," pipeline for details on each check.",[873,1653,1654],{},[856,1655,1656,1657,1659,1660,1662,1663,1665,1666,1668,1669,1671],{},"Always place ",[860,1658,920],{}," and ",[860,1661,1246],{}," before ",[860,1664,913],{}," in the middleware chain. The ",[860,1667,913],{}," middleware expects ",[860,1670,930],{}," and the refresh cookies to already be present.",[856,1673,1674],{},[935,1675,1676],{},"Recommended chain",[939,1678,1680],{"className":941,"code":1679,"language":943,"meta":944,"style":944},"router.get('\u002Fprotected',\n  requireAccessToken,\n  requireRefreshToken,\n  getFingerPrint,\n  protectRoute,\n  yourHandler\n)\n",[860,1681,1682,1707,1715,1723,1731,1739,1745],{"__ignoreMap":944},[948,1683,1684,1687,1689,1693,1696,1699,1702,1704],{"class":950,"line":951},[948,1685,1686],{"class":962},"router",[948,1688,899],{"class":958},[948,1690,1692],{"class":1691},"sHOzp","get",[948,1694,1695],{"class":958},"(",[948,1697,1698],{"class":971},"'",[948,1700,1701],{"class":975},"\u002Fprotected",[948,1703,1698],{"class":971},[948,1705,1706],{"class":958},",\n",[948,1708,1710,1713],{"class":950,"line":1709},2,[948,1711,1712],{"class":962},"  requireAccessToken",[948,1714,1706],{"class":958},[948,1716,1718,1721],{"class":950,"line":1717},3,[948,1719,1720],{"class":962},"  requireRefreshToken",[948,1722,1706],{"class":958},[948,1724,1726,1729],{"class":950,"line":1725},4,[948,1727,1728],{"class":962},"  getFingerPrint",[948,1730,1706],{"class":958},[948,1732,1734,1737],{"class":950,"line":1733},5,[948,1735,1736],{"class":962},"  protectRoute",[948,1738,1706],{"class":958},[948,1740,1742],{"class":950,"line":1741},6,[948,1743,1744],{"class":962},"  yourHandler\n",[948,1746,1748],{"class":950,"line":1747},7,[948,1749,1750],{"class":958},")\n",[901,1752],{},[915,1754,1756],{"id":1755},"acceptcookieonly",[860,1757,1758],{},"acceptCookieOnly",[856,1760,1761,1762,1765],{},"A strict input guard for cookie-only endpoints such as token rotation and logout. Rejects any request that carries a body, query string, or ",[860,1763,1764],{},"Content-Type"," header. This prevents injection vectors on endpoints that should only read from cookies.",[856,1767,1768],{},[935,1769,937],{},[939,1771,1773],{"className":941,"code":1772,"language":943,"meta":944,"style":944},"import { acceptCookieOnly } from '@riavzon\u002Fauth'\n",[860,1774,1775],{"__ignoreMap":944},[948,1776,1777,1779,1781,1783,1785,1787,1789,1791],{"class":950,"line":951},[948,1778,955],{"class":954},[948,1780,959],{"class":958},[948,1782,1758],{"class":962},[948,1784,965],{"class":958},[948,1786,968],{"class":954},[948,1788,972],{"class":971},[948,1790,862],{"class":975},[948,1792,978],{"class":971},[856,1794,1795],{},[935,1796,983],{},[985,1798,1799,1807],{},[988,1800,1801],{},[991,1802,1803,1805],{},[994,1804,996],{},[994,1806,999],{},[1001,1808,1809,1818,1828,1842,1855,1863],{},[991,1810,1811,1815],{},[1006,1812,1813],{},[860,1814,1113],{},[1006,1816,1817],{},"Must be present (string)",[991,1819,1820,1825],{},[1006,1821,1822],{},[860,1823,1824],{},"req.body",[1006,1826,1827],{},"Must be empty or absent",[991,1829,1830,1835],{},[1006,1831,1832,1010],{},[860,1833,1834],{},"content-length",[1006,1836,1837,1838,1841],{},"Must be ",[860,1839,1840],{},"0"," or absent",[991,1843,1844,1849],{},[1006,1845,1846,1010],{},[860,1847,1848],{},"transfer-encoding",[1006,1850,1851,1852],{},"Must not contain ",[860,1853,1854],{},"chunked",[991,1856,1857,1860],{},[1006,1858,1859],{},"Query string",[1006,1861,1862],{},"Must be empty",[991,1864,1865,1869],{},[1006,1866,1867,1010],{},[860,1868,1764],{},[1006,1870,1871],{},"Must be absent",[856,1873,1874],{},[935,1875,1052],{},[985,1877,1878,1886],{},[988,1879,1880],{},[991,1881,1882,1884],{},[994,1883,1061],{},[994,1885,1064],{},[1001,1887,1888,1898,1910,1921],{},[991,1889,1890,1894],{},[1006,1891,1892],{},[860,1893,1073],{},[1006,1895,1896],{},[860,1897,1366],{},[991,1899,1900,1905],{},[1006,1901,1902],{},[860,1903,1904],{},"400",[1006,1906,1907],{},[860,1908,1909],{},"{ error: 'Request body not allowed' }",[991,1911,1912,1916],{},[1006,1913,1914],{},[860,1915,1904],{},[1006,1917,1918],{},[860,1919,1920],{},"{ error: 'Query string not allowed' }",[991,1922,1923,1927],{},[1006,1924,1925],{},[860,1926,1904],{},[1006,1928,1929],{},[860,1930,1931],{},"{ error: 'Content-Type not allowed' }",[1092,1933,1934],{},[856,1935,1936,1937,1939],{},"Place this after ",[860,1938,1246],{}," but before the controller. The middleware validates that only cookies are used for authentication data -- no body, no query parameters, no content type.",[901,1941],{},[904,1943,1945],{"id":1944},"security-middleware","Security Middleware",[856,1947,1948,1949,1951,1952,899],{},"These middleware functions are applied globally by ",[860,1950,870],{},". You typically don't need to add them manually unless you're building a custom Express app without ",[860,1953,870],{},[915,1955,1957],{"id":1956},"helmet",[860,1958,1956],{},[856,1960,1961,1962,1968],{},"Applies the ",[892,1963,1967],{"href":1964,"rel":1965},"https:\u002F\u002Fhelmetjs.github.io\u002F",[1966],"nofollow","Helmet"," security headers to every response. Pre-configured with the service's security policy.",[856,1970,1971],{},[935,1972,1973],{},"Headers set",[985,1975,1976,1985],{},[988,1977,1978],{},[991,1979,1980,1983],{},[994,1981,1982],{},"Header",[994,1984,999],{},[1001,1986,1987,1999,2011,2023,2033],{},[991,1988,1989,1994],{},[1006,1990,1991],{},[860,1992,1993],{},"X-Frame-Options",[1006,1995,1996],{},[860,1997,1998],{},"DENY",[991,2000,2001,2006],{},[1006,2002,2003],{},[860,2004,2005],{},"Content-Security-Policy",[1006,2007,2008],{},[860,2009,2010],{},"frame-ancestors 'none'",[991,2012,2013,2018],{},[1006,2014,2015],{},[860,2016,2017],{},"Referrer-Policy",[1006,2019,2020],{},[860,2021,2022],{},"origin",[991,2024,2025,2030],{},[1006,2026,2027],{},[860,2028,2029],{},"Cross-Origin-Embedder-Policy",[1006,2031,2032],{},"Enabled",[991,2034,2035,2038],{},[1006,2036,2037],{},"Standard Helmet defaults",[1006,2039,2040,2043,2044,2047],{},[860,2041,2042],{},"X-Content-Type-Options",", ",[860,2045,2046],{},"X-DNS-Prefetch-Control",", etc.",[1214,2049,2050],{},[856,2051,2052,2053,2055,2056,899],{},"This middleware is not exported from ",[860,2054,862],{},". It is applied automatically by ",[860,2057,870],{},[901,2059],{},[915,2061,2063],{"id":2062},"headers",[860,2064,2062],{},[856,2066,2067],{},"Sets standard no-cache response headers on every response. This prevents browsers and proxies from caching sensitive authentication responses.",[856,2069,2070],{},[935,2071,1973],{},[985,2073,2074,2082],{},[988,2075,2076],{},[991,2077,2078,2080],{},[994,2079,1982],{},[994,2081,999],{},[1001,2083,2084,2096,2108],{},[991,2085,2086,2091],{},[1006,2087,2088],{},[860,2089,2090],{},"Cache-Control",[1006,2092,2093],{},[860,2094,2095],{},"no-cache, private, max-age=0",[991,2097,2098,2103],{},[1006,2099,2100],{},[860,2101,2102],{},"Pragma",[1006,2104,2105],{},[860,2106,2107],{},"no-cache",[991,2109,2110,2115],{},[1006,2111,2112],{},[860,2113,2114],{},"Expires",[1006,2116,2117],{},[860,2118,1840],{},[1214,2120,2121],{},[856,2122,2052,2123,2055,2125,899],{},[860,2124,862],{},[860,2126,870],{},[901,2128],{},[915,2130,2132],{"id":2131},"validateip",[860,2133,2134],{},"validateIp",[856,2136,2137,2138,2140,2141,2144,2145,899],{},"Validates that ",[860,2139,1469],{}," resolves to a valid IP address using Node's ",[860,2142,2143],{},"net.isIP()",". If the IP is missing or invalid, the request is rejected with ",[860,2146,2147],{},"403 Forbidden",[856,2149,2150],{},[935,2151,1052],{},[985,2153,2154,2162],{},[988,2155,2156],{},[991,2157,2158,2160],{},[994,2159,1061],{},[994,2161,1064],{},[1001,2163,2164],{},[991,2165,2166,2171],{},[1006,2167,2168],{},[860,2169,2170],{},"403",[1006,2172,2173,2176],{},[860,2174,2175],{},"Forbidden"," (plain text)",[1214,2178,2179],{},[856,2180,2052,2181,2055,2183,899],{},[860,2182,862],{},[860,2184,870],{},[901,2186],{},[915,2188,2190],{"id":2189},"hmacauth",[860,2191,2192],{},"hmacAuth",[856,2194,2195,2196,2199,2200,2203],{},"Verifies inbound requests using ",[892,2197,2198],{"href":136},"HMAC"," headers and a shared secret. Only active when ",[860,2201,2202],{},"service.Hmac"," is configured. Validates the client identity, timestamp freshness, signature integrity, and request uniqueness (replay protection via nonce cache).",[856,2205,2206],{},[935,2207,2208],{},"Required headers",[985,2210,2211,2220],{},[988,2212,2213],{},[991,2214,2215,2217],{},[994,2216,1982],{},[994,2218,2219],{},"Description",[1001,2221,2222,2235,2245,2258],{},[991,2223,2224,2229],{},[1006,2225,2226],{},[860,2227,2228],{},"X-Client-Id",[1006,2230,2231,2232],{},"The client identifier matching the configured ",[860,2233,2234],{},"clientId",[991,2236,2237,2242],{},[1006,2238,2239],{},[860,2240,2241],{},"X-Timestamp",[1006,2243,2244],{},"Client timestamp in milliseconds",[991,2246,2247,2252],{},[1006,2248,2249],{},[860,2250,2251],{},"X-Signature",[1006,2253,2254,2255],{},"HMAC-SHA256 hex digest of ",[860,2256,2257],{},"clientId:timestamp:method:url:requestId",[991,2259,2260,2265],{},[1006,2261,2262],{},[860,2263,2264],{},"X-Request-ID",[1006,2266,2267],{},"A unique request identifier (nonce)",[856,2269,2270],{},[935,2271,2272],{},"Validation steps",[2274,2275,2276,2280,2286,2289,2292],"ol",{},[2277,2278,2279],"li",{},"Checks that all four headers are present",[2277,2281,2282,2283,2285],{},"Verifies the ",[860,2284,2228],{}," matches the configured value",[2277,2287,2288],{},"Rejects requests with clock skew exceeding the configured threshold (default: 5 minutes)",[2277,2290,2291],{},"Rejects replayed request IDs using an LRU nonce cache",[2277,2293,2294,2295],{},"Recomputes the HMAC-SHA256 signature and compares using ",[860,2296,2297],{},"crypto.timingSafeEqual()",[856,2299,2300],{},[935,2301,2302],{},"Bypass",[2304,2305,2306],"ul",{},[2277,2307,2308,2309,2312,2313,881,2316,2319],{},"Local ",[860,2310,2311],{},"GET \u002Fhealth"," requests (from ",[860,2314,2315],{},"127.0.0.1",[860,2317,2318],{},"::1",") are allowed without HMAC headers",[856,2321,2322],{},[935,2323,1052],{},[985,2325,2326,2334],{},[988,2327,2328],{},[991,2329,2330,2332],{},[994,2331,1061],{},[994,2333,1064],{},[1001,2335,2336],{},[991,2337,2338,2342],{},[1006,2339,2340],{},[860,2341,1073],{},[1006,2343,2344],{},"Reason string (missing headers, unknown client, timestamp skew, replay detected, or signature mismatch)",[856,2346,2347,2348,2350],{},"See the ",[892,2349,135],{"href":136}," page for integration details and client-side signing examples.",[1214,2352,2353],{},[856,2354,2052,2355,2055,2357,2359,2360,2362],{},[860,2356,862],{},[860,2358,870],{}," when ",[860,2361,2202],{}," is configured.",[901,2364],{},[915,2366,2368],{"id":2367},"validatecontenttype",[860,2369,2370],{},"validateContentType",[856,2372,2373,2374,2376,2377,899],{},"A factory function that returns middleware enforcing a specific ",[860,2375,1764],{}," header. If the request's content type does not match the expected value, the request is rejected with ",[860,2378,2147],{},[856,2380,2381],{},[935,2382,937],{},[939,2384,2386],{"className":941,"code":2385,"language":943,"meta":944,"style":944},"import { validateContentType } from '@riavzon\u002Fauth'\n",[860,2387,2388],{"__ignoreMap":944},[948,2389,2390,2392,2394,2396,2398,2400,2402,2404],{"class":950,"line":951},[948,2391,955],{"class":954},[948,2393,959],{"class":958},[948,2395,2370],{"class":962},[948,2397,965],{"class":958},[948,2399,968],{"class":954},[948,2401,972],{"class":971},[948,2403,862],{"class":975},[948,2405,978],{"class":971},[856,2407,2408],{},[935,2409,2410],{},"Signature",[939,2412,2414],{"className":941,"code":2413,"language":943,"meta":944,"style":944},"function validateContentType(expected: string): RequestHandler\n",[860,2415,2416],{"__ignoreMap":944},[948,2417,2418,2422,2425,2427,2431,2435,2439,2441,2443],{"class":950,"line":951},[948,2419,2421],{"class":2420},"sl46w","function",[948,2423,2424],{"class":1691}," validateContentType",[948,2426,1695],{"class":958},[948,2428,2430],{"class":2429},"sygFZ","expected",[948,2432,2434],{"class":2433},"saOXh",":",[948,2436,2438],{"class":2437},"sFs1U"," string",[948,2440,1047],{"class":958},[948,2442,2434],{"class":2433},[948,2444,2445],{"class":2437}," RequestHandler\n",[856,2447,2448],{},[935,2449,2450],{},"Parameters",[2452,2453,2454],"field-group",{},[2455,2456,2459],"field",{":required":2457,"name":2430,"type":2458},"true","string",[856,2460,2461,2462,899],{},"The expected MIME type, for example ",[860,2463,2464],{},"'application\u002Fjson'",[856,2466,2467],{},[935,2468,2469],{},"Usage",[939,2471,2473],{"className":941,"code":2472,"language":943,"meta":944,"style":944},"router.post('\u002Fdata',\n  validateContentType('application\u002Fjson'),\n  express.json(),\n  yourHandler\n)\n",[860,2474,2475,2495,2512,2524,2528],{"__ignoreMap":944},[948,2476,2477,2479,2481,2484,2486,2488,2491,2493],{"class":950,"line":951},[948,2478,1686],{"class":962},[948,2480,899],{"class":958},[948,2482,2483],{"class":1691},"post",[948,2485,1695],{"class":958},[948,2487,1698],{"class":971},[948,2489,2490],{"class":975},"\u002Fdata",[948,2492,1698],{"class":971},[948,2494,1706],{"class":958},[948,2496,2497,2500,2502,2504,2507,2509],{"class":950,"line":1709},[948,2498,2499],{"class":1691},"  validateContentType",[948,2501,1695],{"class":958},[948,2503,1698],{"class":971},[948,2505,2506],{"class":975},"application\u002Fjson",[948,2508,1698],{"class":971},[948,2510,2511],{"class":958},"),\n",[948,2513,2514,2517,2519,2521],{"class":950,"line":1717},[948,2515,2516],{"class":962},"  express",[948,2518,899],{"class":958},[948,2520,5],{"class":1691},[948,2522,2523],{"class":958},"(),\n",[948,2525,2526],{"class":950,"line":1725},[948,2527,1744],{"class":962},[948,2529,2530],{"class":950,"line":1733},[948,2531,1750],{"class":958},[856,2533,2534],{},[935,2535,1052],{},[985,2537,2538,2546],{},[988,2539,2540],{},[991,2541,2542,2544],{},[994,2543,1061],{},[994,2545,1064],{},[1001,2547,2548],{},[991,2549,2550,2554],{},[1006,2551,2552],{},[860,2553,2170],{},[1006,2555,2556],{},[860,2557,2558],{},"{ error: 'not allowed.' }",[901,2560],{},[904,2562,2564],{"id":2563},"verification-middleware","Verification Middleware",[856,2566,2567],{},"These middleware functions handle magic link and MFA verification on specific routes. They are used in the magic link route chains and are also exported for custom route composition.",[915,2569,2571],{"id":2570},"verifymfa",[860,2572,2573],{},"verifyMFA",[856,2575,2576,2577,2579],{},"Verifies a one-time MFA code submitted via email. On success, issues new access and refresh tokens and calls ",[860,2578,1225],{},". On failure, responds with the appropriate error status.",[856,2581,2582],{},[935,2583,937],{},[939,2585,2587],{"className":941,"code":2586,"language":943,"meta":944,"style":944},"import { verifyMFA } from '@riavzon\u002Fauth'\n",[860,2588,2589],{"__ignoreMap":944},[948,2590,2591,2593,2595,2597,2599,2601,2603,2605],{"class":950,"line":951},[948,2592,955],{"class":954},[948,2594,959],{"class":958},[948,2596,2573],{"class":962},[948,2598,965],{"class":958},[948,2600,968],{"class":954},[948,2602,972],{"class":971},[948,2604,862],{"class":975},[948,2606,978],{"class":971},[856,2608,2609],{},[935,2610,983],{},[985,2612,2613,2621],{},[988,2614,2615],{},[991,2616,2617,2619],{},[994,2618,996],{},[994,2620,999],{},[1001,2622,2623,2633,2646,2659],{},[991,2624,2625,2630],{},[1006,2626,2627],{},[860,2628,2629],{},"req.body.code",[1006,2631,2632],{},"The MFA code submitted by the user",[991,2634,2635,2640],{},[1006,2636,2637],{},[860,2638,2639],{},"req.link.purpose",[1006,2641,1837,2642,2645],{},[860,2643,2644],{},"MAGIC_LINK_MFA_CHECKS"," (set by upstream link verification)",[991,2647,2648,2653],{},[1006,2649,2650],{},[860,2651,2652],{},"req.link.subject",[1006,2654,2655,2656],{},"Must match ",[860,2657,2658],{},"MAGIC_LINK_MFA_CHECKS_{visitor}",[991,2660,2661,2666],{},[1006,2662,2663],{},[860,2664,2665],{},"req.link.visitor",[1006,2667,2668],{},"The visitor ID from the verified magic link",[856,2670,2671],{},[935,2672,2673],{},"Responses",[985,2675,2676,2684],{},[988,2677,2678],{},[991,2679,2680,2682],{},[994,2681,1061],{},[994,2683,1581],{},[1001,2685,2686,2696,2705,2714,2723],{},[991,2687,2688,2693],{},[1006,2689,2690],{},[860,2691,2692],{},"200",[1006,2694,2695],{},"Code verified, new tokens issued",[991,2697,2698,2702],{},[1006,2699,2700],{},[860,2701,1904],{},[1006,2703,2704],{},"Malformed input or purpose\u002Fsubject mismatch",[991,2706,2707,2711],{},[1006,2708,2709],{},[860,2710,1073],{},[1006,2712,2713],{},"Invalid or expired code",[991,2715,2716,2720],{},[1006,2717,2718],{},[860,2719,2170],{},[1006,2721,2722],{},"User is banned",[991,2724,2725,2729],{},[1006,2726,2727],{},[860,2728,1623],{},[1006,2730,1626],{},[856,2732,2733,2734,2736],{},"See ",[892,2735,123],{"href":124}," for the full adaptive MFA flow.",[901,2738],{},[915,2740,2742],{"id":2741},"verifynewpassword",[860,2743,2744],{},"verifyNewPassword",[856,2746,2747,2748,2753],{},"Handles the password reset completion step after a user clicks the magic link. Validates the new password against the Zod schema, checks for ",[892,2749,2752],{"href":2750,"rel":2751},"https:\u002F\u002Fhaveibeenpwned.com\u002FAPI\u002Fv3#PwnedPasswords",[1966],"data breach exposure",", hashes the password, and updates it in the database.",[856,2755,2756],{},[935,2757,937],{},[939,2759,2761],{"className":941,"code":2760,"language":943,"meta":944,"style":944},"import { verifyNewPassword } from '@riavzon\u002Fauth'\n",[860,2762,2763],{"__ignoreMap":944},[948,2764,2765,2767,2769,2771,2773,2775,2777,2779],{"class":950,"line":951},[948,2766,955],{"class":954},[948,2768,959],{"class":958},[948,2770,2744],{"class":962},[948,2772,965],{"class":958},[948,2774,968],{"class":954},[948,2776,972],{"class":971},[948,2778,862],{"class":975},[948,2780,978],{"class":971},[856,2782,2783],{},[935,2784,983],{},[985,2786,2787,2795],{},[988,2788,2789],{},[991,2790,2791,2793],{},[994,2792,996],{},[994,2794,999],{},[1001,2796,2797,2807,2817,2828,2839],{},[991,2798,2799,2804],{},[1006,2800,2801],{},[860,2802,2803],{},"req.body.password",[1006,2805,2806],{},"The new password",[991,2808,2809,2814],{},[1006,2810,2811],{},[860,2812,2813],{},"req.body.confirmedPassword",[1006,2815,2816],{},"Password confirmation (must match)",[991,2818,2819,2823],{},[1006,2820,2821],{},[860,2822,2639],{},[1006,2824,1837,2825,2645],{},[860,2826,2827],{},"PASSWORD_RESET",[991,2829,2830,2834],{},[1006,2831,2832],{},[860,2833,2652],{},[1006,2835,2655,2836],{},[860,2837,2838],{},"PASSWORD_RESET_{visitor}",[991,2840,2841,2846],{},[1006,2842,2843],{},[860,2844,2845],{},"req.link.jti",[1006,2847,2848],{},"The link's unique identifier for rate limiting",[856,2850,2851],{},[935,2852,2673],{},[985,2854,2855,2863],{},[988,2856,2857],{},[991,2858,2859,2861],{},[994,2860,1061],{},[994,2862,1581],{},[1001,2864,2865,2874,2883],{},[991,2866,2867,2871],{},[1006,2868,2869],{},[860,2870,2692],{},[1006,2872,2873],{},"Password updated",[991,2875,2876,2880],{},[1006,2877,2878],{},[860,2879,1904],{},[1006,2881,2882],{},"Validation error, password mismatch, or password found in data breaches",[991,2884,2885,2889],{},[1006,2886,2887],{},[860,2888,2170],{},[1006,2890,2891],{},"XSS attempt detected (user banned)",[856,2893,2894],{},[935,2895,2896],{},"Rate limiting",[856,2898,2899,2900,2903,2904,2906],{},"This middleware applies per-IP and per-composite-key (",[860,2901,2902],{},"ip_visitor",") rate limiting with consecutive failure tracking. See ",[892,2905,147],{"href":148}," for details.",[901,2908],{},[915,2910,2912],{"id":2911},"custommfaflowsverification",[860,2913,2914],{},"customMfaFlowsVerification",[856,2916,2917,2918,2920,2921,2924],{},"Verifies custom MFA magic links used for sensitive actions such as account deletion, payment confirmation, or email changes. Validates the temporary JWT token, checks the random hash using ",[860,2919,2297],{},", enforces single-use semantics, and populates ",[860,2922,2923],{},"req.link"," on success.",[856,2926,2927],{},[935,2928,937],{},[939,2930,2932],{"className":941,"code":2931,"language":943,"meta":944,"style":944},"import { customMfaFlowsVerification } from '@riavzon\u002Fauth'\n",[860,2933,2934],{"__ignoreMap":944},[948,2935,2936,2938,2940,2942,2944,2946,2948,2950],{"class":950,"line":951},[948,2937,955],{"class":954},[948,2939,959],{"class":958},[948,2941,2914],{"class":962},[948,2943,965],{"class":958},[948,2945,968],{"class":954},[948,2947,972],{"class":971},[948,2949,862],{"class":975},[948,2951,978],{"class":971},[856,2953,2954],{},[935,2955,983],{},[985,2957,2958,2966],{},[988,2959,2960],{},[991,2961,2962,2964],{},[994,2963,996],{},[994,2965,999],{},[1001,2967,2968,2978,2988,3001],{},[991,2969,2970,2975],{},[1006,2971,2972],{},[860,2973,2974],{},"req.query.token",[1006,2976,2977],{},"The temporary JWT token from the magic link URL",[991,2979,2980,2985],{},[1006,2981,2982],{},[860,2983,2984],{},"req.query.random",[1006,2986,2987],{},"The random hash for cryptographic verification",[991,2989,2990,2995],{},[1006,2991,2992],{},[860,2993,2994],{},"req.query.reason",[1006,2996,2997,2998,1047],{},"The MFA flow reason (for example, ",[860,2999,3000],{},"PAYMENT_CONFIRM",[991,3002,3003,3008],{},[1006,3004,3005],{},[860,3006,3007],{},"req.query.visitor",[1006,3009,3010],{},"The visitor identifier",[856,3012,3013],{},[935,3014,1022],{},[985,3016,3017,3025],{},[988,3018,3019],{},[991,3020,3021,3023],{},[994,3022,1031],{},[994,3024,999],{},[1001,3026,3027,3036,3045,3054],{},[991,3028,3029,3033],{},[1006,3030,3031],{},[860,3032,2665],{},[1006,3034,3035],{},"The verified visitor ID",[991,3037,3038,3042],{},[1006,3039,3040],{},[860,3041,2652],{},[1006,3043,3044],{},"The link subject string",[991,3046,3047,3051],{},[1006,3048,3049],{},[860,3050,2639],{},[1006,3052,3053],{},"The link purpose\u002Freason",[991,3055,3056,3060],{},[1006,3057,3058],{},[860,3059,2845],{},[1006,3061,3062],{},"The link's unique identifier",[856,3064,3065],{},[935,3066,3067],{},"Behavior by HTTP method",[985,3069,3070,3080],{},[988,3071,3072],{},[991,3073,3074,3077],{},[994,3075,3076],{},"Method",[994,3078,3079],{},"Behavior",[1001,3081,3082,3095],{},[991,3083,3084,3089],{},[1006,3085,3086],{},[860,3087,3088],{},"GET",[1006,3090,3091,3092,3094],{},"Preview the link status. Limited to a configurable number of previews. Returns ",[860,3093,2692],{}," with link metadata.",[991,3096,3097,3102],{},[1006,3098,3099],{},[860,3100,3101],{},"POST",[1006,3103,3104,3105,3107,3108,899],{},"Consume the link. Limited to a single use. On success, populates ",[860,3106,2923],{}," and calls ",[860,3109,1225],{},[856,3111,3112],{},[935,3113,1052],{},[985,3115,3116,3124],{},[988,3117,3118],{},[991,3119,3120,3122],{},[994,3121,1061],{},[994,3123,1581],{},[1001,3125,3126,3135,3144],{},[991,3127,3128,3132],{},[1006,3129,3130],{},[860,3131,1904],{},[1006,3133,3134],{},"Invalid, expired, or already-used link; validation errors",[991,3136,3137,3141],{},[1006,3138,3139],{},[860,3140,1073],{},[1006,3142,3143],{},"Payload mismatch or hash verification failure",[991,3145,3146,3150],{},[1006,3147,3148],{},[860,3149,2170],{},[1006,3151,3152],{},"XSS attempt detected",[856,3154,3155],{},[935,3156,2896],{},[856,3158,3159,3160,899],{},"Applies per-IP rate limiting with consecutive failure tracking. See ",[892,3161,147],{"href":148},[856,3163,3164,3165,3167],{},"See also: ",[892,3166,115],{"href":116}," for the full custom MFA flow documentation.",[901,3169],{},[904,3171,3173],{"id":3172},"request-enrichment","Request Enrichment",[915,3175,3177],{"id":3176},"getfingerprint",[860,3178,1234],{},[856,3180,3181,3182,3184,3185,3188],{},"Collects device, browser, geo, and network information from the incoming request and attaches it to ",[860,3183,1479],{},". Uses ",[860,3186,3187],{},"@riavzon\u002Fbot-detector"," for User-Agent parsing and IP geolocation.",[856,3190,3191],{},[935,3192,937],{},[939,3194,3196],{"className":941,"code":3195,"language":943,"meta":944,"style":944},"import { getFingerPrint } from '@riavzon\u002Fauth'\n",[860,3197,3198],{"__ignoreMap":944},[948,3199,3200,3202,3204,3206,3208,3210,3212,3214],{"class":950,"line":951},[948,3201,955],{"class":954},[948,3203,959],{"class":958},[948,3205,1234],{"class":962},[948,3207,965],{"class":958},[948,3209,968],{"class":954},[948,3211,972],{"class":971},[948,3213,862],{"class":975},[948,3215,978],{"class":971},[856,3217,3218],{},[935,3219,1022],{},[985,3221,3222,3233],{},[988,3223,3224],{},[991,3225,3226,3228,3231],{},[994,3227,1031],{},[994,3229,3230],{},"Type",[994,3232,2219],{},[1001,3234,3235,3249,3262,3277,3291,3305,3319,3333,3347,3361,3375,3389,3403,3417,3431,3445,3460,3474,3488,3502,3516,3530,3544,3558,3572,3587],{},[991,3236,3237,3242,3246],{},[1006,3238,3239],{},[860,3240,3241],{},"req.fingerPrint.userAgent",[1006,3243,3244],{},[860,3245,2458],{},[1006,3247,3248],{},"Raw User-Agent header",[991,3250,3251,3256,3260],{},[1006,3252,3253],{},[860,3254,3255],{},"req.fingerPrint.ipAddress",[1006,3257,3258],{},[860,3259,2458],{},[1006,3261,1472],{},[991,3263,3264,3269,3274],{},[1006,3265,3266],{},[860,3267,3268],{},"req.fingerPrint.country",[1006,3270,3271],{},[860,3272,3273],{},"string?",[1006,3275,3276],{},"Country name",[991,3278,3279,3284,3288],{},[1006,3280,3281],{},[860,3282,3283],{},"req.fingerPrint.countryCode",[1006,3285,3286],{},[860,3287,3273],{},[1006,3289,3290],{},"ISO country code",[991,3292,3293,3298,3302],{},[1006,3294,3295],{},[860,3296,3297],{},"req.fingerPrint.region",[1006,3299,3300],{},[860,3301,3273],{},[1006,3303,3304],{},"Region\u002Fstate code",[991,3306,3307,3312,3316],{},[1006,3308,3309],{},[860,3310,3311],{},"req.fingerPrint.regionName",[1006,3313,3314],{},[860,3315,3273],{},[1006,3317,3318],{},"Region\u002Fstate full name",[991,3320,3321,3326,3330],{},[1006,3322,3323],{},[860,3324,3325],{},"req.fingerPrint.city",[1006,3327,3328],{},[860,3329,3273],{},[1006,3331,3332],{},"City name",[991,3334,3335,3340,3344],{},[1006,3336,3337],{},[860,3338,3339],{},"req.fingerPrint.district",[1006,3341,3342],{},[860,3343,3273],{},[1006,3345,3346],{},"City district or subdivision",[991,3348,3349,3354,3358],{},[1006,3350,3351],{},[860,3352,3353],{},"req.fingerPrint.lat",[1006,3355,3356],{},[860,3357,3273],{},[1006,3359,3360],{},"Latitude",[991,3362,3363,3368,3372],{},[1006,3364,3365],{},[860,3366,3367],{},"req.fingerPrint.lon",[1006,3369,3370],{},[860,3371,3273],{},[1006,3373,3374],{},"Longitude",[991,3376,3377,3382,3386],{},[1006,3378,3379],{},[860,3380,3381],{},"req.fingerPrint.timezone",[1006,3383,3384],{},[860,3385,3273],{},[1006,3387,3388],{},"IANA timezone",[991,3390,3391,3396,3400],{},[1006,3392,3393],{},[860,3394,3395],{},"req.fingerPrint.currency",[1006,3397,3398],{},[860,3399,3273],{},[1006,3401,3402],{},"Local currency code",[991,3404,3405,3410,3414],{},[1006,3406,3407],{},[860,3408,3409],{},"req.fingerPrint.isp",[1006,3411,3412],{},[860,3413,3273],{},[1006,3415,3416],{},"Internet service provider",[991,3418,3419,3424,3428],{},[1006,3420,3421],{},[860,3422,3423],{},"req.fingerPrint.org",[1006,3425,3426],{},[860,3427,3273],{},[1006,3429,3430],{},"Organization name",[991,3432,3433,3438,3442],{},[1006,3434,3435],{},[860,3436,3437],{},"req.fingerPrint.as_org",[1006,3439,3440],{},[860,3441,3273],{},[1006,3443,3444],{},"Autonomous system organization",[991,3446,3447,3452,3457],{},[1006,3448,3449],{},[860,3450,3451],{},"req.fingerPrint.proxy",[1006,3453,3454],{},[860,3455,3456],{},"boolean?",[1006,3458,3459],{},"Whether the IP is a known proxy",[991,3461,3462,3467,3471],{},[1006,3463,3464],{},[860,3465,3466],{},"req.fingerPrint.hosting",[1006,3468,3469],{},[860,3470,3456],{},[1006,3472,3473],{},"Whether the IP belongs to a hosting provider",[991,3475,3476,3481,3485],{},[1006,3477,3478],{},[860,3479,3480],{},"req.fingerPrint.device",[1006,3482,3483],{},[860,3484,2458],{},[1006,3486,3487],{},"Device type",[991,3489,3490,3495,3499],{},[1006,3491,3492],{},[860,3493,3494],{},"req.fingerPrint.deviceVendor",[1006,3496,3497],{},[860,3498,3273],{},[1006,3500,3501],{},"Device manufacturer",[991,3503,3504,3509,3513],{},[1006,3505,3506],{},[860,3507,3508],{},"req.fingerPrint.deviceModel",[1006,3510,3511],{},[860,3512,3273],{},[1006,3514,3515],{},"Device model name",[991,3517,3518,3523,3527],{},[1006,3519,3520],{},[860,3521,3522],{},"req.fingerPrint.browser",[1006,3524,3525],{},[860,3526,3273],{},[1006,3528,3529],{},"Browser name",[991,3531,3532,3537,3541],{},[1006,3533,3534],{},[860,3535,3536],{},"req.fingerPrint.browserType",[1006,3538,3539],{},[860,3540,3273],{},[1006,3542,3543],{},"Browser category",[991,3545,3546,3551,3555],{},[1006,3547,3548],{},[860,3549,3550],{},"req.fingerPrint.browserVersion",[1006,3552,3553],{},[860,3554,3273],{},[1006,3556,3557],{},"Browser version",[991,3559,3560,3565,3569],{},[1006,3561,3562],{},[860,3563,3564],{},"req.fingerPrint.os",[1006,3566,3567],{},[860,3568,3273],{},[1006,3570,3571],{},"Operating system",[991,3573,3574,3579,3584],{},[1006,3575,3576],{},[860,3577,3578],{},"req.fingerPrint.bot",[1006,3580,3581],{},[860,3582,3583],{},"boolean",[1006,3585,3586],{},"Whether the client is a known bot",[991,3588,3589,3594,3598],{},[1006,3590,3591],{},[860,3592,3593],{},"req.fingerPrint.botAI",[1006,3595,3596],{},[860,3597,3583],{},[1006,3599,3600],{},"Whether the client is an AI crawler",[856,3602,3603],{},[935,3604,3605],{},"Error behavior",[856,3607,3608,3609,3611,3612,3614],{},"If fingerprinting fails (for example, malformed User-Agent or geolocation service unavailable), the middleware logs the error and calls ",[860,3610,1225],{}," without setting ",[860,3613,1479],{},". Downstream middleware should handle a potentially undefined fingerprint gracefully.",[856,3616,2733,3617,3619],{},[892,3618,127],{"href":128}," for how fingerprint data is used in anomaly detection.",[901,3621],{},[904,3623,3625],{"id":3624},"error-handling","Error Handling",[856,3627,3628,3629,3631],{},"These middleware functions are registered at the end of the middleware stack by ",[860,3630,870],{},". They catch unmatched routes and unhandled errors.",[915,3633,3635],{"id":3634},"notfoundhandler",[860,3636,3637],{},"notFoundHandler",[856,3639,3640,3641,3644],{},"Returns a standardized JSON ",[860,3642,3643],{},"404"," response for any request that doesn't match a registered route. Registered after all route handlers.",[856,3646,3647],{},[935,3648,3649],{},"Response",[985,3651,3652,3660],{},[988,3653,3654],{},[991,3655,3656,3658],{},[994,3657,1061],{},[994,3659,1064],{},[1001,3661,3662],{},[991,3663,3664,3668],{},[1006,3665,3666],{},[860,3667,3643],{},[1006,3669,3670],{},[860,3671,3672],{},"{ error: \"The page you are looking for doesn't exists\" }",[1214,3674,3675],{},[856,3676,2052,3677,2055,3679,899],{},[860,3678,862],{},[860,3680,870],{},[901,3682],{},[915,3684,3686],{"id":3685},"finalunhandlederrors",[860,3687,3688],{},"finalUnHandledErrors",[856,3690,3691],{},"The last-resort Express error handler. Catches any unhandled error that propagates through the middleware stack, logs it, and returns a normalized JSON error response.",[856,3693,3694],{},[935,3695,3696],{},"Error handler signature",[939,3698,3700],{"className":941,"code":3699,"language":943,"meta":944,"style":944},"(err: any, req: Request, res: Response, next: NextFunction) => void\n",[860,3701,3702],{"__ignoreMap":944},[948,3703,3704,3706,3709,3711,3714,3716,3719,3721,3724,3726,3729,3731,3734,3736,3739,3741,3744,3747,3750],{"class":950,"line":951},[948,3705,1695],{"class":958},[948,3707,3708],{"class":2429},"err",[948,3710,2434],{"class":2433},[948,3712,3713],{"class":2437}," any",[948,3715,2043],{"class":958},[948,3717,3718],{"class":2429},"req",[948,3720,2434],{"class":2433},[948,3722,3723],{"class":2437}," Request",[948,3725,2043],{"class":958},[948,3727,3728],{"class":2429},"res",[948,3730,2434],{"class":2433},[948,3732,3733],{"class":2437}," Response",[948,3735,2043],{"class":958},[948,3737,3738],{"class":2429},"next",[948,3740,2434],{"class":2433},[948,3742,3743],{"class":2437}," NextFunction",[948,3745,3746],{"class":958},") ",[948,3748,3749],{"class":2420},"=>",[948,3751,3752],{"class":2420}," void\n",[856,3754,3755],{},[935,3756,3757],{},"Status code logic",[2304,3759,3760,3770],{},[2277,3761,3762,3763,3766,3767],{},"Uses the existing ",[860,3764,3765],{},"res.statusCode"," if it is greater than ",[860,3768,3769],{},"415",[2277,3771,3772,3773,3775],{},"Defaults to ",[860,3774,1623],{}," otherwise",[856,3777,3778],{},[935,3779,3649],{},[985,3781,3782,3790],{},[988,3783,3784],{},[991,3785,3786,3788],{},[994,3787,1061],{},[994,3789,1064],{},[1001,3791,3792],{},[991,3793,3794,3797],{},[1006,3795,3796],{},"Varies",[1006,3798,3799],{},[860,3800,3801],{},"{ error: string }",[1214,3803,3804],{},[856,3805,2052,3806,2055,3808,899],{},[860,3807,862],{},[860,3809,870],{},[901,3811],{},[904,3813,143],{"id":3814},"logging",[915,3816,3818],{"id":3817},"httplogger",[860,3819,3820],{},"httpLogger",[856,3822,3823,3824,3827,3828,3831,3832,3834,3835,3837],{},"A ",[860,3825,3826],{},"pino-http"," middleware that logs every HTTP request and response. Writes structured JSON logs to ",[860,3829,3830],{},"auth-logs\u002Fhttp.log",". Automatically redacts the ",[860,3833,926],{}," header and ",[860,3836,1221],{}," cookie values in log output.",[856,3839,3840],{},[935,3841,3842],{},"Features",[2304,3844,3845,3852,3861,3878,3881],{},[2277,3846,3847,3848,3851],{},"Generates a unique ",[860,3849,3850],{},"X-Request-Id"," header for each request (or uses the existing one)",[2277,3853,3854,3855,1659,3858,3860],{},"Redacts ",[860,3856,3857],{},"req.headers.authorization",[860,3859,1113],{}," in logs",[2277,3862,3863,3864,2043,3867,2043,3870,3873,3874,3877],{},"Skips logging for static asset requests (",[860,3865,3866],{},".css",[860,3868,3869],{},".js",[860,3871,3872],{},".png",", etc.) and ",[860,3875,3876],{},".well-known\u002F"," paths",[2277,3879,3880],{},"Logs IP address, User-Agent, full URL, and cookies as structured context",[2277,3882,3883,3884,3887,3888,3891,3892,3895],{},"Auto-selects log level based on response status: ",[860,3885,3886],{},"info"," for 2xx\u002F3xx, ",[860,3889,3890],{},"warn"," for 4xx, ",[860,3893,3894],{},"error"," for 5xx",[1214,3897,3898],{},[856,3899,2052,3900,2055,3902,899],{},[860,3901,862],{},[860,3903,870],{},[901,3905],{},[904,3907,3909],{"id":3908},"internal-link-verification","Internal Link Verification",[856,3911,3912],{},"The following middleware functions handle magic link verification for built-in flows (MFA and password reset). They are not exported individually but are used internally by the magic link route handlers.",[915,3914,3916],{"id":3915},"linkmfaverification",[860,3917,3918],{},"linkMfaVerification",[856,3920,3921,3922,3924,3925,3927,3928,3930,3931,3933],{},"Verifies MFA magic links. On ",[860,3923,3088],{},", previews the link status and allows a configurable number of views. On ",[860,3926,3101],{},", consumes the link (single-use) and populates ",[860,3929,2923],{}," for the downstream ",[860,3932,2573],{}," handler.",[856,3935,3936],{},[935,3937,3938],{},"Validation pipeline",[2274,3940,3941,3956,3959,3962,3965,3970],{},[2277,3942,3943,3944,2043,3947,2043,3950,2043,3952,3955],{},"Validates query parameters (",[860,3945,3946],{},"token",[860,3948,3949],{},"random",[860,3951,1615],{},[860,3953,3954],{},"visitor",") against a Zod schema",[2277,3957,3958],{},"Applies per-IP rate limiting with consecutive failure tracking",[2277,3960,3961],{},"Verifies the temporary JWT signature and expiry",[2277,3963,3964],{},"Checks visitor identity match between URL and token payload",[2277,3966,3967,3968],{},"Verifies the random hash using ",[860,3969,2297],{},[2277,3971,3972],{},"Enforces configurable GET\u002FPOST usage limits per JTI",[901,3974],{},[915,3976,3978],{"id":3977},"linkpasswordverification",[860,3979,3980],{},"linkPasswordVerification",[856,3982,3983,3984,3986,3987,3990],{},"Verifies password reset magic links. Follows the same validation pipeline as ",[860,3985,3918],{}," but uses separate rate limiter instances and threshold configuration (",[860,3988,3989],{},"magic_links.thresholds.linkPasswordVerification",").",[901,3992],{},[904,3994,3996],{"id":3995},"middleware-stack-order","Middleware Stack Order",[856,3998,3999,4000,4002],{},"When ",[860,4001,870],{}," wires the Express app, middleware is applied in this exact order:",[4004,4005,4007,4013,4016,4023,4030,4035,4038,4043,4046,4051,4054,4060,4065,4071,4078,4084,4087,4093,4096,4103,4109,4113,4134,4139,4142,4147],"steps",{"level":4006},"4",[4008,4009,4011],"h4",{"id":4010},"httplogger-1",[860,4012,3820],{},[856,4014,4015],{},"Structured request\u002Fresponse logging with automatic redaction.",[4008,4017,4019,4020],{"id":4018},"disable-x-powered-by","Disable ",[860,4021,4022],{},"x-powered-by",[856,4024,4025,4026,4029],{},"Removes the default Express ",[860,4027,4028],{},"X-Powered-By"," header.",[4008,4031,4033],{"id":4032},"helmet-1",[860,4034,1956],{},[856,4036,4037],{},"Security headers (CSP, X-Frame-Options, Referrer-Policy, etc.).",[4008,4039,4041],{"id":4040},"headers-1",[860,4042,2062],{},[856,4044,4045],{},"No-cache headers for authentication responses.",[4008,4047,4049],{"id":4048},"validateip-1",[860,4050,2134],{},[856,4052,4053],{},"Rejects requests with invalid or missing IP addresses.",[4008,4055,4057,4059],{"id":4056},"hmacauth-conditional",[860,4058,2192],{}," (conditional)",[856,4061,4062,4063,2362],{},"HMAC signature verification. Only applied when ",[860,4064,2202],{},[4008,4066,4068],{"id":4067},"apiverificationroute",[860,4069,4070],{},"apiVerificationRoute()",[856,4072,4073,4074,4077],{},"Mounts ",[860,4075,4076],{},"GET \u002Fapi\u002Fpublic\u002Fverify"," before JSON parsing, cookie parsing, and the\nbot-detector middleware.",[4008,4079,4081],{"id":4080},"expressjson",[860,4082,4083],{},"express.json()",[856,4085,4086],{},"Global JSON body parser.",[4008,4088,4090],{"id":4089},"cookieparser",[860,4091,4092],{},"cookieParser()",[856,4094,4095],{},"Cookie parsing.",[4008,4097,4099,4102],{"id":4098},"apiresponse-bot-detector",[860,4100,4101],{},"ApiResponse"," (Bot Detector)",[856,4104,4105,4106,899],{},"Mounts the bot detection endpoint at ",[860,4107,4108],{},"\u002Fcheck",[4008,4110,4112],{"id":4111},"route-handlers","Route handlers",[856,4114,4115,4118,4119,4118,4122,4118,4125,4118,4128,4118,4131],{},[860,4116,4117],{},"authenticationRoutes"," -> ",[860,4120,4121],{},"tokenRotationRoutes",[860,4123,4124],{},"magicLinks",[860,4126,4127],{},"bffAccessRoute",[860,4129,4130],{},"apiProtectedRoutes",[860,4132,4133],{},"\u002Foperational\u002Fconfig",[4008,4135,4137],{"id":4136},"notfoundhandler-1",[860,4138,3637],{},[856,4140,4141],{},"Catches unmatched routes.",[4008,4143,4145],{"id":4144},"finalunhandlederrors-1",[860,4146,3688],{},[856,4148,4149],{},"Last-resort error handler.",[4151,4152,4153],"style",{},"html pre.shiki code .sZ328, html code.shiki .sZ328{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#FF79C6}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 .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 .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);}html pre.shiki code .sHOzp, html code.shiki .sHOzp{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#50FA7B}html pre.shiki code .sl46w, html code.shiki .sl46w{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#FF79C6}html pre.shiki code .sygFZ, html code.shiki .sygFZ{--shiki-light:#001080;--shiki-light-font-style:inherit;--shiki-default:#001080;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .saOXh, html code.shiki .saOXh{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#FF79C6}html pre.shiki code .sFs1U, html code.shiki .sFs1U{--shiki-light:#267F99;--shiki-light-font-style:inherit;--shiki-default:#267F99;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}",{"title":944,"searchDepth":1709,"depth":1709,"links":4155},[4156,4163,4170,4175,4178,4182,4185,4189],{"id":906,"depth":1709,"text":907,"children":4157},[4158,4159,4160,4161,4162],{"id":917,"depth":1717,"text":920},{"id":1104,"depth":1717,"text":1107},{"id":1243,"depth":1717,"text":1246},{"id":1379,"depth":1717,"text":913},{"id":1755,"depth":1717,"text":1758},{"id":1944,"depth":1709,"text":1945,"children":4164},[4165,4166,4167,4168,4169],{"id":1956,"depth":1717,"text":1956},{"id":2062,"depth":1717,"text":2062},{"id":2131,"depth":1717,"text":2134},{"id":2189,"depth":1717,"text":2192},{"id":2367,"depth":1717,"text":2370},{"id":2563,"depth":1709,"text":2564,"children":4171},[4172,4173,4174],{"id":2570,"depth":1717,"text":2573},{"id":2741,"depth":1717,"text":2744},{"id":2911,"depth":1717,"text":2914},{"id":3172,"depth":1709,"text":3173,"children":4176},[4177],{"id":3176,"depth":1717,"text":1234},{"id":3624,"depth":1709,"text":3625,"children":4179},[4180,4181],{"id":3634,"depth":1717,"text":3637},{"id":3685,"depth":1717,"text":3688},{"id":3814,"depth":1709,"text":143,"children":4183},[4184],{"id":3817,"depth":1717,"text":3820},{"id":3908,"depth":1709,"text":3909,"children":4186},[4187,4188],{"id":3915,"depth":1717,"text":3918},{"id":3977,"depth":1717,"text":3980},{"id":3995,"depth":1709,"text":3996},"Complete reference for all middleware exported by @riavzon\u002Fauth, covering authentication guards, security layers, verification handlers, and request enrichment.","md","i-lucide-shield",{},null,"---\ntitle: Middleware Reference\ndescription: Complete reference for all middleware exported by @riavzon\u002Fauth, covering authentication guards, security layers, verification handlers, and request enrichment.\nicon: i-lucide-shield\n---\n\nEvery middleware exported by `@riavzon\u002Fauth` is documented here. Middleware functions follow the standard Express `(req, res, next)` signature unless noted otherwise. When using `bootstrapApp()`, the global middleware stack is already wired in the correct order. You only need to apply route-level middleware when building custom routes.\n\n::warning\nAll middleware depends on a resolved configuration. Call `configuration()` or `bootstrapApp()` before mounting any of these functions.\n::\n\nFor the full middleware stack order applied by `bootstrapApp()`, see the [Service](\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice#middleware-stack) page. For route-level middleware chains per endpoint, see the [Routes Reference](\u002Fdocs\u002Fiam\u002Fapi\u002Froutes).\n\n---\n\n## Authentication Guards\n\nThese middleware functions enforce token presence and validity on protected routes. They don't verify the token contents themselves -- that responsibility belongs to `protectRoute`.\n\n### `requireAccessToken`\n\nExtracts the Bearer token from the `Authorization` header and attaches it to `req.token`. If the header is missing or malformed, the request is rejected immediately.\n\n**Import**\n\n```ts\nimport { requireAccessToken } from '@riavzon\u002Fauth'\n```\n\n**Reads**\n\n| Source | Value |\n| --- | --- |\n| `Authorization` header | Must start with `Bearer ` followed by the token string |\n\n**Sets**\n\n| Target | Value |\n| --- | --- |\n| `req.token` | The raw access token string (header value after `Bearer `) |\n\n**Responses on failure**\n\n| Status | Body |\n| --- | --- |\n| `401` | `{ ok: false, error: 'Missing Bearer token' }` |\n| `401` | `{ error: 'Access token missing' }` (empty token after prefix) |\n\n::tip\nThis middleware only checks that a token is present. It does not verify the signature or decode the payload. Use `protectRoute` downstream for full verification.\n::\n\n---\n\n### `checkForActiveMfa`\n\nChecks the anomaly cache for the current refresh token and short-circuits\nrequests that already have an unresolved MFA or re-login requirement. It hashes\n`req.cookies.session`, looks up that key in `anomaliesCache()`, and returns the\ncached response before the request reaches `protectRoute` or a sensitive\ncontroller.\n\n**Import**\n\n```ts\nimport { checkForActiveMfa } from '@riavzon\u002Fauth'\n```\n\n**Reads**\n\n| Source | Value |\n| --- | --- |\n| `req.cookies.session` | The refresh token cookie |\n\n**Responses on failure**\n\n| Status | Body |\n| --- | --- |\n| `202` | `{ mfa: true, message: 'A login link has been sent to your email.' }` |\n| `401` | `{ error: 'Re-login is required', message: cached.anomalyType }` |\n\n::note\nIf the `session` cookie is missing, or if the cached anomaly is already\nresolved, this middleware calls `next()` and leaves the request untouched.\n::\n\n::tip\nThe built-in BFF, API management, custom MFA, and refresh-session routes place\nthis middleware after `getFingerPrint` and before `protectRoute` or the\ncontroller.\n::\n\n---\n\n### `requireRefreshToken`\n\nChecks that the `session` cookie containing the refresh token is present. Rejects the request if the cookie is missing.\n\n**Import**\n\n```ts\nimport { requireRefreshToken } from '@riavzon\u002Fauth'\n```\n**Responses on failure**\n\n| Status | Body |\n| --- | --- |\n| `401` | `{ error: 'Re-login is required', message: cached.anomalyType }` |\n| `202` | `{ mfa: true, message: 'A login link has been sent to your email.' }` |\n\n\n**Reads**\n\n| Source | Value |\n| --- | --- |\n| `req.cookies.session` | The refresh token cookie |\n\n**Responses on failure**\n\n| Status | Body |\n| --- | --- |\n| `401` | `{ error: 'Refresh token missing' }` |\n\n::note\nThis middleware does not consume or verify the refresh token. Downstream handlers like `protectRoute` or the rotation controllers handle the actual verification.\n::\n\n---\n\n### `protectRoute`\n\nThe primary authentication middleware. Verifies the access token signature, decodes the payload, runs the full [anomaly detection](\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies) pipeline against the session context, and enriches the request with the authenticated user's identity. If anomalies trigger MFA, the middleware sends the challenge email and responds with `202`.\n\n**Import**\n\n```ts\nimport { protectRoute } from '@riavzon\u002Fauth'\n```\n\n**Reads**\n\n| Source | Value |\n| --- | --- |\n| `req.token` | The raw access token (set by `requireAccessToken`) |\n| `req.cookies.session` | The refresh token cookie |\n| `req.cookies.canary_id` | The canary cookie for anomaly detection |\n| `req.ip` | Client IP address |\n| `req.fingerPrint` | Device fingerprint (set by `getFingerPrint`) |\n| `User-Agent` header | Browser and device identification |\n\n**Sets**\n\n| Target | Value |\n| --- | --- |\n| `req.user.userId` | The authenticated user's numeric ID |\n| `req.user.visitor_id` | The visitor identifier string |\n| `req.user.accessTokenId` | The access token's `jti` claim (useful for rate limiter keying) |\n| `req.user.roles` | Array of role strings from the token payload |\n| `req.user.payload` | The full decoded JWT payload object |\n\n**Responses on failure**\n\n| Status | Body | Meaning |\n| --- | --- | --- |\n| `202` | MFA challenge email sent | Anomaly detection triggered adaptive MFA |\n| `401` | `{ error: '...' }` or `{ error: '...', reason: '...' }` | Missing token, missing refresh cookies, malformed payload, verification failed, or re-login required (includes `reason` field with the anomaly description) |\n| `500` | Internal error | MFA dispatch failure or verification flow error |\n\n**Anomaly detection**\n\nThe middleware calls `strangeThings()` internally, which runs nine checks including cookie binding, IP drift, user-agent drift, and geo anomalies. When anomalies are detected but the session is recoverable, the middleware automatically sends an MFA challenge email to the user and responds with `202 Accepted`. The client must then complete the MFA flow before retrying the original request.\n\nSee the full [Anomaly Detection](\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies) pipeline for details on each check.\n\n::warning\nAlways place `requireAccessToken` and `requireRefreshToken` before `protectRoute` in the middleware chain. The `protectRoute` middleware expects `req.token` and the refresh cookies to already be present.\n::\n\n**Recommended chain**\n\n```ts\nrouter.get('\u002Fprotected',\n  requireAccessToken,\n  requireRefreshToken,\n  getFingerPrint,\n  protectRoute,\n  yourHandler\n)\n```\n\n---\n\n### `acceptCookieOnly`\n\nA strict input guard for cookie-only endpoints such as token rotation and logout. Rejects any request that carries a body, query string, or `Content-Type` header. This prevents injection vectors on endpoints that should only read from cookies.\n\n**Import**\n\n```ts\nimport { acceptCookieOnly } from '@riavzon\u002Fauth'\n```\n\n**Reads**\n\n| Source | Value |\n| --- | --- |\n| `req.cookies.session` | Must be present (string) |\n| `req.body` | Must be empty or absent |\n| `content-length` header | Must be `0` or absent |\n| `transfer-encoding` header | Must not contain `chunked` |\n| Query string | Must be empty |\n| `Content-Type` header | Must be absent |\n\n**Responses on failure**\n\n| Status | Body |\n| --- | --- |\n| `401` | `{ error: 'Refresh token missing' }` |\n| `400` | `{ error: 'Request body not allowed' }` |\n| `400` | `{ error: 'Query string not allowed' }` |\n| `400` | `{ error: 'Content-Type not allowed' }` |\n\n::tip\nPlace this after `requireRefreshToken` but before the controller. The middleware validates that only cookies are used for authentication data -- no body, no query parameters, no content type.\n::\n\n---\n\n## Security Middleware\n\nThese middleware functions are applied globally by `bootstrapApp()`. You typically don't need to add them manually unless you're building a custom Express app without `bootstrapApp()`.\n\n### `helmet`\n\nApplies the [Helmet](https:\u002F\u002Fhelmetjs.github.io\u002F) security headers to every response. Pre-configured with the service's security policy.\n\n**Headers set**\n\n| Header | Value |\n| --- | --- |\n| `X-Frame-Options` | `DENY` |\n| `Content-Security-Policy` | `frame-ancestors 'none'` |\n| `Referrer-Policy` | `origin` |\n| `Cross-Origin-Embedder-Policy` | Enabled |\n| Standard Helmet defaults | `X-Content-Type-Options`, `X-DNS-Prefetch-Control`, etc. |\n\n::note\nThis middleware is not exported from `@riavzon\u002Fauth`. It is applied automatically by `bootstrapApp()`.\n::\n\n---\n\n### `headers`\n\nSets standard no-cache response headers on every response. This prevents browsers and proxies from caching sensitive authentication responses.\n\n**Headers set**\n\n| Header | Value |\n| --- | --- |\n| `Cache-Control` | `no-cache, private, max-age=0` |\n| `Pragma` | `no-cache` |\n| `Expires` | `0` |\n\n::note\nThis middleware is not exported from `@riavzon\u002Fauth`. It is applied automatically by `bootstrapApp()`.\n::\n\n---\n\n### `validateIp`\n\nValidates that `req.ip` resolves to a valid IP address using Node's `net.isIP()`. If the IP is missing or invalid, the request is rejected with `403 Forbidden`.\n\n**Responses on failure**\n\n| Status | Body |\n| --- | --- |\n| `403` | `Forbidden` (plain text) |\n\n::note\nThis middleware is not exported from `@riavzon\u002Fauth`. It is applied automatically by `bootstrapApp()`.\n::\n\n---\n\n### `hmacAuth`\n\nVerifies inbound requests using [HMAC](\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac) headers and a shared secret. Only active when `service.Hmac` is configured. Validates the client identity, timestamp freshness, signature integrity, and request uniqueness (replay protection via nonce cache).\n\n**Required headers**\n\n| Header | Description |\n| --- | --- |\n| `X-Client-Id` | The client identifier matching the configured `clientId` |\n| `X-Timestamp` | Client timestamp in milliseconds |\n| `X-Signature` | HMAC-SHA256 hex digest of `clientId:timestamp:method:url:requestId` |\n| `X-Request-ID` | A unique request identifier (nonce) |\n\n**Validation steps**\n\n1. Checks that all four headers are present\n2. Verifies the `X-Client-Id` matches the configured value\n3. Rejects requests with clock skew exceeding the configured threshold (default: 5 minutes)\n4. Rejects replayed request IDs using an LRU nonce cache\n5. Recomputes the HMAC-SHA256 signature and compares using `crypto.timingSafeEqual()`\n\n**Bypass**\n\n- Local `GET \u002Fhealth` requests (from `127.0.0.1` or `::1`) are allowed without HMAC headers\n\n**Responses on failure**\n\n| Status | Body |\n| --- | --- |\n| `401` | Reason string (missing headers, unknown client, timestamp skew, replay detected, or signature mismatch) |\n\nSee the [HMAC Authentication](\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac) page for integration details and client-side signing examples.\n\n::note\nThis middleware is not exported from `@riavzon\u002Fauth`. It is applied automatically by `bootstrapApp()` when `service.Hmac` is configured.\n::\n\n---\n\n### `validateContentType`\n\nA factory function that returns middleware enforcing a specific `Content-Type` header. If the request's content type does not match the expected value, the request is rejected with `403 Forbidden`.\n\n**Import**\n\n```ts\nimport { validateContentType } from '@riavzon\u002Fauth'\n```\n\n**Signature**\n\n```ts\nfunction validateContentType(expected: string): RequestHandler\n```\n\n**Parameters**\n\n::field-group\n  ::field{name=\"expected\" type=\"string\" required}\n  The expected MIME type, for example `'application\u002Fjson'`.\n  ::\n::\n\n**Usage**\n\n```ts\nrouter.post('\u002Fdata',\n  validateContentType('application\u002Fjson'),\n  express.json(),\n  yourHandler\n)\n```\n\n**Responses on failure**\n\n| Status | Body |\n| --- | --- |\n| `403` | `{ error: 'not allowed.' }` |\n\n---\n\n## Verification Middleware\n\nThese middleware functions handle magic link and MFA verification on specific routes. They are used in the magic link route chains and are also exported for custom route composition.\n\n### `verifyMFA`\n\nVerifies a one-time MFA code submitted via email. On success, issues new access and refresh tokens and calls `next()`. On failure, responds with the appropriate error status.\n\n**Import**\n\n```ts\nimport { verifyMFA } from '@riavzon\u002Fauth'\n```\n\n**Reads**\n\n| Source | Value |\n| --- | --- |\n| `req.body.code` | The MFA code submitted by the user |\n| `req.link.purpose` | Must be `MAGIC_LINK_MFA_CHECKS` (set by upstream link verification) |\n| `req.link.subject` | Must match `MAGIC_LINK_MFA_CHECKS_{visitor}` |\n| `req.link.visitor` | The visitor ID from the verified magic link |\n\n**Responses**\n\n| Status | Meaning |\n| --- | --- |\n| `200` | Code verified, new tokens issued |\n| `400` | Malformed input or purpose\u002Fsubject mismatch |\n| `401` | Invalid or expired code |\n| `403` | User is banned |\n| `500` | Internal error |\n\nSee [MFA](\u002Fdocs\u002Fiam\u002Fessentials\u002Fmfa) for the full adaptive MFA flow.\n\n---\n\n### `verifyNewPassword`\n\nHandles the password reset completion step after a user clicks the magic link. Validates the new password against the Zod schema, checks for [data breach exposure](https:\u002F\u002Fhaveibeenpwned.com\u002FAPI\u002Fv3#PwnedPasswords), hashes the password, and updates it in the database.\n\n**Import**\n\n```ts\nimport { verifyNewPassword } from '@riavzon\u002Fauth'\n```\n\n**Reads**\n\n| Source | Value |\n| --- | --- |\n| `req.body.password` | The new password |\n| `req.body.confirmedPassword` | Password confirmation (must match) |\n| `req.link.purpose` | Must be `PASSWORD_RESET` (set by upstream link verification) |\n| `req.link.subject` | Must match `PASSWORD_RESET_{visitor}` |\n| `req.link.jti` | The link's unique identifier for rate limiting |\n\n**Responses**\n\n| Status | Meaning |\n| --- | --- |\n| `200` | Password updated |\n| `400` | Validation error, password mismatch, or password found in data breaches |\n| `403` | XSS attempt detected (user banned) |\n\n**Rate limiting**\n\nThis middleware applies per-IP and per-composite-key (`ip_visitor`) rate limiting with consecutive failure tracking. See [Rate Limiting](\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting) for details.\n\n---\n\n### `customMfaFlowsVerification`\n\nVerifies custom MFA magic links used for sensitive actions such as account deletion, payment confirmation, or email changes. Validates the temporary JWT token, checks the random hash using `crypto.timingSafeEqual()`, enforces single-use semantics, and populates `req.link` on success.\n\n**Import**\n\n```ts\nimport { customMfaFlowsVerification } from '@riavzon\u002Fauth'\n```\n\n**Reads**\n\n| Source | Value |\n| --- | --- |\n| `req.query.token` | The temporary JWT token from the magic link URL |\n| `req.query.random` | The random hash for cryptographic verification |\n| `req.query.reason` | The MFA flow reason (for example, `PAYMENT_CONFIRM`) |\n| `req.query.visitor` | The visitor identifier |\n\n**Sets**\n\n| Target | Value |\n| --- | --- |\n| `req.link.visitor` | The verified visitor ID |\n| `req.link.subject` | The link subject string |\n| `req.link.purpose` | The link purpose\u002Freason |\n| `req.link.jti` | The link's unique identifier |\n\n**Behavior by HTTP method**\n\n| Method | Behavior |\n| --- | --- |\n| `GET` | Preview the link status. Limited to a configurable number of previews. Returns `200` with link metadata. |\n| `POST` | Consume the link. Limited to a single use. On success, populates `req.link` and calls `next()`. |\n\n**Responses on failure**\n\n| Status | Meaning |\n| --- | --- |\n| `400` | Invalid, expired, or already-used link; validation errors |\n| `401` | Payload mismatch or hash verification failure |\n| `403` | XSS attempt detected |\n\n**Rate limiting**\n\nApplies per-IP rate limiting with consecutive failure tracking. See [Rate Limiting](\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting).\n\nSee also: [Magic Links](\u002Fdocs\u002Fiam\u002Fessentials\u002Fmagic-links) for the full custom MFA flow documentation.\n\n---\n\n## Request Enrichment\n\n### `getFingerPrint`\n\nCollects device, browser, geo, and network information from the incoming request and attaches it to `req.fingerPrint`. Uses `@riavzon\u002Fbot-detector` for User-Agent parsing and IP geolocation.\n\n**Import**\n\n```ts\nimport { getFingerPrint } from '@riavzon\u002Fauth'\n```\n\n**Sets**\n\n| Target | Type | Description |\n| --- | --- | --- |\n| `req.fingerPrint.userAgent` | `string` | Raw User-Agent header |\n| `req.fingerPrint.ipAddress` | `string` | Client IP address |\n| `req.fingerPrint.country` | `string?` | Country name |\n| `req.fingerPrint.countryCode` | `string?` | ISO country code |\n| `req.fingerPrint.region` | `string?` | Region\u002Fstate code |\n| `req.fingerPrint.regionName` | `string?` | Region\u002Fstate full name |\n| `req.fingerPrint.city` | `string?` | City name |\n| `req.fingerPrint.district` | `string?` | City district or subdivision |\n| `req.fingerPrint.lat` | `string?` | Latitude |\n| `req.fingerPrint.lon` | `string?` | Longitude |\n| `req.fingerPrint.timezone` | `string?` | IANA timezone |\n| `req.fingerPrint.currency` | `string?` | Local currency code |\n| `req.fingerPrint.isp` | `string?` | Internet service provider |\n| `req.fingerPrint.org` | `string?` | Organization name |\n| `req.fingerPrint.as_org` | `string?` | Autonomous system organization |\n| `req.fingerPrint.proxy` | `boolean?` | Whether the IP is a known proxy |\n| `req.fingerPrint.hosting` | `boolean?` | Whether the IP belongs to a hosting provider |\n| `req.fingerPrint.device` | `string` | Device type |\n| `req.fingerPrint.deviceVendor` | `string?` | Device manufacturer |\n| `req.fingerPrint.deviceModel` | `string?` | Device model name |\n| `req.fingerPrint.browser` | `string?` | Browser name |\n| `req.fingerPrint.browserType` | `string?` | Browser category |\n| `req.fingerPrint.browserVersion` | `string?` | Browser version |\n| `req.fingerPrint.os` | `string?` | Operating system |\n| `req.fingerPrint.bot` | `boolean` | Whether the client is a known bot |\n| `req.fingerPrint.botAI` | `boolean` | Whether the client is an AI crawler |\n\n**Error behavior**\n\nIf fingerprinting fails (for example, malformed User-Agent or geolocation service unavailable), the middleware logs the error and calls `next()` without setting `req.fingerPrint`. Downstream middleware should handle a potentially undefined fingerprint gracefully.\n\nSee [Fingerprinting](\u002Fdocs\u002Fiam\u002Fessentials\u002Ffingerprinting) for how fingerprint data is used in anomaly detection.\n\n---\n\n## Error Handling\n\nThese middleware functions are registered at the end of the middleware stack by `bootstrapApp()`. They catch unmatched routes and unhandled errors.\n\n### `notFoundHandler`\n\nReturns a standardized JSON `404` response for any request that doesn't match a registered route. Registered after all route handlers.\n\n**Response**\n\n| Status | Body |\n| --- | --- |\n| `404` | `{ error: \"The page you are looking for doesn't exists\" }` |\n\n::note\nThis middleware is not exported from `@riavzon\u002Fauth`. It is applied automatically by `bootstrapApp()`.\n::\n\n---\n\n### `finalUnHandledErrors`\n\nThe last-resort Express error handler. Catches any unhandled error that propagates through the middleware stack, logs it, and returns a normalized JSON error response.\n\n**Error handler signature**\n\n```ts\n(err: any, req: Request, res: Response, next: NextFunction) => void\n```\n\n**Status code logic**\n\n- Uses the existing `res.statusCode` if it is greater than `415`\n- Defaults to `500` otherwise\n\n**Response**\n\n| Status | Body |\n| --- | --- |\n| Varies | `{ error: string }` |\n\n::note\nThis middleware is not exported from `@riavzon\u002Fauth`. It is applied automatically by `bootstrapApp()`.\n::\n\n---\n\n## Logging\n\n### `httpLogger`\n\nA `pino-http` middleware that logs every HTTP request and response. Writes structured JSON logs to `auth-logs\u002Fhttp.log`. Automatically redacts the `Authorization` header and `session` cookie values in log output.\n\n**Features**\n\n- Generates a unique `X-Request-Id` header for each request (or uses the existing one)\n- Redacts `req.headers.authorization` and `req.cookies.session` in logs\n- Skips logging for static asset requests (`.css`, `.js`, `.png`, etc.) and `.well-known\u002F` paths\n- Logs IP address, User-Agent, full URL, and cookies as structured context\n- Auto-selects log level based on response status: `info` for 2xx\u002F3xx, `warn` for 4xx, `error` for 5xx\n\n::note\nThis middleware is not exported from `@riavzon\u002Fauth`. It is applied automatically by `bootstrapApp()`.\n::\n\n---\n\n## Internal Link Verification\n\nThe following middleware functions handle magic link verification for built-in flows (MFA and password reset). They are not exported individually but are used internally by the magic link route handlers.\n\n### `linkMfaVerification`\n\nVerifies MFA magic links. On `GET`, previews the link status and allows a configurable number of views. On `POST`, consumes the link (single-use) and populates `req.link` for the downstream `verifyMFA` handler.\n\n**Validation pipeline**\n\n1. Validates query parameters (`token`, `random`, `reason`, `visitor`) against a Zod schema\n2. Applies per-IP rate limiting with consecutive failure tracking\n3. Verifies the temporary JWT signature and expiry\n4. Checks visitor identity match between URL and token payload\n5. Verifies the random hash using `crypto.timingSafeEqual()`\n6. Enforces configurable GET\u002FPOST usage limits per JTI\n\n---\n\n### `linkPasswordVerification`\n\nVerifies password reset magic links. Follows the same validation pipeline as `linkMfaVerification` but uses separate rate limiter instances and threshold configuration (`magic_links.thresholds.linkPasswordVerification`).\n\n---\n\n## Middleware Stack Order\n\nWhen `bootstrapApp()` wires the Express app, middleware is applied in this exact order:\n\n::steps{level=\"4\"}\n\n#### `httpLogger`\nStructured request\u002Fresponse logging with automatic redaction.\n\n#### Disable `x-powered-by`\nRemoves the default Express `X-Powered-By` header.\n\n#### `helmet`\nSecurity headers (CSP, X-Frame-Options, Referrer-Policy, etc.).\n\n#### `headers`\nNo-cache headers for authentication responses.\n\n#### `validateIp`\nRejects requests with invalid or missing IP addresses.\n\n#### `hmacAuth` (conditional)\nHMAC signature verification. Only applied when `service.Hmac` is configured.\n\n#### `apiVerificationRoute()`\nMounts `GET \u002Fapi\u002Fpublic\u002Fverify` before JSON parsing, cookie parsing, and the\nbot-detector middleware.\n\n#### `express.json()`\nGlobal JSON body parser.\n\n#### `cookieParser()`\nCookie parsing.\n\n#### `ApiResponse` (Bot Detector)\nMounts the bot detection endpoint at `\u002Fcheck`.\n\n#### Route handlers\n`authenticationRoutes` -> `tokenRotationRoutes` -> `magicLinks` -> `bffAccessRoute` -> `apiProtectedRoutes` -> `\u002Foperational\u002Fconfig`\n\n#### `notFoundHandler`\nCatches unmatched routes.\n\n#### `finalUnHandledErrors`\nLast-resort error handler.\n\n::\n",{"title":250,"description":4190},"ESs6B3Ty7zabd2qoFyT0GbVH4lpKw6ekLPZWdPT0p5Y",[4199,4200],{"title":246,"path":247,"stem":248,"children":-1},{"title":254,"path":255,"stem":256,"children":-1},{"id":851,"title":250,"body":4202,"description":4190,"extension":4191,"icon":4192,"meta":6906,"module":4194,"navigation":8,"path":251,"rawbody":4195,"seo":6907,"stem":252,"__hash__":4197},{"type":853,"value":4203,"toc":6870},[4204,4212,4220,4228,4230,4232,4236,4240,4246,4250,4272,4276,4298,4302,4324,4328,4360,4366,4368,4372,4380,4384,4406,4410,4430,4434,4466,4474,4482,4484,4488,4492,4496,4518,4522,4554,4558,4578,4582,4604,4610,4612,4616,4622,4626,4648,4652,4716,4720,4774,4778,4828,4832,4838,4842,4856,4860,4914,4916,4920,4924,4928,4950,4954,5016,5020,5072,5078,5080,5082,5088,5092,5097,5101,5161,5169,5171,5175,5177,5181,5223,5231,5233,5237,5245,5249,5271,5279,5281,5285,5291,5295,5343,5347,5363,5367,5377,5381,5401,5405,5415,5417,5421,5427,5431,5453,5457,5481,5485,5493,5497,5551,5555,5577,5579,5581,5583,5587,5591,5595,5617,5621,5669,5673,5725,5729,5731,5735,5740,5744,5766,5770,5826,5830,5866,5870,5876,5878,5882,5888,5892,5914,5918,5964,5968,6012,6016,6050,6054,6090,6094,6098,6102,6104,6106,6110,6116,6120,6142,6146,6472,6476,6482,6486,6488,6490,6494,6498,6502,6506,6528,6536,6538,6542,6544,6548,6592,6596,6608,6612,6632,6640,6642,6644,6648,6658,6662,6694,6702,6704,6706,6708,6712,6722,6726,6750,6752,6756,6762,6764,6766,6770,6868],[856,4205,858,4206,863,4208,867,4210,871],{},[860,4207,862],{},[860,4209,866],{},[860,4211,870],{},[873,4213,4214],{},[856,4215,877,4216,881,4218,884],{},[860,4217,880],{},[860,4219,870],{},[856,4221,887,4222,890,4224,896,4226,899],{},[860,4223,870],{},[892,4225,895],{"href":894},[892,4227,254],{"href":255},[901,4229],{},[904,4231,907],{"id":906},[856,4233,910,4234,899],{},[860,4235,913],{},[915,4237,4238],{"id":917},[860,4239,920],{},[856,4241,923,4242,927,4244,931],{},[860,4243,926],{},[860,4245,930],{},[856,4247,4248],{},[935,4249,937],{},[939,4251,4252],{"className":941,"code":942,"language":943,"meta":944,"style":944},[860,4253,4254],{"__ignoreMap":944},[948,4255,4256,4258,4260,4262,4264,4266,4268,4270],{"class":950,"line":951},[948,4257,955],{"class":954},[948,4259,959],{"class":958},[948,4261,920],{"class":962},[948,4263,965],{"class":958},[948,4265,968],{"class":954},[948,4267,972],{"class":971},[948,4269,862],{"class":975},[948,4271,978],{"class":971},[856,4273,4274],{},[935,4275,983],{},[985,4277,4278,4286],{},[988,4279,4280],{},[991,4281,4282,4284],{},[994,4283,996],{},[994,4285,999],{},[1001,4287,4288],{},[991,4289,4290,4294],{},[1006,4291,4292,1010],{},[860,4293,926],{},[1006,4295,1013,4296,1017],{},[860,4297,1016],{},[856,4299,4300],{},[935,4301,1022],{},[985,4303,4304,4312],{},[988,4305,4306],{},[991,4307,4308,4310],{},[994,4309,1031],{},[994,4311,999],{},[1001,4313,4314],{},[991,4315,4316,4320],{},[1006,4317,4318],{},[860,4319,930],{},[1006,4321,1044,4322,1047],{},[860,4323,1016],{},[856,4325,4326],{},[935,4327,1052],{},[985,4329,4330,4338],{},[988,4331,4332],{},[991,4333,4334,4336],{},[994,4335,1061],{},[994,4337,1064],{},[1001,4339,4340,4350],{},[991,4341,4342,4346],{},[1006,4343,4344],{},[860,4345,1073],{},[1006,4347,4348],{},[860,4349,1078],{},[991,4351,4352,4356],{},[1006,4353,4354],{},[860,4355,1073],{},[1006,4357,4358,1090],{},[860,4359,1089],{},[1092,4361,4362],{},[856,4363,1096,4364,1099],{},[860,4365,913],{},[901,4367],{},[915,4369,4370],{"id":1104},[860,4371,1107],{},[856,4373,1110,4374,1114,4376,1118,4378,1121],{},[860,4375,1113],{},[860,4377,1117],{},[860,4379,913],{},[856,4381,4382],{},[935,4383,937],{},[939,4385,4386],{"className":941,"code":1128,"language":943,"meta":944,"style":944},[860,4387,4388],{"__ignoreMap":944},[948,4389,4390,4392,4394,4396,4398,4400,4402,4404],{"class":950,"line":951},[948,4391,955],{"class":954},[948,4393,959],{"class":958},[948,4395,1107],{"class":962},[948,4397,965],{"class":958},[948,4399,968],{"class":954},[948,4401,972],{"class":971},[948,4403,862],{"class":975},[948,4405,978],{"class":971},[856,4407,4408],{},[935,4409,983],{},[985,4411,4412,4420],{},[988,4413,4414],{},[991,4415,4416,4418],{},[994,4417,996],{},[994,4419,999],{},[1001,4421,4422],{},[991,4423,4424,4428],{},[1006,4425,4426],{},[860,4427,1113],{},[1006,4429,1173],{},[856,4431,4432],{},[935,4433,1052],{},[985,4435,4436,4444],{},[988,4437,4438],{},[991,4439,4440,4442],{},[994,4441,1061],{},[994,4443,1064],{},[1001,4445,4446,4456],{},[991,4447,4448,4452],{},[1006,4449,4450],{},[860,4451,1196],{},[1006,4453,4454],{},[860,4455,1201],{},[991,4457,4458,4462],{},[1006,4459,4460],{},[860,4461,1073],{},[1006,4463,4464],{},[860,4465,1212],{},[1214,4467,4468],{},[856,4469,1218,4470,1222,4472,1226],{},[860,4471,1221],{},[860,4473,1225],{},[1092,4475,4476],{},[856,4477,1231,4478,1235,4480,1238],{},[860,4479,1234],{},[860,4481,913],{},[901,4483],{},[915,4485,4486],{"id":1243},[860,4487,1246],{},[856,4489,1249,4490,1252],{},[860,4491,1221],{},[856,4493,4494],{},[935,4495,937],{},[939,4497,4498],{"className":941,"code":1259,"language":943,"meta":944,"style":944},[860,4499,4500],{"__ignoreMap":944},[948,4501,4502,4504,4506,4508,4510,4512,4514,4516],{"class":950,"line":951},[948,4503,955],{"class":954},[948,4505,959],{"class":958},[948,4507,1246],{"class":962},[948,4509,965],{"class":958},[948,4511,968],{"class":954},[948,4513,972],{"class":971},[948,4515,862],{"class":975},[948,4517,978],{"class":971},[856,4519,4520],{},[935,4521,1052],{},[985,4523,4524,4532],{},[988,4525,4526],{},[991,4527,4528,4530],{},[994,4529,1061],{},[994,4531,1064],{},[1001,4533,4534,4544],{},[991,4535,4536,4540],{},[1006,4537,4538],{},[860,4539,1073],{},[1006,4541,4542],{},[860,4543,1212],{},[991,4545,4546,4550],{},[1006,4547,4548],{},[860,4549,1196],{},[1006,4551,4552],{},[860,4553,1201],{},[856,4555,4556],{},[935,4557,983],{},[985,4559,4560,4568],{},[988,4561,4562],{},[991,4563,4564,4566],{},[994,4565,996],{},[994,4567,999],{},[1001,4569,4570],{},[991,4571,4572,4576],{},[1006,4573,4574],{},[860,4575,1113],{},[1006,4577,1173],{},[856,4579,4580],{},[935,4581,1052],{},[985,4583,4584,4592],{},[988,4585,4586],{},[991,4587,4588,4590],{},[994,4589,1061],{},[994,4591,1064],{},[1001,4593,4594],{},[991,4595,4596,4600],{},[1006,4597,4598],{},[860,4599,1073],{},[1006,4601,4602],{},[860,4603,1366],{},[1214,4605,4606],{},[856,4607,1371,4608,1374],{},[860,4609,913],{},[901,4611],{},[915,4613,4614],{"id":1379},[860,4615,913],{},[856,4617,1384,4618,1388,4620,899],{},[892,4619,1387],{"href":96},[860,4621,1196],{},[856,4623,4624],{},[935,4625,937],{},[939,4627,4628],{"className":941,"code":1397,"language":943,"meta":944,"style":944},[860,4629,4630],{"__ignoreMap":944},[948,4631,4632,4634,4636,4638,4640,4642,4644,4646],{"class":950,"line":951},[948,4633,955],{"class":954},[948,4635,959],{"class":958},[948,4637,913],{"class":962},[948,4639,965],{"class":958},[948,4641,968],{"class":954},[948,4643,972],{"class":971},[948,4645,862],{"class":975},[948,4647,978],{"class":971},[856,4649,4650],{},[935,4651,983],{},[985,4653,4654,4662],{},[988,4655,4656],{},[991,4657,4658,4660],{},[994,4659,996],{},[994,4661,999],{},[1001,4663,4664,4674,4682,4690,4698,4708],{},[991,4665,4666,4670],{},[1006,4667,4668],{},[860,4669,930],{},[1006,4671,1442,4672,1047],{},[860,4673,920],{},[991,4675,4676,4680],{},[1006,4677,4678],{},[860,4679,1113],{},[1006,4681,1173],{},[991,4683,4684,4688],{},[1006,4685,4686],{},[860,4687,1459],{},[1006,4689,1462],{},[991,4691,4692,4696],{},[1006,4693,4694],{},[860,4695,1469],{},[1006,4697,1472],{},[991,4699,4700,4704],{},[1006,4701,4702],{},[860,4703,1479],{},[1006,4705,1482,4706,1047],{},[860,4707,1234],{},[991,4709,4710,4714],{},[1006,4711,4712,1010],{},[860,4713,1491],{},[1006,4715,1494],{},[856,4717,4718],{},[935,4719,1022],{},[985,4721,4722,4730],{},[988,4723,4724],{},[991,4725,4726,4728],{},[994,4727,1031],{},[994,4729,999],{},[1001,4731,4732,4740,4748,4758,4766],{},[991,4733,4734,4738],{},[1006,4735,4736],{},[860,4737,1517],{},[1006,4739,1520],{},[991,4741,4742,4746],{},[1006,4743,4744],{},[860,4745,1527],{},[1006,4747,1530],{},[991,4749,4750,4754],{},[1006,4751,4752],{},[860,4753,1537],{},[1006,4755,1540,4756,1544],{},[860,4757,1543],{},[991,4759,4760,4764],{},[1006,4761,4762],{},[860,4763,1551],{},[1006,4765,1554],{},[991,4767,4768,4772],{},[1006,4769,4770],{},[860,4771,1561],{},[1006,4773,1564],{},[856,4775,4776],{},[935,4777,1052],{},[985,4779,4780,4790],{},[988,4781,4782],{},[991,4783,4784,4786,4788],{},[994,4785,1061],{},[994,4787,1064],{},[994,4789,1581],{},[1001,4791,4792,4802,4818],{},[991,4793,4794,4798,4800],{},[1006,4795,4796],{},[860,4797,1196],{},[1006,4799,1592],{},[1006,4801,1595],{},[991,4803,4804,4808,4814],{},[1006,4805,4806],{},[860,4807,1073],{},[1006,4809,4810,881,4812],{},[860,4811,1606],{},[860,4813,1609],{},[1006,4815,1612,4816,1616],{},[860,4817,1615],{},[991,4819,4820,4824,4826],{},[1006,4821,4822],{},[860,4823,1623],{},[1006,4825,1626],{},[1006,4827,1629],{},[856,4829,4830],{},[935,4831,1634],{},[856,4833,1637,4834,1641,4836,1645],{},[860,4835,1640],{},[860,4837,1644],{},[856,4839,1648,4840,1651],{},[892,4841,95],{"href":96},[873,4843,4844],{},[856,4845,1656,4846,1659,4848,1662,4850,1665,4852,1668,4854,1671],{},[860,4847,920],{},[860,4849,1246],{},[860,4851,913],{},[860,4853,913],{},[860,4855,930],{},[856,4857,4858],{},[935,4859,1676],{},[939,4861,4862],{"className":941,"code":1679,"language":943,"meta":944,"style":944},[860,4863,4864,4882,4888,4894,4900,4906,4910],{"__ignoreMap":944},[948,4865,4866,4868,4870,4872,4874,4876,4878,4880],{"class":950,"line":951},[948,4867,1686],{"class":962},[948,4869,899],{"class":958},[948,4871,1692],{"class":1691},[948,4873,1695],{"class":958},[948,4875,1698],{"class":971},[948,4877,1701],{"class":975},[948,4879,1698],{"class":971},[948,4881,1706],{"class":958},[948,4883,4884,4886],{"class":950,"line":1709},[948,4885,1712],{"class":962},[948,4887,1706],{"class":958},[948,4889,4890,4892],{"class":950,"line":1717},[948,4891,1720],{"class":962},[948,4893,1706],{"class":958},[948,4895,4896,4898],{"class":950,"line":1725},[948,4897,1728],{"class":962},[948,4899,1706],{"class":958},[948,4901,4902,4904],{"class":950,"line":1733},[948,4903,1736],{"class":962},[948,4905,1706],{"class":958},[948,4907,4908],{"class":950,"line":1741},[948,4909,1744],{"class":962},[948,4911,4912],{"class":950,"line":1747},[948,4913,1750],{"class":958},[901,4915],{},[915,4917,4918],{"id":1755},[860,4919,1758],{},[856,4921,1761,4922,1765],{},[860,4923,1764],{},[856,4925,4926],{},[935,4927,937],{},[939,4929,4930],{"className":941,"code":1772,"language":943,"meta":944,"style":944},[860,4931,4932],{"__ignoreMap":944},[948,4933,4934,4936,4938,4940,4942,4944,4946,4948],{"class":950,"line":951},[948,4935,955],{"class":954},[948,4937,959],{"class":958},[948,4939,1758],{"class":962},[948,4941,965],{"class":958},[948,4943,968],{"class":954},[948,4945,972],{"class":971},[948,4947,862],{"class":975},[948,4949,978],{"class":971},[856,4951,4952],{},[935,4953,983],{},[985,4955,4956,4964],{},[988,4957,4958],{},[991,4959,4960,4962],{},[994,4961,996],{},[994,4963,999],{},[1001,4965,4966,4974,4982,4992,5002,5008],{},[991,4967,4968,4972],{},[1006,4969,4970],{},[860,4971,1113],{},[1006,4973,1817],{},[991,4975,4976,4980],{},[1006,4977,4978],{},[860,4979,1824],{},[1006,4981,1827],{},[991,4983,4984,4988],{},[1006,4985,4986,1010],{},[860,4987,1834],{},[1006,4989,1837,4990,1841],{},[860,4991,1840],{},[991,4993,4994,4998],{},[1006,4995,4996,1010],{},[860,4997,1848],{},[1006,4999,1851,5000],{},[860,5001,1854],{},[991,5003,5004,5006],{},[1006,5005,1859],{},[1006,5007,1862],{},[991,5009,5010,5014],{},[1006,5011,5012,1010],{},[860,5013,1764],{},[1006,5015,1871],{},[856,5017,5018],{},[935,5019,1052],{},[985,5021,5022,5030],{},[988,5023,5024],{},[991,5025,5026,5028],{},[994,5027,1061],{},[994,5029,1064],{},[1001,5031,5032,5042,5052,5062],{},[991,5033,5034,5038],{},[1006,5035,5036],{},[860,5037,1073],{},[1006,5039,5040],{},[860,5041,1366],{},[991,5043,5044,5048],{},[1006,5045,5046],{},[860,5047,1904],{},[1006,5049,5050],{},[860,5051,1909],{},[991,5053,5054,5058],{},[1006,5055,5056],{},[860,5057,1904],{},[1006,5059,5060],{},[860,5061,1920],{},[991,5063,5064,5068],{},[1006,5065,5066],{},[860,5067,1904],{},[1006,5069,5070],{},[860,5071,1931],{},[1092,5073,5074],{},[856,5075,1936,5076,1939],{},[860,5077,1246],{},[901,5079],{},[904,5081,1945],{"id":1944},[856,5083,1948,5084,1951,5086,899],{},[860,5085,870],{},[860,5087,870],{},[915,5089,5090],{"id":1956},[860,5091,1956],{},[856,5093,1961,5094,1968],{},[892,5095,1967],{"href":1964,"rel":5096},[1966],[856,5098,5099],{},[935,5100,1973],{},[985,5102,5103,5111],{},[988,5104,5105],{},[991,5106,5107,5109],{},[994,5108,1982],{},[994,5110,999],{},[1001,5112,5113,5123,5133,5143,5151],{},[991,5114,5115,5119],{},[1006,5116,5117],{},[860,5118,1993],{},[1006,5120,5121],{},[860,5122,1998],{},[991,5124,5125,5129],{},[1006,5126,5127],{},[860,5128,2005],{},[1006,5130,5131],{},[860,5132,2010],{},[991,5134,5135,5139],{},[1006,5136,5137],{},[860,5138,2017],{},[1006,5140,5141],{},[860,5142,2022],{},[991,5144,5145,5149],{},[1006,5146,5147],{},[860,5148,2029],{},[1006,5150,2032],{},[991,5152,5153,5155],{},[1006,5154,2037],{},[1006,5156,5157,2043,5159,2047],{},[860,5158,2042],{},[860,5160,2046],{},[1214,5162,5163],{},[856,5164,2052,5165,2055,5167,899],{},[860,5166,862],{},[860,5168,870],{},[901,5170],{},[915,5172,5173],{"id":2062},[860,5174,2062],{},[856,5176,2067],{},[856,5178,5179],{},[935,5180,1973],{},[985,5182,5183,5191],{},[988,5184,5185],{},[991,5186,5187,5189],{},[994,5188,1982],{},[994,5190,999],{},[1001,5192,5193,5203,5213],{},[991,5194,5195,5199],{},[1006,5196,5197],{},[860,5198,2090],{},[1006,5200,5201],{},[860,5202,2095],{},[991,5204,5205,5209],{},[1006,5206,5207],{},[860,5208,2102],{},[1006,5210,5211],{},[860,5212,2107],{},[991,5214,5215,5219],{},[1006,5216,5217],{},[860,5218,2114],{},[1006,5220,5221],{},[860,5222,1840],{},[1214,5224,5225],{},[856,5226,2052,5227,2055,5229,899],{},[860,5228,862],{},[860,5230,870],{},[901,5232],{},[915,5234,5235],{"id":2131},[860,5236,2134],{},[856,5238,2137,5239,2140,5241,2144,5243,899],{},[860,5240,1469],{},[860,5242,2143],{},[860,5244,2147],{},[856,5246,5247],{},[935,5248,1052],{},[985,5250,5251,5259],{},[988,5252,5253],{},[991,5254,5255,5257],{},[994,5256,1061],{},[994,5258,1064],{},[1001,5260,5261],{},[991,5262,5263,5267],{},[1006,5264,5265],{},[860,5266,2170],{},[1006,5268,5269,2176],{},[860,5270,2175],{},[1214,5272,5273],{},[856,5274,2052,5275,2055,5277,899],{},[860,5276,862],{},[860,5278,870],{},[901,5280],{},[915,5282,5283],{"id":2189},[860,5284,2192],{},[856,5286,2195,5287,2199,5289,2203],{},[892,5288,2198],{"href":136},[860,5290,2202],{},[856,5292,5293],{},[935,5294,2208],{},[985,5296,5297,5305],{},[988,5298,5299],{},[991,5300,5301,5303],{},[994,5302,1982],{},[994,5304,2219],{},[1001,5306,5307,5317,5325,5335],{},[991,5308,5309,5313],{},[1006,5310,5311],{},[860,5312,2228],{},[1006,5314,2231,5315],{},[860,5316,2234],{},[991,5318,5319,5323],{},[1006,5320,5321],{},[860,5322,2241],{},[1006,5324,2244],{},[991,5326,5327,5331],{},[1006,5328,5329],{},[860,5330,2251],{},[1006,5332,2254,5333],{},[860,5334,2257],{},[991,5336,5337,5341],{},[1006,5338,5339],{},[860,5340,2264],{},[1006,5342,2267],{},[856,5344,5345],{},[935,5346,2272],{},[2274,5348,5349,5351,5355,5357,5359],{},[2277,5350,2279],{},[2277,5352,2282,5353,2285],{},[860,5354,2228],{},[2277,5356,2288],{},[2277,5358,2291],{},[2277,5360,2294,5361],{},[860,5362,2297],{},[856,5364,5365],{},[935,5366,2302],{},[2304,5368,5369],{},[2277,5370,2308,5371,2312,5373,881,5375,2319],{},[860,5372,2311],{},[860,5374,2315],{},[860,5376,2318],{},[856,5378,5379],{},[935,5380,1052],{},[985,5382,5383,5391],{},[988,5384,5385],{},[991,5386,5387,5389],{},[994,5388,1061],{},[994,5390,1064],{},[1001,5392,5393],{},[991,5394,5395,5399],{},[1006,5396,5397],{},[860,5398,1073],{},[1006,5400,2344],{},[856,5402,2347,5403,2350],{},[892,5404,135],{"href":136},[1214,5406,5407],{},[856,5408,2052,5409,2055,5411,2359,5413,2362],{},[860,5410,862],{},[860,5412,870],{},[860,5414,2202],{},[901,5416],{},[915,5418,5419],{"id":2367},[860,5420,2370],{},[856,5422,2373,5423,2376,5425,899],{},[860,5424,1764],{},[860,5426,2147],{},[856,5428,5429],{},[935,5430,937],{},[939,5432,5433],{"className":941,"code":2385,"language":943,"meta":944,"style":944},[860,5434,5435],{"__ignoreMap":944},[948,5436,5437,5439,5441,5443,5445,5447,5449,5451],{"class":950,"line":951},[948,5438,955],{"class":954},[948,5440,959],{"class":958},[948,5442,2370],{"class":962},[948,5444,965],{"class":958},[948,5446,968],{"class":954},[948,5448,972],{"class":971},[948,5450,862],{"class":975},[948,5452,978],{"class":971},[856,5454,5455],{},[935,5456,2410],{},[939,5458,5459],{"className":941,"code":2413,"language":943,"meta":944,"style":944},[860,5460,5461],{"__ignoreMap":944},[948,5462,5463,5465,5467,5469,5471,5473,5475,5477,5479],{"class":950,"line":951},[948,5464,2421],{"class":2420},[948,5466,2424],{"class":1691},[948,5468,1695],{"class":958},[948,5470,2430],{"class":2429},[948,5472,2434],{"class":2433},[948,5474,2438],{"class":2437},[948,5476,1047],{"class":958},[948,5478,2434],{"class":2433},[948,5480,2445],{"class":2437},[856,5482,5483],{},[935,5484,2450],{},[2452,5486,5487],{},[2455,5488,5489],{":required":2457,"name":2430,"type":2458},[856,5490,2461,5491,899],{},[860,5492,2464],{},[856,5494,5495],{},[935,5496,2469],{},[939,5498,5499],{"className":941,"code":2472,"language":943,"meta":944,"style":944},[860,5500,5501,5519,5533,5543,5547],{"__ignoreMap":944},[948,5502,5503,5505,5507,5509,5511,5513,5515,5517],{"class":950,"line":951},[948,5504,1686],{"class":962},[948,5506,899],{"class":958},[948,5508,2483],{"class":1691},[948,5510,1695],{"class":958},[948,5512,1698],{"class":971},[948,5514,2490],{"class":975},[948,5516,1698],{"class":971},[948,5518,1706],{"class":958},[948,5520,5521,5523,5525,5527,5529,5531],{"class":950,"line":1709},[948,5522,2499],{"class":1691},[948,5524,1695],{"class":958},[948,5526,1698],{"class":971},[948,5528,2506],{"class":975},[948,5530,1698],{"class":971},[948,5532,2511],{"class":958},[948,5534,5535,5537,5539,5541],{"class":950,"line":1717},[948,5536,2516],{"class":962},[948,5538,899],{"class":958},[948,5540,5],{"class":1691},[948,5542,2523],{"class":958},[948,5544,5545],{"class":950,"line":1725},[948,5546,1744],{"class":962},[948,5548,5549],{"class":950,"line":1733},[948,5550,1750],{"class":958},[856,5552,5553],{},[935,5554,1052],{},[985,5556,5557,5565],{},[988,5558,5559],{},[991,5560,5561,5563],{},[994,5562,1061],{},[994,5564,1064],{},[1001,5566,5567],{},[991,5568,5569,5573],{},[1006,5570,5571],{},[860,5572,2170],{},[1006,5574,5575],{},[860,5576,2558],{},[901,5578],{},[904,5580,2564],{"id":2563},[856,5582,2567],{},[915,5584,5585],{"id":2570},[860,5586,2573],{},[856,5588,2576,5589,2579],{},[860,5590,1225],{},[856,5592,5593],{},[935,5594,937],{},[939,5596,5597],{"className":941,"code":2586,"language":943,"meta":944,"style":944},[860,5598,5599],{"__ignoreMap":944},[948,5600,5601,5603,5605,5607,5609,5611,5613,5615],{"class":950,"line":951},[948,5602,955],{"class":954},[948,5604,959],{"class":958},[948,5606,2573],{"class":962},[948,5608,965],{"class":958},[948,5610,968],{"class":954},[948,5612,972],{"class":971},[948,5614,862],{"class":975},[948,5616,978],{"class":971},[856,5618,5619],{},[935,5620,983],{},[985,5622,5623,5631],{},[988,5624,5625],{},[991,5626,5627,5629],{},[994,5628,996],{},[994,5630,999],{},[1001,5632,5633,5641,5651,5661],{},[991,5634,5635,5639],{},[1006,5636,5637],{},[860,5638,2629],{},[1006,5640,2632],{},[991,5642,5643,5647],{},[1006,5644,5645],{},[860,5646,2639],{},[1006,5648,1837,5649,2645],{},[860,5650,2644],{},[991,5652,5653,5657],{},[1006,5654,5655],{},[860,5656,2652],{},[1006,5658,2655,5659],{},[860,5660,2658],{},[991,5662,5663,5667],{},[1006,5664,5665],{},[860,5666,2665],{},[1006,5668,2668],{},[856,5670,5671],{},[935,5672,2673],{},[985,5674,5675,5683],{},[988,5676,5677],{},[991,5678,5679,5681],{},[994,5680,1061],{},[994,5682,1581],{},[1001,5684,5685,5693,5701,5709,5717],{},[991,5686,5687,5691],{},[1006,5688,5689],{},[860,5690,2692],{},[1006,5692,2695],{},[991,5694,5695,5699],{},[1006,5696,5697],{},[860,5698,1904],{},[1006,5700,2704],{},[991,5702,5703,5707],{},[1006,5704,5705],{},[860,5706,1073],{},[1006,5708,2713],{},[991,5710,5711,5715],{},[1006,5712,5713],{},[860,5714,2170],{},[1006,5716,2722],{},[991,5718,5719,5723],{},[1006,5720,5721],{},[860,5722,1623],{},[1006,5724,1626],{},[856,5726,2733,5727,2736],{},[892,5728,123],{"href":124},[901,5730],{},[915,5732,5733],{"id":2741},[860,5734,2744],{},[856,5736,2747,5737,2753],{},[892,5738,2752],{"href":2750,"rel":5739},[1966],[856,5741,5742],{},[935,5743,937],{},[939,5745,5746],{"className":941,"code":2760,"language":943,"meta":944,"style":944},[860,5747,5748],{"__ignoreMap":944},[948,5749,5750,5752,5754,5756,5758,5760,5762,5764],{"class":950,"line":951},[948,5751,955],{"class":954},[948,5753,959],{"class":958},[948,5755,2744],{"class":962},[948,5757,965],{"class":958},[948,5759,968],{"class":954},[948,5761,972],{"class":971},[948,5763,862],{"class":975},[948,5765,978],{"class":971},[856,5767,5768],{},[935,5769,983],{},[985,5771,5772,5780],{},[988,5773,5774],{},[991,5775,5776,5778],{},[994,5777,996],{},[994,5779,999],{},[1001,5781,5782,5790,5798,5808,5818],{},[991,5783,5784,5788],{},[1006,5785,5786],{},[860,5787,2803],{},[1006,5789,2806],{},[991,5791,5792,5796],{},[1006,5793,5794],{},[860,5795,2813],{},[1006,5797,2816],{},[991,5799,5800,5804],{},[1006,5801,5802],{},[860,5803,2639],{},[1006,5805,1837,5806,2645],{},[860,5807,2827],{},[991,5809,5810,5814],{},[1006,5811,5812],{},[860,5813,2652],{},[1006,5815,2655,5816],{},[860,5817,2838],{},[991,5819,5820,5824],{},[1006,5821,5822],{},[860,5823,2845],{},[1006,5825,2848],{},[856,5827,5828],{},[935,5829,2673],{},[985,5831,5832,5840],{},[988,5833,5834],{},[991,5835,5836,5838],{},[994,5837,1061],{},[994,5839,1581],{},[1001,5841,5842,5850,5858],{},[991,5843,5844,5848],{},[1006,5845,5846],{},[860,5847,2692],{},[1006,5849,2873],{},[991,5851,5852,5856],{},[1006,5853,5854],{},[860,5855,1904],{},[1006,5857,2882],{},[991,5859,5860,5864],{},[1006,5861,5862],{},[860,5863,2170],{},[1006,5865,2891],{},[856,5867,5868],{},[935,5869,2896],{},[856,5871,2899,5872,2903,5874,2906],{},[860,5873,2902],{},[892,5875,147],{"href":148},[901,5877],{},[915,5879,5880],{"id":2911},[860,5881,2914],{},[856,5883,2917,5884,2920,5886,2924],{},[860,5885,2297],{},[860,5887,2923],{},[856,5889,5890],{},[935,5891,937],{},[939,5893,5894],{"className":941,"code":2931,"language":943,"meta":944,"style":944},[860,5895,5896],{"__ignoreMap":944},[948,5897,5898,5900,5902,5904,5906,5908,5910,5912],{"class":950,"line":951},[948,5899,955],{"class":954},[948,5901,959],{"class":958},[948,5903,2914],{"class":962},[948,5905,965],{"class":958},[948,5907,968],{"class":954},[948,5909,972],{"class":971},[948,5911,862],{"class":975},[948,5913,978],{"class":971},[856,5915,5916],{},[935,5917,983],{},[985,5919,5920,5928],{},[988,5921,5922],{},[991,5923,5924,5926],{},[994,5925,996],{},[994,5927,999],{},[1001,5929,5930,5938,5946,5956],{},[991,5931,5932,5936],{},[1006,5933,5934],{},[860,5935,2974],{},[1006,5937,2977],{},[991,5939,5940,5944],{},[1006,5941,5942],{},[860,5943,2984],{},[1006,5945,2987],{},[991,5947,5948,5952],{},[1006,5949,5950],{},[860,5951,2994],{},[1006,5953,2997,5954,1047],{},[860,5955,3000],{},[991,5957,5958,5962],{},[1006,5959,5960],{},[860,5961,3007],{},[1006,5963,3010],{},[856,5965,5966],{},[935,5967,1022],{},[985,5969,5970,5978],{},[988,5971,5972],{},[991,5973,5974,5976],{},[994,5975,1031],{},[994,5977,999],{},[1001,5979,5980,5988,5996,6004],{},[991,5981,5982,5986],{},[1006,5983,5984],{},[860,5985,2665],{},[1006,5987,3035],{},[991,5989,5990,5994],{},[1006,5991,5992],{},[860,5993,2652],{},[1006,5995,3044],{},[991,5997,5998,6002],{},[1006,5999,6000],{},[860,6001,2639],{},[1006,6003,3053],{},[991,6005,6006,6010],{},[1006,6007,6008],{},[860,6009,2845],{},[1006,6011,3062],{},[856,6013,6014],{},[935,6015,3067],{},[985,6017,6018,6026],{},[988,6019,6020],{},[991,6021,6022,6024],{},[994,6023,3076],{},[994,6025,3079],{},[1001,6027,6028,6038],{},[991,6029,6030,6034],{},[1006,6031,6032],{},[860,6033,3088],{},[1006,6035,3091,6036,3094],{},[860,6037,2692],{},[991,6039,6040,6044],{},[1006,6041,6042],{},[860,6043,3101],{},[1006,6045,3104,6046,3107,6048,899],{},[860,6047,2923],{},[860,6049,1225],{},[856,6051,6052],{},[935,6053,1052],{},[985,6055,6056,6064],{},[988,6057,6058],{},[991,6059,6060,6062],{},[994,6061,1061],{},[994,6063,1581],{},[1001,6065,6066,6074,6082],{},[991,6067,6068,6072],{},[1006,6069,6070],{},[860,6071,1904],{},[1006,6073,3134],{},[991,6075,6076,6080],{},[1006,6077,6078],{},[860,6079,1073],{},[1006,6081,3143],{},[991,6083,6084,6088],{},[1006,6085,6086],{},[860,6087,2170],{},[1006,6089,3152],{},[856,6091,6092],{},[935,6093,2896],{},[856,6095,3159,6096,899],{},[892,6097,147],{"href":148},[856,6099,3164,6100,3167],{},[892,6101,115],{"href":116},[901,6103],{},[904,6105,3173],{"id":3172},[915,6107,6108],{"id":3176},[860,6109,1234],{},[856,6111,3181,6112,3184,6114,3188],{},[860,6113,1479],{},[860,6115,3187],{},[856,6117,6118],{},[935,6119,937],{},[939,6121,6122],{"className":941,"code":3195,"language":943,"meta":944,"style":944},[860,6123,6124],{"__ignoreMap":944},[948,6125,6126,6128,6130,6132,6134,6136,6138,6140],{"class":950,"line":951},[948,6127,955],{"class":954},[948,6129,959],{"class":958},[948,6131,1234],{"class":962},[948,6133,965],{"class":958},[948,6135,968],{"class":954},[948,6137,972],{"class":971},[948,6139,862],{"class":975},[948,6141,978],{"class":971},[856,6143,6144],{},[935,6145,1022],{},[985,6147,6148,6158],{},[988,6149,6150],{},[991,6151,6152,6154,6156],{},[994,6153,1031],{},[994,6155,3230],{},[994,6157,2219],{},[1001,6159,6160,6172,6184,6196,6208,6220,6232,6244,6256,6268,6280,6292,6304,6316,6328,6340,6352,6364,6376,6388,6400,6412,6424,6436,6448,6460],{},[991,6161,6162,6166,6170],{},[1006,6163,6164],{},[860,6165,3241],{},[1006,6167,6168],{},[860,6169,2458],{},[1006,6171,3248],{},[991,6173,6174,6178,6182],{},[1006,6175,6176],{},[860,6177,3255],{},[1006,6179,6180],{},[860,6181,2458],{},[1006,6183,1472],{},[991,6185,6186,6190,6194],{},[1006,6187,6188],{},[860,6189,3268],{},[1006,6191,6192],{},[860,6193,3273],{},[1006,6195,3276],{},[991,6197,6198,6202,6206],{},[1006,6199,6200],{},[860,6201,3283],{},[1006,6203,6204],{},[860,6205,3273],{},[1006,6207,3290],{},[991,6209,6210,6214,6218],{},[1006,6211,6212],{},[860,6213,3297],{},[1006,6215,6216],{},[860,6217,3273],{},[1006,6219,3304],{},[991,6221,6222,6226,6230],{},[1006,6223,6224],{},[860,6225,3311],{},[1006,6227,6228],{},[860,6229,3273],{},[1006,6231,3318],{},[991,6233,6234,6238,6242],{},[1006,6235,6236],{},[860,6237,3325],{},[1006,6239,6240],{},[860,6241,3273],{},[1006,6243,3332],{},[991,6245,6246,6250,6254],{},[1006,6247,6248],{},[860,6249,3339],{},[1006,6251,6252],{},[860,6253,3273],{},[1006,6255,3346],{},[991,6257,6258,6262,6266],{},[1006,6259,6260],{},[860,6261,3353],{},[1006,6263,6264],{},[860,6265,3273],{},[1006,6267,3360],{},[991,6269,6270,6274,6278],{},[1006,6271,6272],{},[860,6273,3367],{},[1006,6275,6276],{},[860,6277,3273],{},[1006,6279,3374],{},[991,6281,6282,6286,6290],{},[1006,6283,6284],{},[860,6285,3381],{},[1006,6287,6288],{},[860,6289,3273],{},[1006,6291,3388],{},[991,6293,6294,6298,6302],{},[1006,6295,6296],{},[860,6297,3395],{},[1006,6299,6300],{},[860,6301,3273],{},[1006,6303,3402],{},[991,6305,6306,6310,6314],{},[1006,6307,6308],{},[860,6309,3409],{},[1006,6311,6312],{},[860,6313,3273],{},[1006,6315,3416],{},[991,6317,6318,6322,6326],{},[1006,6319,6320],{},[860,6321,3423],{},[1006,6323,6324],{},[860,6325,3273],{},[1006,6327,3430],{},[991,6329,6330,6334,6338],{},[1006,6331,6332],{},[860,6333,3437],{},[1006,6335,6336],{},[860,6337,3273],{},[1006,6339,3444],{},[991,6341,6342,6346,6350],{},[1006,6343,6344],{},[860,6345,3451],{},[1006,6347,6348],{},[860,6349,3456],{},[1006,6351,3459],{},[991,6353,6354,6358,6362],{},[1006,6355,6356],{},[860,6357,3466],{},[1006,6359,6360],{},[860,6361,3456],{},[1006,6363,3473],{},[991,6365,6366,6370,6374],{},[1006,6367,6368],{},[860,6369,3480],{},[1006,6371,6372],{},[860,6373,2458],{},[1006,6375,3487],{},[991,6377,6378,6382,6386],{},[1006,6379,6380],{},[860,6381,3494],{},[1006,6383,6384],{},[860,6385,3273],{},[1006,6387,3501],{},[991,6389,6390,6394,6398],{},[1006,6391,6392],{},[860,6393,3508],{},[1006,6395,6396],{},[860,6397,3273],{},[1006,6399,3515],{},[991,6401,6402,6406,6410],{},[1006,6403,6404],{},[860,6405,3522],{},[1006,6407,6408],{},[860,6409,3273],{},[1006,6411,3529],{},[991,6413,6414,6418,6422],{},[1006,6415,6416],{},[860,6417,3536],{},[1006,6419,6420],{},[860,6421,3273],{},[1006,6423,3543],{},[991,6425,6426,6430,6434],{},[1006,6427,6428],{},[860,6429,3550],{},[1006,6431,6432],{},[860,6433,3273],{},[1006,6435,3557],{},[991,6437,6438,6442,6446],{},[1006,6439,6440],{},[860,6441,3564],{},[1006,6443,6444],{},[860,6445,3273],{},[1006,6447,3571],{},[991,6449,6450,6454,6458],{},[1006,6451,6452],{},[860,6453,3578],{},[1006,6455,6456],{},[860,6457,3583],{},[1006,6459,3586],{},[991,6461,6462,6466,6470],{},[1006,6463,6464],{},[860,6465,3593],{},[1006,6467,6468],{},[860,6469,3583],{},[1006,6471,3600],{},[856,6473,6474],{},[935,6475,3605],{},[856,6477,3608,6478,3611,6480,3614],{},[860,6479,1225],{},[860,6481,1479],{},[856,6483,2733,6484,3619],{},[892,6485,127],{"href":128},[901,6487],{},[904,6489,3625],{"id":3624},[856,6491,3628,6492,3631],{},[860,6493,870],{},[915,6495,6496],{"id":3634},[860,6497,3637],{},[856,6499,3640,6500,3644],{},[860,6501,3643],{},[856,6503,6504],{},[935,6505,3649],{},[985,6507,6508,6516],{},[988,6509,6510],{},[991,6511,6512,6514],{},[994,6513,1061],{},[994,6515,1064],{},[1001,6517,6518],{},[991,6519,6520,6524],{},[1006,6521,6522],{},[860,6523,3643],{},[1006,6525,6526],{},[860,6527,3672],{},[1214,6529,6530],{},[856,6531,2052,6532,2055,6534,899],{},[860,6533,862],{},[860,6535,870],{},[901,6537],{},[915,6539,6540],{"id":3685},[860,6541,3688],{},[856,6543,3691],{},[856,6545,6546],{},[935,6547,3696],{},[939,6549,6550],{"className":941,"code":3699,"language":943,"meta":944,"style":944},[860,6551,6552],{"__ignoreMap":944},[948,6553,6554,6556,6558,6560,6562,6564,6566,6568,6570,6572,6574,6576,6578,6580,6582,6584,6586,6588,6590],{"class":950,"line":951},[948,6555,1695],{"class":958},[948,6557,3708],{"class":2429},[948,6559,2434],{"class":2433},[948,6561,3713],{"class":2437},[948,6563,2043],{"class":958},[948,6565,3718],{"class":2429},[948,6567,2434],{"class":2433},[948,6569,3723],{"class":2437},[948,6571,2043],{"class":958},[948,6573,3728],{"class":2429},[948,6575,2434],{"class":2433},[948,6577,3733],{"class":2437},[948,6579,2043],{"class":958},[948,6581,3738],{"class":2429},[948,6583,2434],{"class":2433},[948,6585,3743],{"class":2437},[948,6587,3746],{"class":958},[948,6589,3749],{"class":2420},[948,6591,3752],{"class":2420},[856,6593,6594],{},[935,6595,3757],{},[2304,6597,6598,6604],{},[2277,6599,3762,6600,3766,6602],{},[860,6601,3765],{},[860,6603,3769],{},[2277,6605,3772,6606,3775],{},[860,6607,1623],{},[856,6609,6610],{},[935,6611,3649],{},[985,6613,6614,6622],{},[988,6615,6616],{},[991,6617,6618,6620],{},[994,6619,1061],{},[994,6621,1064],{},[1001,6623,6624],{},[991,6625,6626,6628],{},[1006,6627,3796],{},[1006,6629,6630],{},[860,6631,3801],{},[1214,6633,6634],{},[856,6635,2052,6636,2055,6638,899],{},[860,6637,862],{},[860,6639,870],{},[901,6641],{},[904,6643,143],{"id":3814},[915,6645,6646],{"id":3817},[860,6647,3820],{},[856,6649,3823,6650,3827,6652,3831,6654,3834,6656,3837],{},[860,6651,3826],{},[860,6653,3830],{},[860,6655,926],{},[860,6657,1221],{},[856,6659,6660],{},[935,6661,3842],{},[2304,6663,6664,6668,6674,6684,6686],{},[2277,6665,3847,6666,3851],{},[860,6667,3850],{},[2277,6669,3854,6670,1659,6672,3860],{},[860,6671,3857],{},[860,6673,1113],{},[2277,6675,3863,6676,2043,6678,2043,6680,3873,6682,3877],{},[860,6677,3866],{},[860,6679,3869],{},[860,6681,3872],{},[860,6683,3876],{},[2277,6685,3880],{},[2277,6687,3883,6688,3887,6690,3891,6692,3895],{},[860,6689,3886],{},[860,6691,3890],{},[860,6693,3894],{},[1214,6695,6696],{},[856,6697,2052,6698,2055,6700,899],{},[860,6699,862],{},[860,6701,870],{},[901,6703],{},[904,6705,3909],{"id":3908},[856,6707,3912],{},[915,6709,6710],{"id":3915},[860,6711,3918],{},[856,6713,3921,6714,3924,6716,3927,6718,3930,6720,3933],{},[860,6715,3088],{},[860,6717,3101],{},[860,6719,2923],{},[860,6721,2573],{},[856,6723,6724],{},[935,6725,3938],{},[2274,6727,6728,6738,6740,6742,6744,6748],{},[2277,6729,3943,6730,2043,6732,2043,6734,2043,6736,3955],{},[860,6731,3946],{},[860,6733,3949],{},[860,6735,1615],{},[860,6737,3954],{},[2277,6739,3958],{},[2277,6741,3961],{},[2277,6743,3964],{},[2277,6745,3967,6746],{},[860,6747,2297],{},[2277,6749,3972],{},[901,6751],{},[915,6753,6754],{"id":3977},[860,6755,3980],{},[856,6757,3983,6758,3986,6760,3990],{},[860,6759,3918],{},[860,6761,3989],{},[901,6763],{},[904,6765,3996],{"id":3995},[856,6767,3999,6768,4002],{},[860,6769,870],{},[4004,6771,6772,6776,6778,6782,6786,6790,6792,6796,6798,6802,6804,6808,6812,6816,6820,6824,6826,6830,6832,6836,6840,6842,6856,6860,6862,6866],{"level":4006},[4008,6773,6774],{"id":4010},[860,6775,3820],{},[856,6777,4015],{},[4008,6779,4019,6780],{"id":4018},[860,6781,4022],{},[856,6783,4025,6784,4029],{},[860,6785,4028],{},[4008,6787,6788],{"id":4032},[860,6789,1956],{},[856,6791,4037],{},[4008,6793,6794],{"id":4040},[860,6795,2062],{},[856,6797,4045],{},[4008,6799,6800],{"id":4048},[860,6801,2134],{},[856,6803,4053],{},[4008,6805,6806,4059],{"id":4056},[860,6807,2192],{},[856,6809,4062,6810,2362],{},[860,6811,2202],{},[4008,6813,6814],{"id":4067},[860,6815,4070],{},[856,6817,4073,6818,4077],{},[860,6819,4076],{},[4008,6821,6822],{"id":4080},[860,6823,4083],{},[856,6825,4086],{},[4008,6827,6828],{"id":4089},[860,6829,4092],{},[856,6831,4095],{},[4008,6833,6834,4102],{"id":4098},[860,6835,4101],{},[856,6837,4105,6838,899],{},[860,6839,4108],{},[4008,6841,4112],{"id":4111},[856,6843,6844,4118,6846,4118,6848,4118,6850,4118,6852,4118,6854],{},[860,6845,4117],{},[860,6847,4121],{},[860,6849,4124],{},[860,6851,4127],{},[860,6853,4130],{},[860,6855,4133],{},[4008,6857,6858],{"id":4136},[860,6859,3637],{},[856,6861,4141],{},[4008,6863,6864],{"id":4144},[860,6865,3688],{},[856,6867,4149],{},[4151,6869,4153],{},{"title":944,"searchDepth":1709,"depth":1709,"links":6871},[6872,6879,6886,6891,6894,6898,6901,6905],{"id":906,"depth":1709,"text":907,"children":6873},[6874,6875,6876,6877,6878],{"id":917,"depth":1717,"text":920},{"id":1104,"depth":1717,"text":1107},{"id":1243,"depth":1717,"text":1246},{"id":1379,"depth":1717,"text":913},{"id":1755,"depth":1717,"text":1758},{"id":1944,"depth":1709,"text":1945,"children":6880},[6881,6882,6883,6884,6885],{"id":1956,"depth":1717,"text":1956},{"id":2062,"depth":1717,"text":2062},{"id":2131,"depth":1717,"text":2134},{"id":2189,"depth":1717,"text":2192},{"id":2367,"depth":1717,"text":2370},{"id":2563,"depth":1709,"text":2564,"children":6887},[6888,6889,6890],{"id":2570,"depth":1717,"text":2573},{"id":2741,"depth":1717,"text":2744},{"id":2911,"depth":1717,"text":2914},{"id":3172,"depth":1709,"text":3173,"children":6892},[6893],{"id":3176,"depth":1717,"text":1234},{"id":3624,"depth":1709,"text":3625,"children":6895},[6896,6897],{"id":3634,"depth":1717,"text":3637},{"id":3685,"depth":1717,"text":3688},{"id":3814,"depth":1709,"text":143,"children":6899},[6900],{"id":3817,"depth":1717,"text":3820},{"id":3908,"depth":1709,"text":3909,"children":6902},[6903,6904],{"id":3915,"depth":1717,"text":3918},{"id":3977,"depth":1717,"text":3980},{"id":3995,"depth":1709,"text":3996},{},{"title":250,"description":4190},1780436284648]