[{"data":1,"prerenderedAt":4438},["ShallowReactive",2],{"navigation_docs":3,"-modules-auth":153,"-modules-auth-surround":4433},[4,35,50,59,144],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting started",false,"\u002Fgetting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Local Development","\u002Fgetting-started\u002Flocal-development","1.getting-started\u002F3.local-development","i-lucide-terminal",{"title":21,"path":22,"stem":23,"icon":24},"Publishing Packages","\u002Fgetting-started\u002Fpublishing","1.getting-started\u002F4.publishing","i-lucide-package-check",{"title":26,"path":27,"stem":28,"icon":29},"Writing a Module","\u002Fgetting-started\u002Fwriting-a-module","1.getting-started\u002F5.writing-a-module","i-lucide-puzzle",{"title":31,"path":32,"stem":33,"icon":34},"UX Patterns","\u002Fgetting-started\u002Fux-patterns","1.getting-started\u002F6.ux-patterns","i-lucide-layout-template",{"title":36,"path":37,"stem":38,"children":39},"Applications","\u002Fapplications","2.applications",[40,45],{"title":41,"path":42,"stem":43,"icon":44},"Website","\u002Fapplications\u002Fwebsite","2.applications\u002F1.website","i-lucide-layout-dashboard",{"title":46,"path":47,"stem":48,"icon":49},"Docs","\u002Fapplications\u002Fdocs","2.applications\u002F2.docs","i-lucide-book-open",{"title":51,"path":52,"stem":53,"children":54},"Layers","\u002Flayers","3.layers",[55],{"title":56,"path":57,"stem":58},"Base Layer","\u002Flayers\u002Fbase","3.layers\u002F1.base",{"title":60,"path":61,"stem":62,"children":63},"Modules","\u002Fmodules","4.modules",[64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140],{"title":65,"path":66,"stem":67},"Account","\u002Fmodules\u002Faccount","4.modules\u002F01.account",{"title":69,"path":70,"stem":71},"Admin","\u002Fmodules\u002Fadmin","4.modules\u002F02.admin",{"title":73,"path":74,"stem":75},"Auth","\u002Fmodules\u002Fauth","4.modules\u002F03.auth",{"title":77,"path":78,"stem":79},"Authorization","\u002Fmodules\u002Fauthorization","4.modules\u002F04.authorization",{"title":81,"path":82,"stem":83},"Cookie Consent","\u002Fmodules\u002Fcookie-consent","4.modules\u002F05.cookie-consent",{"title":85,"path":86,"stem":87},"Events","\u002Fmodules\u002Fevents","4.modules\u002F06.events",{"title":89,"path":90,"stem":91},"Forms","\u002Fmodules\u002Fforms","4.modules\u002F07.forms",{"title":93,"path":94,"stem":95},"MCP","\u002Fmodules\u002Fmcp","4.modules\u002F08.mcp",{"title":97,"path":98,"stem":99},"Menu","\u002Fmodules\u002Fmenu","4.modules\u002F09.menu",{"title":101,"path":102,"stem":103},"Module Kit","\u002Fmodules\u002Fmodule-kit","4.modules\u002F10.module-kit",{"title":105,"path":106,"stem":107},"Notify","\u002Fmodules\u002Fnotify","4.modules\u002F11.notify",{"title":109,"path":110,"stem":111},"OAuth Server","\u002Fmodules\u002Foauth-server","4.modules\u002F12.oauth-server",{"title":113,"path":114,"stem":115},"Payments","\u002Fmodules\u002Fpayments","4.modules\u002F13.payments",{"title":117,"path":118,"stem":119},"Preferences","\u002Fmodules\u002Fpreferences","4.modules\u002F14.preferences",{"title":121,"path":122,"stem":123},"Stripe","\u002Fmodules\u002Fstripe","4.modules\u002F15.stripe",{"title":125,"path":126,"stem":127},"Subscriptions","\u002Fmodules\u002Fsubscriptions","4.modules\u002F16.subscriptions",{"title":129,"path":130,"stem":131},"UI","\u002Fmodules\u002Fui","4.modules\u002F17.ui",{"title":133,"path":134,"stem":135},"Users","\u002Fmodules\u002Fusers","4.modules\u002F18.users",{"title":137,"path":138,"stem":139},"Widget","\u002Fmodules\u002Fwidget","4.modules\u002F19.widget",{"title":141,"path":142,"stem":143},"Email Templates","\u002Fmodules\u002Femail-templates","4.modules\u002F20.email-templates",{"title":145,"path":146,"stem":147,"children":148},"Packages","\u002Fpackages","5.packages",[149],{"title":150,"path":151,"stem":152},"CLI","\u002Fpackages\u002Fcli","5.packages\u002F4.cli",{"id":154,"title":73,"body":155,"description":4427,"extension":4428,"links":4429,"meta":4430,"navigation":1611,"path":74,"seo":4431,"stem":75,"__hash__":4432},"docs\u002F4.modules\u002F03.auth.md",{"type":156,"value":157,"toc":4406},"minimark",[158,189,242,249,327,332,337,362,535,550,554,655,660,924,935,951,955,988,1120,1136,1217,1221,1225,1237,1354,1423,1650,1663,1666,1704,1717,1731,1751,1755,1758,1860,1871,1875,1885,2083,2149,2353,2356,2410,2449,2451,2478,2496,2601,2653,2656,2758,2762,2775,2799,2828,2832,2846,2946,2965,2980,2984,3014,3025,3157,3161,3164,3677,3684,3687,3757,3761,4118,4121,4124,4134,4227,4245,4249,4275,4346,4402],[159,160,161,162,169,170,174,175,177,178,180,181,183,184,188],"p",{},"The ",[163,164,168],"a",{"href":165,"rel":166},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002F4.x\u002Fguide\u002Fmodules",[167],"nofollow","Nuxt module"," that owns ",[171,172,173],"strong",{},"authentication",": how people sign in, and for\nevery server route, who is calling and how. ",[163,176,133],{"href":134},", ",[163,179,77],{"href":78},",\n",[163,182,109],{"href":110}," and the feature modules build on it; it depends on none of them and knows users\nonly through the ",[185,186,187],"code",{},"AuthUserStore"," that Users provides.",[190,191,192,232],"note",{},[159,193,194,197,198,177,201,177,204,209,210,215,216,219,220,223,224,227,228,231],{},[171,195,196],{},"Requires"," ",[185,199,200],{},"@nuxthub\u002Fcore",[185,202,203],{},"@frigear-nu\u002Fmodule-kit",[163,205,206],{"href":106},[185,207,208],{},"@frigear-nu\u002Fnotify"," (sign-in emails),\n",[163,211,212],{"href":98},[185,213,214],{},"@frigear-nu\u002Fmenu"," (logout item) and ",[185,217,218],{},"nuxt-auth-utils",". All are installed automatically. Passkeys\nneed the optional peers ",[185,221,222],{},"@simplewebauthn\u002Fbrowser"," and ",[185,225,226],{},"@simplewebauthn\u002Fserver","; the shipped pages need ",[185,229,230],{},"@nuxt\u002Fui",".",[159,233,234,235,237,238,241],{},"The config key is ",[185,236,173],{},", not ",[185,239,240],{},"auth"," (that belongs to nuxt-auth-utils).",[159,243,244,245,248],{},"A caller is one of three kinds, all resolved into the same ",[185,246,247],{},"AuthPrincipal",":",[250,251,252,270],"table",{},[253,254,255],"thead",{},[256,257,258,264,267],"tr",{},[259,260,261],"th",{},[185,262,263],{},"kind",[259,265,266],{},"Credential",[259,268,269],{},"Scopes",[271,272,273,295,311],"tbody",{},[256,274,275,281,288],{},[276,277,278],"td",{},[185,279,280],{},"session",[276,282,283,284],{},"Sealed cookie from ",[163,285,218],{"href":286,"rel":287},"https:\u002F\u002Fgithub.com\u002Fatinux\u002Fnuxt-auth-utils",[167],[276,289,290,291,294],{},"Everything (",[185,292,293],{},"*",")",[256,296,297,302,308],{},[276,298,299],{},[185,300,301],{},"user-token",[276,303,304,307],{},[185,305,306],{},"Authorization: Bearer fnu_…",", a static token the user created",[276,309,310],{},"The scopes chosen at creation",[256,312,313,318,324],{},[276,314,315],{},[185,316,317],{},"oauth",[276,319,320,323],{},[185,321,322],{},"Authorization: Bearer \u003CJWT>",", an access token issued to an application",[276,325,326],{},"The scopes the user granted",[328,329,331],"h2",{"id":330},"quick-setup","Quick setup",[159,333,334,336],{},[163,335,133],{"href":134}," installs Auth for you. Add it yourself when you use it on its own:",[338,339,344],"pre",{"className":340,"code":341,"language":342,"meta":343,"style":343},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @frigear-nu\u002Fauth\n","bash","",[185,345,346],{"__ignoreMap":343},[347,348,351,355,359],"span",{"class":349,"line":350},"line",1,[347,352,354],{"class":353},"sBMFI","pnpm",[347,356,358],{"class":357},"sfazB"," add",[347,360,361],{"class":357}," @frigear-nu\u002Fauth\n",[338,363,367],{"className":364,"code":365,"language":366,"meta":343,"style":343},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  modules: ['@nuxthub\u002Fcore', '@frigear-nu\u002Fauth'],\n  authentication: {\n    settings: {\n      password: true,\n      pages: { login: true, register: '\u002Fsign-up' },\n      oauth: { github: true },\n    },\n  },\n})\n","ts",[185,368,369,390,425,436,446,460,495,514,520,526],{"__ignoreMap":343},[347,370,371,375,378,382,386],{"class":349,"line":350},[347,372,374],{"class":373},"s7zQu","export",[347,376,377],{"class":373}," default",[347,379,381],{"class":380},"s2Zo4"," defineNuxtConfig",[347,383,385],{"class":384},"sTEyZ","(",[347,387,389],{"class":388},"sMK4o","{\n",[347,391,393,397,399,402,405,407,409,412,415,418,420,423],{"class":349,"line":392},2,[347,394,396],{"class":395},"swJcz","  modules",[347,398,248],{"class":388},[347,400,401],{"class":384}," [",[347,403,404],{"class":388},"'",[347,406,200],{"class":357},[347,408,404],{"class":388},[347,410,411],{"class":388},",",[347,413,414],{"class":388}," '",[347,416,417],{"class":357},"@frigear-nu\u002Fauth",[347,419,404],{"class":388},[347,421,422],{"class":384},"]",[347,424,180],{"class":388},[347,426,428,431,433],{"class":349,"line":427},3,[347,429,430],{"class":395},"  authentication",[347,432,248],{"class":388},[347,434,435],{"class":388}," {\n",[347,437,439,442,444],{"class":349,"line":438},4,[347,440,441],{"class":395},"    settings",[347,443,248],{"class":388},[347,445,435],{"class":388},[347,447,449,452,454,458],{"class":349,"line":448},5,[347,450,451],{"class":395},"      password",[347,453,248],{"class":388},[347,455,457],{"class":456},"sfNiH"," true",[347,459,180],{"class":388},[347,461,463,466,468,471,474,476,478,480,483,485,487,490,492],{"class":349,"line":462},6,[347,464,465],{"class":395},"      pages",[347,467,248],{"class":388},[347,469,470],{"class":388}," {",[347,472,473],{"class":395}," login",[347,475,248],{"class":388},[347,477,457],{"class":456},[347,479,411],{"class":388},[347,481,482],{"class":395}," register",[347,484,248],{"class":388},[347,486,414],{"class":388},[347,488,489],{"class":357},"\u002Fsign-up",[347,491,404],{"class":388},[347,493,494],{"class":388}," },\n",[347,496,498,501,503,505,508,510,512],{"class":349,"line":497},7,[347,499,500],{"class":395},"      oauth",[347,502,248],{"class":388},[347,504,470],{"class":388},[347,506,507],{"class":395}," github",[347,509,248],{"class":388},[347,511,457],{"class":456},[347,513,494],{"class":388},[347,515,517],{"class":349,"line":516},8,[347,518,519],{"class":388},"    },\n",[347,521,523],{"class":349,"line":522},9,[347,524,525],{"class":388},"  },\n",[347,527,529,532],{"class":349,"line":528},10,[347,530,531],{"class":388},"}",[347,533,534],{"class":384},")\n",[536,537,538,539,542,543,547,548,231],"warning",{},"The module extends the ",[185,540,541],{},"users"," table (see ",[163,544,546],{"href":545},"#database","Database","). That only changes the generated Drizzle schema, so\ngenerate and commit a migration in your app and in every fixture that includes the module. See\n",[163,549,101],{"href":102},[328,551,553],{"id":552},"options","Options",[250,555,556,572],{},[253,557,558],{},[256,559,560,563,566,569],{},[259,561,562],{},"Option",[259,564,565],{},"Type",[259,567,568],{},"Default",[259,570,571],{},"Purpose",[271,573,574,597,617,637],{},[256,575,576,581,586,591],{},[276,577,578],{},[185,579,580],{},"tokenTtlDays",[276,582,583],{},[185,584,585],{},"number | null",[276,587,588],{},[185,589,590],{},"null",[276,592,593,594,596],{},"Default lifetime for new user tokens; ",[185,595,590],{}," = never expire.",[256,598,599,604,609,612],{},[276,600,601],{},[185,602,603],{},"userStore",[276,605,606],{},[185,607,608],{},"string",[276,610,611],{},"the one from Users",[276,613,614,615,231],{},"Path to a module whose default export is an ",[185,616,187],{},[256,618,619,624,629,634],{},[276,620,621],{},[185,622,623],{},"scopes",[276,625,626],{},[185,627,628],{},"AuthScopeDefinition[]",[276,630,631],{},[185,632,633],{},"[]",[276,635,636],{},"Extra scopes users can pick for tokens.",[256,638,639,644,649,652],{},[276,640,641],{},[185,642,643],{},"settings",[276,645,646],{},[185,647,648],{},"AuthSettings",[276,650,651],{},"see below",[276,653,654],{},"The sign-in flows.",[656,657,658],"h3",{"id":643},[185,659,643],{},[250,661,662,674],{},[253,663,664],{},[256,665,666,668,670,672],{},[259,667,562],{},[259,669,565],{},[259,671,568],{},[259,673,571],{},[271,675,676,696,719,738,768,786,813,836,858,888,905],{},[256,677,678,683,688,693],{},[276,679,680],{},[185,681,682],{},"password",[276,684,685],{},[185,686,687],{},"boolean",[276,689,690],{},[185,691,692],{},"true",[276,694,695],{},"Email\u002Fpassword login and register routes, composables and pages.",[256,697,698,703,707,714],{},[276,699,700],{},[185,701,702],{},"passwordReset",[276,704,705],{},[185,706,687],{},[276,708,709,711,712],{},[185,710,692],{}," with ",[185,713,682],{},[276,715,716,717,231],{},"Forgot\u002Freset-password routes. Needs ",[185,718,682],{},[256,720,721,726,730,735],{},[276,722,723],{},[185,724,725],{},"webAuthn",[276,727,728],{},[185,729,687],{},[276,731,732],{},[185,733,734],{},"false",[276,736,737],{},"Passkey routes, composables and table.",[256,739,740,745,750,753],{},[276,741,742],{},[185,743,744],{},"magicLink",[276,746,747],{},[185,748,749],{},"boolean | { signUp?, cooldown? }",[276,751,752],{},"off",[276,754,755,756,759,760,763,764,767],{},"Emailed single-use sign-in link. Following it verifies the address. ",[185,757,758],{},"signUp: true"," creates accounts for unknown addresses; ",[185,761,762],{},"cooldown"," = minimum seconds between two links for one user (default ",[185,765,766],{},"60",").",[256,769,770,775,779,783],{},[276,771,772],{},[185,773,774],{},"verifyEmail",[276,776,777],{},[185,778,687],{},[276,780,781],{},[185,782,734],{},[276,784,785],{},"Users who register with a password must verify their address (emailed link) before they can log in; registration creates no session.",[256,787,788,793,798,803],{},[276,789,790],{},[185,791,792],{},"cleanup",[276,794,795],{},[185,796,797],{},"string | false",[276,799,800],{},[185,801,802],{},"'0 3 * * *'",[276,804,805,806,809,810,812],{},"Cron for the ",[185,807,808],{},"auth:clear-expired-tokens"," task (expired magic links and resets); ",[185,811,734],{}," schedules nothing, the task stays registered.",[256,814,815,820,825,827],{},[276,816,817],{},[185,818,819],{},"pages.login",[276,821,822],{},[185,823,824],{},"string | boolean",[276,826,752],{},[276,828,829,830,832,833,231],{},"Login page. ",[185,831,692],{}," = ",[185,834,835],{},"\u002Flogin",[256,837,838,843,847,849],{},[276,839,840],{},[185,841,842],{},"pages.register",[276,844,845],{},[185,846,824],{},[276,848,752],{},[276,850,851,852,832,854,857],{},"Register page. ",[185,853,692],{},[185,855,856],{},"\u002Fregister",". May be an absolute URL: the login page links to it and no local page is added.",[256,859,860,865,869,874],{},[276,861,862],{},[185,863,864],{},"afterLogin",[276,866,867],{},[185,868,608],{},[276,870,871],{},[185,872,873],{},"'\u002F'",[276,875,876,877,880,881,883,884,887],{},"Where users land after signing in (password, passkey, magic link, OAuth\u002FSSO) when no ",[185,878,879],{},"?redirect="," was requested. Must be an absolute path on this site. A ",[185,882,879],{}," on the login page or on ",[185,885,886],{},"\u002Fapi\u002Fauth\u002F\u003Cprovider>"," takes precedence.",[256,889,890,895,899,902],{},[276,891,892],{},[185,893,894],{},"session.mapper",[276,896,897],{},[185,898,608],{},[276,900,901],{},"pass-through",[276,903,904],{},"Path to a default-export function mapping the stored user to the session user shape.",[256,906,907,911,916,921],{},[276,908,909],{},[185,910,317],{},[276,912,913],{},[185,914,915],{},"{ github?, google?, facebook?, frigear? }",[276,917,918],{},[185,919,920],{},"{}",[276,922,923],{},"Registers the shipped OAuth routes.",[159,925,926,927,930,931,934],{},"Provider credentials are read by nuxt-auth-utils from ",[185,928,929],{},"NUXT_OAUTH_\u003CPROVIDER>_CLIENT_ID"," and\n",[185,932,933],{},"NUXT_OAUTH_\u003CPROVIDER>_CLIENT_SECRET",". Other nuxt-auth-utils providers can be added in the host app.",[159,936,937,938,940,941,930,944,947,948,950],{},"The login and register pages are enabled per path. With ",[185,939,819],{}," the module also registers ",[185,942,943],{},"\u002Fforgot-password",[185,945,946],{},"\u002Freset-password"," (when ",[185,949,702],{}," is on). The login page renders the password form, passkey and magic link\ncontrols and OAuth buttons that are actually enabled.",[656,952,954],{"id":953},"log-in-with-frigearnu","Log in with frigear.nu",[159,956,957,960,961,964,965,968,969,972,973,975,976,979,980,983,984,987],{},[185,958,959],{},"oauth.frigear"," registers ",[185,962,963],{},"GET \u002Fauth\u002Ffrigear",", an OIDC login against frigear.nu for PR previews and local development.\nIt is decided ",[171,966,967],{},"per request",": active when ",[185,970,971],{},"runtimeConfig.previewDeployment"," is ",[185,974,692],{}," or ",[185,977,978],{},"runtimeConfig.frigear.sso","\nhas a client id and secret; otherwise the route answers ",[185,981,982],{},"404"," and the button is hidden. Register ",[185,985,986],{},"\u003Corigin>\u002Fauth\u002Ffrigear","\nas the callback on frigear.nu.",[250,989,990,1002],{},[253,991,992],{},[256,993,994,997,1000],{},[259,995,996],{},"Runtime config",[259,998,999],{},"Env var",[259,1001,571],{},[271,1003,1004,1019,1034,1049,1064,1085,1105],{},[256,1005,1006,1011,1016],{},[276,1007,1008],{},[185,1009,1010],{},"previewDeployment",[276,1012,1013],{},[185,1014,1015],{},"NUXT_PREVIEW_DEPLOYMENT",[276,1017,1018],{},"Enables the login without credentials (set it yourself, e.g. from a CI marker).",[256,1020,1021,1026,1031],{},[276,1022,1023],{},[185,1024,1025],{},"frigear.sso.url",[276,1027,1028],{},[185,1029,1030],{},"NUXT_FRIGEAR_SSO_URL",[276,1032,1033],{},"Identity provider origin (defaults to the frigear.nu origin).",[256,1035,1036,1041,1046],{},[276,1037,1038],{},[185,1039,1040],{},"frigear.sso.clientId",[276,1042,1043],{},[185,1044,1045],{},"NUXT_FRIGEAR_SSO_CLIENT_ID",[276,1047,1048],{},"OAuth client id.",[256,1050,1051,1056,1061],{},[276,1052,1053],{},[185,1054,1055],{},"frigear.sso.clientSecret",[276,1057,1058],{},[185,1059,1060],{},"NUXT_FRIGEAR_SSO_CLIENT_SECRET",[276,1062,1063],{},"OAuth client secret.",[256,1065,1066,1071,1076],{},[276,1067,1068],{},[185,1069,1070],{},"frigear.forceId",[276,1072,1073],{},[185,1074,1075],{},"NUXT_FRIGEAR_FORCE_ID",[276,1077,1078,1079,1082,1083,767],{},"Make the local ",[185,1080,1081],{},"users.id"," equal the frigear.nu id (default ",[185,1084,734],{},[256,1086,1087,1092,1095],{},[276,1088,1089],{},[185,1090,1091],{},"frigear.syncRole",[276,1093,1094],{},"-",[276,1096,1097,1098,1100,1101,1104],{},"Apply the role claim at every login (default ",[185,1099,692],{},"). Declare it in your ",[185,1102,1103],{},"runtimeConfig"," to override.",[256,1106,1107,1112,1117],{},[276,1108,1109],{},[185,1110,1111],{},"public.authentication.frigearSso",[276,1113,1114],{},[185,1115,1116],{},"NUXT_PUBLIC_AUTHENTICATION_FRIGEAR_SSO",[276,1118,1119],{},"Show the login button; a build-time default, overridable at runtime.",[159,1121,1122,1123,1126,1127,180,1130,223,1133,231],{},"Instead of ",[185,1124,1125],{},"frigear.sso",", the credentials can come from nuxt-auth-utils' ",[185,1128,1129],{},"NUXT_OAUTH_OIDC_CLIENT_ID",[185,1131,1132],{},"NUXT_OAUTH_OIDC_CLIENT_SECRET",[185,1134,1135],{},"NUXT_OAUTH_OIDC_OPENID_CONFIG",[1137,1138,1139,1154,1163,1196],"ul",{},[1140,1141,161,1142,1145,1146,1149,1150,1153],"li",{},[185,1143,1144],{},"id_token"," is verified against the provider's ",[185,1147,1148],{},"jwks_uri"," (cached for an hour), including issuer and audience.\nUsers are matched by email; a verified ",[185,1151,1152],{},"email_verified"," claim verifies the address.",[1140,1155,1156,1159,1160,1162],{},[185,1157,1158],{},"forceId"," updates a user with that id, re-keys an existing user with the same email (rows referencing ",[185,1161,1081],{},"\nfollow; a different user holding the id moves to the next free id), or creates a user with that id.",[1140,1164,161,1165,1168,1169,1172,1173,1176,1177,1179,1180,1183,1184,1186,1187,1189,1190,1193,1194,231],{},[185,1166,1167],{},"role"," claim, else the namespaced ",[185,1170,1171],{},"https:\u002F\u002Ffrigear.nu\u002Fclaims\u002Frole",", else the first of ",[185,1174,1175],{},"roles",", is applied to the\nlocal ",[185,1178,1167],{}," at ",[171,1181,1182],{},"every login",". Without a claim the stored role is left alone. It needs the ",[185,1185,1167],{}," column of\n",[163,1188,77],{"href":78},". These claim names follow the current frigear.nu and will change when this\napp becomes frigear.nu. The provider side is the host's: add the claim in the ",[185,1191,1192],{},"oauth:claims"," hook of\n",[163,1195,109],{"href":110},[1140,1197,1198,1199,1202,1203,177,1206,177,1209,1212,1213,1216],{},"The optional ",[185,1200,1201],{},"color_mode"," claim (",[185,1204,1205],{},"light",[185,1207,1208],{},"dark",[185,1210,1211],{},"system",") is kept on the session as ",[185,1214,1215],{},"frigear.colorMode"," and applied\nonce per login.",[328,1218,1220],{"id":1219},"server","Server",[656,1222,1224],{"id":1223},"protecting-a-route","Protecting a route",[159,1226,1227,223,1230,1233,1234,231],{},[185,1228,1229],{},"requireAuth",[185,1231,1232],{},"getAuth"," are auto-imported in server code; use them instead of nuxt-auth-utils'\n",[185,1235,1236],{},"requireUserSession",[338,1238,1240],{"className":364,"code":1239,"language":366,"meta":343,"style":343},"\u002F\u002F server\u002Fapi\u002Ftickets.get.ts\nexport default defineEventHandler(async (event) => {\n  const { user } = await requireAuth(event, { scopes: ['tickets:read'] })\n  return getTickets(user.id)\n})\n",[185,1241,1242,1248,1277,1328,1348],{"__ignoreMap":343},[347,1243,1244],{"class":349,"line":350},[347,1245,1247],{"class":1246},"sHwdD","\u002F\u002F server\u002Fapi\u002Ftickets.get.ts\n",[347,1249,1250,1252,1254,1257,1259,1263,1266,1270,1272,1275],{"class":349,"line":392},[347,1251,374],{"class":373},[347,1253,377],{"class":373},[347,1255,1256],{"class":380}," defineEventHandler",[347,1258,385],{"class":384},[347,1260,1262],{"class":1261},"spNyl","async",[347,1264,1265],{"class":388}," (",[347,1267,1269],{"class":1268},"sHdIc","event",[347,1271,294],{"class":388},[347,1273,1274],{"class":1261}," =>",[347,1276,435],{"class":388},[347,1278,1279,1282,1284,1287,1290,1293,1296,1299,1301,1303,1305,1307,1310,1312,1314,1316,1319,1321,1324,1326],{"class":349,"line":427},[347,1280,1281],{"class":1261},"  const",[347,1283,470],{"class":388},[347,1285,1286],{"class":384}," user",[347,1288,1289],{"class":388}," }",[347,1291,1292],{"class":388}," =",[347,1294,1295],{"class":373}," await",[347,1297,1298],{"class":380}," requireAuth",[347,1300,385],{"class":395},[347,1302,1269],{"class":384},[347,1304,411],{"class":388},[347,1306,470],{"class":388},[347,1308,1309],{"class":395}," scopes",[347,1311,248],{"class":388},[347,1313,401],{"class":395},[347,1315,404],{"class":388},[347,1317,1318],{"class":357},"tickets:read",[347,1320,404],{"class":388},[347,1322,1323],{"class":395},"] ",[347,1325,531],{"class":388},[347,1327,534],{"class":395},[347,1329,1330,1333,1336,1338,1341,1343,1346],{"class":349,"line":438},[347,1331,1332],{"class":373},"  return",[347,1334,1335],{"class":380}," getTickets",[347,1337,385],{"class":395},[347,1339,1340],{"class":384},"user",[347,1342,231],{"class":388},[347,1344,1345],{"class":384},"id",[347,1347,534],{"class":395},[347,1349,1350,1352],{"class":349,"line":448},[347,1351,531],{"class":388},[347,1353,534],{"class":384},[250,1355,1356,1366],{},[253,1357,1358],{},[256,1359,1360,1363],{},[259,1361,1362],{},"Call",[259,1364,1365],{},"Behaviour",[271,1367,1368,1382,1396,1410],{},[256,1369,1370,1375],{},[276,1371,1372],{},[185,1373,1374],{},"requireAuth(event)",[276,1376,1377,1378,1381],{},"The principal from any credential. ",[185,1379,1380],{},"401"," without a valid one.",[256,1383,1384,1389],{},[276,1385,1386],{},[185,1387,1388],{},"requireAuth(event, { scopes })",[276,1390,1391,1392,1395],{},"Also needs every scope. ",[185,1393,1394],{},"403 insufficient_scope"," otherwise. Sessions pass.",[256,1397,1398,1403],{},[276,1399,1400],{},[185,1401,1402],{},"requireAuth(event, { sessionOnly: true })",[276,1404,1405,1406,1409],{},"Cookie sessions only. ",[185,1407,1408],{},"403 session_required"," for tokens.",[256,1411,1412,1417],{},[276,1413,1414],{},[185,1415,1416],{},"getAuth(event)",[276,1418,1419,1420,1422],{},"The principal or ",[185,1421,590],{},". Never throws.",[338,1424,1426],{"className":364,"code":1425,"language":366,"meta":343,"style":343},"type AuthPrincipal =\n  | { kind: 'session', user: AuthUser, scopes: string[] }\n  | { kind: 'user-token', user: AuthUser, scopes: string[], token: { id: string, name: string, prefix: string } }\n  | { kind: 'oauth', user: AuthUser, scopes: string[], client: { id: string } }\n\ninterface RequireUserOptions {\n  scopes?: string[]\n  sessionOnly?: boolean\n}\n",[185,1427,1428,1439,1481,1554,1607,1613,1623,1636,1646],{"__ignoreMap":343},[347,1429,1430,1433,1436],{"class":349,"line":350},[347,1431,1432],{"class":1261},"type",[347,1434,1435],{"class":353}," AuthPrincipal",[347,1437,1438],{"class":388}," =\n",[347,1440,1441,1444,1446,1449,1451,1453,1455,1457,1459,1461,1463,1466,1468,1470,1472,1475,1478],{"class":349,"line":392},[347,1442,1443],{"class":388},"  |",[347,1445,470],{"class":388},[347,1447,1448],{"class":395}," kind",[347,1450,248],{"class":388},[347,1452,414],{"class":388},[347,1454,280],{"class":357},[347,1456,404],{"class":388},[347,1458,411],{"class":388},[347,1460,1286],{"class":395},[347,1462,248],{"class":388},[347,1464,1465],{"class":353}," AuthUser",[347,1467,411],{"class":388},[347,1469,1309],{"class":395},[347,1471,248],{"class":388},[347,1473,1474],{"class":353}," string",[347,1476,1477],{"class":384},"[] ",[347,1479,1480],{"class":388},"}\n",[347,1482,1483,1485,1487,1489,1491,1493,1495,1497,1499,1501,1503,1505,1507,1509,1511,1513,1515,1517,1520,1522,1524,1527,1529,1531,1533,1536,1538,1540,1542,1545,1547,1549,1551],{"class":349,"line":427},[347,1484,1443],{"class":388},[347,1486,470],{"class":388},[347,1488,1448],{"class":395},[347,1490,248],{"class":388},[347,1492,414],{"class":388},[347,1494,301],{"class":357},[347,1496,404],{"class":388},[347,1498,411],{"class":388},[347,1500,1286],{"class":395},[347,1502,248],{"class":388},[347,1504,1465],{"class":353},[347,1506,411],{"class":388},[347,1508,1309],{"class":395},[347,1510,248],{"class":388},[347,1512,1474],{"class":353},[347,1514,633],{"class":384},[347,1516,411],{"class":388},[347,1518,1519],{"class":395}," token",[347,1521,248],{"class":388},[347,1523,470],{"class":388},[347,1525,1526],{"class":395}," id",[347,1528,248],{"class":388},[347,1530,1474],{"class":353},[347,1532,411],{"class":388},[347,1534,1535],{"class":395}," name",[347,1537,248],{"class":388},[347,1539,1474],{"class":353},[347,1541,411],{"class":388},[347,1543,1544],{"class":395}," prefix",[347,1546,248],{"class":388},[347,1548,1474],{"class":353},[347,1550,1289],{"class":388},[347,1552,1553],{"class":388}," }\n",[347,1555,1556,1558,1560,1562,1564,1566,1568,1570,1572,1574,1576,1578,1580,1582,1584,1586,1588,1590,1593,1595,1597,1599,1601,1603,1605],{"class":349,"line":438},[347,1557,1443],{"class":388},[347,1559,470],{"class":388},[347,1561,1448],{"class":395},[347,1563,248],{"class":388},[347,1565,414],{"class":388},[347,1567,317],{"class":357},[347,1569,404],{"class":388},[347,1571,411],{"class":388},[347,1573,1286],{"class":395},[347,1575,248],{"class":388},[347,1577,1465],{"class":353},[347,1579,411],{"class":388},[347,1581,1309],{"class":395},[347,1583,248],{"class":388},[347,1585,1474],{"class":353},[347,1587,633],{"class":384},[347,1589,411],{"class":388},[347,1591,1592],{"class":395}," client",[347,1594,248],{"class":388},[347,1596,470],{"class":388},[347,1598,1526],{"class":395},[347,1600,248],{"class":388},[347,1602,1474],{"class":353},[347,1604,1289],{"class":388},[347,1606,1553],{"class":388},[347,1608,1609],{"class":349,"line":448},[347,1610,1612],{"emptyLinePlaceholder":1611},true,"\n",[347,1614,1615,1618,1621],{"class":349,"line":462},[347,1616,1617],{"class":1261},"interface",[347,1619,1620],{"class":353}," RequireUserOptions",[347,1622,435],{"class":388},[347,1624,1625,1628,1631,1633],{"class":349,"line":497},[347,1626,1627],{"class":395},"  scopes",[347,1629,1630],{"class":388},"?:",[347,1632,1474],{"class":353},[347,1634,1635],{"class":384},"[]\n",[347,1637,1638,1641,1643],{"class":349,"line":516},[347,1639,1640],{"class":395},"  sessionOnly",[347,1642,1630],{"class":388},[347,1644,1645],{"class":353}," boolean\n",[347,1647,1648],{"class":349,"line":522},[347,1649,1480],{"class":388},[159,1651,1652,1655,1656,223,1659,1662],{},[163,1653,133],{"href":1654},"\u002Fmodules\u002Fusers#server"," builds ",[185,1657,1658],{},"requireUser(event, options)",[185,1660,1661],{},"getUser(event, { scopes })"," on\ntop, returning just the user.",[159,1664,1665],{},"Other server helpers:",[338,1667,1669],{"className":364,"code":1668,"language":366,"meta":343,"style":343},"mapUserToSession(storedUser) \u002F\u002F strips the password hash and applies `session.mapper`; use it to refresh the session\ngetLoginPath(event) \u002F\u002F the login page path (`pages.login`, else `\u002Flogin`)\ndeleteUserAuthData(userId) \u002F\u002F removes tokens, passkeys, reset codes and sign-in links (call when deleting a user)\n",[185,1670,1671,1682,1693],{"__ignoreMap":343},[347,1672,1673,1676,1679],{"class":349,"line":350},[347,1674,1675],{"class":380},"mapUserToSession",[347,1677,1678],{"class":384},"(storedUser) ",[347,1680,1681],{"class":1246},"\u002F\u002F strips the password hash and applies `session.mapper`; use it to refresh the session\n",[347,1683,1684,1687,1690],{"class":349,"line":392},[347,1685,1686],{"class":380},"getLoginPath",[347,1688,1689],{"class":384},"(event) ",[347,1691,1692],{"class":1246},"\u002F\u002F the login page path (`pages.login`, else `\u002Flogin`)\n",[347,1694,1695,1698,1701],{"class":349,"line":427},[347,1696,1697],{"class":380},"deleteUserAuthData",[347,1699,1700],{"class":384},"(userId) ",[347,1702,1703],{"class":1246},"\u002F\u002F removes tokens, passkeys, reset codes and sign-in links (call when deleting a user)\n",[159,1705,1706,1709,1710,1713,1714,1716],{},[171,1707,1708],{},"Which routes should accept tokens?"," Default to ",[171,1711,1712],{},"session only"," for anything that changes who the user is or how\nthey sign in (password, email, passkeys, profile, cookie consent, billing portal, OAuth consent, the users admin,\nmanaging API tokens). Use ",[185,1715,623],{}," for reads and actions an integration plausibly needs: tickets, subscriptions, form\nsubmissions.",[159,1718,1719,1720,1723,1724,1727,1728,767],{},"Roles stay authoritative. A token carries no role: the user is loaded from the database on ",[171,1721,1722],{},"every"," bearer request, so\na role change, a ban or a deleted account applies to the next call. A ",[171,1725,1726],{},"cookie session"," holds a snapshot from login\ntime, so a role change reaches it after the next sign-in (see ",[163,1729,77],{"href":1730},"\u002Fmodules\u002Fauthorization#roles-in-sessions-and-tokens",[159,1732,1733,1734,1737,1738,1265,1741,177,1743,1746,1747,1750],{},"A request that carries a token a resolver claims (",[185,1735,1736],{},"fnu_…"," or a JWT) and it is invalid, expired or revoked is\n",[171,1739,1740],{},"unauthenticated",[185,1742,1380],{},[185,1744,1745],{},"WWW-Authenticate: Bearer error=\"invalid_token\"","), even with a valid session cookie.\nTokens no resolver claims, such as per-form ",[185,1748,1749],{},"ffk_"," tokens, are ignored and the other credentials apply.",[656,1752,1754],{"id":1753},"policy-gates","Policy gates",[159,1756,1757],{},"Staff gates are decided by the host through a Nitro hook, denied by default. A module defines them without knowing who\nis staff:",[338,1759,1761],{"className":364,"code":1760,"language":366,"meta":343,"style":343},"const gate = definePolicyGate('events:authorize')\nawait gate.assert(event, userId) \u002F\u002F 403 unless a hook listener sets ctx.allowed = true\n\n\u002F\u002F A Nitro plugin that only offers these scopes to users the gate lets in\nexport default defineStaffScopes(['events:manage', 'events:pii'], gate.isAllowed)\n",[185,1762,1763,1788,1812,1816,1821],{"__ignoreMap":343},[347,1764,1765,1768,1771,1774,1777,1779,1781,1784,1786],{"class":349,"line":350},[347,1766,1767],{"class":1261},"const",[347,1769,1770],{"class":384}," gate ",[347,1772,1773],{"class":388},"=",[347,1775,1776],{"class":380}," definePolicyGate",[347,1778,385],{"class":384},[347,1780,404],{"class":388},[347,1782,1783],{"class":357},"events:authorize",[347,1785,404],{"class":388},[347,1787,534],{"class":384},[347,1789,1790,1793,1796,1798,1801,1804,1806,1809],{"class":349,"line":392},[347,1791,1792],{"class":373},"await",[347,1794,1795],{"class":384}," gate",[347,1797,231],{"class":388},[347,1799,1800],{"class":380},"assert",[347,1802,1803],{"class":384},"(event",[347,1805,411],{"class":388},[347,1807,1808],{"class":384}," userId) ",[347,1810,1811],{"class":1246},"\u002F\u002F 403 unless a hook listener sets ctx.allowed = true\n",[347,1813,1814],{"class":349,"line":427},[347,1815,1612],{"emptyLinePlaceholder":1611},[347,1817,1818],{"class":349,"line":438},[347,1819,1820],{"class":1246},"\u002F\u002F A Nitro plugin that only offers these scopes to users the gate lets in\n",[347,1822,1823,1825,1827,1830,1833,1835,1838,1840,1842,1844,1847,1849,1851,1853,1855,1857],{"class":349,"line":448},[347,1824,374],{"class":373},[347,1826,377],{"class":373},[347,1828,1829],{"class":380}," defineStaffScopes",[347,1831,1832],{"class":384},"([",[347,1834,404],{"class":388},[347,1836,1837],{"class":357},"events:manage",[347,1839,404],{"class":388},[347,1841,411],{"class":388},[347,1843,414],{"class":388},[347,1845,1846],{"class":357},"events:pii",[347,1848,404],{"class":388},[347,1850,422],{"class":384},[347,1852,411],{"class":388},[347,1854,1795],{"class":384},[347,1856,231],{"class":388},[347,1858,1859],{"class":384},"isAllowed)\n",[159,1861,1862,1863,1866,1867,1870],{},"Host listeners must identify the caller from ",[185,1864,1865],{},"ctx.userId",", never from the session on ",[185,1868,1869],{},"ctx.event",": the session is empty\nfor bearer requests.",[656,1872,1874],{"id":1873},"extending-build-time","Extending (build time)",[159,1876,1877,1878,1881,1882,248],{},"A module's ",[185,1879,1880],{},"setup()"," can import these from ",[185,1883,1884],{},"@frigear-nu\u002Fauth\u002Futils",[338,1886,1888],{"className":364,"code":1887,"language":366,"meta":343,"style":343},"addAuthScope(nuxt, { name: 'reports:admin', description: 'Run reports', roles: ['admin'] })\n\naddAuthResolver(nuxt, {\n  name: 'my-tokens',\n  prefix: 'mt_', \u002F\u002F or `jwt: true`; one of the two is required\n  resolver: resolver.resolve('.\u002Fruntime\u002Fserver\u002Fresolvers\u002Fmy-token'),\n  order: 100, \u002F\u002F lower runs first\n})\n\nsetAuthUserStore(nuxt, resolver.resolve('.\u002Fruntime\u002Fserver\u002Fuser-store')) \u002F\u002F first registration wins\n",[185,1889,1890,1949,1953,1964,1980,1999,2027,2043,2049,2053],{"__ignoreMap":343},[347,1891,1892,1895,1898,1900,1902,1904,1906,1908,1911,1913,1915,1918,1920,1922,1925,1927,1929,1932,1934,1936,1938,1941,1943,1945,1947],{"class":349,"line":350},[347,1893,1894],{"class":380},"addAuthScope",[347,1896,1897],{"class":384},"(nuxt",[347,1899,411],{"class":388},[347,1901,470],{"class":388},[347,1903,1535],{"class":395},[347,1905,248],{"class":388},[347,1907,414],{"class":388},[347,1909,1910],{"class":357},"reports:admin",[347,1912,404],{"class":388},[347,1914,411],{"class":388},[347,1916,1917],{"class":395}," description",[347,1919,248],{"class":388},[347,1921,414],{"class":388},[347,1923,1924],{"class":357},"Run reports",[347,1926,404],{"class":388},[347,1928,411],{"class":388},[347,1930,1931],{"class":395}," roles",[347,1933,248],{"class":388},[347,1935,401],{"class":384},[347,1937,404],{"class":388},[347,1939,1940],{"class":357},"admin",[347,1942,404],{"class":388},[347,1944,1323],{"class":384},[347,1946,531],{"class":388},[347,1948,534],{"class":384},[347,1950,1951],{"class":349,"line":392},[347,1952,1612],{"emptyLinePlaceholder":1611},[347,1954,1955,1958,1960,1962],{"class":349,"line":427},[347,1956,1957],{"class":380},"addAuthResolver",[347,1959,1897],{"class":384},[347,1961,411],{"class":388},[347,1963,435],{"class":388},[347,1965,1966,1969,1971,1973,1976,1978],{"class":349,"line":438},[347,1967,1968],{"class":395},"  name",[347,1970,248],{"class":388},[347,1972,414],{"class":388},[347,1974,1975],{"class":357},"my-tokens",[347,1977,404],{"class":388},[347,1979,180],{"class":388},[347,1981,1982,1985,1987,1989,1992,1994,1996],{"class":349,"line":448},[347,1983,1984],{"class":395},"  prefix",[347,1986,248],{"class":388},[347,1988,414],{"class":388},[347,1990,1991],{"class":357},"mt_",[347,1993,404],{"class":388},[347,1995,411],{"class":388},[347,1997,1998],{"class":1246}," \u002F\u002F or `jwt: true`; one of the two is required\n",[347,2000,2001,2004,2006,2009,2011,2014,2016,2018,2021,2023,2025],{"class":349,"line":462},[347,2002,2003],{"class":395},"  resolver",[347,2005,248],{"class":388},[347,2007,2008],{"class":384}," resolver",[347,2010,231],{"class":388},[347,2012,2013],{"class":380},"resolve",[347,2015,385],{"class":384},[347,2017,404],{"class":388},[347,2019,2020],{"class":357},".\u002Fruntime\u002Fserver\u002Fresolvers\u002Fmy-token",[347,2022,404],{"class":388},[347,2024,294],{"class":384},[347,2026,180],{"class":388},[347,2028,2029,2032,2034,2038,2040],{"class":349,"line":497},[347,2030,2031],{"class":395},"  order",[347,2033,248],{"class":388},[347,2035,2037],{"class":2036},"sbssI"," 100",[347,2039,411],{"class":388},[347,2041,2042],{"class":1246}," \u002F\u002F lower runs first\n",[347,2044,2045,2047],{"class":349,"line":516},[347,2046,531],{"class":388},[347,2048,534],{"class":384},[347,2050,2051],{"class":349,"line":522},[347,2052,1612],{"emptyLinePlaceholder":1611},[347,2054,2055,2058,2060,2062,2064,2066,2068,2070,2072,2075,2077,2080],{"class":349,"line":528},[347,2056,2057],{"class":380},"setAuthUserStore",[347,2059,1897],{"class":384},[347,2061,411],{"class":388},[347,2063,2008],{"class":384},[347,2065,231],{"class":388},[347,2067,2013],{"class":380},[347,2069,385],{"class":384},[347,2071,404],{"class":388},[347,2073,2074],{"class":357},".\u002Fruntime\u002Fserver\u002Fuser-store",[347,2076,404],{"class":388},[347,2078,2079],{"class":384},")) ",[347,2081,2082],{"class":1246},"\u002F\u002F first registration wins\n",[338,2084,2086],{"className":364,"code":2085,"language":366,"meta":343,"style":343},"\u002F\u002F resolver: return a principal, or null when the token is invalid\nexport default async function (event: H3Event, token: string): Promise\u003CAuthPrincipal | null> { … }\n",[185,2087,2088,2093],{"__ignoreMap":343},[347,2089,2090],{"class":349,"line":350},[347,2091,2092],{"class":1246},"\u002F\u002F resolver: return a principal, or null when the token is invalid\n",[347,2094,2095,2097,2099,2102,2105,2107,2109,2111,2114,2116,2118,2120,2122,2125,2128,2131,2133,2136,2139,2142,2144,2147],{"class":349,"line":392},[347,2096,374],{"class":373},[347,2098,377],{"class":373},[347,2100,2101],{"class":1261}," async",[347,2103,2104],{"class":1261}," function",[347,2106,1265],{"class":388},[347,2108,1269],{"class":1268},[347,2110,248],{"class":388},[347,2112,2113],{"class":353}," H3Event",[347,2115,411],{"class":388},[347,2117,1519],{"class":1268},[347,2119,248],{"class":388},[347,2121,1474],{"class":353},[347,2123,2124],{"class":388},"):",[347,2126,2127],{"class":353}," Promise",[347,2129,2130],{"class":388},"\u003C",[347,2132,247],{"class":353},[347,2134,2135],{"class":388}," |",[347,2137,2138],{"class":353}," null",[347,2140,2141],{"class":388},">",[347,2143,470],{"class":388},[347,2145,2146],{"class":395}," … ",[347,2148,1480],{"class":388},[338,2150,2152],{"className":364,"code":2151,"language":366,"meta":343,"style":343},"interface AuthUserStore {\n  findById(id: string | number): Promise\u003CAuthStoredUser | null>\n  findByEmail(email: string): Promise\u003CAuthStoredUser | null>\n  create(values: AuthUserCreate): Promise\u003CAuthStoredUser>\n  update(id: number, values: AuthUserUpdate): Promise\u003CAuthStoredUser | null>\n  remove(id: number): Promise\u003Cvoid>\n  \u002F** Gives the user a new id, taking everything that references it along. *\u002F\n  changeId(from: number, to: number): Promise\u003Cvoid>\n}\n",[185,2153,2154,2163,2197,2225,2250,2287,2311,2316,2349],{"__ignoreMap":343},[347,2155,2156,2158,2161],{"class":349,"line":350},[347,2157,1617],{"class":1261},[347,2159,2160],{"class":353}," AuthUserStore",[347,2162,435],{"class":388},[347,2164,2165,2168,2170,2172,2174,2176,2178,2181,2183,2185,2187,2190,2192,2194],{"class":349,"line":392},[347,2166,2167],{"class":395},"  findById",[347,2169,385],{"class":388},[347,2171,1345],{"class":1268},[347,2173,248],{"class":388},[347,2175,1474],{"class":353},[347,2177,2135],{"class":388},[347,2179,2180],{"class":353}," number",[347,2182,2124],{"class":388},[347,2184,2127],{"class":353},[347,2186,2130],{"class":388},[347,2188,2189],{"class":353},"AuthStoredUser",[347,2191,2135],{"class":388},[347,2193,2138],{"class":353},[347,2195,2196],{"class":388},">\n",[347,2198,2199,2202,2204,2207,2209,2211,2213,2215,2217,2219,2221,2223],{"class":349,"line":427},[347,2200,2201],{"class":395},"  findByEmail",[347,2203,385],{"class":388},[347,2205,2206],{"class":1268},"email",[347,2208,248],{"class":388},[347,2210,1474],{"class":353},[347,2212,2124],{"class":388},[347,2214,2127],{"class":353},[347,2216,2130],{"class":388},[347,2218,2189],{"class":353},[347,2220,2135],{"class":388},[347,2222,2138],{"class":353},[347,2224,2196],{"class":388},[347,2226,2227,2230,2232,2235,2237,2240,2242,2244,2246,2248],{"class":349,"line":438},[347,2228,2229],{"class":395},"  create",[347,2231,385],{"class":388},[347,2233,2234],{"class":1268},"values",[347,2236,248],{"class":388},[347,2238,2239],{"class":353}," AuthUserCreate",[347,2241,2124],{"class":388},[347,2243,2127],{"class":353},[347,2245,2130],{"class":388},[347,2247,2189],{"class":353},[347,2249,2196],{"class":388},[347,2251,2252,2255,2257,2259,2261,2263,2265,2268,2270,2273,2275,2277,2279,2281,2283,2285],{"class":349,"line":448},[347,2253,2254],{"class":395},"  update",[347,2256,385],{"class":388},[347,2258,1345],{"class":1268},[347,2260,248],{"class":388},[347,2262,2180],{"class":353},[347,2264,411],{"class":388},[347,2266,2267],{"class":1268}," values",[347,2269,248],{"class":388},[347,2271,2272],{"class":353}," AuthUserUpdate",[347,2274,2124],{"class":388},[347,2276,2127],{"class":353},[347,2278,2130],{"class":388},[347,2280,2189],{"class":353},[347,2282,2135],{"class":388},[347,2284,2138],{"class":353},[347,2286,2196],{"class":388},[347,2288,2289,2292,2294,2296,2298,2300,2302,2304,2306,2309],{"class":349,"line":462},[347,2290,2291],{"class":395},"  remove",[347,2293,385],{"class":388},[347,2295,1345],{"class":1268},[347,2297,248],{"class":388},[347,2299,2180],{"class":353},[347,2301,2124],{"class":388},[347,2303,2127],{"class":353},[347,2305,2130],{"class":388},[347,2307,2308],{"class":353},"void",[347,2310,2196],{"class":388},[347,2312,2313],{"class":349,"line":497},[347,2314,2315],{"class":1246},"  \u002F** Gives the user a new id, taking everything that references it along. *\u002F\n",[347,2317,2318,2321,2323,2326,2328,2330,2332,2335,2337,2339,2341,2343,2345,2347],{"class":349,"line":516},[347,2319,2320],{"class":395},"  changeId",[347,2322,385],{"class":388},[347,2324,2325],{"class":1268},"from",[347,2327,248],{"class":388},[347,2329,2180],{"class":353},[347,2331,411],{"class":388},[347,2333,2334],{"class":1268}," to",[347,2336,248],{"class":388},[347,2338,2180],{"class":353},[347,2340,2124],{"class":388},[347,2342,2127],{"class":353},[347,2344,2130],{"class":388},[347,2346,2308],{"class":353},[347,2348,2196],{"class":388},[347,2350,2351],{"class":349,"line":522},[347,2352,1480],{"class":388},[159,2354,2355],{},"The same helpers are also available as Nuxt build hooks, for modules that prefer hooks:",[250,2357,2358,2368],{},[253,2359,2360],{},[256,2361,2362,2365],{},[259,2363,2364],{},"Hook",[259,2366,2367],{},"Payload",[271,2369,2370,2383,2394],{},[256,2371,2372,2377],{},[276,2373,2374],{},[185,2375,2376],{},"auth:resolvers",[276,2378,2379,2382],{},[185,2380,2381],{},"AuthResolverDefinition[]"," (push to register)",[256,2384,2385,2390],{},[276,2386,2387],{},[185,2388,2389],{},"auth:scopes",[276,2391,2392,2382],{},[185,2393,628],{},[256,2395,2396,2401],{},[276,2397,2398],{},[185,2399,2400],{},"auth:user-store",[276,2402,2403,2406,2407,294],{},[185,2404,2405],{},"{ path?: string }"," (set ",[185,2408,2409],{},"path",[159,2411,2412,2413,177,2416,177,2419,177,2422,177,2425,177,2428,180,2431,177,2434,177,2437,177,2440,177,2443,223,2446,231],{},"The utils also export ",[185,2414,2415],{},"ALL_SCOPES",[185,2417,2418],{},"hasScope",[185,2420,2421],{},"hasScopes",[185,2423,2424],{},"isPiiScope",[185,2426,2427],{},"isGrantableScope",[185,2429,2430],{},"parseScopeString",[185,2432,2433],{},"USER_TOKEN_PREFIX",[185,2435,2436],{},"generateUserToken",[185,2438,2439],{},"hashToken",[185,2441,2442],{},"parseBearer",[185,2444,2445],{},"looksLikeJwt",[185,2447,2448],{},"tokenStatus",[656,2450,269],{"id":623},[159,2452,2453,2454,2457,2458,2460,2461,2464,2465,2468,2469,2471,2472,2474,2475,2477],{},"Scopes are ",[185,2455,2456],{},"resource:action"," strings. ",[185,2459,293],{}," grants everything and ",[185,2462,2463],{},"resource:*"," every action of one resource. Personal-data\nscopes (",[185,2466,2467],{},"resource:pii",") are the exception: neither ",[185,2470,293],{}," nor ",[185,2473,2463],{}," covers them, so a token only sees other people's\npersonal data when the user picked that scope by name. Sessions are full access, so ",[163,2476,93],{"href":94}," tools strip\npersonal data for them as well. Scopes only narrow: a token never does more than its owner can.",[159,2479,2480,2481,2484,2485,2487,2488,2491,2492,2495],{},"A scope is only offered to users who may use it: the token UI lists, and ",[185,2482,2483],{},"POST \u002Fapi\u002Fauth\u002Ftokens"," accepts, just the\nscopes available to the signed-in user. Restrict a scope with ",[185,2486,1175],{},", or for other policy set ",[185,2489,2490],{},"ctx.available = false","\nin the ",[185,2493,2494],{},"auth:scope-available"," hook:",[338,2497,2499],{"className":364,"code":2498,"language":366,"meta":343,"style":343},"nitroApp.hooks.hook('auth:scope-available', (ctx) => {\n  if (ctx.scope.name === 'reports:export') ctx.available = canExport(ctx.user.id)\n})\n",[185,2500,2501,2537,2595],{"__ignoreMap":343},[347,2502,2503,2506,2508,2511,2513,2516,2518,2520,2522,2524,2526,2528,2531,2533,2535],{"class":349,"line":350},[347,2504,2505],{"class":384},"nitroApp",[347,2507,231],{"class":388},[347,2509,2510],{"class":384},"hooks",[347,2512,231],{"class":388},[347,2514,2515],{"class":380},"hook",[347,2517,385],{"class":384},[347,2519,404],{"class":388},[347,2521,2494],{"class":357},[347,2523,404],{"class":388},[347,2525,411],{"class":388},[347,2527,1265],{"class":388},[347,2529,2530],{"class":1268},"ctx",[347,2532,294],{"class":388},[347,2534,1274],{"class":1261},[347,2536,435],{"class":388},[347,2538,2539,2542,2544,2546,2548,2551,2553,2556,2559,2561,2564,2566,2569,2571,2573,2576,2578,2581,2583,2585,2587,2589,2591,2593],{"class":349,"line":392},[347,2540,2541],{"class":373},"  if",[347,2543,1265],{"class":395},[347,2545,2530],{"class":384},[347,2547,231],{"class":388},[347,2549,2550],{"class":384},"scope",[347,2552,231],{"class":388},[347,2554,2555],{"class":384},"name",[347,2557,2558],{"class":388}," ===",[347,2560,414],{"class":388},[347,2562,2563],{"class":357},"reports:export",[347,2565,404],{"class":388},[347,2567,2568],{"class":395},") ",[347,2570,2530],{"class":384},[347,2572,231],{"class":388},[347,2574,2575],{"class":384},"available",[347,2577,1292],{"class":388},[347,2579,2580],{"class":380}," canExport",[347,2582,385],{"class":395},[347,2584,2530],{"class":384},[347,2586,231],{"class":388},[347,2588,1340],{"class":384},[347,2590,231],{"class":388},[347,2592,1345],{"class":384},[347,2594,534],{"class":395},[347,2596,2597,2599],{"class":349,"line":427},[347,2598,531],{"class":388},[347,2600,534],{"class":384},[338,2602,2604],{"className":364,"code":2603,"language":366,"meta":343,"style":343},"interface AuthScopeDefinition {\n  name: string\n  description?: string\n  \u002F** Only users with one of these roles may pick the scope. Omit for every user. *\u002F\n  roles?: string[]\n}\n",[185,2605,2606,2615,2624,2633,2638,2649],{"__ignoreMap":343},[347,2607,2608,2610,2613],{"class":349,"line":350},[347,2609,1617],{"class":1261},[347,2611,2612],{"class":353}," AuthScopeDefinition",[347,2614,435],{"class":388},[347,2616,2617,2619,2621],{"class":349,"line":392},[347,2618,1968],{"class":395},[347,2620,248],{"class":388},[347,2622,2623],{"class":353}," string\n",[347,2625,2626,2629,2631],{"class":349,"line":427},[347,2627,2628],{"class":395},"  description",[347,2630,1630],{"class":388},[347,2632,2623],{"class":353},[347,2634,2635],{"class":349,"line":438},[347,2636,2637],{"class":1246},"  \u002F** Only users with one of these roles may pick the scope. Omit for every user. *\u002F\n",[347,2639,2640,2643,2645,2647],{"class":349,"line":448},[347,2641,2642],{"class":395},"  roles",[347,2644,1630],{"class":388},[347,2646,1474],{"class":353},[347,2648,1635],{"class":384},[347,2650,2651],{"class":349,"line":462},[347,2652,1480],{"class":388},[159,2654,2655],{},"Registered by the built-in modules:",[250,2657,2658,2668],{},[253,2659,2660],{},[256,2661,2662,2665],{},[259,2663,2664],{},"Scope",[259,2666,2667],{},"Module",[271,2669,2670,2687,2704,2718,2732,2747],{},[256,2671,2672,2683],{},[276,2673,2674,177,2676,177,2678,177,2680],{},[185,2675,1837],{},[185,2677,1846],{},[185,2679,1318],{},[185,2681,2682],{},"tickets:write",[276,2684,2685],{},[163,2686,85],{"href":86},[256,2688,2689,2700],{},[276,2690,2691,177,2694,177,2697],{},[185,2692,2693],{},"forms:manage",[185,2695,2696],{},"forms:pii",[185,2698,2699],{},"forms:submit",[276,2701,2702],{},[163,2703,89],{"href":90},[256,2705,2706,2714],{},[276,2707,2708,177,2711],{},[185,2709,2710],{},"payments:read",[185,2712,2713],{},"payments:write",[276,2715,2716],{},[163,2717,113],{"href":114},[256,2719,2720,2728],{},[276,2721,2722,177,2725],{},[185,2723,2724],{},"subscriptions:read",[185,2726,2727],{},"subscriptions:write",[276,2729,2730],{},[163,2731,125],{"href":126},[256,2733,2734,2739],{},[276,2735,2736],{},[185,2737,2738],{},"profile:read",[276,2740,2741,2743,2744,294],{},[163,2742,133],{"href":134}," (with ",[185,2745,2746],{},"settings.mcp",[256,2748,2749,2754],{},[276,2750,2751],{},[185,2752,2753],{},"oauth:read",[276,2755,2756],{},[163,2757,109],{"href":110},[656,2759,2761],{"id":2760},"user-api-tokens","User API tokens",[159,2763,2764,2765,2767,2768,2771,2772,2774],{},"Users create tokens (",[185,2766,1736],{},") on the account page (",[185,2769,2770],{},"\u002Faccount\u002Fapi-tokens",", see ",[163,2773,65],{"href":66},") or through\nthe API. Use one like this, for example from an MCP client:",[338,2776,2778],{"className":340,"code":2777,"language":342,"meta":343,"style":343},"curl -H \"Authorization: Bearer fnu_…\" https:\u002F\u002Fexample.com\u002Fapi\u002Ftickets\n",[185,2779,2780],{"__ignoreMap":343},[347,2781,2782,2785,2788,2791,2793,2796],{"class":349,"line":350},[347,2783,2784],{"class":353},"curl",[347,2786,2787],{"class":357}," -H",[347,2789,2790],{"class":388}," \"",[347,2792,306],{"class":357},[347,2794,2795],{"class":388},"\"",[347,2797,2798],{"class":357}," https:\u002F\u002Fexample.com\u002Fapi\u002Ftickets\n",[1137,2800,2801,2804,2814],{},[1140,2802,2803],{},"Only the SHA-256 of a token is stored, plus a prefix and the last four characters. A lost token is replaced, not\nlooked up.",[1140,2805,2806,2807,2809,2810,2813],{},"Tokens are accepted in the ",[185,2808,77],{}," header ",[171,2811,2812],{},"only","; query-string tokens are ignored.",[1140,2815,2816,2817,2820,2821,2823,2824,2827],{},"Tokens can expire (",[185,2818,2819],{},"expiresInDays",", or ",[185,2822,580],{},") and be revoked. ",[185,2825,2826],{},"lastUsedAt"," is written at most every five\nminutes and a failure to write it never fails a request.",[656,2829,2831],{"id":2830},"oauth-access-tokens","OAuth access tokens",[159,2833,2834,2835,2837,2838,2841,2842,2845],{},"With ",[163,2836,109],{"href":110},", an application the user signed in to calls the API as that user:\n",[185,2839,2840],{},"principal.user"," is the user and ",[185,2843,2844],{},"principal.client.id"," the application.",[338,2847,2849],{"className":364,"code":2848,"language":366,"meta":343,"style":343},"const principal = await requireAuth(event, { scopes: ['tickets:read'] })\nif (principal.kind === 'oauth') console.log(`called by application ${principal.client.id}`)\n",[185,2850,2851,2888],{"__ignoreMap":343},[347,2852,2853,2855,2858,2860,2862,2864,2866,2868,2870,2872,2874,2876,2878,2880,2882,2884,2886],{"class":349,"line":350},[347,2854,1767],{"class":1261},[347,2856,2857],{"class":384}," principal ",[347,2859,1773],{"class":388},[347,2861,1295],{"class":373},[347,2863,1298],{"class":380},[347,2865,1803],{"class":384},[347,2867,411],{"class":388},[347,2869,470],{"class":388},[347,2871,1309],{"class":395},[347,2873,248],{"class":388},[347,2875,401],{"class":384},[347,2877,404],{"class":388},[347,2879,1318],{"class":357},[347,2881,404],{"class":388},[347,2883,1323],{"class":384},[347,2885,531],{"class":388},[347,2887,534],{"class":384},[347,2889,2890,2893,2896,2898,2901,2904,2906,2908,2910,2913,2915,2918,2920,2923,2926,2929,2932,2934,2937,2939,2941,2944],{"class":349,"line":392},[347,2891,2892],{"class":373},"if",[347,2894,2895],{"class":384}," (principal",[347,2897,231],{"class":388},[347,2899,2900],{"class":384},"kind ",[347,2902,2903],{"class":388},"===",[347,2905,414],{"class":388},[347,2907,317],{"class":357},[347,2909,404],{"class":388},[347,2911,2912],{"class":384},") console",[347,2914,231],{"class":388},[347,2916,2917],{"class":380},"log",[347,2919,385],{"class":384},[347,2921,2922],{"class":388},"`",[347,2924,2925],{"class":357},"called by application ",[347,2927,2928],{"class":388},"${",[347,2930,2931],{"class":384},"principal",[347,2933,231],{"class":388},[347,2935,2936],{"class":384},"client",[347,2938,231],{"class":388},[347,2940,1345],{"class":384},[347,2942,2943],{"class":388},"}`",[347,2945,534],{"class":384},[159,2947,2948,2949,2952,2953,2956,2957,2960,2961,2964],{},"The OAuth server accepts every registered API scope besides ",[185,2950,2951],{},"openid profile email",". On every request the token is\nchecked against live state: the application must be active, the user must exist and still pass the application's role\nrequirement and the ",[185,2954,2955],{},"oauth:application:access"," hook, so disabling an application or changing a role cuts access\nimmediately. ID tokens are not credentials; only access tokens (",[185,2958,2959],{},"typ: at+jwt",") authenticate. The audience is the\napplication, so ",[185,2962,2963],{},"aud"," is not required to match this server; verification is signature (JWKS), issuer and type.",[159,2966,2967,2968,1265,2971,2973,2974,2979],{},"A static user token is enough for an MCP client that sends ",[185,2969,2970],{},"Authorization: Bearer …",[163,2972,93],{"href":94},"). Clients\nthat need the full OAuth flow also need protected-resource metadata\n(",[163,2975,2978],{"href":2976,"rel":2977},"https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc9728",[167],"RFC 9728",") and dynamic client registration, which this module does not\nprovide.",[656,2981,2983],{"id":2982},"auth-emails","Auth emails",[159,2985,2986,2987,2990,2991,2993,2994,2997,2998,3000,3001,177,3004,177,3007,3010,3011,231],{},"Magic link, verification and password reset emails are dispatched as ",[185,2988,2989],{},"EmailNotification","s through\n",[163,2992,105],{"href":106}," (configure the delivery driver under the ",[185,2995,2996],{},"notify"," key). With\n",[163,2999,141],{"href":142}," installed, they are rendered from the module's Vue templates\n(",[185,3002,3003],{},"auth-magic-link",[185,3005,3006],{},"auth-verify-email",[185,3008,3009],{},"auth-password-reset","). Override one by adding ",[185,3012,3013],{},"app\u002Femails\u002F\u003Cname>.vue",[159,3015,3016,3017,3020,3021,3024],{},"Without templates, you can brand the magic link and verification emails by replacing subject\u002Fbody in the ",[185,3018,3019],{},"auth:email","\nhook. Delete ",[185,3022,3023],{},"ctx.notification.template"," there if a template should not render over your body:",[338,3026,3028],{"className":364,"code":3027,"language":366,"meta":343,"style":343},"export default defineNitroPlugin((nitro) => {\n  nitro.hooks.hook('auth:email', (ctx) => {\n    \u002F\u002F ctx.type: 'magic-link' | 'verify-email'; ctx.data: { name, url }\n    ctx.notification.subject = 'Velkommen til Frigear'\n    ctx.notification.body = renderMyTemplate(ctx.data)\n  })\n})\n",[185,3029,3030,3052,3085,3090,3115,3144,3151],{"__ignoreMap":343},[347,3031,3032,3034,3036,3039,3041,3043,3046,3048,3050],{"class":349,"line":350},[347,3033,374],{"class":373},[347,3035,377],{"class":373},[347,3037,3038],{"class":380}," defineNitroPlugin",[347,3040,385],{"class":384},[347,3042,385],{"class":388},[347,3044,3045],{"class":1268},"nitro",[347,3047,294],{"class":388},[347,3049,1274],{"class":1261},[347,3051,435],{"class":388},[347,3053,3054,3057,3059,3061,3063,3065,3067,3069,3071,3073,3075,3077,3079,3081,3083],{"class":349,"line":392},[347,3055,3056],{"class":384},"  nitro",[347,3058,231],{"class":388},[347,3060,2510],{"class":384},[347,3062,231],{"class":388},[347,3064,2515],{"class":380},[347,3066,385],{"class":395},[347,3068,404],{"class":388},[347,3070,3019],{"class":357},[347,3072,404],{"class":388},[347,3074,411],{"class":388},[347,3076,1265],{"class":388},[347,3078,2530],{"class":1268},[347,3080,294],{"class":388},[347,3082,1274],{"class":1261},[347,3084,435],{"class":388},[347,3086,3087],{"class":349,"line":427},[347,3088,3089],{"class":1246},"    \u002F\u002F ctx.type: 'magic-link' | 'verify-email'; ctx.data: { name, url }\n",[347,3091,3092,3095,3097,3100,3102,3105,3107,3109,3112],{"class":349,"line":438},[347,3093,3094],{"class":384},"    ctx",[347,3096,231],{"class":388},[347,3098,3099],{"class":384},"notification",[347,3101,231],{"class":388},[347,3103,3104],{"class":384},"subject",[347,3106,1292],{"class":388},[347,3108,414],{"class":388},[347,3110,3111],{"class":357},"Velkommen til Frigear",[347,3113,3114],{"class":388},"'\n",[347,3116,3117,3119,3121,3123,3125,3128,3130,3133,3135,3137,3139,3142],{"class":349,"line":448},[347,3118,3094],{"class":384},[347,3120,231],{"class":388},[347,3122,3099],{"class":384},[347,3124,231],{"class":388},[347,3126,3127],{"class":384},"body",[347,3129,1292],{"class":388},[347,3131,3132],{"class":380}," renderMyTemplate",[347,3134,385],{"class":395},[347,3136,2530],{"class":384},[347,3138,231],{"class":388},[347,3140,3141],{"class":384},"data",[347,3143,534],{"class":395},[347,3145,3146,3149],{"class":349,"line":462},[347,3147,3148],{"class":388},"  }",[347,3150,534],{"class":395},[347,3152,3153,3155],{"class":349,"line":497},[347,3154,531],{"class":388},[347,3156,534],{"class":384},[328,3158,3160],{"id":3159},"app","App",[159,3162,3163],{},"All composables are auto-imported and can be overridden by re-declaring one of the same name in the app.",[338,3165,3167],{"className":364,"code":3166,"language":366,"meta":343,"style":343},"const { login, pending, error, isEnabled, passwordLoginEnabled, passkeyLoginEnabled, oauthProviders } = useLogin()\nawait login({ email: 'ada@example.com', password: 'secret' })\n\nconst { register, pending, error, isEnabled } = useRegistration()\nawait register({ name: 'Ada', email: 'ada@example.com', password: 'secret' })\n\nconst { requestReset, resetPassword, pending, error, isEnabled } = usePasswordReset()\nawait requestReset({ email: 'ada@example.com' })\nawait resetPassword({ code, password, confirmPassword }) \u002F\u002F signs the user in\n\nconst { sendMagicLink, pending, error, isEnabled } = useMagicLink()\nawait sendMagicLink({ email: 'ada@example.com', name: 'Ada', redirect: '\u002Fdashboard' }) \u002F\u002F redirect: same-origin path\n\nconst { isEnabled, registerPasskey, authenticateWithPasskey, listPasskeys, removePasskey } = usePasskeys()\nawait registerPasskey(user.email, 'MacBook') \u002F\u002F the name is optional\nconst passkeys = await listPasskeys() \u002F\u002F [{ id, name, createdAt, counter, backedUp, transports }], never the public key\nawait removePasskey(passkeys[0].id) \u002F\u002F only the signed-in user's own (404 otherwise)\n\nconst { login: loginPath, register: registerPath } = useAuthPages() \u002F\u002F '\u002Flogin' by default\n",[185,3168,3169,3217,3258,3262,3292,3341,3345,3380,3404,3433,3437,3468,3522,3527,3565,3593,3613,3637,3642],{"__ignoreMap":343},[347,3170,3171,3173,3175,3177,3179,3182,3184,3187,3189,3192,3194,3197,3199,3202,3204,3207,3209,3211,3214],{"class":349,"line":350},[347,3172,1767],{"class":1261},[347,3174,470],{"class":388},[347,3176,473],{"class":384},[347,3178,411],{"class":388},[347,3180,3181],{"class":384}," pending",[347,3183,411],{"class":388},[347,3185,3186],{"class":384}," error",[347,3188,411],{"class":388},[347,3190,3191],{"class":384}," isEnabled",[347,3193,411],{"class":388},[347,3195,3196],{"class":384}," passwordLoginEnabled",[347,3198,411],{"class":388},[347,3200,3201],{"class":384}," passkeyLoginEnabled",[347,3203,411],{"class":388},[347,3205,3206],{"class":384}," oauthProviders ",[347,3208,531],{"class":388},[347,3210,1292],{"class":388},[347,3212,3213],{"class":380}," useLogin",[347,3215,3216],{"class":384},"()\n",[347,3218,3219,3221,3223,3225,3228,3231,3233,3235,3238,3240,3242,3245,3247,3249,3252,3254,3256],{"class":349,"line":392},[347,3220,1792],{"class":373},[347,3222,473],{"class":380},[347,3224,385],{"class":384},[347,3226,3227],{"class":388},"{",[347,3229,3230],{"class":395}," email",[347,3232,248],{"class":388},[347,3234,414],{"class":388},[347,3236,3237],{"class":357},"ada@example.com",[347,3239,404],{"class":388},[347,3241,411],{"class":388},[347,3243,3244],{"class":395}," password",[347,3246,248],{"class":388},[347,3248,414],{"class":388},[347,3250,3251],{"class":357},"secret",[347,3253,404],{"class":388},[347,3255,1289],{"class":388},[347,3257,534],{"class":384},[347,3259,3260],{"class":349,"line":427},[347,3261,1612],{"emptyLinePlaceholder":1611},[347,3263,3264,3266,3268,3270,3272,3274,3276,3278,3280,3283,3285,3287,3290],{"class":349,"line":438},[347,3265,1767],{"class":1261},[347,3267,470],{"class":388},[347,3269,482],{"class":384},[347,3271,411],{"class":388},[347,3273,3181],{"class":384},[347,3275,411],{"class":388},[347,3277,3186],{"class":384},[347,3279,411],{"class":388},[347,3281,3282],{"class":384}," isEnabled ",[347,3284,531],{"class":388},[347,3286,1292],{"class":388},[347,3288,3289],{"class":380}," useRegistration",[347,3291,3216],{"class":384},[347,3293,3294,3296,3298,3300,3302,3304,3306,3308,3311,3313,3315,3317,3319,3321,3323,3325,3327,3329,3331,3333,3335,3337,3339],{"class":349,"line":448},[347,3295,1792],{"class":373},[347,3297,482],{"class":380},[347,3299,385],{"class":384},[347,3301,3227],{"class":388},[347,3303,1535],{"class":395},[347,3305,248],{"class":388},[347,3307,414],{"class":388},[347,3309,3310],{"class":357},"Ada",[347,3312,404],{"class":388},[347,3314,411],{"class":388},[347,3316,3230],{"class":395},[347,3318,248],{"class":388},[347,3320,414],{"class":388},[347,3322,3237],{"class":357},[347,3324,404],{"class":388},[347,3326,411],{"class":388},[347,3328,3244],{"class":395},[347,3330,248],{"class":388},[347,3332,414],{"class":388},[347,3334,3251],{"class":357},[347,3336,404],{"class":388},[347,3338,1289],{"class":388},[347,3340,534],{"class":384},[347,3342,3343],{"class":349,"line":462},[347,3344,1612],{"emptyLinePlaceholder":1611},[347,3346,3347,3349,3351,3354,3356,3359,3361,3363,3365,3367,3369,3371,3373,3375,3378],{"class":349,"line":497},[347,3348,1767],{"class":1261},[347,3350,470],{"class":388},[347,3352,3353],{"class":384}," requestReset",[347,3355,411],{"class":388},[347,3357,3358],{"class":384}," resetPassword",[347,3360,411],{"class":388},[347,3362,3181],{"class":384},[347,3364,411],{"class":388},[347,3366,3186],{"class":384},[347,3368,411],{"class":388},[347,3370,3282],{"class":384},[347,3372,531],{"class":388},[347,3374,1292],{"class":388},[347,3376,3377],{"class":380}," usePasswordReset",[347,3379,3216],{"class":384},[347,3381,3382,3384,3386,3388,3390,3392,3394,3396,3398,3400,3402],{"class":349,"line":516},[347,3383,1792],{"class":373},[347,3385,3353],{"class":380},[347,3387,385],{"class":384},[347,3389,3227],{"class":388},[347,3391,3230],{"class":395},[347,3393,248],{"class":388},[347,3395,414],{"class":388},[347,3397,3237],{"class":357},[347,3399,404],{"class":388},[347,3401,1289],{"class":388},[347,3403,534],{"class":384},[347,3405,3406,3408,3410,3412,3414,3417,3419,3421,3423,3426,3428,3430],{"class":349,"line":522},[347,3407,1792],{"class":373},[347,3409,3358],{"class":380},[347,3411,385],{"class":384},[347,3413,3227],{"class":388},[347,3415,3416],{"class":384}," code",[347,3418,411],{"class":388},[347,3420,3244],{"class":384},[347,3422,411],{"class":388},[347,3424,3425],{"class":384}," confirmPassword ",[347,3427,531],{"class":388},[347,3429,2568],{"class":384},[347,3431,3432],{"class":1246},"\u002F\u002F signs the user in\n",[347,3434,3435],{"class":349,"line":528},[347,3436,1612],{"emptyLinePlaceholder":1611},[347,3438,3440,3442,3444,3447,3449,3451,3453,3455,3457,3459,3461,3463,3466],{"class":349,"line":3439},11,[347,3441,1767],{"class":1261},[347,3443,470],{"class":388},[347,3445,3446],{"class":384}," sendMagicLink",[347,3448,411],{"class":388},[347,3450,3181],{"class":384},[347,3452,411],{"class":388},[347,3454,3186],{"class":384},[347,3456,411],{"class":388},[347,3458,3282],{"class":384},[347,3460,531],{"class":388},[347,3462,1292],{"class":388},[347,3464,3465],{"class":380}," useMagicLink",[347,3467,3216],{"class":384},[347,3469,3471,3473,3475,3477,3479,3481,3483,3485,3487,3489,3491,3493,3495,3497,3499,3501,3503,3506,3508,3510,3513,3515,3517,3519],{"class":349,"line":3470},12,[347,3472,1792],{"class":373},[347,3474,3446],{"class":380},[347,3476,385],{"class":384},[347,3478,3227],{"class":388},[347,3480,3230],{"class":395},[347,3482,248],{"class":388},[347,3484,414],{"class":388},[347,3486,3237],{"class":357},[347,3488,404],{"class":388},[347,3490,411],{"class":388},[347,3492,1535],{"class":395},[347,3494,248],{"class":388},[347,3496,414],{"class":388},[347,3498,3310],{"class":357},[347,3500,404],{"class":388},[347,3502,411],{"class":388},[347,3504,3505],{"class":395}," redirect",[347,3507,248],{"class":388},[347,3509,414],{"class":388},[347,3511,3512],{"class":357},"\u002Fdashboard",[347,3514,404],{"class":388},[347,3516,1289],{"class":388},[347,3518,2568],{"class":384},[347,3520,3521],{"class":1246},"\u002F\u002F redirect: same-origin path\n",[347,3523,3525],{"class":349,"line":3524},13,[347,3526,1612],{"emptyLinePlaceholder":1611},[347,3528,3530,3532,3534,3536,3538,3541,3543,3546,3548,3551,3553,3556,3558,3560,3563],{"class":349,"line":3529},14,[347,3531,1767],{"class":1261},[347,3533,470],{"class":388},[347,3535,3191],{"class":384},[347,3537,411],{"class":388},[347,3539,3540],{"class":384}," registerPasskey",[347,3542,411],{"class":388},[347,3544,3545],{"class":384}," authenticateWithPasskey",[347,3547,411],{"class":388},[347,3549,3550],{"class":384}," listPasskeys",[347,3552,411],{"class":388},[347,3554,3555],{"class":384}," removePasskey ",[347,3557,531],{"class":388},[347,3559,1292],{"class":388},[347,3561,3562],{"class":380}," usePasskeys",[347,3564,3216],{"class":384},[347,3566,3568,3570,3572,3575,3577,3579,3581,3583,3586,3588,3590],{"class":349,"line":3567},15,[347,3569,1792],{"class":373},[347,3571,3540],{"class":380},[347,3573,3574],{"class":384},"(user",[347,3576,231],{"class":388},[347,3578,2206],{"class":384},[347,3580,411],{"class":388},[347,3582,414],{"class":388},[347,3584,3585],{"class":357},"MacBook",[347,3587,404],{"class":388},[347,3589,2568],{"class":384},[347,3591,3592],{"class":1246},"\u002F\u002F the name is optional\n",[347,3594,3596,3598,3601,3603,3605,3607,3610],{"class":349,"line":3595},16,[347,3597,1767],{"class":1261},[347,3599,3600],{"class":384}," passkeys ",[347,3602,1773],{"class":388},[347,3604,1295],{"class":373},[347,3606,3550],{"class":380},[347,3608,3609],{"class":384},"() ",[347,3611,3612],{"class":1246},"\u002F\u002F [{ id, name, createdAt, counter, backedUp, transports }], never the public key\n",[347,3614,3616,3618,3621,3624,3627,3629,3631,3634],{"class":349,"line":3615},17,[347,3617,1792],{"class":373},[347,3619,3620],{"class":380}," removePasskey",[347,3622,3623],{"class":384},"(passkeys[",[347,3625,3626],{"class":2036},"0",[347,3628,422],{"class":384},[347,3630,231],{"class":388},[347,3632,3633],{"class":384},"id) ",[347,3635,3636],{"class":1246},"\u002F\u002F only the signed-in user's own (404 otherwise)\n",[347,3638,3640],{"class":349,"line":3639},18,[347,3641,1612],{"emptyLinePlaceholder":1611},[347,3643,3645,3647,3649,3651,3653,3656,3658,3660,3662,3665,3667,3669,3672,3674],{"class":349,"line":3644},19,[347,3646,1767],{"class":1261},[347,3648,470],{"class":388},[347,3650,473],{"class":395},[347,3652,248],{"class":388},[347,3654,3655],{"class":384}," loginPath",[347,3657,411],{"class":388},[347,3659,482],{"class":395},[347,3661,248],{"class":388},[347,3663,3664],{"class":384}," registerPath ",[347,3666,531],{"class":388},[347,3668,1292],{"class":388},[347,3670,3671],{"class":380}," useAuthPages",[347,3673,3609],{"class":384},[347,3675,3676],{"class":1246},"\u002F\u002F '\u002Flogin' by default\n",[159,3678,3679,3680,3683],{},"The module also registers the ",[185,3681,3682],{},"AuthCard"," component when a login or local register page is enabled.",[328,3685,3686],{"id":2510},"Hooks",[250,3688,3689,3700],{},[253,3690,3691],{},[256,3692,3693,3695,3698],{},[259,3694,2364],{},[259,3696,3697],{},"When",[259,3699,2367],{},[271,3701,3702,3722,3736],{},[256,3703,3704,3709,3712],{},[276,3705,3706,3708],{},[185,3707,2494],{}," (Nitro)",[276,3710,3711],{},"A user's available token scopes are computed",[276,3713,3714,3717,3718,3721],{},[185,3715,3716],{},"{ event, user: { id, role? }, scope, available }",": set ",[185,3719,3720],{},"available = false"," to hide",[256,3723,3724,3728,3731],{},[276,3725,3726,3708],{},[185,3727,3019],{},[276,3729,3730],{},"A magic-link or verification email is about to be sent",[276,3732,3733],{},[185,3734,3735],{},"{ type, notification, data: { name, url } }",[256,3737,3738,3747,3750],{},[276,3739,3740,177,3742,177,3744,3746],{},[185,3741,2376],{},[185,3743,2389],{},[185,3745,2400],{}," (Nuxt)",[276,3748,3749],{},"Build time, when the virtual modules are generated",[276,3751,3752,3753],{},"See ",[163,3754,3756],{"href":3755},"#extending-build-time","Extending",[328,3758,3760],{"id":3759},"routes","Routes",[250,3762,3763,3777],{},[253,3764,3765],{},[256,3766,3767,3770,3773,3775],{},[259,3768,3769],{},"Method",[259,3771,3772],{},"Path",[259,3774,73],{},[259,3776,571],{},[271,3778,3779,3800,3819,3837,3857,3883,3904,3927,3946,3964,3982,4001,4026,4047,4063,4086,4102],{},[256,3780,3781,3786,3791,3794],{},[276,3782,3783],{},[185,3784,3785],{},"GET",[276,3787,3788],{},[185,3789,3790],{},"\u002Fauth\u002Flogout",[276,3792,3793],{},"none",[276,3795,3796,3797,231],{},"Clears the session and redirects to ",[185,3798,3799],{},"\u002F",[256,3801,3802,3807,3812,3814],{},[276,3803,3804],{},[185,3805,3806],{},"POST",[276,3808,3809],{},[185,3810,3811],{},"\u002Fapi\u002Fauth\u002Flogin",[276,3813,3793],{},[276,3815,3816,3817,767],{},"Email\u002Fpassword login (",[185,3818,682],{},[256,3820,3821,3825,3830,3832],{},[276,3822,3823],{},[185,3824,3806],{},[276,3826,3827],{},[185,3828,3829],{},"\u002Fapi\u002Fauth\u002Fregister",[276,3831,3793],{},[276,3833,3834,3835,767],{},"Email\u002Fpassword registration (",[185,3836,682],{},[256,3838,3839,3843,3848,3850],{},[276,3840,3841],{},[185,3842,3806],{},[276,3844,3845],{},[185,3846,3847],{},"\u002Fapi\u002Fauth\u002Fforgot-password",[276,3849,3793],{},[276,3851,3852,3853,1265,3855,767],{},"Email a reset link for ",[185,3854,2206],{},[185,3856,702],{},[256,3858,3859,3863,3868,3870],{},[276,3860,3861],{},[185,3862,3806],{},[276,3864,3865],{},[185,3866,3867],{},"\u002Fapi\u002Fauth\u002Freset-password",[276,3869,3793],{},[276,3871,3872,3873,177,3875,177,3877,3880,3881,767],{},"Reset with ",[185,3874,185],{},[185,3876,682],{},[185,3878,3879],{},"confirmPassword",", then sign in (",[185,3882,702],{},[256,3884,3885,3889,3894,3896],{},[276,3886,3887],{},[185,3888,3806],{},[276,3890,3891],{},[185,3892,3893],{},"\u002Fapi\u002Fauth\u002Fmagic-link",[276,3895,3793],{},[276,3897,3898,3899,1265,3902,767],{},"Email a single-use link. Always answers ",[185,3900,3901],{},"{ ok: true }",[185,3903,744],{},[256,3905,3906,3910,3915,3917],{},[276,3907,3908],{},[185,3909,3785],{},[276,3911,3912],{},[185,3913,3914],{},"\u002Fauth\u002Fmagic-link?code=",[276,3916,3793],{},[276,3918,3919,3920,1265,3923,975,3925,767],{},"Consume the link, verify the email, sign in, redirect. A bad link goes to the login page with ",[185,3921,3922],{},"?error=magic-link",[185,3924,744],{},[185,3926,774],{},[256,3928,3929,3933,3938,3941],{},[276,3930,3931],{},[185,3932,3806],{},[276,3934,3935],{},[185,3936,3937],{},"\u002Fapi\u002Fauth\u002Fwebauthn\u002Fregister",[276,3939,3940],{},"session for existing users",[276,3942,3943,3944,767],{},"Register a passkey. An unknown email creates the account; an existing one needs that user's session (",[185,3945,725],{},[256,3947,3948,3952,3957,3959],{},[276,3949,3950],{},[185,3951,3806],{},[276,3953,3954],{},[185,3955,3956],{},"\u002Fapi\u002Fauth\u002Fwebauthn\u002Fauthenticate",[276,3958,3793],{},[276,3960,3961,3962,767],{},"Sign in with a passkey (",[185,3963,725],{},[256,3965,3966,3970,3975,3977],{},[276,3967,3968],{},[185,3969,3785],{},[276,3971,3972],{},[185,3973,3974],{},"\u002Fapi\u002Fauth\u002Fwebauthn\u002Fcredentials",[276,3976,280],{},[276,3978,3979,3980,767],{},"List your passkeys (",[185,3981,725],{},[256,3983,3984,3989,3994,3996],{},[276,3985,3986],{},[185,3987,3988],{},"DELETE",[276,3990,3991],{},[185,3992,3993],{},"\u002Fapi\u002Fauth\u002Fwebauthn\u002Fcredentials\u002F:id",[276,3995,280],{},[276,3997,3998,3999,767],{},"Remove one of your passkeys (",[185,4000,725],{},[256,4002,4003,4007,4018,4020],{},[276,4004,4005],{},[185,4006,3785],{},[276,4008,4009,177,4012,177,4015],{},[185,4010,4011],{},"\u002Fapi\u002Fauth\u002Fgithub",[185,4013,4014],{},"\u002Fgoogle",[185,4016,4017],{},"\u002Ffacebook",[276,4019,3793],{},[276,4021,4022,4023,767],{},"OAuth login (",[185,4024,4025],{},"oauth.\u003Cprovider>",[256,4027,4028,4032,4037,4039],{},[276,4029,4030],{},[185,4031,3785],{},[276,4033,4034],{},[185,4035,4036],{},"\u002Fauth\u002Ffrigear",[276,4038,3793],{},[276,4040,4041,4042,4044,4045,767],{},"Log in with frigear.nu; ",[185,4043,982],{}," unless enabled (",[185,4046,959],{},[256,4048,4049,4053,4058,4060],{},[276,4050,4051],{},[185,4052,3785],{},[276,4054,4055],{},[185,4056,4057],{},"\u002Fapi\u002Fauth\u002Ftokens",[276,4059,1712],{},[276,4061,4062],{},"Your tokens: name, prefix, last 4, scopes, expiry, last use, status.",[256,4064,4065,4069,4073,4075],{},[276,4066,4067],{},[185,4068,3806],{},[276,4070,4071],{},[185,4072,4057],{},[276,4074,1712],{},[276,4076,4077,4078,4081,4082,4085],{},"Create ",[185,4079,4080],{},"{ name, scopes, expiresInDays? }",". The plaintext ",[185,4083,4084],{},"token"," is in this response only.",[256,4087,4088,4092,4097,4099],{},[276,4089,4090],{},[185,4091,3988],{},[276,4093,4094],{},[185,4095,4096],{},"\u002Fapi\u002Fauth\u002Ftokens\u002F:id",[276,4098,1712],{},[276,4100,4101],{},"Revoke; the row is kept for the audit trail.",[256,4103,4104,4108,4113,4115],{},[276,4105,4106],{},[185,4107,3785],{},[276,4109,4110],{},[185,4111,4112],{},"\u002Fapi\u002Fauth\u002Fscopes",[276,4114,1712],{},[276,4116,4117],{},"The scopes that can be granted to you.",[159,4119,4120],{},"Magic and verification links expire after 2 hours and are consumed atomically.",[328,4122,546],{"id":4123},"database",[159,4125,4126,4127,4129,4130,4133],{},"None of the tables has a foreign key to ",[185,4128,541],{}," (this module sits below it); whoever deletes a user calls\n",[185,4131,4132],{},"deleteUserAuthData(userId)",", as the users admin does.",[250,4135,4136,4149],{},[253,4137,4138],{},[256,4139,4140,4143,4146],{},[259,4141,4142],{},"Table",[259,4144,4145],{},"Present when",[259,4147,4148],{},"Holds",[271,4150,4151,4164,4178,4201],{},[256,4152,4153,4158,4161],{},[276,4154,4155],{},[185,4156,4157],{},"auth_user_tokens",[276,4159,4160],{},"always",[276,4162,4163],{},"Hashed user tokens: name, prefix, last 4, scopes, expiry, revoke and last-use timestamps.",[256,4165,4166,4171,4175],{},[276,4167,4168],{},[185,4169,4170],{},"user_credentials",[276,4172,4173],{},[185,4174,725],{},[276,4176,4177],{},"One row per passkey.",[256,4179,4180,4185,4189],{},[276,4181,4182],{},[185,4183,4184],{},"password_resets",[276,4186,4187],{},[185,4188,702],{},[276,4190,4191,4192,711,4194,4197,4198,231],{},"Unique reset ",[185,4193,185],{},[185,4195,4196],{},"expiresAt"," \u002F ",[185,4199,4200],{},"usedAt",[256,4202,4203,4208,4214],{},[276,4204,4205],{},[185,4206,4207],{},"magic_links",[276,4209,4210,975,4212],{},[185,4211,744],{},[185,4213,774],{},[276,4215,4216,4217,4219,4220,177,4223,4197,4225,231],{},"Unique single-use ",[185,4218,185],{},", optional internal ",[185,4221,4222],{},"redirectUrl",[185,4224,4196],{},[185,4226,4200],{},[159,4228,4229,4230,177,4232,223,4235,4238,4239,4241,4242,4244],{},"It also adds ",[185,4231,682],{},[185,4233,4234],{},"email_verified_at",[185,4236,4237],{},"last_login_at"," to the ",[185,4240,541],{}," table owned by\n",[163,4243,133],{"href":134}," (ignored without it).",[328,4246,4248],{"id":4247},"translations","Translations",[159,4250,4251,4252,223,4255,4258,4259,4262,4263,4266,4267,4270,4271,248],{},"The module registers ",[185,4253,4254],{},"da",[185,4256,4257],{},"en"," locale files under the ",[185,4260,4261],{},"auth.*"," namespace, read through ",[185,4264,4265],{},"@nuxtjs\u002Fi18n","; without it\nthe English defaults are used. Override strings in your app's ",[185,4268,4269],{},"i18n\u002Flocales\u002F\u003Ccode>.json",", see\n",[163,4272,4274],{"href":4273},"\u002Fmodules\u002Fmodule-kit#overriding-module-strings-in-your-app","overriding module strings",[338,4276,4280],{"className":4277,"code":4278,"language":4279,"meta":343,"style":343},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{ \"auth\": { \"signIn\": \"Log in\", \"email\": { \"label\": \"Your email\" } } }\n","json",[185,4281,4282],{"__ignoreMap":343},[347,4283,4284,4286,4288,4290,4292,4294,4296,4298,4301,4303,4305,4307,4310,4312,4314,4316,4318,4320,4322,4324,4326,4329,4331,4333,4335,4338,4340,4342,4344],{"class":349,"line":350},[347,4285,3227],{"class":388},[347,4287,2790],{"class":388},[347,4289,240],{"class":1261},[347,4291,2795],{"class":388},[347,4293,248],{"class":388},[347,4295,470],{"class":388},[347,4297,2790],{"class":388},[347,4299,4300],{"class":353},"signIn",[347,4302,2795],{"class":388},[347,4304,248],{"class":388},[347,4306,2790],{"class":388},[347,4308,4309],{"class":357},"Log in",[347,4311,2795],{"class":388},[347,4313,411],{"class":388},[347,4315,2790],{"class":388},[347,4317,2206],{"class":353},[347,4319,2795],{"class":388},[347,4321,248],{"class":388},[347,4323,470],{"class":388},[347,4325,2790],{"class":388},[347,4327,4328],{"class":2036},"label",[347,4330,2795],{"class":388},[347,4332,248],{"class":388},[347,4334,2790],{"class":388},[347,4336,4337],{"class":357},"Your email",[347,4339,2795],{"class":388},[347,4341,1289],{"class":388},[347,4343,1289],{"class":388},[347,4345,1553],{"class":388},[159,4347,4348,4349,177,4351,177,4354,177,4357,177,4360,177,4363,177,4366,177,4369,180,4372,177,4375,177,4378,177,4381,177,4384,177,4387,177,4390,180,4393,177,4396,223,4399,231],{},"Key groups: ",[185,4350,4300],{},[185,4352,4353],{},"signUp",[185,4355,4356],{},"signOut",[185,4358,4359],{},"signedInAs",[185,4361,4362],{},"name.*",[185,4364,4365],{},"email.*",[185,4367,4368],{},"password.*",[185,4370,4371],{},"forgotPassword.*",[185,4373,4374],{},"resetPassword.*",[185,4376,4377],{},"magicLink.*",[185,4379,4380],{},"verifyEmail.*",[185,4382,4383],{},"confirm.*",[185,4385,4386],{},"passkey.*",[185,4388,4389],{},"emailPassword.*",[185,4391,4392],{},"passkeys.*",[185,4394,4395],{},"oauth.\u003Cprovider>.label",[185,4397,4398],{},"menu.*",[185,4400,4401],{},"errors.*",[4403,4404,4405],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":343,"searchDepth":392,"depth":392,"links":4407},[4408,4409,4413,4422,4423,4424,4425,4426],{"id":330,"depth":392,"text":331},{"id":552,"depth":392,"text":553,"children":4410},[4411,4412],{"id":643,"depth":427,"text":643},{"id":953,"depth":427,"text":954},{"id":1219,"depth":392,"text":1220,"children":4414},[4415,4416,4417,4418,4419,4420,4421],{"id":1223,"depth":427,"text":1224},{"id":1753,"depth":427,"text":1754},{"id":1873,"depth":427,"text":1874},{"id":623,"depth":427,"text":269},{"id":2760,"depth":427,"text":2761},{"id":2830,"depth":427,"text":2831},{"id":2982,"depth":427,"text":2983},{"id":3159,"depth":392,"text":3160},{"id":2510,"depth":392,"text":3686},{"id":3759,"depth":392,"text":3760},{"id":4123,"depth":392,"text":546},{"id":4247,"depth":392,"text":4248},"Sign-in (password, magic link, OAuth, passkeys), user API tokens and one requireAuth for cookie sessions, tokens and OAuth access tokens, with scopes.","md",null,{},{"title":73,"description":4427},"JvnQYjVfVPG3NmR-0S0hpP2ScbqIHLFj8WFKNeNyZx0",[4434,4436],{"title":69,"path":70,"stem":71,"description":4435,"children":-1},"Generic admin area - guarded shell, dashboard and navigation that other modules contribute to.",{"title":77,"path":78,"stem":79,"description":4437,"children":-1},"Policy-based authorization (abilities, route rules and \u003CCan>) with a role column on users.",1792824485285]