[{"data":1,"prerenderedAt":629},["ShallowReactive",2],{"navigation":3,"\u002Fsign-in\u002Ftwo-factor":178,"\u002Fsign-in\u002Ftwo-factor-surround":624},[4,23,78,95,123,143,158],{"title":5,"path":6,"stem":7,"children":8,"icon":22},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F3.configuration","i-lucide-settings",false,{"title":24,"icon":22,"path":25,"stem":26,"children":27,"page":22},"Sign-in","\u002Fsign-in","2.sign-in",[28,33,38,43,48,53,58,63,68,73],{"title":29,"path":30,"stem":31,"icon":32},"Sign-in pages","\u002Fsign-in\u002Fpages","2.sign-in\u002F1.pages","i-lucide-log-in",{"title":34,"path":35,"stem":36,"icon":37},"Several accounts","\u002Fsign-in\u002Fmulti-session","2.sign-in\u002F10.multi-session","i-lucide-users-round",{"title":39,"path":40,"stem":41,"icon":42},"Account page","\u002Fsign-in\u002Faccount","2.sign-in\u002F2.account","i-lucide-circle-user",{"title":44,"path":45,"stem":46,"icon":47},"Other methods","\u002Fsign-in\u002Fmethods","2.sign-in\u002F3.methods","i-lucide-key-square",{"title":49,"path":50,"stem":51,"icon":52},"Sign-in providers","\u002Fsign-in\u002Fproviders","2.sign-in\u002F4.providers","i-lucide-share-2",{"title":54,"path":55,"stem":56,"icon":57},"Two-factor","\u002Fsign-in\u002Ftwo-factor","2.sign-in\u002F5.two-factor","i-lucide-shield-check",{"title":59,"path":60,"stem":61,"icon":62},"Passkeys","\u002Fsign-in\u002Fpasskeys","2.sign-in\u002F6.passkeys","i-lucide-fingerprint",{"title":64,"path":65,"stem":66,"icon":67},"Phone numbers","\u002Fsign-in\u002Fphone-numbers","2.sign-in\u002F7.phone-numbers","i-lucide-smartphone",{"title":69,"path":70,"stem":71,"icon":72},"Signing in devices","\u002Fsign-in\u002Fdevices","2.sign-in\u002F8.devices","i-lucide-tv",{"title":74,"path":75,"stem":76,"icon":77},"Security","\u002Fsign-in\u002Fsecurity","2.sign-in\u002F9.security","i-lucide-lock-keyhole",{"title":79,"path":80,"stem":81,"children":82,"icon":22},"Organizations","\u002Forganizations","3.organizations\u002F1.index",[83,85,90],{"title":79,"path":80,"stem":81,"icon":84},"i-lucide-building-2",{"title":86,"path":87,"stem":88,"icon":89},"Roles","\u002Forganizations\u002Froles","3.organizations\u002F2.roles","i-lucide-shield",{"title":91,"path":92,"stem":93,"icon":94},"Single sign-on","\u002Forganizations\u002Fsso","3.organizations\u002F3.sso","i-lucide-key-round",{"title":96,"path":97,"stem":98,"children":99,"icon":22},"Admin dashboard","\u002Fadmin","4.admin\u002F1.index",[100,103,108,113,118],{"title":101,"path":97,"stem":98,"icon":102},"Overview","i-lucide-layout-dashboard",{"title":104,"path":105,"stem":106,"icon":107},"Managing users","\u002Fadmin\u002Fusers","4.admin\u002F2.users","i-lucide-user-cog",{"title":109,"path":110,"stem":111,"icon":112},"Staff roles","\u002Fadmin\u002Froles","4.admin\u002F3.roles","i-lucide-shield-user",{"title":114,"path":115,"stem":116,"icon":117},"Audit log","\u002Fadmin\u002Faudit-log","4.admin\u002F4.audit-log","i-lucide-history",{"title":119,"path":120,"stem":121,"icon":122},"Your own pages","\u002Fadmin\u002Fextending","4.admin\u002F5.extending","i-lucide-layout-panel-left",{"title":124,"icon":22,"path":125,"stem":126,"children":127,"page":22},"Integrations","\u002Fintegrations","5.integrations",[128,133,138],{"title":129,"path":130,"stem":131,"icon":132},"Stripe","\u002Fintegrations\u002Fstripe","5.integrations\u002F1.stripe","i-simple-icons-stripe",{"title":134,"path":135,"stem":136,"icon":137},"API keys","\u002Fintegrations\u002Fapi-keys","5.integrations\u002F2.api-keys","i-lucide-key",{"title":139,"path":140,"stem":141,"icon":142},"Tokens","\u002Fintegrations\u002Ftokens","5.integrations\u002F3.tokens","i-lucide-ticket",{"title":144,"icon":22,"path":145,"stem":146,"children":147,"page":22},"Customization","\u002Fcustomization","6.customization",[148,153],{"title":149,"path":150,"stem":151,"icon":152},"Emails","\u002Fcustomization\u002Femails","6.customization\u002F1.emails","i-lucide-mail",{"title":154,"path":155,"stem":156,"icon":157},"Languages","\u002Fcustomization\u002Flanguages","6.customization\u002F2.languages","i-lucide-languages",{"title":159,"icon":22,"path":160,"stem":161,"children":162,"page":22},"Reference","\u002Freference","7.reference",[163,168,173],{"title":164,"path":165,"stem":166,"icon":167},"How it works","\u002Freference\u002Fhow-it-works","7.reference\u002F1.how-it-works","i-lucide-cog",{"title":169,"path":170,"stem":171,"icon":172},"API reference","\u002Freference\u002Fapi","7.reference\u002F2.api","i-lucide-braces",{"title":174,"path":175,"stem":176,"icon":177},"Contributing","\u002Freference\u002Fcontributing","7.reference\u002F3.contributing","i-lucide-git-pull-request",{"id":179,"title":180,"body":181,"description":617,"extension":618,"links":619,"meta":620,"navigation":621,"path":55,"seo":622,"stem":56,"__hash__":623},"docs\u002F2.sign-in\u002F5.two-factor.md","Two-factor authentication",{"type":182,"value":183,"toc":608},"minimark",[184,189,201,206,383,387,418,422,431,442,448,457,461,475,487,490,500,507,511,561,565,582,586,604],[185,186],"screenshot",{"alt":187,"name":188},"The account page's security tab, with two-factor's Email me codes and Set up an authenticator app","account-security",[190,191,192,193,200],"p",{},"Better Auth's ",[194,195,199],"a",{"href":196,"rel":197},"https:\u002F\u002Fbetter-auth.com\u002Fdocs\u002Fplugins\u002F2fa",[198],"nofollow","Two-Factor plugin",", added by the module.",[202,203,205],"h2",{"id":204},"turning-it-on","Turning it on",[207,208,210,215,368,372],"steps",{"level":209},"3",[211,212,214],"h3",{"id":213},"enable-it","Enable it",[216,217,223],"pre",{"className":218,"code":219,"filename":220,"language":221,"meta":222,"style":222},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  betterAuthUi: {\n    twoFactor: {\n      enabled: true,\n      \u002F\u002F Codes by email as well as authenticator apps (needs emails.send).\n      otp: true,\n      \u002F\u002F Who must have it on: true for everyone, or roles.\n      required: ['admin', 'moderator']\n    }\n  }\n})\n","nuxt.config.ts","ts","",[224,225,226,250,263,273,288,295,307,313,347,353,359],"code",{"__ignoreMap":222},[227,228,231,235,238,242,246],"span",{"class":229,"line":230},"line",1,[227,232,234],{"class":233},"s7zQu","export",[227,236,237],{"class":233}," default",[227,239,241],{"class":240},"s2Zo4"," defineNuxtConfig",[227,243,245],{"class":244},"sTEyZ","(",[227,247,249],{"class":248},"sMK4o","{\n",[227,251,253,257,260],{"class":229,"line":252},2,[227,254,256],{"class":255},"swJcz","  betterAuthUi",[227,258,259],{"class":248},":",[227,261,262],{"class":248}," {\n",[227,264,266,269,271],{"class":229,"line":265},3,[227,267,268],{"class":255},"    twoFactor",[227,270,259],{"class":248},[227,272,262],{"class":248},[227,274,276,279,281,285],{"class":229,"line":275},4,[227,277,278],{"class":255},"      enabled",[227,280,259],{"class":248},[227,282,284],{"class":283},"sfNiH"," true",[227,286,287],{"class":248},",\n",[227,289,291],{"class":229,"line":290},5,[227,292,294],{"class":293},"sHwdD","      \u002F\u002F Codes by email as well as authenticator apps (needs emails.send).\n",[227,296,298,301,303,305],{"class":229,"line":297},6,[227,299,300],{"class":255},"      otp",[227,302,259],{"class":248},[227,304,284],{"class":283},[227,306,287],{"class":248},[227,308,310],{"class":229,"line":309},7,[227,311,312],{"class":293},"      \u002F\u002F Who must have it on: true for everyone, or roles.\n",[227,314,316,319,321,324,327,331,333,336,339,342,344],{"class":229,"line":315},8,[227,317,318],{"class":255},"      required",[227,320,259],{"class":248},[227,322,323],{"class":244}," [",[227,325,326],{"class":248},"'",[227,328,330],{"class":329},"sfazB","admin",[227,332,326],{"class":248},[227,334,335],{"class":248},",",[227,337,338],{"class":248}," '",[227,340,341],{"class":329},"moderator",[227,343,326],{"class":248},[227,345,346],{"class":244},"]\n",[227,348,350],{"class":229,"line":349},9,[227,351,352],{"class":248},"    }\n",[227,354,356],{"class":229,"line":355},10,[227,357,358],{"class":248},"  }\n",[227,360,362,365],{"class":229,"line":361},11,[227,363,364],{"class":248},"}",[227,366,367],{"class":244},")\n",[211,369,371],{"id":370},"run-better-auths-migrations","Run Better Auth's migrations",[190,373,374,375,378,379,382],{},"The plugin adds a ",[224,376,377],{},"twoFactorEnabled"," column to the user table and a ",[224,380,381],{},"twoFactor"," table.",[202,384,386],{"id":385},"how-people-use-it","How people use it",[388,389,390,402,412],"ul",{},[391,392,393,397,398,401],"li",{},[394,395,396],"strong",{},"Setting it up",", on the account page: scan a QR code, confirm with the app's first code, and save the backup\ncodes. The QR code is drawn in the browser, so the secret never leaves it. With ",[224,399,400],{},"otp",", codes can be emailed\ninstead. Users with a password confirm with it; users who only sign in with a provider can set it up too.",[391,403,404,407,408,411],{},[394,405,406],{},"Signing in"," then asks for a code on ",[224,409,410],{},"\u002Ftwo-factor",": from the app, by email, or a backup code (each works once),\nwith \"Trust this device\". After signing in, they go on to where they were heading.",[391,413,414,417],{},[394,415,416],{},"Too many wrong codes"," lock the account for a while (Better Auth's own lockout).",[202,419,421],{"id":420},"every-sign-in-is-challenged","Every sign-in is challenged",[190,423,424,425,430],{},"Better Auth's plugin only challenges password sign-ins, and\n",[194,426,429],{"href":427,"rel":428},"https:\u002F\u002Fbetter-auth.com\u002Fdocs\u002Fplugins\u002F2fa#sign-in-with-2fa",[198],"suggests hooks"," for the rest. The module adds them, so\nthese are challenged too:",[388,432,433,436,439],{},[391,434,435],{},"social and Generic OAuth sign-ins;",[391,437,438],{},"social ID tokens and One Tap;",[391,440,441],{},"sign-in links and codes by email.",[190,443,444,445,447],{},"They run the plugin's own challenge, so codes, trusted devices and the lockout work the same. Provider sign-ins go to\n",[224,446,410],{}," instead of signing straight in.",[449,450,451],"tip",{},[190,452,453,456],{},[394,454,455],{},"Passkeys aren't challenged."," A passkey is already two factors: something you have, plus your device's fingerprint,\nface or PIN.",[202,458,460],{"id":459},"requiring-it","Requiring it",[190,462,463,466,467,470,471,474],{},[224,464,465],{},"required"," makes two-factor mandatory, for everyone (",[224,468,469],{},"true",") or for some roles (",[224,472,473],{},"['admin', 'moderator']","). Until\nthose users set it up:",[388,476,477,480],{},[391,478,479],{},"pages send them to the account page, with a banner saying why;",[391,481,482,483,486],{},"your ",[224,484,485],{},"\u002Fapi"," routes, the admin's and Better Auth's admin endpoints answer 403.",[190,488,489],{},"Better Auth's other endpoints stay open, since setting two-factor up goes through them. Once it's on, they can't turn\nit off.",[190,491,492,495,496,499],{},[394,493,494],{},"A passkey sign-in counts."," A session started with a passkey isn't held back, while one started with a password or\na provider still needs two-factor. The module notes passkey sessions in Better Auth's ",[224,497,498],{},"verification"," table, as the\nTwo-Factor plugin does for trusted devices, so there's no extra table.",[190,501,502,503,506],{},"Users are matched by their ",[194,504,505],{"href":110},"admin roles",", so a role change applies on their next request. Guests are\nnever required to use it.",[202,508,510],{"id":509},"options","Options",[512,513,514,520,533,542,553],"field-group",{},[515,516],"field",{"name":517,"type":518,"default":519},"enabled","boolean","false",[515,521,522],{"name":400,"type":518,"default":519},[190,523,524,525,528,529,532],{},"Codes by email as well as authenticator apps. Sent through ",[224,526,527],{},"emails.send"," with the ",[224,530,531],{},"two-factor-code"," template.",[515,534,536],{"name":465,"type":535,"default":519},"boolean | string[]",[190,537,538,539,541],{},"Who must have it on: ",[224,540,469],{}," for everyone, or a list of roles.",[515,543,546],{"name":544,"type":545},"issuer","string",[190,547,548,549,552],{},"The name authenticator apps show. Defaults to your Better Auth ",[224,550,551],{},"appName",".",[515,554,558],{"name":555,"type":556,"default":557},"trustDeviceMaxAge","number","2592000",[190,559,560],{},"Seconds \"Trust this device\" lasts (30 days).",[202,562,564],{"id":563},"in-the-admin","In the admin",[388,566,567,570,573],{},[391,568,569],{},"A shield on the users list for users who have it on, and a \"Two-factor off\" filter.",[391,571,572],{},"A badge on each user's page, including \"Required, not set up\".",[391,574,575,578,579,552],{},[394,576,577],{},"Lost their device?"," Staff can turn a user's two-factor off from their page. See\n",[194,580,104],{"href":581},"\u002Fadmin\u002Fusers#lost-a-device",[202,583,585],{"id":584},"adding-the-plugin-yourself","Adding the plugin yourself",[190,587,588,589,592,593,596,597,600,601,603],{},"Leave ",[224,590,591],{},"twoFactor.enabled"," off, add ",[224,594,595],{},"twoFactor()"," and ",[224,598,599],{},"twoFactorClient()"," to your auth configs, and the account page\npicks it up. The extra challenges and ",[224,602,465],{}," only come with the module's plugin.",[605,606,607],"style",{},"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 .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);}",{"title":222,"searchDepth":230,"depth":252,"links":609},[610,611,612,613,614,615,616],{"id":204,"depth":252,"text":205},{"id":385,"depth":252,"text":386},{"id":420,"depth":252,"text":421},{"id":459,"depth":252,"text":460},{"id":509,"depth":252,"text":510},{"id":563,"depth":252,"text":564},{"id":584,"depth":252,"text":585},"Authenticator apps, codes by email, backup codes, and requiring it for some roles.","md",null,{},{"title":54,"icon":57},{"title":180,"description":617},"TiembXyVb6ZjTla5Ea3oPykeEpNMeDYNBvpkNVf81_U",[625,627],{"title":49,"path":50,"stem":51,"description":626,"icon":52,"children":-1},"Google, GitHub, Discord and more, game platforms, and sign-in in a popup.",{"title":59,"path":60,"stem":61,"description":628,"icon":62,"children":-1},"Sign in with a fingerprint, face or PIN instead of a password.",1793019844246]