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