[{"data":1,"prerenderedAt":3156},["ShallowReactive",2],{"navLinks":3,"sidebar_docs_navigation_\u002Fdocs\u002Fauth-h3client":64,"navigation":217,"navLinks_footer":829,"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth_page":842,"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth_surround":2210,"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth":2213},{"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":20,"path":22,"stem":70,"children":71},"docs\u002Fauth-h3client\u002Findex",[72,73,82,119,145,167,170,191,195],{"title":20,"path":22,"stem":70},{"title":14,"path":74,"stem":75,"children":76},"\u002Fdocs\u002Fauth-h3client\u002Fgetting-started","docs\u002Fauth-h3client\u002F00.getting-started\u002Findex",[77,78],{"title":14,"path":74,"stem":75},{"title":79,"path":80,"stem":81},"Nuxt Module","\u002Fdocs\u002Fauth-h3client\u002Fgetting-started\u002Fnuxt","docs\u002Fauth-h3client\u002F00.getting-started\u002F00.nuxt",{"title":83,"path":84,"stem":85,"children":86},"Essentials","\u002Fdocs\u002Fauth-h3client\u002Fessentials","docs\u002Fauth-h3client\u002F01.essentials\u002Findex",[87,88,92,96,100,104,108,111,115],{"title":83,"path":84,"stem":85},{"title":89,"path":90,"stem":91},"Session Management","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fsession","docs\u002Fauth-h3client\u002F01.essentials\u002F00.session",{"title":93,"path":94,"stem":95},"Route Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Froute-protection","docs\u002Fauth-h3client\u002F01.essentials\u002F01.route-protection",{"title":97,"path":98,"stem":99},"CSRF Protection","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcsrf","docs\u002Fauth-h3client\u002F01.essentials\u002F02.csrf",{"title":101,"path":102,"stem":103},"Auth Flows","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fauth-flows","docs\u002Fauth-h3client\u002F01.essentials\u002F03.auth-flows",{"title":105,"path":106,"stem":107},"OAuth and OIDC","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Foauth","docs\u002Fauth-h3client\u002F01.essentials\u002F04.oauth",{"title":33,"path":109,"stem":110},"\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fbot-detection","docs\u002Fauth-h3client\u002F01.essentials\u002F05.bot-detection",{"title":112,"path":113,"stem":114},"Cookies","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Fcookies","docs\u002Fauth-h3client\u002F01.essentials\u002F06.cookies",{"title":116,"path":117,"stem":118},"Logging","\u002Fdocs\u002Fauth-h3client\u002Fessentials\u002Flogging","docs\u002Fauth-h3client\u002F01.essentials\u002F07.logging",{"title":120,"path":121,"stem":122,"children":123},"MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa","docs\u002Fauth-h3client\u002F02.mfa\u002Findex",[124,125,129,133,137,141],{"title":120,"path":121,"stem":122},{"title":126,"path":127,"stem":128},"Built-in MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fbuilt-in-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F01.built-in-flow",{"title":130,"path":131,"stem":132},"Password Reset","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fpassword-reset","docs\u002Fauth-h3client\u002F02.mfa\u002F02.password-reset",{"title":134,"path":135,"stem":136},"Email Change","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Femail-change","docs\u002Fauth-h3client\u002F02.mfa\u002F03.email-change",{"title":138,"path":139,"stem":140},"Custom MFA Flow","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fcustom-flow","docs\u002Fauth-h3client\u002F02.mfa\u002F04.custom-flow",{"title":142,"path":143,"stem":144},"Client-Side MFA","\u002Fdocs\u002Fauth-h3client\u002Fmfa\u002Fclient-side","docs\u002Fauth-h3client\u002F02.mfa\u002F05.client-side",{"title":146,"path":147,"stem":148,"children":149},"Client-side","\u002Fdocs\u002Fauth-h3client\u002Fclient","docs\u002Fauth-h3client\u002F03.client\u002Findex",[150,151,155,159,163],{"title":146,"path":147,"stem":148},{"title":152,"path":153,"stem":154},"useAuthData","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-auth-data","docs\u002Fauth-h3client\u002F03.client\u002F00.use-auth-data",{"title":156,"path":157,"stem":158},"useMagicLink","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fuse-magic-link","docs\u002Fauth-h3client\u002F03.client\u002F01.use-magic-link",{"title":160,"path":161,"stem":162},"executeRequest","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fexecute-request","docs\u002Fauth-h3client\u002F03.client\u002F02.execute-request",{"title":164,"path":165,"stem":166},"getCsrfToken","\u002Fdocs\u002Fauth-h3client\u002Fclient\u002Fget-csrf-token","docs\u002Fauth-h3client\u002F03.client\u002F03.get-csrf-token",{"title":38,"path":168,"stem":169},"\u002Fdocs\u002Fauth-h3client\u002Fsecurity","docs\u002Fauth-h3client\u002F04.security",{"title":171,"path":172,"stem":173,"children":174,"page":53},"Guides","\u002Fdocs\u002Fauth-h3client\u002Fguides","docs\u002Fauth-h3client\u002F05.guides",[175,179,183,187],{"title":176,"path":177,"stem":178},"H3 and Nitro Setup","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fh3-nitro","docs\u002Fauth-h3client\u002F05.guides\u002F00.h3-nitro",{"title":180,"path":181,"stem":182},"HMAC Inter-service Auth","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fhmac","docs\u002Fauth-h3client\u002F05.guides\u002Fhmac",{"title":184,"path":185,"stem":186},"Image Upload","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fimage-upload","docs\u002Fauth-h3client\u002F05.guides\u002Fimage-upload",{"title":188,"path":189,"stem":190},"mTLS Configuration","\u002Fdocs\u002Fauth-h3client\u002Fguides\u002Fmtls","docs\u002Fauth-h3client\u002F05.guides\u002Fmtls",{"title":192,"path":193,"stem":194},"Configuration","\u002Fdocs\u002Fauth-h3client\u002Fconfiguration","docs\u002Fauth-h3client\u002F06.configuration",{"title":196,"path":197,"stem":198,"children":199},"API Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi","docs\u002Fauth-h3client\u002F07.api\u002Findex",[200,201,205,209,213],{"title":196,"path":197,"stem":198},{"title":202,"path":203,"stem":204},"Routes Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcontrollers","docs\u002Fauth-h3client\u002F07.api\u002F00.controllers",{"title":206,"path":207,"stem":208},"Middleware Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fmiddleware","docs\u002Fauth-h3client\u002F07.api\u002F01.middleware",{"title":210,"path":211,"stem":212},"Client-side Reference","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Fcomposables","docs\u002Fauth-h3client\u002F07.api\u002F02.composables",{"title":214,"path":215,"stem":216},"Utilities","\u002Fdocs\u002Fauth-h3client\u002Fapi\u002Futilities","docs\u002Fauth-h3client\u002F07.api\u002F03.utilities",[218],{"title":9,"path":66,"stem":67,"children":219,"page":53},[220,268,386,391,569,636],{"title":20,"path":22,"stem":70,"children":221},[222,223,227,238,246,253,254,260,261],{"title":20,"path":22,"stem":70},{"title":14,"path":74,"stem":75,"children":224},[225,226],{"title":14,"path":74,"stem":75},{"title":79,"path":80,"stem":81},{"title":83,"path":84,"stem":85,"children":228},[229,230,231,232,233,234,235,236,237],{"title":83,"path":84,"stem":85},{"title":89,"path":90,"stem":91},{"title":93,"path":94,"stem":95},{"title":97,"path":98,"stem":99},{"title":101,"path":102,"stem":103},{"title":105,"path":106,"stem":107},{"title":33,"path":109,"stem":110},{"title":112,"path":113,"stem":114},{"title":116,"path":117,"stem":118},{"title":120,"path":121,"stem":122,"children":239},[240,241,242,243,244,245],{"title":120,"path":121,"stem":122},{"title":126,"path":127,"stem":128},{"title":130,"path":131,"stem":132},{"title":134,"path":135,"stem":136},{"title":138,"path":139,"stem":140},{"title":142,"path":143,"stem":144},{"title":146,"path":147,"stem":148,"children":247},[248,249,250,251,252],{"title":146,"path":147,"stem":148},{"title":152,"path":153,"stem":154},{"title":156,"path":157,"stem":158},{"title":160,"path":161,"stem":162},{"title":164,"path":165,"stem":166},{"title":38,"path":168,"stem":169},{"title":171,"path":172,"stem":173,"children":255,"page":53},[256,257,258,259],{"title":176,"path":177,"stem":178},{"title":180,"path":181,"stem":182},{"title":184,"path":185,"stem":186},{"title":188,"path":189,"stem":190},{"title":192,"path":193,"stem":194},{"title":196,"path":197,"stem":198,"children":262},[263,264,265,266,267],{"title":196,"path":197,"stem":198},{"title":202,"path":203,"stem":204},{"title":206,"path":207,"stem":208},{"title":210,"path":211,"stem":212},{"title":214,"path":215,"stem":216},{"title":269,"path":35,"stem":270,"children":271},"Bot Detector","docs\u002Fbot-detection\u002Findex",[272,273,276,280,284,303,377,380,383],{"title":269,"path":35,"stem":270},{"title":14,"path":274,"stem":275},"\u002Fdocs\u002Fbot-detection\u002Fgetting-started","docs\u002Fbot-detection\u002F00.getting-started",{"title":277,"path":278,"stem":279},"CLI","\u002Fdocs\u002Fbot-detection\u002Fcli","docs\u002Fbot-detection\u002F01.cli",{"title":281,"path":282,"stem":283},"Data Sources","\u002Fdocs\u002Fbot-detection\u002Fdata-sources","docs\u002Fbot-detection\u002F02.data-sources",{"title":171,"path":285,"stem":286,"children":287,"page":53},"\u002Fdocs\u002Fbot-detection\u002Fguides","docs\u002Fbot-detection\u002F03.guides",[288,292,296,299],{"title":289,"path":290,"stem":291},"Custom Checkers","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fcustom","docs\u002Fbot-detection\u002F03.guides\u002FCUSTOM",{"title":293,"path":294,"stem":295},"Scheduling Database Generation","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fgenerate","docs\u002Fbot-detection\u002F03.guides\u002FGENERATE",{"title":116,"path":297,"stem":298},"\u002Fdocs\u002Fbot-detection\u002Fguides\u002Flogging","docs\u002Fbot-detection\u002F03.guides\u002FLOGGING",{"title":300,"path":301,"stem":302},"Score Modes and Reputation Healing","\u002Fdocs\u002Fbot-detection\u002Fguides\u002Fscore","docs\u002Fbot-detection\u002F03.guides\u002FSCORE",{"title":304,"path":305,"stem":306,"children":307},"Checkers","\u002Fdocs\u002Fbot-detection\u002Fcheckers","docs\u002Fbot-detection\u002F04.checkers\u002Findex",[308,309,313,317,321,325,329,333,337,341,345,349,353,357,361,365,369,373],{"title":304,"path":305,"stem":306},{"title":310,"path":311,"stem":312},"IP Validation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fip-validation","docs\u002Fbot-detection\u002F04.checkers\u002F01.ip-validation",{"title":314,"path":315,"stem":316},"Good \u002F Bad Bot Verification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgood-bots","docs\u002Fbot-detection\u002F04.checkers\u002F02.good-bots",{"title":318,"path":319,"stem":320},"Browser & Device Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbrowser-device","docs\u002Fbot-detection\u002F04.checkers\u002F03.browser-device",{"title":322,"path":323,"stem":324},"Locale Map","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Flocale-map","docs\u002Fbot-detection\u002F04.checkers\u002F04.locale-map",{"title":326,"path":327,"stem":328},"Known Threats","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-threats","docs\u002Fbot-detection\u002F04.checkers\u002F05.known-threats",{"title":330,"path":331,"stem":332},"ASN Classification","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fasn-classification","docs\u002Fbot-detection\u002F04.checkers\u002F06.asn-classification",{"title":334,"path":335,"stem":336},"Tor Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftor-analysis","docs\u002Fbot-detection\u002F04.checkers\u002F07.tor-analysis",{"title":338,"path":339,"stem":340},"Timezone Consistency","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Ftimezone-consistency","docs\u002Fbot-detection\u002F04.checkers\u002F08.timezone-consistency",{"title":342,"path":343,"stem":344},"Honeypot","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fhoneypot","docs\u002Fbot-detection\u002F04.checkers\u002F09.honeypot",{"title":346,"path":347,"stem":348},"Known Bad IPs","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ips","docs\u002Fbot-detection\u002F04.checkers\u002F10.known-bad-ips",{"title":350,"path":351,"stem":352},"Behavior Rate","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fbehavior-rate","docs\u002Fbot-detection\u002F04.checkers\u002F11.behavior-rate",{"title":354,"path":355,"stem":356},"Proxy \u002F ISP \u002F Cookie","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fproxy-isp-cookies","docs\u002Fbot-detection\u002F04.checkers\u002F12.proxy-isp-cookies",{"title":358,"path":359,"stem":360},"Session Coherence","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fsession-coherence","docs\u002Fbot-detection\u002F04.checkers\u002F13.session-coherence",{"title":362,"path":363,"stem":364},"Velocity Fingerprint","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fvelocity-fingerprint","docs\u002Fbot-detection\u002F04.checkers\u002F14.velocity-fingerprint",{"title":366,"path":367,"stem":368},"UA & Header Analysis","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fua-header","docs\u002Fbot-detection\u002F04.checkers\u002F15.ua-header",{"title":370,"path":371,"stem":372},"Geolocation","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fgeolocation","docs\u002Fbot-detection\u002F04.checkers\u002F16.geolocation",{"title":374,"path":375,"stem":376},"Known Bad User-Agents","\u002Fdocs\u002Fbot-detection\u002Fcheckers\u002Fknown-bad-ua","docs\u002Fbot-detection\u002F04.checkers\u002F17.known-bad-ua",{"title":38,"path":378,"stem":379},"\u002Fdocs\u002Fbot-detection\u002Fsecurity","docs\u002Fbot-detection\u002F04.security",{"title":196,"path":381,"stem":382},"\u002Fdocs\u002Fbot-detection\u002Fapi","docs\u002Fbot-detection\u002F05.api",{"title":192,"path":384,"stem":385},"\u002Fdocs\u002Fbot-detection\u002Fconfiguration","docs\u002Fbot-detection\u002F06.configuration",{"title":387,"path":11,"stem":388,"children":389},"Introduction","docs\u002Fgetting-started\u002Findex",[390],{"title":387,"path":11,"stem":388},{"title":27,"path":29,"stem":392,"children":393},"docs\u002Fiam\u002Findex",[394,395,398,533,536,552,555],{"title":27,"path":29,"stem":392},{"title":14,"path":396,"stem":397},"\u002Fdocs\u002Fiam\u002Fgetting-started","docs\u002Fiam\u002F00.getting-started",{"title":83,"path":399,"stem":400,"children":401},"\u002Fdocs\u002Fiam\u002Fessentials","docs\u002Fiam\u002F01.essentials\u002Findex",[402,403,407,411,415,419,423,427,431,435,439,443,446,450,454,458,462,465,469,473,476,480,483],{"title":83,"path":399,"stem":400},{"title":404,"path":405,"stem":406},"Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Ftokens","docs\u002Fiam\u002F01.essentials\u002F00.tokens",{"title":408,"path":409,"stem":410},"Access Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Faccess-tokens","docs\u002Fiam\u002F01.essentials\u002F01.access-tokens",{"title":412,"path":413,"stem":414},"Refresh Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Frefresh-tokens","docs\u002Fiam\u002F01.essentials\u002F02.refresh-tokens",{"title":416,"path":417,"stem":418},"Anomaly Detection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fanomalies","docs\u002Fiam\u002F01.essentials\u002F03.anomalies",{"title":420,"path":421,"stem":422},"Signup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fsignup","docs\u002Fiam\u002F01.essentials\u002F04.signup",{"title":424,"path":425,"stem":426},"Login","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogin","docs\u002Fiam\u002F01.essentials\u002F05.login",{"title":428,"path":429,"stem":430},"Logout","\u002Fdocs\u002Fiam\u002Fessentials\u002Flogout","docs\u002Fiam\u002F01.essentials\u002F06.logout",{"title":432,"path":433,"stem":434},"OAuth","\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth","docs\u002Fiam\u002F01.essentials\u002F07.oauth",{"title":436,"path":437,"stem":438},"Magic Links","\u002Fdocs\u002Fiam\u002Fessentials\u002Fmagic-links","docs\u002Fiam\u002F01.essentials\u002F08.magic-links",{"title":440,"path":441,"stem":442},"Emails","\u002Fdocs\u002Fiam\u002Fessentials\u002Femails","docs\u002Fiam\u002F01.essentials\u002F09.emails",{"title":120,"path":444,"stem":445},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fmfa","docs\u002Fiam\u002F01.essentials\u002F10.mfa",{"title":447,"path":448,"stem":449},"Fingerprinting","\u002Fdocs\u002Fiam\u002Fessentials\u002Ffingerprinting","docs\u002Fiam\u002F01.essentials\u002F11.fingerprinting",{"title":451,"path":452,"stem":453},"Backend for Frontend","\u002Fdocs\u002Fiam\u002Fessentials\u002Fbff","docs\u002Fiam\u002F01.essentials\u002F12.bff",{"title":455,"path":456,"stem":457},"HMAC Authentication","\u002Fdocs\u002Fiam\u002Fessentials\u002Fhmac","docs\u002Fiam\u002F01.essentials\u002F13.hmac",{"title":459,"path":460,"stem":461},"XSS Protection","\u002Fdocs\u002Fiam\u002Fessentials\u002Fxss","docs\u002Fiam\u002F01.essentials\u002F14.xss",{"title":116,"path":463,"stem":464},"\u002Fdocs\u002Fiam\u002Fessentials\u002Flogging","docs\u002Fiam\u002F01.essentials\u002F15.logging",{"title":466,"path":467,"stem":468},"Rate Limiting","\u002Fdocs\u002Fiam\u002Fessentials\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F16.rate-limiting",{"title":470,"path":471,"stem":472},"Database","\u002Fdocs\u002Fiam\u002Fessentials\u002Fdatabase","docs\u002Fiam\u002F01.essentials\u002F17.database",{"title":112,"path":474,"stem":475},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fcookies","docs\u002Fiam\u002F01.essentials\u002F18.cookies",{"title":477,"path":478,"stem":479},"Service Startup","\u002Fdocs\u002Fiam\u002Fessentials\u002Fservice","docs\u002Fiam\u002F01.essentials\u002F19.service",{"title":130,"path":481,"stem":482},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fpassword-reset","docs\u002Fiam\u002F01.essentials\u002F20.password-reset",{"title":484,"path":485,"stem":486,"children":487},"API Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi","docs\u002Fiam\u002F01.essentials\u002F21.api\u002Findex",[488,489,493,497,527,530],{"title":484,"path":485,"stem":486},{"title":490,"path":491,"stem":492},"Creating Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fcreation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F00.creation",{"title":494,"path":495,"stem":496},"Verifying Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fverification","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F01.verification",{"title":498,"path":499,"stem":500,"children":501},"Manage Tokens","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002Findex",[502,503,507,511,515,519,523],{"title":498,"path":499,"stem":500},{"title":504,"path":505,"stem":506},"Privileges","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fprivilege","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F00.privilege",{"title":508,"path":509,"stem":510},"Revocation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frevocation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F01.revocation",{"title":512,"path":513,"stem":514},"Rotation","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Frotation","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F02.rotation",{"title":516,"path":517,"stem":518},"IP Restriction","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fip-updates","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F03.ip-updates",{"title":520,"path":521,"stem":522},"Metadata","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Fmetadata","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F04.metadata",{"title":524,"path":525,"stem":526},"Token Listing","\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fmanagement\u002Flist","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F02.management\u002F05.list",{"title":466,"path":528,"stem":529},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Frate-limiting","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F03.rate-limiting",{"title":38,"path":531,"stem":532},"\u002Fdocs\u002Fiam\u002Fessentials\u002Fapi\u002Fsecurity","docs\u002Fiam\u002F01.essentials\u002F21.api\u002F04.security",{"title":38,"path":534,"stem":535},"\u002Fdocs\u002Fiam\u002Fsecurity","docs\u002Fiam\u002F02.security",{"title":171,"path":537,"stem":538,"children":539,"page":53},"\u002Fdocs\u002Fiam\u002Fguides","docs\u002Fiam\u002F03.guides",[540,544,548],{"title":541,"path":542,"stem":543},"Deployment","\u002Fdocs\u002Fiam\u002Fguides\u002Fdeployment","docs\u002Fiam\u002F03.guides\u002Fdeployment",{"title":545,"path":546,"stem":547},"Operation Scripts","\u002Fdocs\u002Fiam\u002Fguides\u002Foperation-scripts","docs\u002Fiam\u002F03.guides\u002Foperation-scripts",{"title":549,"path":550,"stem":551},"Role-Based Access Control","\u002Fdocs\u002Fiam\u002Fguides\u002Frbac","docs\u002Fiam\u002F03.guides\u002Frbac",{"title":192,"path":553,"stem":554},"\u002Fdocs\u002Fiam\u002Fconfiguration","docs\u002Fiam\u002F04.configuration",{"title":556,"path":557,"stem":558,"children":559,"page":53},"Api","\u002Fdocs\u002Fiam\u002Fapi","docs\u002Fiam\u002F05.API",[560,563,566],{"title":196,"path":561,"stem":562},"\u002Fdocs\u002Fiam\u002Fapi\u002Fapi","docs\u002Fiam\u002F05.API\u002F00.api",{"title":206,"path":564,"stem":565},"\u002Fdocs\u002Fiam\u002Fapi\u002Fmiddlewares","docs\u002Fiam\u002F05.API\u002F02.middlewares",{"title":202,"path":567,"stem":568},"\u002Fdocs\u002Fiam\u002Fapi\u002Froutes","docs\u002Fiam\u002F05.API\u002F03.routes",{"title":40,"path":42,"stem":570,"children":571},"docs\u002Fshield-base\u002Findex",[572,573,576,580,621,625,629,633],{"title":40,"path":42,"stem":570},{"title":14,"path":574,"stem":575},"\u002Fdocs\u002Fshield-base\u002Fgetting-started","docs\u002Fshield-base\u002F00.getting-started",{"title":577,"path":578,"stem":579},"CLI Reference","\u002Fdocs\u002Fshield-base\u002Fcli","docs\u002Fshield-base\u002F01.cli",{"title":281,"path":581,"stem":582,"children":583},"\u002Fdocs\u002Fshield-base\u002Fdata-sources","docs\u002Fshield-base\u002F02.data-sources\u002Findex",[584,585,589,593,597,601,605,609,613,617],{"title":281,"path":581,"stem":582},{"title":586,"path":587,"stem":588},"BGP \u002F ASN","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fbgp","docs\u002Fshield-base\u002F02.data-sources\u002Fbgp",{"title":590,"path":591,"stem":592},"City Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcity","docs\u002Fshield-base\u002F02.data-sources\u002Fcity",{"title":594,"path":595,"stem":596},"Country Geolocation","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcountry","docs\u002Fshield-base\u002F02.data-sources\u002Fcountry",{"title":598,"path":599,"stem":600},"Verified Crawlers","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fcrawlers","docs\u002Fshield-base\u002F02.data-sources\u002Fcrawlers",{"title":602,"path":603,"stem":604},"Disposable Emails","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Femail","docs\u002Fshield-base\u002F02.data-sources\u002Femail",{"title":606,"path":607,"stem":608},"FireHOL Threat Intelligence","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ffirehol","docs\u002Fshield-base\u002F02.data-sources\u002Ffirehol",{"title":610,"path":611,"stem":612},"Proxy Detection","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fproxy","docs\u002Fshield-base\u002F02.data-sources\u002Fproxy",{"title":614,"path":615,"stem":616},"Tor Nodes","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Ftor","docs\u002Fshield-base\u002F02.data-sources\u002Ftor",{"title":618,"path":619,"stem":620},"Suspicious User-Agents","\u002Fdocs\u002Fshield-base\u002Fdata-sources\u002Fuseragent","docs\u002Fshield-base\u002F02.data-sources\u002Fuseragent",{"title":622,"path":623,"stem":624},"Programmatic Usage","\u002Fdocs\u002Fshield-base\u002Fusage","docs\u002Fshield-base\u002F03.usage",{"title":626,"path":627,"stem":628},"Custom Data Sources","\u002Fdocs\u002Fshield-base\u002Fcustom-data-sources","docs\u002Fshield-base\u002F04.custom-data-sources",{"title":630,"path":631,"stem":632},"TypeScript Types","\u002Fdocs\u002Fshield-base\u002Ftypes","docs\u002Fshield-base\u002F05.types",{"title":196,"path":634,"stem":635},"\u002Fdocs\u002Fshield-base\u002Fapi","docs\u002Fshield-base\u002F06.api",{"title":214,"path":48,"stem":637,"children":638},"docs\u002Futils\u002Findex",[639,640,657,690,787],{"title":214,"path":48,"stem":637},{"title":641,"path":642,"stem":643,"children":644,"page":53},"Eslint","\u002Fdocs\u002Futils\u002Feslint","docs\u002Futils\u002Feslint",[645,649,653],{"title":646,"path":647,"stem":648},"React Config","\u002Fdocs\u002Futils\u002Feslint\u002Freact","docs\u002Futils\u002Feslint\u002Freact",{"title":650,"path":651,"stem":652},"TypeScript Config","\u002Fdocs\u002Futils\u002Feslint\u002Ftypescript","docs\u002Futils\u002Feslint\u002Ftypescript",{"title":654,"path":655,"stem":656},"Vue Config","\u002Fdocs\u002Futils\u002Feslint\u002Fvue","docs\u002Futils\u002Feslint\u002Fvue",{"title":658,"path":659,"stem":660,"children":661,"page":53},"Server","\u002Fdocs\u002Futils\u002Fserver","docs\u002Futils\u002Fserver",[662,666,670,674,678,682,686],{"title":663,"path":664,"stem":665},"Encryption","\u002Fdocs\u002Futils\u002Fserver\u002Fencryption","docs\u002Futils\u002Fserver\u002Fencryption",{"title":667,"path":668,"stem":669},"Path Resolver","\u002Fdocs\u002Futils\u002Fserver\u002Fpathresolver","docs\u002Futils\u002Fserver\u002FpathResolver",{"title":671,"path":672,"stem":673},"File Replacements","\u002Fdocs\u002Futils\u002Fserver\u002Freplace","docs\u002Futils\u002Fserver\u002Freplace",{"title":675,"path":676,"stem":677},"run","\u002Fdocs\u002Futils\u002Fserver\u002Frun","docs\u002Futils\u002Fserver\u002Frun",{"title":679,"path":680,"stem":681},"scheduleTask","\u002Fdocs\u002Futils\u002Fserver\u002Fscheduletask","docs\u002Futils\u002Fserver\u002FscheduleTask",{"title":683,"path":684,"stem":685},"spawnRun","\u002Fdocs\u002Futils\u002Fserver\u002Fspawnrun","docs\u002Futils\u002Fserver\u002FspawnRun",{"title":687,"path":688,"stem":689},"uploadCsv","\u002Fdocs\u002Futils\u002Fserver\u002Fuploadcsv","docs\u002Futils\u002Fserver\u002FuploadCsv",{"title":691,"path":692,"stem":693,"children":694,"page":53},"Shared","\u002Fdocs\u002Futils\u002Fshared","docs\u002Futils\u002Fshared",[695,699,703,707,711,715,719,723,727,731,735,739,743,747,751,755,759,763,767,771,775,779,783],{"title":696,"path":697,"stem":698},"BatchQueue","\u002Fdocs\u002Futils\u002Fshared\u002Fbatchqueue","docs\u002Futils\u002Fshared\u002FbatchQueue",{"title":700,"path":701,"stem":702},"capitalize","\u002Fdocs\u002Futils\u002Fshared\u002Fcapitalize","docs\u002Futils\u002Fshared\u002Fcapitalize",{"title":704,"path":705,"stem":706},"chunkProcess","\u002Fdocs\u002Futils\u002Fshared\u002Fchunkprocess","docs\u002Futils\u002Fshared\u002FchunkProcess",{"title":708,"path":709,"stem":710},"cleanObject","\u002Fdocs\u002Futils\u002Fshared\u002Fcleanobject","docs\u002Futils\u002Fshared\u002FcleanObject",{"title":712,"path":713,"stem":714},"createConfigManager","\u002Fdocs\u002Futils\u002Fshared\u002Fconfigurationdefiner","docs\u002Futils\u002Fshared\u002FconfigurationDefiner",{"title":716,"path":717,"stem":718},"debounce","\u002Fdocs\u002Futils\u002Fshared\u002Fdebounce","docs\u002Futils\u002Fshared\u002Fdebounce",{"title":720,"path":721,"stem":722},"ensureArray","\u002Fdocs\u002Futils\u002Fshared\u002Fensurearray","docs\u002Futils\u002Fshared\u002FensureArray",{"title":724,"path":725,"stem":726},"fetchWithRetry","\u002Fdocs\u002Futils\u002Fshared\u002Ffetchwithretry","docs\u002Futils\u002Fshared\u002FfetchWithRetry",{"title":728,"path":729,"stem":730},"filterEmptyValues","\u002Fdocs\u002Futils\u002Fshared\u002Ffilteremptyvalues","docs\u002Futils\u002Fshared\u002FfilterEmptyValues",{"title":732,"path":733,"stem":734},"findStringsInObject","\u002Fdocs\u002Futils\u002Fshared\u002Ffindobjectvalues","docs\u002Futils\u002Fshared\u002FfindObjectValues",{"title":736,"path":737,"stem":738},"fisherYatesShuffle","\u002Fdocs\u002Futils\u002Fshared\u002Ffisheryatesshuffle","docs\u002Futils\u002Fshared\u002FfisherYatesShuffle",{"title":740,"path":741,"stem":742},"getRandomImage","\u002Fdocs\u002Futils\u002Fshared\u002Fgetrandomimage","docs\u002Futils\u002Fshared\u002FgetRandomImage",{"title":744,"path":745,"stem":746},"isObjectHasValues","\u002Fdocs\u002Futils\u002Fshared\u002Fisobjecthasvalues","docs\u002Futils\u002Fshared\u002FisObjectHasValues",{"title":748,"path":749,"stem":750},"isAsyncOrPromise","\u002Fdocs\u002Futils\u002Fshared\u002Fispromise","docs\u002Futils\u002Fshared\u002FisPromise",{"title":752,"path":753,"stem":754},"MiniCache","\u002Fdocs\u002Futils\u002Fshared\u002Fminicache","docs\u002Futils\u002Fshared\u002FminiCache",{"title":756,"path":757,"stem":758},"parseCookies","\u002Fdocs\u002Futils\u002Fshared\u002Fparserawcookies","docs\u002Futils\u002Fshared\u002FparseRawCookies",{"title":760,"path":761,"stem":762},"safeAction","\u002Fdocs\u002Futils\u002Fshared\u002Fpromiselocker","docs\u002Futils\u002Fshared\u002FpromiseLocker",{"title":764,"path":765,"stem":766},"Random","\u002Fdocs\u002Futils\u002Fshared\u002Frandom","docs\u002Futils\u002Fshared\u002Frandom",{"title":768,"path":769,"stem":770},"range","\u002Fdocs\u002Futils\u002Fshared\u002Frange","docs\u002Futils\u002Fshared\u002Frange",{"title":772,"path":773,"stem":774},"rateLimiters","\u002Fdocs\u002Futils\u002Fshared\u002Fratelimiters","docs\u002Futils\u002Fshared\u002FrateLimiters",{"title":776,"path":777,"stem":778},"safeObjectMerge","\u002Fdocs\u002Futils\u002Fshared\u002Fsafemerge","docs\u002Futils\u002Fshared\u002FsafeMerge",{"title":780,"path":781,"stem":782},"textTruncation","\u002Fdocs\u002Futils\u002Fshared\u002Ftexttruncation","docs\u002Futils\u002Fshared\u002FtextTruncation",{"title":784,"path":785,"stem":786},"validateZodSchema","\u002Fdocs\u002Futils\u002Fshared\u002Fvalidatezodschema","docs\u002Futils\u002Fshared\u002FvalidateZodSchema",{"title":788,"path":789,"stem":790,"children":791},"Utility Types","\u002Fdocs\u002Futils\u002Ftypes","docs\u002Futils\u002Ftypes\u002Findex",[792,793,797,801,805,809,813,817,821,825],{"title":788,"path":789,"stem":790},{"title":794,"path":795,"stem":796},"Brand","\u002Fdocs\u002Futils\u002Ftypes\u002Fbrand","docs\u002Futils\u002Ftypes\u002FBrand",{"title":798,"path":799,"stem":800},"DeepPartial","\u002Fdocs\u002Futils\u002Ftypes\u002Fdeeppartial","docs\u002Futils\u002Ftypes\u002FDeepPartial",{"title":802,"path":803,"stem":804},"Merge","\u002Fdocs\u002Futils\u002Ftypes\u002Fmerge","docs\u002Futils\u002Ftypes\u002FMerge",{"title":806,"path":807,"stem":808},"NonNullable","\u002Fdocs\u002Futils\u002Ftypes\u002Fnonnullable","docs\u002Futils\u002Ftypes\u002FNonNullable",{"title":810,"path":811,"stem":812},"Prettify","\u002Fdocs\u002Futils\u002Ftypes\u002Fprettify","docs\u002Futils\u002Ftypes\u002FPrettify",{"title":814,"path":815,"stem":816},"PromiseType","\u002Fdocs\u002Futils\u002Ftypes\u002Fpromisetype","docs\u002Futils\u002Ftypes\u002FPromiseType",{"title":818,"path":819,"stem":820},"RequireKeys","\u002Fdocs\u002Futils\u002Ftypes\u002Frequirekeys","docs\u002Futils\u002Ftypes\u002FRequireKeys",{"title":822,"path":823,"stem":824},"StandardResponse","\u002Fdocs\u002Futils\u002Ftypes\u002Fstandardresponse","docs\u002Futils\u002Ftypes\u002FStandardResponse",{"title":826,"path":827,"stem":828},"ValueOf","\u002Fdocs\u002Futils\u002Ftypes\u002Fvalueof","docs\u002Futils\u002Ftypes\u002FValueOf",{"id":4,"extension":5,"links":830,"meta":841,"stem":62,"__hash__":63},[831,839,840],{"nested":8,"label":9,"icon":10,"to":11,"children":832},[833,834,835,836,837,838],{"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":843,"title":105,"body":844,"description":2202,"extension":2203,"icon":2204,"meta":2205,"module":2206,"navigation":8,"path":106,"rawbody":2207,"seo":2208,"stem":107,"__hash__":2209},"docs\u002Fdocs\u002Fauth-h3client\u002F01.essentials\u002F04.oauth.md",{"type":845,"value":846,"toc":2186},"minimark",[847,851,854,859,875,880,891,1194,1198,1201,1398,1402,1533,1557,1559,1563,1573,1588,1591,1636,1662,1668,1771,1773,1777,1788,1794,1797,1975,1996,2002,2005,2090,2092,2096,2099,2169,2171,2175,2182],[848,849,850],"p",{},"The module handles the complete OAuth and OIDC authorization code flow at the gateway level. The browser never sees provider tokens or client secrets. Two handlers manage the flow: one that builds the authorization URL and redirects the user, and one that handles the provider callback, exchanges the code for tokens, verifies the result, and proxies the user data to the IAM service.",[852,853],"hr",{},[855,856,858],"h2",{"id":857},"provider-configuration","Provider configuration",[848,860,861,862,866,867,870,871,874],{},"Providers are defined in the ",[863,864,865],"code",{},"OAuthProviders"," array in the configuration. Each provider is either an OIDC provider (",[863,868,869],{},"kind: 'oidc'",") or a generic OAuth provider (",[863,872,873],{},"kind: 'oauth'",").",[876,877,879],"h3",{"id":878},"oidc-provider","OIDC provider",[848,881,882,883,886,887,890],{},"OIDC providers expose a discovery document at ",[863,884,885],{},"\u002F.well-known\u002Fopenid-configuration",". The module fetches this document automatically using the ",[863,888,889],{},"issuer"," URL to discover the authorization and token endpoints. Use this kind for Google, Microsoft, Okta, and any provider that supports OpenID Connect.",[892,893,899],"pre",{"className":894,"code":895,"filename":896,"language":897,"meta":898,"style":898},"language-ts shiki shiki-themes light-plus light-plus dracula","OAuthProviders: [\n  {\n    kind: 'oidc',\n    name: 'google',\n    issuer: 'https:\u002F\u002Faccounts.google.com',\n    clientId: process.env.OAUTH_GOOGLE_CLIENT_ID!,\n    clientSecret: process.env.OAUTH_GOOGLE_CLIENT_SECRET!,\n    redirectUri: 'https:\u002F\u002Fapp.example.com\u002Foauth\u002Fcallback\u002Fgoogle',\n    defaultScopes: ['openid', 'email', 'profile'],\n    supportPKCE: true,\n    redirectUrlOnSuccess: 'https:\u002F\u002Fapp.example.com\u002Fdashboard',\n    redirectUrlOnError: 'https:\u002F\u002Fapp.example.com\u002Flogin',\n    extraAuthParams: {\n      access_type: 'offline',\n      prompt: 'consent'\n    }\n  }\n]\n","server\u002Fplugins\u002Fauth.ts","ts","",[863,900,901,910,916,941,958,975,1004,1027,1044,1084,1098,1115,1132,1143,1160,1176,1182,1188],{"__ignoreMap":898},[902,903,906],"span",{"class":904,"line":905},"line",1,[902,907,909],{"class":908},"sDd4n","OAuthProviders: [\n",[902,911,913],{"class":904,"line":912},2,[902,914,915],{"class":908},"  {\n",[902,917,919,923,927,931,935,938],{"class":904,"line":918},3,[902,920,922],{"class":921},"sjsA6","    kind",[902,924,926],{"class":925},"s34zl",":",[902,928,930],{"class":929},"sFkSl"," '",[902,932,934],{"class":933},"sFB1V","oidc",[902,936,937],{"class":929},"'",[902,939,940],{"class":908},",\n",[902,942,944,947,949,951,954,956],{"class":904,"line":943},4,[902,945,946],{"class":921},"    name",[902,948,926],{"class":925},[902,950,930],{"class":929},[902,952,953],{"class":933},"google",[902,955,937],{"class":929},[902,957,940],{"class":908},[902,959,961,964,966,968,971,973],{"class":904,"line":960},5,[902,962,963],{"class":921},"    issuer",[902,965,926],{"class":925},[902,967,930],{"class":929},[902,969,970],{"class":933},"https:\u002F\u002Faccounts.google.com",[902,972,937],{"class":929},[902,974,940],{"class":908},[902,976,978,981,983,986,989,992,994,998,1002],{"class":904,"line":977},6,[902,979,980],{"class":921},"    clientId",[902,982,926],{"class":925},[902,984,985],{"class":921}," process",[902,987,988],{"class":908},".",[902,990,991],{"class":921},"env",[902,993,988],{"class":908},[902,995,997],{"class":996},"sPzPf","OAUTH_GOOGLE_CLIENT_ID",[902,999,1001],{"class":1000},"saOXh","!",[902,1003,940],{"class":908},[902,1005,1007,1010,1012,1014,1016,1018,1020,1023,1025],{"class":904,"line":1006},7,[902,1008,1009],{"class":921},"    clientSecret",[902,1011,926],{"class":925},[902,1013,985],{"class":921},[902,1015,988],{"class":908},[902,1017,991],{"class":921},[902,1019,988],{"class":908},[902,1021,1022],{"class":996},"OAUTH_GOOGLE_CLIENT_SECRET",[902,1024,1001],{"class":1000},[902,1026,940],{"class":908},[902,1028,1030,1033,1035,1037,1040,1042],{"class":904,"line":1029},8,[902,1031,1032],{"class":921},"    redirectUri",[902,1034,926],{"class":925},[902,1036,930],{"class":929},[902,1038,1039],{"class":933},"https:\u002F\u002Fapp.example.com\u002Foauth\u002Fcallback\u002Fgoogle",[902,1041,937],{"class":929},[902,1043,940],{"class":908},[902,1045,1047,1050,1052,1055,1057,1060,1062,1065,1067,1070,1072,1074,1076,1079,1081],{"class":904,"line":1046},9,[902,1048,1049],{"class":921},"    defaultScopes",[902,1051,926],{"class":925},[902,1053,1054],{"class":908}," [",[902,1056,937],{"class":929},[902,1058,1059],{"class":933},"openid",[902,1061,937],{"class":929},[902,1063,1064],{"class":908},", ",[902,1066,937],{"class":929},[902,1068,1069],{"class":933},"email",[902,1071,937],{"class":929},[902,1073,1064],{"class":908},[902,1075,937],{"class":929},[902,1077,1078],{"class":933},"profile",[902,1080,937],{"class":929},[902,1082,1083],{"class":908},"],\n",[902,1085,1087,1090,1092,1096],{"class":904,"line":1086},10,[902,1088,1089],{"class":921},"    supportPKCE",[902,1091,926],{"class":925},[902,1093,1095],{"class":1094},"sjR7W"," true",[902,1097,940],{"class":908},[902,1099,1101,1104,1106,1108,1111,1113],{"class":904,"line":1100},11,[902,1102,1103],{"class":921},"    redirectUrlOnSuccess",[902,1105,926],{"class":925},[902,1107,930],{"class":929},[902,1109,1110],{"class":933},"https:\u002F\u002Fapp.example.com\u002Fdashboard",[902,1112,937],{"class":929},[902,1114,940],{"class":908},[902,1116,1118,1121,1123,1125,1128,1130],{"class":904,"line":1117},12,[902,1119,1120],{"class":921},"    redirectUrlOnError",[902,1122,926],{"class":925},[902,1124,930],{"class":929},[902,1126,1127],{"class":933},"https:\u002F\u002Fapp.example.com\u002Flogin",[902,1129,937],{"class":929},[902,1131,940],{"class":908},[902,1133,1135,1138,1140],{"class":904,"line":1134},13,[902,1136,1137],{"class":921},"    extraAuthParams",[902,1139,926],{"class":925},[902,1141,1142],{"class":908}," {\n",[902,1144,1146,1149,1151,1153,1156,1158],{"class":904,"line":1145},14,[902,1147,1148],{"class":921},"      access_type",[902,1150,926],{"class":925},[902,1152,930],{"class":929},[902,1154,1155],{"class":933},"offline",[902,1157,937],{"class":929},[902,1159,940],{"class":908},[902,1161,1163,1166,1168,1170,1173],{"class":904,"line":1162},15,[902,1164,1165],{"class":921},"      prompt",[902,1167,926],{"class":925},[902,1169,930],{"class":929},[902,1171,1172],{"class":933},"consent",[902,1174,1175],{"class":929},"'\n",[902,1177,1179],{"class":904,"line":1178},16,[902,1180,1181],{"class":908},"    }\n",[902,1183,1185],{"class":904,"line":1184},17,[902,1186,1187],{"class":908},"  }\n",[902,1189,1191],{"class":904,"line":1190},18,[902,1192,1193],{"class":908},"]\n",[876,1195,1197],{"id":1196},"generic-oauth-provider","Generic OAuth provider",[848,1199,1200],{},"Generic OAuth providers require explicit endpoint URLs. Use this kind for GitHub, X (Twitter), LinkedIn, and any provider that does not support OIDC discovery.",[892,1202,1204],{"className":894,"code":1203,"language":897,"meta":898,"style":898},"{\n  kind: 'oauth',\n  name: 'github',\n  authorizationEndpoint: 'https:\u002F\u002Fgithub.com\u002Flogin\u002Foauth\u002Fauthorize',\n  tokenEndpoint: 'https:\u002F\u002Fgithub.com\u002Flogin\u002Foauth\u002Faccess_token',\n  userInfoEndpoint: 'https:\u002F\u002Fapi.github.com\u002Fuser',\n  clientId: process.env.OAUTH_GITHUB_CLIENT_ID!,\n  clientSecret: process.env.OAUTH_GITHUB_CLIENT_SECRET!,\n  redirectUri: 'https:\u002F\u002Fapp.example.com\u002Foauth\u002Fcallback\u002Fgithub',\n  defaultScopes: ['read:user', 'user:email'],\n  supportPKCE: true,\n  redirectUrlOnSuccess: 'https:\u002F\u002Fapp.example.com\u002Fdashboard',\n  redirectUrlOnError: 'https:\u002F\u002Fapp.example.com\u002Flogin'\n}\n",[863,1205,1206,1211,1225,1239,1253,1267,1281,1302,1322,1336,1359,1369,1382,1393],{"__ignoreMap":898},[902,1207,1208],{"class":904,"line":905},[902,1209,1210],{"class":908},"{\n",[902,1212,1213,1216,1218,1221,1223],{"class":904,"line":912},[902,1214,1215],{"class":908},"  kind: ",[902,1217,937],{"class":929},[902,1219,1220],{"class":933},"oauth",[902,1222,937],{"class":929},[902,1224,940],{"class":908},[902,1226,1227,1230,1232,1235,1237],{"class":904,"line":918},[902,1228,1229],{"class":908},"  name: ",[902,1231,937],{"class":929},[902,1233,1234],{"class":933},"github",[902,1236,937],{"class":929},[902,1238,940],{"class":908},[902,1240,1241,1244,1246,1249,1251],{"class":904,"line":943},[902,1242,1243],{"class":908},"  authorizationEndpoint: ",[902,1245,937],{"class":929},[902,1247,1248],{"class":933},"https:\u002F\u002Fgithub.com\u002Flogin\u002Foauth\u002Fauthorize",[902,1250,937],{"class":929},[902,1252,940],{"class":908},[902,1254,1255,1258,1260,1263,1265],{"class":904,"line":960},[902,1256,1257],{"class":908},"  tokenEndpoint: ",[902,1259,937],{"class":929},[902,1261,1262],{"class":933},"https:\u002F\u002Fgithub.com\u002Flogin\u002Foauth\u002Faccess_token",[902,1264,937],{"class":929},[902,1266,940],{"class":908},[902,1268,1269,1272,1274,1277,1279],{"class":904,"line":977},[902,1270,1271],{"class":908},"  userInfoEndpoint: ",[902,1273,937],{"class":929},[902,1275,1276],{"class":933},"https:\u002F\u002Fapi.github.com\u002Fuser",[902,1278,937],{"class":929},[902,1280,940],{"class":908},[902,1282,1283,1286,1289,1291,1293,1295,1298,1300],{"class":904,"line":1006},[902,1284,1285],{"class":908},"  clientId: ",[902,1287,1288],{"class":921},"process",[902,1290,988],{"class":908},[902,1292,991],{"class":921},[902,1294,988],{"class":908},[902,1296,1297],{"class":996},"OAUTH_GITHUB_CLIENT_ID",[902,1299,1001],{"class":1000},[902,1301,940],{"class":908},[902,1303,1304,1307,1309,1311,1313,1315,1318,1320],{"class":904,"line":1029},[902,1305,1306],{"class":908},"  clientSecret: ",[902,1308,1288],{"class":921},[902,1310,988],{"class":908},[902,1312,991],{"class":921},[902,1314,988],{"class":908},[902,1316,1317],{"class":996},"OAUTH_GITHUB_CLIENT_SECRET",[902,1319,1001],{"class":1000},[902,1321,940],{"class":908},[902,1323,1324,1327,1329,1332,1334],{"class":904,"line":1046},[902,1325,1326],{"class":908},"  redirectUri: ",[902,1328,937],{"class":929},[902,1330,1331],{"class":933},"https:\u002F\u002Fapp.example.com\u002Foauth\u002Fcallback\u002Fgithub",[902,1333,937],{"class":929},[902,1335,940],{"class":908},[902,1337,1338,1341,1343,1346,1348,1350,1352,1355,1357],{"class":904,"line":1086},[902,1339,1340],{"class":908},"  defaultScopes: [",[902,1342,937],{"class":929},[902,1344,1345],{"class":933},"read:user",[902,1347,937],{"class":929},[902,1349,1064],{"class":908},[902,1351,937],{"class":929},[902,1353,1354],{"class":933},"user:email",[902,1356,937],{"class":929},[902,1358,1083],{"class":908},[902,1360,1361,1364,1367],{"class":904,"line":1100},[902,1362,1363],{"class":908},"  supportPKCE: ",[902,1365,1366],{"class":1094},"true",[902,1368,940],{"class":908},[902,1370,1371,1374,1376,1378,1380],{"class":904,"line":1117},[902,1372,1373],{"class":908},"  redirectUrlOnSuccess: ",[902,1375,937],{"class":929},[902,1377,1110],{"class":933},[902,1379,937],{"class":929},[902,1381,940],{"class":908},[902,1383,1384,1387,1389,1391],{"class":904,"line":1134},[902,1385,1386],{"class":908},"  redirectUrlOnError: ",[902,1388,937],{"class":929},[902,1390,1127],{"class":933},[902,1392,1175],{"class":929},[902,1394,1395],{"class":904,"line":1145},[902,1396,1397],{"class":908},"}\n",[876,1399,1401],{"id":1400},"provider-fields","Provider fields",[1403,1404,1405,1413,1428,1434,1440,1446,1456,1466,1472,1478,1495,1510,1517,1524],"field-group",{},[1406,1407,1410],"field",{"name":1408,"type":1409,":required":1366},"kind","\"oidc\" | \"oauth\"",[848,1411,1412],{},"Selects the provider variant. OIDC providers use discovery; generic OAuth providers require explicit endpoint URLs.",[1406,1414,1417],{"name":1415,"type":1416,":required":1366},"name","string",[848,1418,1419,1420,1423,1424,1427],{},"Identifier used in the route path. The authorization URL is ",[863,1421,1422],{},"\u002Foauth\u002F:name"," and the callback is ",[863,1425,1426],{},"\u002Foauth\u002Fcallback\u002F:name",". This value must match exactly.",[1406,1429,1431],{"name":1430,"type":1416,":required":1366},"clientId",[848,1432,1433],{},"OAuth application client ID from the provider dashboard.",[1406,1435,1437],{"name":1436,"type":1416,":required":1366},"clientSecret",[848,1438,1439],{},"OAuth application client secret. Never expose this to the browser.",[1406,1441,1443],{"name":1442,"type":1416,":required":1366},"redirectUri",[848,1444,1445],{},"The full callback URL registered with the provider. Must match exactly, including the protocol and path.",[1406,1447,1450],{"name":1448,"type":1449},"defaultScopes","string[]",[848,1451,1452,1453,1455],{},"Scopes to request. For OIDC providers, include ",[863,1454,1059],{}," to receive an ID token.",[1406,1457,1460],{"name":1458,"type":1459},"supportPKCE","boolean",[848,1461,1462,1463,988],{},"Enables PKCE (Proof Key for Code Exchange). Recommended for all providers that support it. Generates a code verifier and challenge pair for each flow and stores the verifier in a short-lived signed cookie. Default to ",[863,1464,1465],{},"false",[1406,1467,1469],{"name":1468,"type":1416,":required":1366},"redirectUrlOnSuccess",[848,1470,1471],{},"Where to send the user after a successful authentication and cookie issuance.",[1406,1473,1475],{"name":1474,"type":1416,":required":1366},"redirectUrlOnError",[848,1476,1477],{},"Where to send the user when the flow fails at any point.",[1406,1479,1482],{"name":1480,"type":1481},"extraAuthParams","Record\u003Cstring, string>",[848,1483,1484,1485,1064,1488,1491,1492,988],{},"Additional query parameters appended to the authorization URL. Useful for provider-specific options such as ",[863,1486,1487],{},"prompt",[863,1489,1490],{},"access_type",", or ",[863,1493,1494],{},"response_mode",[1406,1496,1499],{"name":1497,"type":1498},"tokenAuthMethod","\"client_secret_post\" | \"client_secret_basic\"",[848,1500,1501,1502,1505,1506,1509],{},"Token endpoint authentication method. Defaults to ",[863,1503,1504],{},"client_secret_basic"," (Authorization header). Use ",[863,1507,1508],{},"client_secret_post"," for providers like LinkedIn that require credentials in the request body.",[1406,1511,1514],{"name":1512,"type":1513},"emailCallBack","Function",[848,1515,1516],{},"Generic OAuth only. A function that fetches the user's email from a separate endpoint when the main user-info endpoint does not return one. Useful for GitHub, where email requires a separate API call.",[1406,1518,1521],{"name":1519,"type":1520},"extraUserInfoCallBacks","Function[]",[848,1522,1523],{},"Generic OAuth only. Additional functions called after the main user-info fetch to enrich the user object with data from other endpoints.",[1406,1525,1526],{"name":889,"type":1416},[848,1527,1528,1529,1532],{},"OIDC only. The provider's issuer URL. Used to build the discovery document URL and to validate the ",[863,1530,1531],{},"iss"," claim in the ID token.",[1534,1535,1536,1554],"caution",{},[848,1537,1538,1539,1543,1544,1064,1547,1550,1551,988],{},"The ",[1540,1541,1542],"a",{"href":433},"IAM service"," require clients to provide a user email and at least one of the following withing a OAuth flow: ",[863,1545,1546],{},"sub",[863,1548,1549],{},"id"," or a ",[863,1552,1553],{},"user_id",[848,1555,1556],{},"Omitting these values will cause the flow to fail, use the callbacks options to provide the necessary data when the provider omits it.",[852,1558],{},[855,1560,1562],{"id":1561},"authorization-redirect","Authorization redirect",[848,1564,1565,1568,1569,1572],{},[863,1566,1567],{},"OAuthRedirect"," handles ",[863,1570,1571],{},"GET \u002Foauth\u002F:provider",". It looks up the provider by name in the configuration and builds the authorization URL.",[848,1574,1575,1576,1579,1580,1583,1584,1587],{},"For OIDC providers, it calls ",[863,1577,1578],{},"discoverOidc(issuer)"," to fetch the ",[863,1581,1582],{},"authorization_endpoint"," from the discovery document. For generic OAuth providers, it uses the configured ",[863,1585,1586],{},"authorizationEndpoint"," directly.",[848,1589,1590],{},"Before redirecting, the handler generates:",[1592,1593,1594,1609,1625],"ul",{},[1595,1596,1597,1598,1601,1602,1605,1606],"li",{},"A random ",[863,1599,1600],{},"state"," value, signed into a short-lived cookie (",[863,1603,1604],{},"state{name}",", 3-minute TTL) using ",[863,1607,1608],{},"createSignedValue",[1595,1610,1611,1612,1615,1616,1619,1620,1622,1623],{},"A PKCE verifier and challenge via ",[863,1613,1614],{},"makePkcePair()",", stored in a ",[863,1617,1618],{},"pkce_v{name}"," cookie when ",[863,1621,1458],{}," is ",[863,1624,1366],{},[1595,1626,1627,1628,1631,1632,1635],{},"A ",[863,1629,1630],{},"nonce"," for OIDC providers, stored in a ",[863,1633,1634],{},"nonce{name}"," cookie",[848,1637,1638,1639,1064,1642,1645,1646,1649,1650,1653,1654,1657,1658,1661],{},"All pre-flow cookies are ",[863,1640,1641],{},"HttpOnly",[863,1643,1644],{},"Secure",", and expire in 3 minutes. For providers that use ",[863,1647,1648],{},"response_mode: form_post",", the ",[863,1651,1652],{},"SameSite"," attribute is set to ",[863,1655,1656],{},"None"," instead of ",[863,1659,1660],{},"Lax"," to allow the POST callback to carry the cookies.",[848,1663,1664,1667],{},[863,1665,1666],{},"useOAuthRoutes(router)"," registers both the redirect and callback routes:",[892,1669,1671],{"className":894,"code":1670,"language":897,"meta":898,"style":898},"import { createRouter } from 'h3'\nimport { useOAuthRoutes } from 'auth-h3client\u002Fv1'\n\nconst router = createRouter()\nuseOAuthRoutes(router)\n\u002F\u002F Registers:\n\u002F\u002F GET  \u002Foauth\u002F:provider\n\u002F\u002F GET  \u002Foauth\u002Fcallback\u002F:provider\n",[863,1672,1673,1697,1717,1722,1742,1755,1761,1766],{"__ignoreMap":898},[902,1674,1675,1679,1682,1685,1688,1691,1693,1695],{"class":904,"line":905},[902,1676,1678],{"class":1677},"sZ328","import",[902,1680,1681],{"class":908}," { ",[902,1683,1684],{"class":921},"createRouter",[902,1686,1687],{"class":908}," } ",[902,1689,1690],{"class":1677},"from",[902,1692,930],{"class":929},[902,1694,876],{"class":933},[902,1696,1175],{"class":929},[902,1698,1699,1701,1703,1706,1708,1710,1712,1715],{"class":904,"line":912},[902,1700,1678],{"class":1677},[902,1702,1681],{"class":908},[902,1704,1705],{"class":921},"useOAuthRoutes",[902,1707,1687],{"class":908},[902,1709,1690],{"class":1677},[902,1711,930],{"class":929},[902,1713,1714],{"class":933},"auth-h3client\u002Fv1",[902,1716,1175],{"class":929},[902,1718,1719],{"class":904,"line":918},[902,1720,1721],{"emptyLinePlaceholder":8},"\n",[902,1723,1724,1728,1732,1735,1739],{"class":904,"line":943},[902,1725,1727],{"class":1726},"sl46w","const",[902,1729,1731],{"class":1730},"s3JHE"," router",[902,1733,1734],{"class":1000}," =",[902,1736,1738],{"class":1737},"sHOzp"," createRouter",[902,1740,1741],{"class":908},"()\n",[902,1743,1744,1746,1749,1752],{"class":904,"line":960},[902,1745,1705],{"class":1737},[902,1747,1748],{"class":908},"(",[902,1750,1751],{"class":921},"router",[902,1753,1754],{"class":908},")\n",[902,1756,1757],{"class":904,"line":977},[902,1758,1760],{"class":1759},"sghk6","\u002F\u002F Registers:\n",[902,1762,1763],{"class":904,"line":1006},[902,1764,1765],{"class":1759},"\u002F\u002F GET  \u002Foauth\u002F:provider\n",[902,1767,1768],{"class":904,"line":1029},[902,1769,1770],{"class":1759},"\u002F\u002F GET  \u002Foauth\u002Fcallback\u002F:provider\n",[852,1772],{},[855,1774,1776],{"id":1775},"callback-handler","Callback handler",[848,1778,1779,1780,1783,1784,1787],{},"The callback route is handled by two components running in sequence: the ",[863,1781,1782],{},"OAuthTokensValidations"," middleware and the ",[863,1785,1786],{},"OAuthSuccessCallBack"," handler.",[876,1789,1791,1793],{"id":1790},"oauthtokensvalidations-middleware",[863,1792,1782],{}," middleware",[848,1795,1796],{},"Runs first on every callback request. Handles all provider-side validation and token exchange before the handler sees the event.",[1798,1799,1801,1806,1827,1831,1848,1852,1862,1867,1883,1892,1896,1899,1950,1964,1968],"steps",{"level":1800},"4",[1802,1803,1805],"h4",{"id":1804},"state-and-code-check","State and code check",[848,1807,1808,1809,1811,1812,1814,1815,1818,1819,1821,1822,1824,1825,988],{},"Reads the authorization code and ",[863,1810,1600],{}," parameter from the request (query string for GET, form body for POST when ",[863,1813,1648],{},"). If the provider returned an ",[863,1816,1817],{},"error"," parameter, clears the OAuth cookies and redirects to ",[863,1820,1474],{},". If ",[863,1823,863],{}," is missing, also redirects to ",[863,1826,1474],{},[1802,1828,1830],{"id":1829},"state-cookie-verification","State cookie verification",[848,1832,1833,1834,1836,1837,1840,1841,1844,1845,1847],{},"Reads the ",[863,1835,1604],{}," cookie and verifies the signed value using ",[863,1838,1839],{},"verifySignedCookie"," with the keyword ",[863,1842,1843],{},"auth-oauth.{providerName}",". A missing cookie, a signature mismatch, or a stale expiry causes a 400 error. Mismatched ",[863,1846,1531],{}," (OIDC only) also causes a 400 error.",[1802,1849,1851],{"id":1850},"code-exchange","Code exchange",[848,1853,1854,1855,1858,1859,988],{},"Exchanges the authorization code for tokens by posting to the provider's token endpoint. For OIDC providers, the endpoint is discovered automatically from the ",[863,1856,1857],{},".well-known\u002Fopenid-configuration"," document. For generic OAuth providers, it uses the configured ",[863,1860,1861],{},"tokenEndpoint",[848,1863,1864,1865,926],{},"Credentials are sent according to ",[863,1866,1497],{},[1592,1868,1869,1878],{},[1595,1870,1871,1873,1874,1877],{},[863,1872,1504],{},": credentials in the ",[863,1875,1876],{},"Authorization: Basic"," header (default when the provider supports it)",[1595,1879,1880,1882],{},[863,1881,1508],{},": credentials in the POST body",[848,1884,1885,1886,1889,1890,988],{},"If ",[863,1887,1888],{},"supportPKCE: true",", the PKCE code verifier is included in the request. On exchange failure, redirects to ",[863,1891,1474],{},[1802,1893,1895],{"id":1894},"id-token-verification-oidc-only","ID token verification (OIDC only)",[848,1897,1898],{},"Verifies the ID token in four steps:",[1900,1901,1902,1913,1925,1937],"ol",{},[1595,1903,1904,1908,1909,1912],{},[1905,1906,1907],"strong",{},"Signature",": calls ",[863,1910,1911],{},"verifyOAuthToken"," to check the JWT signature against the provider's JWKS endpoint, confirming the token was issued by the expected provider.",[1595,1914,1915,1918,1919,1921,1922,1924],{},[1905,1916,1917],{},"Nonce",": checks that the ",[863,1920,1630],{}," claim in the token matches the ",[863,1923,1634],{}," cookie set during the redirect step.",[1595,1926,1927,1930,1931,1934,1935,988],{},[1905,1928,1929],{},"Authorized party",": if the ",[863,1932,1933],{},"azp"," claim is present, checks it matches the configured ",[863,1936,1430],{},[1595,1938,1939,1930,1942,1945,1946,1949],{},[1905,1940,1941],{},"Access token binding",[863,1943,1944],{},"at_hash"," claim is present, calls ",[863,1947,1948],{},"atHashCheck"," to verify it matches a hash of the access token.",[848,1951,1952,1953,1956,1957,1960,1961,988],{},"If the provider exposes a ",[863,1954,1955],{},"userinfo_endpoint",", also fetches the user profile and verifies that ",[863,1958,1959],{},"userinfo.sub"," matches ",[863,1962,1963],{},"id_token.sub",[1802,1965,1967],{"id":1966},"user-info-fetch-oauth-only","User info fetch (OAuth only)",[848,1969,1970,1971,1974],{},"For generic OAuth providers, fetches user info from the configured ",[863,1972,1973],{},"userInfoEndpoint"," using the access token as a Bearer token.",[848,1976,1977,1978,1064,1981,1984,1985,1988,1989,1064,1991,1984,1993,1995],{},"On success, sets ",[863,1979,1980],{},"event.context.provider",[863,1982,1983],{},"event.context.userData",", and ",[863,1986,1987],{},"event.context.accessToken"," for the handler. Clears the ",[863,1990,1604],{},[863,1992,1618],{},[863,1994,1634],{}," cookies regardless of outcome.",[876,1997,1999,2001],{"id":1998},"oauthsuccesscallback-handler",[863,2000,1786],{}," handler",[848,2003,2004],{},"Runs after the middleware. Enriches the user object and proxies it to the IAM service.",[1798,2006,2007,2011,2027,2031,2050,2054,2065,2069],{"level":1800},[1802,2008,2010],{"id":2009},"email-resolution-oauth-only","Email resolution (OAuth only)",[848,2012,2013,2014,2016,2017,2019,2020,2023,2024,2026],{},"If the user object has no ",[863,2015,1069],{}," field and ",[863,2018,1512],{}," is configured, calls it with the access token to fetch the email from a separate provider endpoint (for example, GitHub's ",[863,2021,2022],{},"\u002Fuser\u002Femails"," API). If no ",[863,2025,1512],{}," is configured, falls back to scanning the user object's keys and values for a field that matches an email regex. Throws 400 if no email can be resolved.",[1802,2028,2030],{"id":2029},"extra-user-info-enrichment-oauth-only","Extra user info enrichment (OAuth only)",[848,2032,1885,2033,2035,2036,2039,2040,2043,2044,2039,2046,2049],{},[863,2034,1519],{}," are configured, calls all of them ",[1905,2037,2038],{},"in parallel"," with ",[863,2041,2042],{},"Promise.all"," and merges each result into the user object using ",[863,2045,776],{},[863,2047,2048],{},"mode: 'drop'",". Conflicting reserved fields are silently dropped; a warning is logged for each dropped key.",[1802,2051,2053],{"id":2052},"iam-proxy","IAM proxy",[848,2055,2056,2057,2060,2061,2064],{},"Forwards the merged user object to the IAM service at ",[863,2058,2059],{},"POST \u002Fauth\u002FOAuth\u002F{providerName}"," with the ",[863,2062,2063],{},"canary_id"," cookie. On success (200 or 201), the IAM service creates or updates the user account and returns session credentials.",[1802,2066,2068],{"id":2067},"cookie-setting-and-redirect","Cookie setting and redirect",[848,2070,2071,2072,2075,2076,2079,2080,2083,2084,2087,2088,988],{},"Sets the ",[863,2073,2074],{},"__Secure-a"," (access token) and ",[863,2077,2078],{},"a-iat"," (issued-at) cookies on the response. Forwards the ",[863,2081,2082],{},"Set-Cookie"," headers from the IAM response (which carry the ",[863,2085,2086],{},"session"," refresh token cookie). Returns HTTP 200 with a temporary HTML page that redirects the browser to ",[863,2089,1468],{},[852,2091],{},[855,2093,2095],{"id":2094},"token-cookie-setup","Token cookie setup",[848,2097,2098],{},"After a successful OAuth callback, the same cookies are issued as in the standard login flow:",[2100,2101,2102,2118],"table",{},[2103,2104,2105],"thead",{},[2106,2107,2108,2112,2115],"tr",{},[2109,2110,2111],"th",{},"Cookie",[2109,2113,2114],{},"Content",[2109,2116,2117],{},"Attributes",[2119,2120,2121,2140,2157],"tbody",{},[2106,2122,2123,2128,2131],{},[2124,2125,2126],"td",{},[863,2127,2074],{},[2124,2129,2130],{},"Access token",[2124,2132,2133,1064,2135,1064,2137],{},[863,2134,1641],{},[863,2136,1644],{},[863,2138,2139],{},"SameSite=Strict",[2106,2141,2142,2146,2149],{},[2124,2143,2144],{},[863,2145,2078],{},[2124,2147,2148],{},"Access token issued-at",[2124,2150,2151,1064,2153,1064,2155],{},[863,2152,1641],{},[863,2154,1644],{},[863,2156,2139],{},[2106,2158,2159,2163,2166],{},[2124,2160,2161],{},[863,2162,2086],{},[2124,2164,2165],{},"Refresh token (from IAM)",[2124,2167,2168],{},"Forwarded from IAM response",[852,2170],{},[855,2172,2174],{"id":2173},"provider-registration-in-the-iam-service","Provider registration in the IAM service",[848,2176,2177,2178,2181],{},"The module handles the OAuth flow at the BFF layer and proxies the resulting user data to the IAM service. The IAM service must have the same provider registered in its configuration to accept the data. See ",[1540,2179,2180],{"href":433},"IAM OAuth"," for the server-side provider setup.",[2183,2184,2185],"style",{},"html pre.shiki code .sDd4n, html code.shiki .sDd4n{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#F8F8F2}html pre.shiki code .sjsA6, html code.shiki .sjsA6{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#F8F8F2}html pre.shiki code .s34zl, html code.shiki .s34zl{--shiki-light:#001080;--shiki-default:#001080;--shiki-dark:#FF79C6}html pre.shiki code .sFkSl, html code.shiki .sFkSl{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#E9F284}html pre.shiki code .sFB1V, html code.shiki .sFB1V{--shiki-light:#A31515;--shiki-default:#A31515;--shiki-dark:#F1FA8C}html pre.shiki code .sPzPf, html code.shiki .sPzPf{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#BD93F9}html pre.shiki code .saOXh, html code.shiki .saOXh{--shiki-light:#000000;--shiki-default:#000000;--shiki-dark:#FF79C6}html pre.shiki code .sjR7W, html code.shiki .sjR7W{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#BD93F9}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZ328, html code.shiki .sZ328{--shiki-light:#AF00DB;--shiki-default:#AF00DB;--shiki-dark:#FF79C6}html pre.shiki code .sl46w, html code.shiki .sl46w{--shiki-light:#0000FF;--shiki-default:#0000FF;--shiki-dark:#FF79C6}html pre.shiki code .s3JHE, html code.shiki .s3JHE{--shiki-light:#0070C1;--shiki-default:#0070C1;--shiki-dark:#F8F8F2}html pre.shiki code .sHOzp, html code.shiki .sHOzp{--shiki-light:#795E26;--shiki-default:#795E26;--shiki-dark:#50FA7B}html pre.shiki code .sghk6, html code.shiki .sghk6{--shiki-light:#008000;--shiki-default:#008000;--shiki-dark:#6272A4}",{"title":898,"searchDepth":912,"depth":912,"links":2187},[2188,2193,2194,2200,2201],{"id":857,"depth":912,"text":858,"children":2189},[2190,2191,2192],{"id":878,"depth":918,"text":879},{"id":1196,"depth":918,"text":1197},{"id":1400,"depth":918,"text":1401},{"id":1561,"depth":912,"text":1562},{"id":1775,"depth":912,"text":1776,"children":2195},[2196,2198],{"id":1790,"depth":918,"text":2197},"OAuthTokensValidations middleware",{"id":1998,"depth":918,"text":2199},"OAuthSuccessCallBack handler",{"id":2094,"depth":912,"text":2095},{"id":2173,"depth":912,"text":2174},"Provider configuration, the authorization redirect, PKCE, the callback exchange, ID token verification via JWKS, at_hash validation, and how user data is merged safely.","md","i-lucide-users",{},null,"---\ntitle: OAuth and OIDC\ndescription: Provider configuration, the authorization redirect, PKCE, the callback exchange, ID token verification via JWKS, at_hash validation, and how user data is merged safely.\nicon: i-lucide-users\n---\n\nThe module handles the complete OAuth and OIDC authorization code flow at the gateway level. The browser never sees provider tokens or client secrets. Two handlers manage the flow: one that builds the authorization URL and redirects the user, and one that handles the provider callback, exchanges the code for tokens, verifies the result, and proxies the user data to the IAM service.\n\n---\n\n## Provider configuration\n\nProviders are defined in the `OAuthProviders` array in the configuration. Each provider is either an OIDC provider (`kind: 'oidc'`) or a generic OAuth provider (`kind: 'oauth'`).\n\n### OIDC provider\n\nOIDC providers expose a discovery document at `\u002F.well-known\u002Fopenid-configuration`. The module fetches this document automatically using the `issuer` URL to discover the authorization and token endpoints. Use this kind for Google, Microsoft, Okta, and any provider that supports OpenID Connect.\n\n```ts [server\u002Fplugins\u002Fauth.ts]\nOAuthProviders: [\n  {\n    kind: 'oidc',\n    name: 'google',\n    issuer: 'https:\u002F\u002Faccounts.google.com',\n    clientId: process.env.OAUTH_GOOGLE_CLIENT_ID!,\n    clientSecret: process.env.OAUTH_GOOGLE_CLIENT_SECRET!,\n    redirectUri: 'https:\u002F\u002Fapp.example.com\u002Foauth\u002Fcallback\u002Fgoogle',\n    defaultScopes: ['openid', 'email', 'profile'],\n    supportPKCE: true,\n    redirectUrlOnSuccess: 'https:\u002F\u002Fapp.example.com\u002Fdashboard',\n    redirectUrlOnError: 'https:\u002F\u002Fapp.example.com\u002Flogin',\n    extraAuthParams: {\n      access_type: 'offline',\n      prompt: 'consent'\n    }\n  }\n]\n```\n\n### Generic OAuth provider\n\nGeneric OAuth providers require explicit endpoint URLs. Use this kind for GitHub, X (Twitter), LinkedIn, and any provider that does not support OIDC discovery.\n\n```ts\n{\n  kind: 'oauth',\n  name: 'github',\n  authorizationEndpoint: 'https:\u002F\u002Fgithub.com\u002Flogin\u002Foauth\u002Fauthorize',\n  tokenEndpoint: 'https:\u002F\u002Fgithub.com\u002Flogin\u002Foauth\u002Faccess_token',\n  userInfoEndpoint: 'https:\u002F\u002Fapi.github.com\u002Fuser',\n  clientId: process.env.OAUTH_GITHUB_CLIENT_ID!,\n  clientSecret: process.env.OAUTH_GITHUB_CLIENT_SECRET!,\n  redirectUri: 'https:\u002F\u002Fapp.example.com\u002Foauth\u002Fcallback\u002Fgithub',\n  defaultScopes: ['read:user', 'user:email'],\n  supportPKCE: true,\n  redirectUrlOnSuccess: 'https:\u002F\u002Fapp.example.com\u002Fdashboard',\n  redirectUrlOnError: 'https:\u002F\u002Fapp.example.com\u002Flogin'\n}\n```\n\n### Provider fields\n\n::field-group\n\n::field{name=\"kind\" type='\"oidc\" | \"oauth\"' required}\nSelects the provider variant. OIDC providers use discovery; generic OAuth providers require explicit endpoint URLs.\n::\n\n::field{name=\"name\" type=\"string\" required}\nIdentifier used in the route path. The authorization URL is `\u002Foauth\u002F:name` and the callback is `\u002Foauth\u002Fcallback\u002F:name`. This value must match exactly.\n::\n\n::field{name=\"clientId\" type=\"string\" required}\nOAuth application client ID from the provider dashboard.\n::\n\n::field{name=\"clientSecret\" type=\"string\" required}\nOAuth application client secret. Never expose this to the browser.\n::\n\n::field{name=\"redirectUri\" type=\"string\" required}\nThe full callback URL registered with the provider. Must match exactly, including the protocol and path.\n::\n\n::field{name=\"defaultScopes\" type=\"string[]\"}\nScopes to request. For OIDC providers, include `openid` to receive an ID token.\n::\n\n::field{name=\"supportPKCE\" type=\"boolean\"}\nEnables PKCE (Proof Key for Code Exchange). Recommended for all providers that support it. Generates a code verifier and challenge pair for each flow and stores the verifier in a short-lived signed cookie. Default to `false`.\n::\n\n::field{name=\"redirectUrlOnSuccess\" type=\"string\" required}\nWhere to send the user after a successful authentication and cookie issuance.\n::\n\n::field{name=\"redirectUrlOnError\" type=\"string\" required}\nWhere to send the user when the flow fails at any point.\n::\n\n::field{name=\"extraAuthParams\" type=\"Record\u003Cstring, string>\"}\nAdditional query parameters appended to the authorization URL. Useful for provider-specific options such as `prompt`, `access_type`, or `response_mode`.\n::\n\n::field{name=\"tokenAuthMethod\" type='\"client_secret_post\" | \"client_secret_basic\"'}\nToken endpoint authentication method. Defaults to `client_secret_basic` (Authorization header). Use `client_secret_post` for providers like LinkedIn that require credentials in the request body.\n::\n\n::field{name=\"emailCallBack\" type=\"Function\"}\nGeneric OAuth only. A function that fetches the user's email from a separate endpoint when the main user-info endpoint does not return one. Useful for GitHub, where email requires a separate API call.\n::\n\n::field{name=\"extraUserInfoCallBacks\" type=\"Function[]\"}\nGeneric OAuth only. Additional functions called after the main user-info fetch to enrich the user object with data from other endpoints.\n::\n\n::field{name=\"issuer\" type=\"string\"}\nOIDC only. The provider's issuer URL. Used to build the discovery document URL and to validate the `iss` claim in the ID token.\n::\n\n::\n\n::caution\nThe [IAM service](\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth) require clients to provide a user email and at least one of the following withing a OAuth flow: `sub`, `id` or a `user_id`.\n\nOmitting these values will cause the flow to fail, use the callbacks options to provide the necessary data when the provider omits it. \n::\n---\n\n## Authorization redirect\n\n`OAuthRedirect` handles `GET \u002Foauth\u002F:provider`. It looks up the provider by name in the configuration and builds the authorization URL.\n\nFor OIDC providers, it calls `discoverOidc(issuer)` to fetch the `authorization_endpoint` from the discovery document. For generic OAuth providers, it uses the configured `authorizationEndpoint` directly.\n\nBefore redirecting, the handler generates:\n\n- A random `state` value, signed into a short-lived cookie (`state{name}`, 3-minute TTL) using `createSignedValue`\n- A PKCE verifier and challenge via `makePkcePair()`, stored in a `pkce_v{name}` cookie when `supportPKCE` is `true`\n- A `nonce` for OIDC providers, stored in a `nonce{name}` cookie\n\nAll pre-flow cookies are `HttpOnly`, `Secure`, and expire in 3 minutes. For providers that use `response_mode: form_post`, the `SameSite` attribute is set to `None` instead of `Lax` to allow the POST callback to carry the cookies.\n\n`useOAuthRoutes(router)` registers both the redirect and callback routes:\n\n```ts\nimport { createRouter } from 'h3'\nimport { useOAuthRoutes } from 'auth-h3client\u002Fv1'\n\nconst router = createRouter()\nuseOAuthRoutes(router)\n\u002F\u002F Registers:\n\u002F\u002F GET  \u002Foauth\u002F:provider\n\u002F\u002F GET  \u002Foauth\u002Fcallback\u002F:provider\n```\n\n---\n\n## Callback handler\n\nThe callback route is handled by two components running in sequence: the `OAuthTokensValidations` middleware and the `OAuthSuccessCallBack` handler.\n\n### `OAuthTokensValidations` middleware\n\nRuns first on every callback request. Handles all provider-side validation and token exchange before the handler sees the event.\n\n::steps{level=\"4\"}\n\n#### State and code check\n\nReads the authorization code and `state` parameter from the request (query string for GET, form body for POST when `response_mode: form_post`). If the provider returned an `error` parameter, clears the OAuth cookies and redirects to `redirectUrlOnError`. If `code` is missing, also redirects to `redirectUrlOnError`.\n\n#### State cookie verification\n\nReads the `state{name}` cookie and verifies the signed value using `verifySignedCookie` with the keyword `auth-oauth.{providerName}`. A missing cookie, a signature mismatch, or a stale expiry causes a 400 error. Mismatched `iss` (OIDC only) also causes a 400 error.\n\n#### Code exchange\n\nExchanges the authorization code for tokens by posting to the provider's token endpoint. For OIDC providers, the endpoint is discovered automatically from the `.well-known\u002Fopenid-configuration` document. For generic OAuth providers, it uses the configured `tokenEndpoint`.\n\nCredentials are sent according to `tokenAuthMethod`:\n\n- `client_secret_basic`: credentials in the `Authorization: Basic` header (default when the provider supports it)\n- `client_secret_post`: credentials in the POST body\n\nIf `supportPKCE: true`, the PKCE code verifier is included in the request. On exchange failure, redirects to `redirectUrlOnError`.\n\n#### ID token verification (OIDC only)\n\nVerifies the ID token in four steps:\n\n1. **Signature**: calls `verifyOAuthToken` to check the JWT signature against the provider's JWKS endpoint, confirming the token was issued by the expected provider.\n2. **Nonce**: checks that the `nonce` claim in the token matches the `nonce{name}` cookie set during the redirect step.\n3. **Authorized party**: if the `azp` claim is present, checks it matches the configured `clientId`.\n4. **Access token binding**: if the `at_hash` claim is present, calls `atHashCheck` to verify it matches a hash of the access token.\n\nIf the provider exposes a `userinfo_endpoint`, also fetches the user profile and verifies that `userinfo.sub` matches `id_token.sub`.\n\n#### User info fetch (OAuth only)\n\nFor generic OAuth providers, fetches user info from the configured `userInfoEndpoint` using the access token as a Bearer token.\n\n::\n\nOn success, sets `event.context.provider`, `event.context.userData`, and `event.context.accessToken` for the handler. Clears the `state{name}`, `pkce_v{name}`, and `nonce{name}` cookies regardless of outcome.\n\n### `OAuthSuccessCallBack` handler\n\nRuns after the middleware. Enriches the user object and proxies it to the IAM service.\n\n::steps{level=\"4\"}\n\n#### Email resolution (OAuth only)\n\nIf the user object has no `email` field and `emailCallBack` is configured, calls it with the access token to fetch the email from a separate provider endpoint (for example, GitHub's `\u002Fuser\u002Femails` API). If no `emailCallBack` is configured, falls back to scanning the user object's keys and values for a field that matches an email regex. Throws 400 if no email can be resolved.\n\n#### Extra user info enrichment (OAuth only)\n\nIf `extraUserInfoCallBacks` are configured, calls all of them **in parallel** with `Promise.all` and merges each result into the user object using `safeObjectMerge` with `mode: 'drop'`. Conflicting reserved fields are silently dropped; a warning is logged for each dropped key.\n\n#### IAM proxy\n\nForwards the merged user object to the IAM service at `POST \u002Fauth\u002FOAuth\u002F{providerName}` with the `canary_id` cookie. On success (200 or 201), the IAM service creates or updates the user account and returns session credentials.\n\n#### Cookie setting and redirect\n\nSets the `__Secure-a` (access token) and `a-iat` (issued-at) cookies on the response. Forwards the `Set-Cookie` headers from the IAM response (which carry the `session` refresh token cookie). Returns HTTP 200 with a temporary HTML page that redirects the browser to `redirectUrlOnSuccess`.\n\n::\n\n---\n\n## Token cookie setup\n\nAfter a successful OAuth callback, the same cookies are issued as in the standard login flow:\n\n| Cookie | Content | Attributes |\n|---|---|---|\n| `__Secure-a` | Access token | `HttpOnly`, `Secure`, `SameSite=Strict` |\n| `a-iat` | Access token issued-at | `HttpOnly`, `Secure`, `SameSite=Strict` |\n| `session` | Refresh token (from IAM) | Forwarded from IAM response |\n\n---\n\n## Provider registration in the IAM service\n\nThe module handles the OAuth flow at the BFF layer and proxies the resulting user data to the IAM service. The IAM service must have the same provider registered in its configuration to accept the data. See [IAM OAuth](\u002Fdocs\u002Fiam\u002Fessentials\u002Foauth) for the server-side provider setup.",{"title":105,"description":2202},"aqpTt8zsFSPuVKcgTRt81343NyVw3fr8f_1yAlKaECc",[2211,2212],{"title":101,"path":102,"stem":103,"children":-1},{"title":33,"path":109,"stem":110,"children":-1},{"id":843,"title":105,"body":2214,"description":2202,"extension":2203,"icon":2204,"meta":3154,"module":2206,"navigation":8,"path":106,"rawbody":2207,"seo":3155,"stem":107,"__hash__":2209},{"type":845,"value":2215,"toc":3140},[2216,2218,2220,2222,2230,2232,2238,2462,2464,2466,2636,2638,2716,2730,2732,2734,2740,2748,2750,2776,2790,2794,2872,2874,2876,2882,2886,2888,2998,3012,3016,3018,3068,3070,3072,3074,3130,3132,3134,3138],[848,2217,850],{},[852,2219],{},[855,2221,858],{"id":857},[848,2223,861,2224,866,2226,870,2228,874],{},[863,2225,865],{},[863,2227,869],{},[863,2229,873],{},[876,2231,879],{"id":878},[848,2233,882,2234,886,2236,890],{},[863,2235,885],{},[863,2237,889],{},[892,2239,2240],{"className":894,"code":895,"filename":896,"language":897,"meta":898,"style":898},[863,2241,2242,2246,2250,2264,2278,2292,2312,2332,2346,2378,2388,2402,2416,2424,2438,2450,2454,2458],{"__ignoreMap":898},[902,2243,2244],{"class":904,"line":905},[902,2245,909],{"class":908},[902,2247,2248],{"class":904,"line":912},[902,2249,915],{"class":908},[902,2251,2252,2254,2256,2258,2260,2262],{"class":904,"line":918},[902,2253,922],{"class":921},[902,2255,926],{"class":925},[902,2257,930],{"class":929},[902,2259,934],{"class":933},[902,2261,937],{"class":929},[902,2263,940],{"class":908},[902,2265,2266,2268,2270,2272,2274,2276],{"class":904,"line":943},[902,2267,946],{"class":921},[902,2269,926],{"class":925},[902,2271,930],{"class":929},[902,2273,953],{"class":933},[902,2275,937],{"class":929},[902,2277,940],{"class":908},[902,2279,2280,2282,2284,2286,2288,2290],{"class":904,"line":960},[902,2281,963],{"class":921},[902,2283,926],{"class":925},[902,2285,930],{"class":929},[902,2287,970],{"class":933},[902,2289,937],{"class":929},[902,2291,940],{"class":908},[902,2293,2294,2296,2298,2300,2302,2304,2306,2308,2310],{"class":904,"line":977},[902,2295,980],{"class":921},[902,2297,926],{"class":925},[902,2299,985],{"class":921},[902,2301,988],{"class":908},[902,2303,991],{"class":921},[902,2305,988],{"class":908},[902,2307,997],{"class":996},[902,2309,1001],{"class":1000},[902,2311,940],{"class":908},[902,2313,2314,2316,2318,2320,2322,2324,2326,2328,2330],{"class":904,"line":1006},[902,2315,1009],{"class":921},[902,2317,926],{"class":925},[902,2319,985],{"class":921},[902,2321,988],{"class":908},[902,2323,991],{"class":921},[902,2325,988],{"class":908},[902,2327,1022],{"class":996},[902,2329,1001],{"class":1000},[902,2331,940],{"class":908},[902,2333,2334,2336,2338,2340,2342,2344],{"class":904,"line":1029},[902,2335,1032],{"class":921},[902,2337,926],{"class":925},[902,2339,930],{"class":929},[902,2341,1039],{"class":933},[902,2343,937],{"class":929},[902,2345,940],{"class":908},[902,2347,2348,2350,2352,2354,2356,2358,2360,2362,2364,2366,2368,2370,2372,2374,2376],{"class":904,"line":1046},[902,2349,1049],{"class":921},[902,2351,926],{"class":925},[902,2353,1054],{"class":908},[902,2355,937],{"class":929},[902,2357,1059],{"class":933},[902,2359,937],{"class":929},[902,2361,1064],{"class":908},[902,2363,937],{"class":929},[902,2365,1069],{"class":933},[902,2367,937],{"class":929},[902,2369,1064],{"class":908},[902,2371,937],{"class":929},[902,2373,1078],{"class":933},[902,2375,937],{"class":929},[902,2377,1083],{"class":908},[902,2379,2380,2382,2384,2386],{"class":904,"line":1086},[902,2381,1089],{"class":921},[902,2383,926],{"class":925},[902,2385,1095],{"class":1094},[902,2387,940],{"class":908},[902,2389,2390,2392,2394,2396,2398,2400],{"class":904,"line":1100},[902,2391,1103],{"class":921},[902,2393,926],{"class":925},[902,2395,930],{"class":929},[902,2397,1110],{"class":933},[902,2399,937],{"class":929},[902,2401,940],{"class":908},[902,2403,2404,2406,2408,2410,2412,2414],{"class":904,"line":1117},[902,2405,1120],{"class":921},[902,2407,926],{"class":925},[902,2409,930],{"class":929},[902,2411,1127],{"class":933},[902,2413,937],{"class":929},[902,2415,940],{"class":908},[902,2417,2418,2420,2422],{"class":904,"line":1134},[902,2419,1137],{"class":921},[902,2421,926],{"class":925},[902,2423,1142],{"class":908},[902,2425,2426,2428,2430,2432,2434,2436],{"class":904,"line":1145},[902,2427,1148],{"class":921},[902,2429,926],{"class":925},[902,2431,930],{"class":929},[902,2433,1155],{"class":933},[902,2435,937],{"class":929},[902,2437,940],{"class":908},[902,2439,2440,2442,2444,2446,2448],{"class":904,"line":1162},[902,2441,1165],{"class":921},[902,2443,926],{"class":925},[902,2445,930],{"class":929},[902,2447,1172],{"class":933},[902,2449,1175],{"class":929},[902,2451,2452],{"class":904,"line":1178},[902,2453,1181],{"class":908},[902,2455,2456],{"class":904,"line":1184},[902,2457,1187],{"class":908},[902,2459,2460],{"class":904,"line":1190},[902,2461,1193],{"class":908},[876,2463,1197],{"id":1196},[848,2465,1200],{},[892,2467,2468],{"className":894,"code":1203,"language":897,"meta":898,"style":898},[863,2469,2470,2474,2486,2498,2510,2522,2534,2552,2570,2582,2602,2610,2622,2632],{"__ignoreMap":898},[902,2471,2472],{"class":904,"line":905},[902,2473,1210],{"class":908},[902,2475,2476,2478,2480,2482,2484],{"class":904,"line":912},[902,2477,1215],{"class":908},[902,2479,937],{"class":929},[902,2481,1220],{"class":933},[902,2483,937],{"class":929},[902,2485,940],{"class":908},[902,2487,2488,2490,2492,2494,2496],{"class":904,"line":918},[902,2489,1229],{"class":908},[902,2491,937],{"class":929},[902,2493,1234],{"class":933},[902,2495,937],{"class":929},[902,2497,940],{"class":908},[902,2499,2500,2502,2504,2506,2508],{"class":904,"line":943},[902,2501,1243],{"class":908},[902,2503,937],{"class":929},[902,2505,1248],{"class":933},[902,2507,937],{"class":929},[902,2509,940],{"class":908},[902,2511,2512,2514,2516,2518,2520],{"class":904,"line":960},[902,2513,1257],{"class":908},[902,2515,937],{"class":929},[902,2517,1262],{"class":933},[902,2519,937],{"class":929},[902,2521,940],{"class":908},[902,2523,2524,2526,2528,2530,2532],{"class":904,"line":977},[902,2525,1271],{"class":908},[902,2527,937],{"class":929},[902,2529,1276],{"class":933},[902,2531,937],{"class":929},[902,2533,940],{"class":908},[902,2535,2536,2538,2540,2542,2544,2546,2548,2550],{"class":904,"line":1006},[902,2537,1285],{"class":908},[902,2539,1288],{"class":921},[902,2541,988],{"class":908},[902,2543,991],{"class":921},[902,2545,988],{"class":908},[902,2547,1297],{"class":996},[902,2549,1001],{"class":1000},[902,2551,940],{"class":908},[902,2553,2554,2556,2558,2560,2562,2564,2566,2568],{"class":904,"line":1029},[902,2555,1306],{"class":908},[902,2557,1288],{"class":921},[902,2559,988],{"class":908},[902,2561,991],{"class":921},[902,2563,988],{"class":908},[902,2565,1317],{"class":996},[902,2567,1001],{"class":1000},[902,2569,940],{"class":908},[902,2571,2572,2574,2576,2578,2580],{"class":904,"line":1046},[902,2573,1326],{"class":908},[902,2575,937],{"class":929},[902,2577,1331],{"class":933},[902,2579,937],{"class":929},[902,2581,940],{"class":908},[902,2583,2584,2586,2588,2590,2592,2594,2596,2598,2600],{"class":904,"line":1086},[902,2585,1340],{"class":908},[902,2587,937],{"class":929},[902,2589,1345],{"class":933},[902,2591,937],{"class":929},[902,2593,1064],{"class":908},[902,2595,937],{"class":929},[902,2597,1354],{"class":933},[902,2599,937],{"class":929},[902,2601,1083],{"class":908},[902,2603,2604,2606,2608],{"class":904,"line":1100},[902,2605,1363],{"class":908},[902,2607,1366],{"class":1094},[902,2609,940],{"class":908},[902,2611,2612,2614,2616,2618,2620],{"class":904,"line":1117},[902,2613,1373],{"class":908},[902,2615,937],{"class":929},[902,2617,1110],{"class":933},[902,2619,937],{"class":929},[902,2621,940],{"class":908},[902,2623,2624,2626,2628,2630],{"class":904,"line":1134},[902,2625,1386],{"class":908},[902,2627,937],{"class":929},[902,2629,1127],{"class":933},[902,2631,1175],{"class":929},[902,2633,2634],{"class":904,"line":1145},[902,2635,1397],{"class":908},[876,2637,1401],{"id":1400},[1403,2639,2640,2644,2652,2656,2660,2664,2670,2676,2680,2684,2694,2702,2706,2710],{},[1406,2641,2642],{"name":1408,"type":1409,":required":1366},[848,2643,1412],{},[1406,2645,2646],{"name":1415,"type":1416,":required":1366},[848,2647,1419,2648,1423,2650,1427],{},[863,2649,1422],{},[863,2651,1426],{},[1406,2653,2654],{"name":1430,"type":1416,":required":1366},[848,2655,1433],{},[1406,2657,2658],{"name":1436,"type":1416,":required":1366},[848,2659,1439],{},[1406,2661,2662],{"name":1442,"type":1416,":required":1366},[848,2663,1445],{},[1406,2665,2666],{"name":1448,"type":1449},[848,2667,1452,2668,1455],{},[863,2669,1059],{},[1406,2671,2672],{"name":1458,"type":1459},[848,2673,1462,2674,988],{},[863,2675,1465],{},[1406,2677,2678],{"name":1468,"type":1416,":required":1366},[848,2679,1471],{},[1406,2681,2682],{"name":1474,"type":1416,":required":1366},[848,2683,1477],{},[1406,2685,2686],{"name":1480,"type":1481},[848,2687,1484,2688,1064,2690,1491,2692,988],{},[863,2689,1487],{},[863,2691,1490],{},[863,2693,1494],{},[1406,2695,2696],{"name":1497,"type":1498},[848,2697,1501,2698,1505,2700,1509],{},[863,2699,1504],{},[863,2701,1508],{},[1406,2703,2704],{"name":1512,"type":1513},[848,2705,1516],{},[1406,2707,2708],{"name":1519,"type":1520},[848,2709,1523],{},[1406,2711,2712],{"name":889,"type":1416},[848,2713,1528,2714,1532],{},[863,2715,1531],{},[1534,2717,2718,2728],{},[848,2719,1538,2720,1543,2722,1064,2724,1550,2726,988],{},[1540,2721,1542],{"href":433},[863,2723,1546],{},[863,2725,1549],{},[863,2727,1553],{},[848,2729,1556],{},[852,2731],{},[855,2733,1562],{"id":1561},[848,2735,2736,1568,2738,1572],{},[863,2737,1567],{},[863,2739,1571],{},[848,2741,1575,2742,1579,2744,1583,2746,1587],{},[863,2743,1578],{},[863,2745,1582],{},[863,2747,1586],{},[848,2749,1590],{},[1592,2751,2752,2760,2770],{},[1595,2753,1597,2754,1601,2756,1605,2758],{},[863,2755,1600],{},[863,2757,1604],{},[863,2759,1608],{},[1595,2761,1611,2762,1615,2764,1619,2766,1622,2768],{},[863,2763,1614],{},[863,2765,1618],{},[863,2767,1458],{},[863,2769,1366],{},[1595,2771,1627,2772,1631,2774,1635],{},[863,2773,1630],{},[863,2775,1634],{},[848,2777,1638,2778,1064,2780,1645,2782,1649,2784,1653,2786,1657,2788,1661],{},[863,2779,1641],{},[863,2781,1644],{},[863,2783,1648],{},[863,2785,1652],{},[863,2787,1656],{},[863,2789,1660],{},[848,2791,2792,1667],{},[863,2793,1666],{},[892,2795,2796],{"className":894,"code":1670,"language":897,"meta":898,"style":898},[863,2797,2798,2816,2834,2838,2850,2860,2864,2868],{"__ignoreMap":898},[902,2799,2800,2802,2804,2806,2808,2810,2812,2814],{"class":904,"line":905},[902,2801,1678],{"class":1677},[902,2803,1681],{"class":908},[902,2805,1684],{"class":921},[902,2807,1687],{"class":908},[902,2809,1690],{"class":1677},[902,2811,930],{"class":929},[902,2813,876],{"class":933},[902,2815,1175],{"class":929},[902,2817,2818,2820,2822,2824,2826,2828,2830,2832],{"class":904,"line":912},[902,2819,1678],{"class":1677},[902,2821,1681],{"class":908},[902,2823,1705],{"class":921},[902,2825,1687],{"class":908},[902,2827,1690],{"class":1677},[902,2829,930],{"class":929},[902,2831,1714],{"class":933},[902,2833,1175],{"class":929},[902,2835,2836],{"class":904,"line":918},[902,2837,1721],{"emptyLinePlaceholder":8},[902,2839,2840,2842,2844,2846,2848],{"class":904,"line":943},[902,2841,1727],{"class":1726},[902,2843,1731],{"class":1730},[902,2845,1734],{"class":1000},[902,2847,1738],{"class":1737},[902,2849,1741],{"class":908},[902,2851,2852,2854,2856,2858],{"class":904,"line":960},[902,2853,1705],{"class":1737},[902,2855,1748],{"class":908},[902,2857,1751],{"class":921},[902,2859,1754],{"class":908},[902,2861,2862],{"class":904,"line":977},[902,2863,1760],{"class":1759},[902,2865,2866],{"class":904,"line":1006},[902,2867,1765],{"class":1759},[902,2869,2870],{"class":904,"line":1029},[902,2871,1770],{"class":1759},[852,2873],{},[855,2875,1776],{"id":1775},[848,2877,1779,2878,1783,2880,1787],{},[863,2879,1782],{},[863,2881,1786],{},[876,2883,2884,1793],{"id":1790},[863,2885,1782],{},[848,2887,1796],{},[1798,2889,2890,2892,2906,2908,2918,2920,2926,2930,2942,2948,2950,2952,2984,2992,2994],{"level":1800},[1802,2891,1805],{"id":1804},[848,2893,1808,2894,1811,2896,1814,2898,1818,2900,1821,2902,1824,2904,988],{},[863,2895,1600],{},[863,2897,1648],{},[863,2899,1817],{},[863,2901,1474],{},[863,2903,863],{},[863,2905,1474],{},[1802,2907,1830],{"id":1829},[848,2909,1833,2910,1836,2912,1840,2914,1844,2916,1847],{},[863,2911,1604],{},[863,2913,1839],{},[863,2915,1843],{},[863,2917,1531],{},[1802,2919,1851],{"id":1850},[848,2921,1854,2922,1858,2924,988],{},[863,2923,1857],{},[863,2925,1861],{},[848,2927,1864,2928,926],{},[863,2929,1497],{},[1592,2931,2932,2938],{},[1595,2933,2934,1873,2936,1877],{},[863,2935,1504],{},[863,2937,1876],{},[1595,2939,2940,1882],{},[863,2941,1508],{},[848,2943,1885,2944,1889,2946,988],{},[863,2945,1888],{},[863,2947,1474],{},[1802,2949,1895],{"id":1894},[848,2951,1898],{},[1900,2953,2954,2960,2968,2976],{},[1595,2955,2956,1908,2958,1912],{},[1905,2957,1907],{},[863,2959,1911],{},[1595,2961,2962,1918,2964,1921,2966,1924],{},[1905,2963,1917],{},[863,2965,1630],{},[863,2967,1634],{},[1595,2969,2970,1930,2972,1934,2974,988],{},[1905,2971,1929],{},[863,2973,1933],{},[863,2975,1430],{},[1595,2977,2978,1930,2980,1945,2982,1949],{},[1905,2979,1941],{},[863,2981,1944],{},[863,2983,1948],{},[848,2985,1952,2986,1956,2988,1960,2990,988],{},[863,2987,1955],{},[863,2989,1959],{},[863,2991,1963],{},[1802,2993,1967],{"id":1966},[848,2995,1970,2996,1974],{},[863,2997,1973],{},[848,2999,1977,3000,1064,3002,1984,3004,1988,3006,1064,3008,1984,3010,1995],{},[863,3001,1980],{},[863,3003,1983],{},[863,3005,1987],{},[863,3007,1604],{},[863,3009,1618],{},[863,3011,1634],{},[876,3013,3014,2001],{"id":1998},[863,3015,1786],{},[848,3017,2004],{},[1798,3019,3020,3022,3032,3034,3046,3048,3054,3056],{"level":1800},[1802,3021,2010],{"id":2009},[848,3023,2013,3024,2016,3026,2019,3028,2023,3030,2026],{},[863,3025,1069],{},[863,3027,1512],{},[863,3029,2022],{},[863,3031,1512],{},[1802,3033,2030],{"id":2029},[848,3035,1885,3036,2035,3038,2039,3040,2043,3042,2039,3044,2049],{},[863,3037,1519],{},[1905,3039,2038],{},[863,3041,2042],{},[863,3043,776],{},[863,3045,2048],{},[1802,3047,2053],{"id":2052},[848,3049,2056,3050,2060,3052,2064],{},[863,3051,2059],{},[863,3053,2063],{},[1802,3055,2068],{"id":2067},[848,3057,2071,3058,2075,3060,2079,3062,2083,3064,2087,3066,988],{},[863,3059,2074],{},[863,3061,2078],{},[863,3063,2082],{},[863,3065,2086],{},[863,3067,1468],{},[852,3069],{},[855,3071,2095],{"id":2094},[848,3073,2098],{},[2100,3075,3076,3086],{},[2103,3077,3078],{},[2106,3079,3080,3082,3084],{},[2109,3081,2111],{},[2109,3083,2114],{},[2109,3085,2117],{},[2119,3087,3088,3104,3120],{},[2106,3089,3090,3094,3096],{},[2124,3091,3092],{},[863,3093,2074],{},[2124,3095,2130],{},[2124,3097,3098,1064,3100,1064,3102],{},[863,3099,1641],{},[863,3101,1644],{},[863,3103,2139],{},[2106,3105,3106,3110,3112],{},[2124,3107,3108],{},[863,3109,2078],{},[2124,3111,2148],{},[2124,3113,3114,1064,3116,1064,3118],{},[863,3115,1641],{},[863,3117,1644],{},[863,3119,2139],{},[2106,3121,3122,3126,3128],{},[2124,3123,3124],{},[863,3125,2086],{},[2124,3127,2165],{},[2124,3129,2168],{},[852,3131],{},[855,3133,2174],{"id":2173},[848,3135,2177,3136,2181],{},[1540,3137,2180],{"href":433},[2183,3139,2185],{},{"title":898,"searchDepth":912,"depth":912,"links":3141},[3142,3147,3148,3152,3153],{"id":857,"depth":912,"text":858,"children":3143},[3144,3145,3146],{"id":878,"depth":918,"text":879},{"id":1196,"depth":918,"text":1197},{"id":1400,"depth":918,"text":1401},{"id":1561,"depth":912,"text":1562},{"id":1775,"depth":912,"text":1776,"children":3149},[3150,3151],{"id":1790,"depth":918,"text":2197},{"id":1998,"depth":918,"text":2199},{"id":2094,"depth":912,"text":2095},{"id":2173,"depth":912,"text":2174},{},{"title":105,"description":2202},1780436290773]