[{"data":1,"prerenderedAt":1906},["ShallowReactive",2],{"navigation_docs":3,"-guides-two-factor-auth":152,"-guides-two-factor-auth-surround":1901},[4,42,68,110,131],{"title":5,"path":6,"stem":7,"children":8,"icon":11},"Getting Started","\u002Fgetting-started","1.getting-started\u002F0.index",[9,12,17,22,27,32,37],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-sparkles",{"title":13,"path":14,"stem":15,"icon":16},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F1.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F2.configuration","i-lucide-settings",{"title":23,"path":24,"stem":25,"icon":26},"Client Setup","\u002Fgetting-started\u002Fclient-setup","1.getting-started\u002F3.client-setup","i-lucide-monitor",{"title":28,"path":29,"stem":30,"icon":31},"Type Augmentation","\u002Fgetting-started\u002Ftype-augmentation","1.getting-started\u002F4.type-augmentation","i-lucide-type",{"title":33,"path":34,"stem":35,"icon":36},"Schema Generation (NuxtHub)","\u002Fgetting-started\u002Fschema-generation","1.getting-started\u002F5.schema-generation","i-lucide-database",{"title":38,"path":39,"stem":40,"icon":41},"How It Works","\u002Fgetting-started\u002Fhow-it-works","1.getting-started\u002F6.how-it-works","i-lucide-workflow",{"title":43,"path":44,"stem":45,"children":46,"page":67},"Core Concepts","\u002Fcore-concepts","2.core-concepts",[47,51,55,59,63],{"title":48,"path":49,"stem":50},"serverAuth()","\u002Fcore-concepts\u002Fserver-auth","2.core-concepts\u002F1.server-auth",{"title":52,"path":53,"stem":54},"Sessions","\u002Fcore-concepts\u002Fsessions","2.core-concepts\u002F2.sessions",{"title":56,"path":57,"stem":58},"Route Protection","\u002Fcore-concepts\u002Froute-protection","2.core-concepts\u002F3.route-protection",{"title":60,"path":61,"stem":62},"Auto‑Imports and Aliases","\u002Fcore-concepts\u002Fauto-imports-aliases","2.core-concepts\u002F4.auto-imports-aliases",{"title":64,"path":65,"stem":66},"Security & Caveats","\u002Fcore-concepts\u002Fsecurity-caveats","2.core-concepts\u002F5.security-caveats",false,{"title":69,"path":70,"stem":71,"children":72,"page":67},"Guides","\u002Fguides","3.guides",[73,77,81,85,89,94,98,102,106],{"title":74,"path":75,"stem":76},"Role‑Based Access","\u002Fguides\u002Frole-based-access","3.guides\u002F1.role-based-access",{"title":78,"path":79,"stem":80},"OAuth Providers","\u002Fguides\u002Foauth-providers","3.guides\u002F2.oauth-providers",{"title":82,"path":83,"stem":84},"Custom Database","\u002Fguides\u002Fcustom-database","3.guides\u002F3.custom-database",{"title":86,"path":87,"stem":88},"Database-less Mode","\u002Fguides\u002Fdatabase-less-mode","3.guides\u002F4.database-less-mode",{"title":90,"path":91,"stem":92,"icon":93},"External Auth Backend","\u002Fguides\u002Fexternal-auth-backend","3.guides\u002F5.external-auth-backend","i-lucide-server",{"title":95,"path":96,"stem":97},"Migrating from nuxt-auth-utils","\u002Fguides\u002Fmigrate-from-nuxt-auth-utils","3.guides\u002F6.migrate-from-nuxt-auth-utils",{"title":99,"path":100,"stem":101},"Two-Factor Authentication (TOTP + Backup Codes)","\u002Fguides\u002Ftwo-factor-auth","3.guides\u002F7.two-factor-auth",{"title":103,"path":104,"stem":105},"Testing","\u002Fguides\u002Ftesting","3.guides\u002F8.testing",{"title":107,"path":108,"stem":109},"Production Deployment","\u002Fguides\u002Fproduction-deployment","3.guides\u002F9.production-deployment",{"title":111,"path":112,"stem":113,"children":114,"page":67},"Integrations","\u002Fintegrations","4.integrations",[115,119,123,127],{"title":116,"path":117,"stem":118},"NuxtHub","\u002Fintegrations\u002Fnuxthub","4.integrations\u002F1.nuxthub",{"title":120,"path":121,"stem":122},"DevTools","\u002Fintegrations\u002Fdevtools","4.integrations\u002F2.devtools",{"title":124,"path":125,"stem":126},"Convex","\u002Fintegrations\u002Fconvex","4.integrations\u002F3.convex",{"title":128,"path":129,"stem":130},"i18n","\u002Fintegrations\u002Fi18n","4.integrations\u002F4.i18n",{"title":132,"path":133,"stem":134,"children":135,"page":67},"API Reference","\u002Fapi","5.api",[136,140,144,148],{"title":137,"path":138,"stem":139},"Composables","\u002Fapi\u002Fcomposables","5.api\u002F1.composables",{"title":141,"path":142,"stem":143},"Server Utilities","\u002Fapi\u002Fserver-utils","5.api\u002F2.server-utils",{"title":145,"path":146,"stem":147},"Components","\u002Fapi\u002Fcomponents","5.api\u002F3.components",{"title":149,"path":150,"stem":151},"Types","\u002Fapi\u002Ftypes","5.api\u002F4.types",{"id":153,"title":99,"body":154,"description":1895,"extension":1896,"links":1897,"meta":1898,"navigation":240,"path":100,"seo":1899,"stem":101,"__hash__":1900},"docs\u002F3.guides\u002F7.two-factor-auth.md",{"type":155,"value":156,"toc":1883},"minimark",[157,161,174,1575,1580,1584,1587,1695,1699,1702,1873,1879],[158,159,160],"p",{},"Use this guide when you already have a database-backed auth setup and want to add TOTP with backup codes.",[158,162,163,164,168,169,173],{},"Better Auth ships a ",[165,166,167],"code",{},"twoFactor"," plugin with TOTP, OTP, and backup codes. It requires a database-backed setup (e.g., ",[170,171],"brand-badge",{"name":172},"nuxthub",").",[175,176,177,182,347,351,474,478,1224,1228,1231,1251,1254,1449,1453,1467,1516,1519,1545,1549],"steps",{},[178,179,181],"h3",{"id":180},"enable-the-plugin-server","Enable the Plugin (Server)",[183,184,190],"pre",{"className":185,"code":186,"filename":187,"language":188,"meta":189,"style":189},"language-ts shiki shiki-themes one-light synthwave-84 synthwave-84","import { defineServerAuth } from '@nuxtjs\u002Fbetter-auth\u002Fconfig'\nimport { twoFactor } from 'better-auth\u002Fplugins\u002Ftwo-factor'\n\nexport default defineServerAuth({\n  emailAndPassword: { enabled: true },\n  plugins: [\n    twoFactor({\n      \u002F\u002F Optional: customize issuer shown in authenticator apps\n      totpOptions: { issuer: 'My Nuxt App' },\n    }),\n  ],\n})\n","server\u002Fauth.config.ts","ts","",[165,191,192,219,235,242,259,283,294,302,309,329,335,341],{"__ignoreMap":189},[193,194,197,201,205,209,212,215],"span",{"class":195,"line":196},"line",1,[193,198,200],{"class":199},"sqe1H","import",[193,202,204],{"class":203},"s17Py"," { ",[193,206,208],{"class":207},"sYvLG","defineServerAuth",[193,210,211],{"class":203}," } ",[193,213,214],{"class":199},"from",[193,216,218],{"class":217},"sPAZv"," '@nuxtjs\u002Fbetter-auth\u002Fconfig'\n",[193,220,222,224,226,228,230,232],{"class":195,"line":221},2,[193,223,200],{"class":199},[193,225,204],{"class":203},[193,227,167],{"class":207},[193,229,211],{"class":203},[193,231,214],{"class":199},[193,233,234],{"class":217}," 'better-auth\u002Fplugins\u002Ftwo-factor'\n",[193,236,238],{"class":195,"line":237},3,[193,239,241],{"emptyLinePlaceholder":240},true,"\n",[193,243,245,248,252,256],{"class":195,"line":244},4,[193,246,247],{"class":199},"export",[193,249,251],{"class":250},"sKg8T"," default",[193,253,255],{"class":254},"sfT9l"," defineServerAuth",[193,257,258],{"class":203},"({\n",[193,260,262,265,269,271,274,276,280],{"class":195,"line":261},5,[193,263,264],{"class":207},"  emailAndPassword",[193,266,268],{"class":267},"sVnqq",":",[193,270,204],{"class":203},[193,272,273],{"class":207},"enabled",[193,275,268],{"class":267},[193,277,279],{"class":278},"s3ZNE"," true",[193,281,282],{"class":203}," },\n",[193,284,286,289,291],{"class":195,"line":285},6,[193,287,288],{"class":207},"  plugins",[193,290,268],{"class":267},[193,292,293],{"class":203}," [\n",[193,295,297,300],{"class":195,"line":296},7,[193,298,299],{"class":254},"    twoFactor",[193,301,258],{"class":203},[193,303,305],{"class":195,"line":304},8,[193,306,308],{"class":307},"st7cf","      \u002F\u002F Optional: customize issuer shown in authenticator apps\n",[193,310,312,315,317,319,322,324,327],{"class":195,"line":311},9,[193,313,314],{"class":207},"      totpOptions",[193,316,268],{"class":267},[193,318,204],{"class":203},[193,320,321],{"class":207},"issuer",[193,323,268],{"class":267},[193,325,326],{"class":217}," 'My Nuxt App'",[193,328,282],{"class":203},[193,330,332],{"class":195,"line":331},10,[193,333,334],{"class":203},"    }),\n",[193,336,338],{"class":195,"line":337},11,[193,339,340],{"class":203},"  ],\n",[193,342,344],{"class":195,"line":343},12,[193,345,346],{"class":203},"})\n",[178,348,350],{"id":349},"register-client-plugin","Register Client Plugin",[183,352,355],{"className":185,"code":353,"filename":354,"language":188,"meta":189,"style":189},"import { navigateTo } from '#imports'\nimport { defineClientAuth } from '@nuxtjs\u002Fbetter-auth\u002Fconfig'\nimport { twoFactorClient } from 'better-auth\u002Fclient\u002Fplugins'\n\nexport default defineClientAuth({\n  plugins: [\n    twoFactorClient({\n      onTwoFactorRedirect() {\n        navigateTo('\u002Ftwo-factor')\n      },\n    }),\n  ],\n})\n","app\u002Fauth.config.ts",[165,356,357,373,388,404,408,419,427,434,442,456,461,465,469],{"__ignoreMap":189},[193,358,359,361,363,366,368,370],{"class":195,"line":196},[193,360,200],{"class":199},[193,362,204],{"class":203},[193,364,365],{"class":207},"navigateTo",[193,367,211],{"class":203},[193,369,214],{"class":199},[193,371,372],{"class":217}," '#imports'\n",[193,374,375,377,379,382,384,386],{"class":195,"line":221},[193,376,200],{"class":199},[193,378,204],{"class":203},[193,380,381],{"class":207},"defineClientAuth",[193,383,211],{"class":203},[193,385,214],{"class":199},[193,387,218],{"class":217},[193,389,390,392,394,397,399,401],{"class":195,"line":237},[193,391,200],{"class":199},[193,393,204],{"class":203},[193,395,396],{"class":207},"twoFactorClient",[193,398,211],{"class":203},[193,400,214],{"class":199},[193,402,403],{"class":217}," 'better-auth\u002Fclient\u002Fplugins'\n",[193,405,406],{"class":195,"line":244},[193,407,241],{"emptyLinePlaceholder":240},[193,409,410,412,414,417],{"class":195,"line":261},[193,411,247],{"class":199},[193,413,251],{"class":250},[193,415,416],{"class":254}," defineClientAuth",[193,418,258],{"class":203},[193,420,421,423,425],{"class":195,"line":285},[193,422,288],{"class":207},[193,424,268],{"class":267},[193,426,293],{"class":203},[193,428,429,432],{"class":195,"line":296},[193,430,431],{"class":254},"    twoFactorClient",[193,433,258],{"class":203},[193,435,436,439],{"class":195,"line":304},[193,437,438],{"class":254},"      onTwoFactorRedirect",[193,440,441],{"class":203},"() {\n",[193,443,444,447,450,453],{"class":195,"line":311},[193,445,446],{"class":254},"        navigateTo",[193,448,449],{"class":203},"(",[193,451,452],{"class":217},"'\u002Ftwo-factor'",[193,454,455],{"class":203},")\n",[193,457,458],{"class":195,"line":331},[193,459,460],{"class":203},"      },\n",[193,462,463],{"class":195,"line":337},[193,464,334],{"class":203},[193,466,467],{"class":195,"line":343},[193,468,340],{"class":203},[193,470,472],{"class":195,"line":471},13,[193,473,346],{"class":203},[178,475,477],{"id":476},"enable-2fa-for-a-user-totp","Enable 2FA for a User (TOTP)",[183,479,482],{"className":185,"code":480,"filename":481,"language":188,"meta":189,"style":189},"\u003Cscript setup lang=\"ts\">\ndefinePageMeta({ auth: 'user' })\nconst client = useAuthClient()\nconst password = ref('')\nconst qr = ref\u003Cstring | null>(null)\nconst backupCodes = ref\u003Cstring[] | null>(null)\nconst error = ref('')\n\nasync function enable2fa() {\n  try {\n    const res = await client?.twoFactor.enable({ password: password.value })\n    if (res?.error) {\n      error.value = res.error.message\n      return\n    }\n    qr.value = res?.totpURI || null\n    backupCodes.value = res?.backupCodes || null\n  } catch (e) {\n    error.value = 'Failed to enable 2FA. Please try again.'\n  }\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cform @submit.prevent=\"enable2fa\">\n    \u003Cinput v-model=\"password\" type=\"password\" placeholder=\"Password\" \u002F>\n    \u003Cbutton type=\"submit\">Enable 2FA\u003C\u002Fbutton>\n  \u003C\u002Fform>\n\n  \u003Cdiv v-if=\"qr\">\n    \u003Cp>Scan this in your authenticator app:\u003C\u002Fp>\n    \u003Cpre>{{ qr }}\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\n  \u003Cdiv v-if=\"backupCodes\">\n    \u003Cp>Backup codes (store securely):\u003C\u002Fp>\n    \u003Cul>\n      \u003Cli v-for=\"code in backupCodes\" :key=\"code\">{{ code }}\u003C\u002Fli>\n    \u003C\u002Ful>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","pages\u002Ftwo-factor.vue",[165,483,484,510,529,547,566,597,626,643,647,660,668,710,729,751,757,763,788,811,827,842,848,854,864,869,880,907,948,981,991,996,1018,1053,1075,1084,1089,1109,1139,1149,1196,1206,1215],{"__ignoreMap":189},[193,485,486,490,494,497,500,504,507],{"class":195,"line":196},[193,487,489],{"class":488},"sn-Jc","\u003C",[193,491,493],{"class":492},"svFNh","script",[193,495,496],{"class":492}," setup",[193,498,499],{"class":492}," lang",[193,501,503],{"class":502},"sQBpM","=",[193,505,506],{"class":217},"\"ts\"",[193,508,509],{"class":488},">\n",[193,511,512,515,518,521,523,526],{"class":195,"line":221},[193,513,514],{"class":254},"definePageMeta",[193,516,517],{"class":203},"({ ",[193,519,520],{"class":207},"auth",[193,522,268],{"class":267},[193,524,525],{"class":217}," 'user'",[193,527,528],{"class":203}," })\n",[193,530,531,534,538,541,544],{"class":195,"line":237},[193,532,533],{"class":199},"const",[193,535,537],{"class":536},"s6Rhl"," client",[193,539,540],{"class":502}," =",[193,542,543],{"class":254}," useAuthClient",[193,545,546],{"class":203},"()\n",[193,548,549,551,554,556,559,561,564],{"class":195,"line":244},[193,550,533],{"class":199},[193,552,553],{"class":536}," password",[193,555,540],{"class":502},[193,557,558],{"class":254}," ref",[193,560,449],{"class":203},[193,562,563],{"class":217},"''",[193,565,455],{"class":203},[193,567,568,570,573,575,577,579,583,586,589,592,595],{"class":195,"line":261},[193,569,533],{"class":199},[193,571,572],{"class":536}," qr",[193,574,540],{"class":502},[193,576,558],{"class":254},[193,578,489],{"class":203},[193,580,582],{"class":581},"sivOE","string",[193,584,585],{"class":488}," |",[193,587,588],{"class":581}," null",[193,590,591],{"class":203},">(",[193,593,594],{"class":278},"null",[193,596,455],{"class":203},[193,598,599,601,604,606,608,610,612,615,618,620,622,624],{"class":195,"line":285},[193,600,533],{"class":199},[193,602,603],{"class":536}," backupCodes",[193,605,540],{"class":502},[193,607,558],{"class":254},[193,609,489],{"class":203},[193,611,582],{"class":581},[193,613,614],{"class":203},"[] ",[193,616,617],{"class":488},"|",[193,619,588],{"class":581},[193,621,591],{"class":203},[193,623,594],{"class":278},[193,625,455],{"class":203},[193,627,628,630,633,635,637,639,641],{"class":195,"line":296},[193,629,533],{"class":199},[193,631,632],{"class":536}," error",[193,634,540],{"class":502},[193,636,558],{"class":254},[193,638,449],{"class":203},[193,640,563],{"class":217},[193,642,455],{"class":203},[193,644,645],{"class":195,"line":304},[193,646,241],{"emptyLinePlaceholder":240},[193,648,649,652,655,658],{"class":195,"line":311},[193,650,651],{"class":199},"async",[193,653,654],{"class":199}," function",[193,656,657],{"class":254}," enable2fa",[193,659,441],{"class":203},[193,661,662,665],{"class":195,"line":331},[193,663,664],{"class":199},"  try",[193,666,667],{"class":203}," {\n",[193,669,670,673,676,678,681,683,686,688,691,694,696,699,701,703,705,708],{"class":195,"line":337},[193,671,672],{"class":199},"    const",[193,674,675],{"class":536}," res",[193,677,540],{"class":502},[193,679,680],{"class":199}," await",[193,682,537],{"class":492},[193,684,685],{"class":203},"?.",[193,687,167],{"class":207},[193,689,690],{"class":203},".",[193,692,693],{"class":254},"enable",[193,695,517],{"class":203},[193,697,698],{"class":207},"password",[193,700,268],{"class":267},[193,702,553],{"class":492},[193,704,690],{"class":203},[193,706,707],{"class":207},"value",[193,709,528],{"class":203},[193,711,712,715,718,721,723,726],{"class":195,"line":343},[193,713,714],{"class":199},"    if",[193,716,717],{"class":203}," (",[193,719,720],{"class":492},"res",[193,722,685],{"class":203},[193,724,725],{"class":207},"error",[193,727,728],{"class":203},") {\n",[193,730,731,734,736,738,740,742,744,746,748],{"class":195,"line":471},[193,732,733],{"class":492},"      error",[193,735,690],{"class":203},[193,737,707],{"class":207},[193,739,540],{"class":502},[193,741,675],{"class":492},[193,743,690],{"class":203},[193,745,725],{"class":207},[193,747,690],{"class":203},[193,749,750],{"class":207},"message\n",[193,752,754],{"class":195,"line":753},14,[193,755,756],{"class":199},"      return\n",[193,758,760],{"class":195,"line":759},15,[193,761,762],{"class":203},"    }\n",[193,764,766,769,771,773,775,777,779,782,785],{"class":195,"line":765},16,[193,767,768],{"class":492},"    qr",[193,770,690],{"class":203},[193,772,707],{"class":207},[193,774,540],{"class":502},[193,776,675],{"class":492},[193,778,685],{"class":203},[193,780,781],{"class":207},"totpURI",[193,783,784],{"class":488}," ||",[193,786,787],{"class":278}," null\n",[193,789,791,794,796,798,800,802,804,807,809],{"class":195,"line":790},17,[193,792,793],{"class":492},"    backupCodes",[193,795,690],{"class":203},[193,797,707],{"class":207},[193,799,540],{"class":502},[193,801,675],{"class":492},[193,803,685],{"class":203},[193,805,806],{"class":207},"backupCodes",[193,808,784],{"class":488},[193,810,787],{"class":278},[193,812,814,817,820,822,825],{"class":195,"line":813},18,[193,815,816],{"class":203},"  } ",[193,818,819],{"class":199},"catch",[193,821,717],{"class":203},[193,823,824],{"class":492},"e",[193,826,728],{"class":203},[193,828,830,833,835,837,839],{"class":195,"line":829},19,[193,831,832],{"class":492},"    error",[193,834,690],{"class":203},[193,836,707],{"class":207},[193,838,540],{"class":502},[193,840,841],{"class":217}," 'Failed to enable 2FA. Please try again.'\n",[193,843,845],{"class":195,"line":844},20,[193,846,847],{"class":203},"  }\n",[193,849,851],{"class":195,"line":850},21,[193,852,853],{"class":203},"}\n",[193,855,857,860,862],{"class":195,"line":856},22,[193,858,859],{"class":488},"\u003C\u002F",[193,861,493],{"class":492},[193,863,509],{"class":488},[193,865,867],{"class":195,"line":866},23,[193,868,241],{"emptyLinePlaceholder":240},[193,870,872,874,878],{"class":195,"line":871},24,[193,873,489],{"class":203},[193,875,877],{"class":876},"s8RlJ","template",[193,879,509],{"class":203},[193,881,883,886,889,892,895,897,900,902,905],{"class":195,"line":882},25,[193,884,885],{"class":488},"  \u003C",[193,887,888],{"class":492},"form",[193,890,891],{"class":203}," @",[193,893,894],{"class":492},"submit",[193,896,690],{"class":203},[193,898,899],{"class":207},"prevent",[193,901,503],{"class":502},[193,903,904],{"class":217},"\"enable2fa\"",[193,906,509],{"class":488},[193,908,910,913,916,919,922,925,927,930,933,935,937,940,942,945],{"class":195,"line":909},26,[193,911,912],{"class":488},"    \u003C",[193,914,915],{"class":492},"input",[193,917,918],{"class":492}," v",[193,920,921],{"class":488},"-",[193,923,924],{"class":492},"model",[193,926,503],{"class":502},[193,928,929],{"class":217},"\"password\"",[193,931,932],{"class":492}," type",[193,934,503],{"class":502},[193,936,929],{"class":217},[193,938,939],{"class":492}," placeholder",[193,941,503],{"class":502},[193,943,944],{"class":217},"\"Password\"",[193,946,947],{"class":488}," \u002F>\n",[193,949,951,953,956,958,960,963,966,969,972,975,977,979],{"class":195,"line":950},27,[193,952,912],{"class":488},[193,954,955],{"class":492},"button",[193,957,932],{"class":492},[193,959,503],{"class":502},[193,961,962],{"class":217},"\"submit\"",[193,964,965],{"class":488},">",[193,967,968],{"class":492},"Enable",[193,970,971],{"class":203}," 2",[193,973,974],{"class":536},"FA",[193,976,859],{"class":488},[193,978,955],{"class":492},[193,980,509],{"class":488},[193,982,984,987,989],{"class":195,"line":983},28,[193,985,986],{"class":488},"  \u003C\u002F",[193,988,888],{"class":492},[193,990,509],{"class":488},[193,992,994],{"class":195,"line":993},29,[193,995,241],{"emptyLinePlaceholder":240},[193,997,999,1001,1004,1006,1008,1011,1013,1016],{"class":195,"line":998},30,[193,1000,885],{"class":488},[193,1002,1003],{"class":492},"div",[193,1005,918],{"class":492},[193,1007,921],{"class":488},[193,1009,1010],{"class":199},"if",[193,1012,503],{"class":502},[193,1014,1015],{"class":217},"\"qr\"",[193,1017,509],{"class":488},[193,1019,1021,1023,1025,1027,1030,1034,1037,1040,1043,1046,1049,1051],{"class":195,"line":1020},31,[193,1022,912],{"class":203},[193,1024,158],{"class":876},[193,1026,965],{"class":203},[193,1028,1029],{"class":492},"Scan",[193,1031,1033],{"class":1032},"sK50a"," this",[193,1035,1036],{"class":199}," in",[193,1038,1039],{"class":492}," your",[193,1041,1042],{"class":492}," authenticator",[193,1044,1045],{"class":581}," app",[193,1047,1048],{"class":203},":\u003C\u002F",[193,1050,158],{"class":876},[193,1052,509],{"class":203},[193,1054,1056,1058,1060,1063,1066,1069,1071,1073],{"class":195,"line":1055},32,[193,1057,912],{"class":203},[193,1059,183],{"class":876},[193,1061,1062],{"class":203},">{{ ",[193,1064,1065],{"class":492},"qr",[193,1067,1068],{"class":203}," }}",[193,1070,859],{"class":488},[193,1072,183],{"class":492},[193,1074,509],{"class":488},[193,1076,1078,1080,1082],{"class":195,"line":1077},33,[193,1079,986],{"class":488},[193,1081,1003],{"class":492},[193,1083,509],{"class":488},[193,1085,1087],{"class":195,"line":1086},34,[193,1088,241],{"emptyLinePlaceholder":240},[193,1090,1092,1094,1096,1098,1100,1102,1104,1107],{"class":195,"line":1091},35,[193,1093,885],{"class":488},[193,1095,1003],{"class":492},[193,1097,918],{"class":492},[193,1099,921],{"class":488},[193,1101,1010],{"class":199},[193,1103,503],{"class":502},[193,1105,1106],{"class":217},"\"backupCodes\"",[193,1108,509],{"class":488},[193,1110,1112,1114,1116,1118,1121,1124,1126,1129,1132,1135,1137],{"class":195,"line":1111},36,[193,1113,912],{"class":203},[193,1115,158],{"class":876},[193,1117,965],{"class":203},[193,1119,1120],{"class":492},"Backup",[193,1122,1123],{"class":254}," codes",[193,1125,717],{"class":203},[193,1127,1128],{"class":492},"store",[193,1130,1131],{"class":492}," securely",[193,1133,1134],{"class":203},"):\u003C\u002F",[193,1136,158],{"class":876},[193,1138,509],{"class":203},[193,1140,1142,1144,1147],{"class":195,"line":1141},37,[193,1143,912],{"class":203},[193,1145,1146],{"class":876},"ul",[193,1148,509],{"class":203},[193,1150,1152,1155,1158,1160,1162,1165,1167,1170,1173,1176,1178,1181,1183,1186,1188,1190,1192,1194],{"class":195,"line":1151},38,[193,1153,1154],{"class":488},"      \u003C",[193,1156,1157],{"class":492},"li",[193,1159,918],{"class":492},[193,1161,921],{"class":488},[193,1163,1164],{"class":492},"for",[193,1166,503],{"class":502},[193,1168,1169],{"class":217},"\"code in backupCodes\"",[193,1171,1172],{"class":203}," :",[193,1174,1175],{"class":492},"key",[193,1177,503],{"class":502},[193,1179,1180],{"class":217},"\"code\"",[193,1182,965],{"class":488},[193,1184,1185],{"class":203},"{{ ",[193,1187,165],{"class":492},[193,1189,1068],{"class":203},[193,1191,859],{"class":488},[193,1193,1157],{"class":492},[193,1195,509],{"class":488},[193,1197,1199,1202,1204],{"class":195,"line":1198},39,[193,1200,1201],{"class":488},"    \u003C\u002F",[193,1203,1146],{"class":492},[193,1205,509],{"class":488},[193,1207,1209,1211,1213],{"class":195,"line":1208},40,[193,1210,986],{"class":488},[193,1212,1003],{"class":492},[193,1214,509],{"class":488},[193,1216,1218,1220,1222],{"class":195,"line":1217},41,[193,1219,859],{"class":488},[193,1221,877],{"class":492},[193,1223,509],{"class":488},[178,1225,1227],{"id":1226},"displaying-the-qr-code","Displaying the QR Code",[158,1229,1230],{},"Install a QR code library:",[183,1232,1236],{"className":1233,"code":1234,"language":1235,"meta":189,"style":189},"language-bash shiki shiki-themes one-light synthwave-84 synthwave-84","pnpm add qrcode\n","bash",[165,1237,1238],{"__ignoreMap":189},[193,1239,1240,1244,1248],{"class":195,"line":196},[193,1241,1243],{"class":1242},"siqUp","pnpm",[193,1245,1247],{"class":1246},"sI3kV"," add",[193,1249,1250],{"class":1246}," qrcode\n",[158,1252,1253],{},"Render the QR code:",[183,1255,1259],{"className":1256,"code":1257,"language":1258,"meta":189,"style":189},"language-vue shiki shiki-themes one-light synthwave-84 synthwave-84","\u003Cscript setup>\nimport QRCode from 'qrcode'\n\nconst qrImage = ref('')\n\nwatch(qr, async (uri) => {\n  if (uri) {\n    qrImage.value = await QRCode.toDataURL(uri)\n  }\n})\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cimg v-if=\"qrImage\" :src=\"qrImage\" alt=\"Scan with authenticator app\" \u002F>\n\u003C\u002Ftemplate>\n","vue",[165,1260,1261,1274,1288,1292,1310,1314,1342,1353,1380,1384,1388,1396,1400,1408,1441],{"__ignoreMap":189},[193,1262,1263,1266,1269,1272],{"class":195,"line":196},[193,1264,489],{"class":1265},"sL9le",[193,1267,493],{"class":1268},"stweg",[193,1270,496],{"class":1271},"s0frj",[193,1273,509],{"class":1265},[193,1275,1276,1279,1282,1285],{"class":195,"line":221},[193,1277,200],{"class":1278},"su8fI",[193,1280,1281],{"class":207}," QRCode",[193,1283,1284],{"class":199}," from",[193,1286,1287],{"class":217}," 'qrcode'\n",[193,1289,1290],{"class":195,"line":237},[193,1291,241],{"emptyLinePlaceholder":240},[193,1293,1294,1296,1299,1301,1303,1306,1308],{"class":195,"line":244},[193,1295,533],{"class":199},[193,1297,1298],{"class":536}," qrImage",[193,1300,540],{"class":502},[193,1302,558],{"class":254},[193,1304,449],{"class":1305},"sEEOt",[193,1307,563],{"class":217},[193,1309,455],{"class":1305},[193,1311,1312],{"class":195,"line":261},[193,1313,241],{"emptyLinePlaceholder":240},[193,1315,1316,1319,1321,1323,1326,1328,1330,1334,1337,1340],{"class":195,"line":285},[193,1317,1318],{"class":254},"watch",[193,1320,449],{"class":1305},[193,1322,1065],{"class":492},[193,1324,1325],{"class":1305},", ",[193,1327,651],{"class":199},[193,1329,717],{"class":1305},[193,1331,1333],{"class":1332},"sgisi","uri",[193,1335,1336],{"class":1305},") ",[193,1338,1339],{"class":199},"=>",[193,1341,667],{"class":1305},[193,1343,1344,1347,1349,1351],{"class":195,"line":296},[193,1345,1346],{"class":199},"  if",[193,1348,717],{"class":1305},[193,1350,1333],{"class":492},[193,1352,728],{"class":1305},[193,1354,1355,1358,1360,1363,1365,1367,1369,1371,1374,1376,1378],{"class":195,"line":304},[193,1356,1357],{"class":492},"    qrImage",[193,1359,690],{"class":1305},[193,1361,707],{"class":1362},"smW3M",[193,1364,540],{"class":502},[193,1366,680],{"class":199},[193,1368,1281],{"class":492},[193,1370,690],{"class":1305},[193,1372,1373],{"class":254},"toDataURL",[193,1375,449],{"class":1305},[193,1377,1333],{"class":492},[193,1379,455],{"class":1305},[193,1381,1382],{"class":195,"line":311},[193,1383,847],{"class":1305},[193,1385,1386],{"class":195,"line":331},[193,1387,346],{"class":1305},[193,1389,1390,1392,1394],{"class":195,"line":337},[193,1391,859],{"class":1265},[193,1393,493],{"class":1268},[193,1395,509],{"class":1265},[193,1397,1398],{"class":195,"line":343},[193,1399,241],{"emptyLinePlaceholder":240},[193,1401,1402,1404,1406],{"class":195,"line":471},[193,1403,489],{"class":1265},[193,1405,877],{"class":1268},[193,1407,509],{"class":1265},[193,1409,1410,1412,1415,1418,1421,1424,1427,1429,1431,1434,1436,1439],{"class":195,"line":753},[193,1411,885],{"class":1265},[193,1413,1414],{"class":1268},"img",[193,1416,1417],{"class":1271}," v-if",[193,1419,503],{"class":1420},"sNM9w",[193,1422,1423],{"class":217},"\"qrImage\"",[193,1425,1426],{"class":1271}," :src",[193,1428,503],{"class":1420},[193,1430,1423],{"class":217},[193,1432,1433],{"class":1271}," alt",[193,1435,503],{"class":1420},[193,1437,1438],{"class":217},"\"Scan with authenticator app\"",[193,1440,947],{"class":1265},[193,1442,1443,1445,1447],{"class":195,"line":759},[193,1444,859],{"class":1265},[193,1446,877],{"class":1268},[193,1448,509],{"class":1265},[178,1450,1452],{"id":1451},"trustverify-during-sign-in","Trust\u002FVerify During Sign-In",[158,1454,1455,1456,1458,1459,1462,1463,1466],{},"When a user signs in and 2FA is required, ",[165,1457,396],{}," triggers ",[165,1460,1461],{},"onTwoFactorRedirect",". On your ",[165,1464,1465],{},"\u002Ftwo-factor"," page, prompt for the code and call:",[183,1468,1470],{"className":185,"code":1469,"language":188,"meta":189,"style":189},"await client?.twoFactor.verifyTotp({\n  code,\n  trustDevice: true, \u002F\u002F optional\n})\n",[165,1471,1472,1490,1498,1512],{"__ignoreMap":189},[193,1473,1474,1477,1479,1481,1483,1485,1488],{"class":195,"line":196},[193,1475,1476],{"class":199},"await",[193,1478,537],{"class":492},[193,1480,685],{"class":203},[193,1482,167],{"class":207},[193,1484,690],{"class":203},[193,1486,1487],{"class":254},"verifyTotp",[193,1489,258],{"class":203},[193,1491,1492,1495],{"class":195,"line":221},[193,1493,1494],{"class":492},"  code",[193,1496,1497],{"class":203},",\n",[193,1499,1500,1503,1505,1507,1509],{"class":195,"line":237},[193,1501,1502],{"class":207},"  trustDevice",[193,1504,268],{"class":267},[193,1506,279],{"class":278},[193,1508,1325],{"class":203},[193,1510,1511],{"class":307},"\u002F\u002F optional\n",[193,1513,1514],{"class":195,"line":244},[193,1515,346],{"class":203},[158,1517,1518],{},"Backup codes can be verified via:",[183,1520,1522],{"className":185,"code":1521,"language":188,"meta":189,"style":189},"await client?.twoFactor.verifyBackupCode({ code })\n",[165,1523,1524],{"__ignoreMap":189},[193,1525,1526,1528,1530,1532,1534,1536,1539,1541,1543],{"class":195,"line":196},[193,1527,1476],{"class":199},[193,1529,537],{"class":492},[193,1531,685],{"class":203},[193,1533,167],{"class":207},[193,1535,690],{"class":203},[193,1537,1538],{"class":254},"verifyBackupCode",[193,1540,517],{"class":203},[193,1542,165],{"class":492},[193,1544,528],{"class":203},[178,1546,1548],{"id":1547},"disable-2fa","Disable 2FA",[183,1550,1552],{"className":185,"code":1551,"language":188,"meta":189,"style":189},"await client?.twoFactor.disable({ password })\n",[165,1553,1554],{"__ignoreMap":189},[193,1555,1556,1558,1560,1562,1564,1566,1569,1571,1573],{"class":195,"line":196},[193,1557,1476],{"class":199},[193,1559,537],{"class":492},[193,1561,685],{"class":203},[193,1563,167],{"class":207},[193,1565,690],{"class":203},[193,1567,1568],{"class":254},"disable",[193,1570,517],{"class":203},[193,1572,698],{"class":492},[193,1574,528],{"class":203},[1576,1577,1579],"h2",{"id":1578},"account-recovery","Account Recovery",[178,1581,1583],{"id":1582},"backup-codes","Backup Codes",[158,1585,1586],{},"Display backup codes to users during 2FA setup. Each code can only be used once.",[183,1588,1590],{"className":1256,"code":1589,"language":1258,"meta":189,"style":189},"\u003Ctemplate>\n  \u003Cdiv v-if=\"backupCodes.length\">\n    \u003Cp>Save these backup codes in a secure location:\u003C\u002Fp>\n    \u003Cul>\n      \u003Cli v-for=\"code in backupCodes\" :key=\"code\">{{ code }}\u003C\u002Fli>\n    \u003C\u002Ful>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[165,1591,1592,1600,1615,1632,1640,1671,1679,1687],{"__ignoreMap":189},[193,1593,1594,1596,1598],{"class":195,"line":196},[193,1595,489],{"class":1265},[193,1597,877],{"class":1268},[193,1599,509],{"class":1265},[193,1601,1602,1604,1606,1608,1610,1613],{"class":195,"line":221},[193,1603,885],{"class":1265},[193,1605,1003],{"class":1268},[193,1607,1417],{"class":1271},[193,1609,503],{"class":1420},[193,1611,1612],{"class":217},"\"backupCodes.length\"",[193,1614,509],{"class":1265},[193,1616,1617,1619,1621,1623,1626,1628,1630],{"class":195,"line":237},[193,1618,912],{"class":1265},[193,1620,158],{"class":1268},[193,1622,965],{"class":1265},[193,1624,1625],{"class":1305},"Save these backup codes in a secure location:",[193,1627,859],{"class":1265},[193,1629,158],{"class":1268},[193,1631,509],{"class":1265},[193,1633,1634,1636,1638],{"class":195,"line":244},[193,1635,912],{"class":1265},[193,1637,1146],{"class":1268},[193,1639,509],{"class":1265},[193,1641,1642,1644,1646,1649,1651,1653,1656,1658,1660,1662,1665,1667,1669],{"class":195,"line":261},[193,1643,1154],{"class":1265},[193,1645,1157],{"class":1268},[193,1647,1648],{"class":1271}," v-for",[193,1650,503],{"class":1420},[193,1652,1169],{"class":217},[193,1654,1655],{"class":1271}," :key",[193,1657,503],{"class":1420},[193,1659,1180],{"class":217},[193,1661,965],{"class":1265},[193,1663,1664],{"class":1305},"{{ code }}",[193,1666,859],{"class":1265},[193,1668,1157],{"class":1268},[193,1670,509],{"class":1265},[193,1672,1673,1675,1677],{"class":195,"line":285},[193,1674,1201],{"class":1265},[193,1676,1146],{"class":1268},[193,1678,509],{"class":1265},[193,1680,1681,1683,1685],{"class":195,"line":296},[193,1682,986],{"class":1265},[193,1684,1003],{"class":1268},[193,1686,509],{"class":1265},[193,1688,1689,1691,1693],{"class":195,"line":304},[193,1690,859],{"class":1265},[193,1692,877],{"class":1268},[193,1694,509],{"class":1265},[178,1696,1698],{"id":1697},"admin-recovery","Admin Recovery",[158,1700,1701],{},"For users who lose their device and backup codes, implement an admin recovery flow:",[183,1703,1706],{"className":185,"code":1704,"filename":1705,"language":188,"meta":189,"style":189},"export default defineEventHandler(async (event) => {\n  await requireUserSession(event, { user: { role: 'admin' } })\n\n  const { userId } = await readBody(event)\n  const auth = serverAuth(event)\n\n  \u002F\u002F Reset 2FA for user (requires admin plugin)\n  await auth.api.admin.disableTwoFactor({ userId })\n\n  return { success: true }\n})\n","server\u002Fapi\u002Fadmin\u002Freset-2fa.ts",[165,1707,1708,1732,1765,1769,1794,1812,1816,1821,1848,1852,1869],{"__ignoreMap":189},[193,1709,1710,1712,1714,1717,1719,1721,1723,1726,1728,1730],{"class":195,"line":196},[193,1711,247],{"class":199},[193,1713,251],{"class":250},[193,1715,1716],{"class":254}," defineEventHandler",[193,1718,449],{"class":203},[193,1720,651],{"class":199},[193,1722,717],{"class":203},[193,1724,1725],{"class":1332},"event",[193,1727,1336],{"class":203},[193,1729,1339],{"class":199},[193,1731,667],{"class":203},[193,1733,1734,1737,1740,1742,1744,1747,1750,1752,1754,1757,1759,1762],{"class":195,"line":221},[193,1735,1736],{"class":199},"  await",[193,1738,1739],{"class":254}," requireUserSession",[193,1741,449],{"class":203},[193,1743,1725],{"class":207},[193,1745,1746],{"class":203},", { ",[193,1748,1749],{"class":207},"user",[193,1751,268],{"class":267},[193,1753,204],{"class":203},[193,1755,1756],{"class":207},"role",[193,1758,268],{"class":267},[193,1760,1761],{"class":217}," 'admin'",[193,1763,1764],{"class":203}," } })\n",[193,1766,1767],{"class":195,"line":237},[193,1768,241],{"emptyLinePlaceholder":240},[193,1770,1771,1774,1776,1779,1781,1783,1785,1788,1790,1792],{"class":195,"line":244},[193,1772,1773],{"class":199},"  const",[193,1775,204],{"class":203},[193,1777,1778],{"class":536},"userId",[193,1780,211],{"class":203},[193,1782,503],{"class":502},[193,1784,680],{"class":199},[193,1786,1787],{"class":254}," readBody",[193,1789,449],{"class":203},[193,1791,1725],{"class":207},[193,1793,455],{"class":203},[193,1795,1796,1798,1801,1803,1806,1808,1810],{"class":195,"line":261},[193,1797,1773],{"class":199},[193,1799,1800],{"class":536}," auth",[193,1802,540],{"class":502},[193,1804,1805],{"class":254}," serverAuth",[193,1807,449],{"class":203},[193,1809,1725],{"class":207},[193,1811,455],{"class":203},[193,1813,1814],{"class":195,"line":285},[193,1815,241],{"emptyLinePlaceholder":240},[193,1817,1818],{"class":195,"line":296},[193,1819,1820],{"class":307},"  \u002F\u002F Reset 2FA for user (requires admin plugin)\n",[193,1822,1823,1825,1827,1829,1832,1834,1837,1839,1842,1844,1846],{"class":195,"line":304},[193,1824,1736],{"class":199},[193,1826,1800],{"class":492},[193,1828,690],{"class":203},[193,1830,1831],{"class":207},"api",[193,1833,690],{"class":203},[193,1835,1836],{"class":207},"admin",[193,1838,690],{"class":203},[193,1840,1841],{"class":254},"disableTwoFactor",[193,1843,517],{"class":203},[193,1845,1778],{"class":207},[193,1847,528],{"class":203},[193,1849,1850],{"class":195,"line":311},[193,1851,241],{"emptyLinePlaceholder":240},[193,1853,1854,1857,1859,1862,1864,1866],{"class":195,"line":331},[193,1855,1856],{"class":199},"  return",[193,1858,204],{"class":203},[193,1860,1861],{"class":207},"success",[193,1863,268],{"class":267},[193,1865,279],{"class":278},[193,1867,1868],{"class":203}," }\n",[193,1870,1871],{"class":195,"line":337},[193,1872,346],{"class":203},[1874,1875,1878],"callout",{"icon":1876,"to":1877},"i-lucide-link","https:\u002F\u002Fbetter-auth.com\u002Fdocs\u002Fplugins\u002F2fa","See the Better Auth 2FA docs for provider options and OTP flows.",[1880,1881,1882],"style",{},"html pre.shiki code .sqe1H, html code.shiki .sqe1H{--shiki-light:#A626A4;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}html pre.shiki code .s17Py, html code.shiki .s17Py{--shiki-light:#383A42;--shiki-default:#BBBBBB;--shiki-dark:#BBBBBB}html pre.shiki code .sYvLG, html code.shiki .sYvLG{--shiki-light:#E45649;--shiki-default:#FF7EDB;--shiki-dark:#FF7EDB}html pre.shiki code .sPAZv, html code.shiki .sPAZv{--shiki-light:#50A14F;--shiki-default:#FF8B39;--shiki-dark:#FF8B39}html pre.shiki code .sKg8T, html code.shiki .sKg8T{--shiki-light:#E45649;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}html pre.shiki code .sfT9l, html code.shiki .sfT9l{--shiki-light:#4078F2;--shiki-default:#36F9F6;--shiki-dark:#36F9F6}html pre.shiki code .sVnqq, html code.shiki .sVnqq{--shiki-light:#0184BC;--shiki-default:#B6B1B1;--shiki-dark:#B6B1B1}html pre.shiki code .s3ZNE, html code.shiki .s3ZNE{--shiki-light:#986801;--shiki-default:#F97E72;--shiki-dark:#F97E72}html pre.shiki code .st7cf, html code.shiki .st7cf{--shiki-light:#A0A1A7;--shiki-light-font-style:italic;--shiki-default:#848BBD;--shiki-default-font-style:italic;--shiki-dark:#848BBD;--shiki-dark-font-style:italic}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 .sn-Jc, html code.shiki .sn-Jc{--shiki-light:#0184BC;--shiki-default:#FEDE5D;--shiki-dark:#FEDE5D}html pre.shiki code .svFNh, html code.shiki .svFNh{--shiki-light:#383A42;--shiki-default:#FF7EDB;--shiki-dark:#FF7EDB}html pre.shiki code .sQBpM, html code.shiki .sQBpM{--shiki-light:#0184BC;--shiki-default:#FFFFFFEE;--shiki-dark:#FFFFFFEE}html pre.shiki code .s6Rhl, html code.shiki .s6Rhl{--shiki-light:#986801;--shiki-default:#FF7EDB;--shiki-dark:#FF7EDB}html pre.shiki code .sivOE, html code.shiki .sivOE{--shiki-light:#383A42;--shiki-default:#FE4450;--shiki-dark:#FE4450}html pre.shiki code .s8RlJ, html code.shiki .s8RlJ{--shiki-light:#C18401;--shiki-default:#FE4450;--shiki-dark:#FE4450}html pre.shiki code .sK50a, html code.shiki .sK50a{--shiki-light:#E45649;--shiki-light-font-weight:inherit;--shiki-default:#FE4450;--shiki-default-font-weight:bold;--shiki-dark:#FE4450;--shiki-dark-font-weight:bold}html pre.shiki code .siqUp, html code.shiki .siqUp{--shiki-light:#4078F2;--shiki-default:#FE4450;--shiki-dark:#FE4450}html pre.shiki code .sI3kV, html code.shiki .sI3kV{--shiki-light:#50A14F;--shiki-default:#BBBBBB;--shiki-dark:#BBBBBB}html pre.shiki code .sL9le, html code.shiki .sL9le{--shiki-light:#383A42;--shiki-default:#36F9F6;--shiki-dark:#36F9F6}html pre.shiki code .stweg, html code.shiki .stweg{--shiki-light:#E45649;--shiki-default:#72F1B8;--shiki-dark:#72F1B8}html pre.shiki code .s0frj, html code.shiki .s0frj{--shiki-light:#986801;--shiki-light-font-style:inherit;--shiki-default:#FEDE5D;--shiki-default-font-style:italic;--shiki-dark:#FEDE5D;--shiki-dark-font-style:italic}html pre.shiki code .su8fI, html code.shiki .su8fI{--shiki-light:#A626A4;--shiki-default:#72F1B8;--shiki-dark:#72F1B8}html pre.shiki code .sEEOt, html code.shiki .sEEOt{--shiki-light:#383A42;--shiki-default:#FFFFFFEE;--shiki-dark:#FFFFFFEE}html pre.shiki code .sgisi, html code.shiki .sgisi{--shiki-light:#383A42;--shiki-light-font-style:inherit;--shiki-default:#FF7EDB;--shiki-default-font-style:italic;--shiki-dark:#FF7EDB;--shiki-dark-font-style:italic}html pre.shiki code .smW3M, html code.shiki .smW3M{--shiki-light:#E45649;--shiki-default:#2EE2FA;--shiki-dark:#2EE2FA}html pre.shiki code .sNM9w, html code.shiki .sNM9w{--shiki-light:#383A42;--shiki-default:#B6B1B1;--shiki-dark:#B6B1B1}",{"title":189,"searchDepth":221,"depth":221,"links":1884},[1885,1886,1887,1888,1889,1890,1891],{"id":180,"depth":237,"text":181},{"id":349,"depth":237,"text":350},{"id":476,"depth":237,"text":477},{"id":1226,"depth":237,"text":1227},{"id":1451,"depth":237,"text":1452},{"id":1547,"depth":237,"text":1548},{"id":1578,"depth":221,"text":1579,"children":1892},[1893,1894],{"id":1582,"depth":237,"text":1583},{"id":1697,"depth":237,"text":1698},"Enable two-factor auth using the Better Auth two-factor plugin.","md",null,{},{"title":99,"description":1895},"dJ-LISJM83DE-q4z58A1BT5yTaBsp9jYkKr5ka-lT6I",[1902,1904],{"title":95,"path":96,"stem":97,"description":1903,"children":-1},"Step-by-step guide to migrate from nuxt-auth-utils to Nuxt Better Auth.",{"title":103,"path":104,"stem":105,"description":1905,"children":-1},"Mock authentication in component tests and verify protected API routes.",1788606329794]