[{"data":1,"prerenderedAt":1472},["ShallowReactive",2],{"navigation":3,"\u002Fguides\u002Finternal-app":250,"\u002Fguides\u002Finternal-app-surround":1467},[4,43,120,143,219],{"title":5,"path":6,"stem":7,"children":8,"icon":42},"Get started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17,22,27,32,37],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Install AuthEndpoints","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-play",{"title":23,"path":24,"stem":25,"icon":26},"Pick your setup","\u002Fgetting-started\u002Fchoose-a-sign-in-stack","1.getting-started\u002F4.choose-a-sign-in-stack","i-lucide-signpost",{"title":28,"path":29,"stem":30,"icon":31},"Use the AuthEndpoints skill with coding agents","\u002Fgetting-started\u002Fai-agents","1.getting-started\u002F5.ai-agents","i-lucide-bot",{"title":33,"path":34,"stem":35,"icon":36},"Password auth","\u002Fgetting-started\u002Fpassword-auth","1.getting-started\u002F6.password-auth","i-lucide-key-round",{"title":38,"path":39,"stem":40,"icon":41},"3.x facade","\u002Fgetting-started\u002Fcompatibility-facade","1.getting-started\u002F7.compatibility-facade","i-lucide-archive","i-lucide-rocket",{"title":44,"path":45,"stem":46,"children":47,"icon":119},"Guides","\u002Fguides","2.guides\u002F01.index",[48,50,55,60,65,70,74,79,84,89,94,99,104,109,114],{"title":44,"path":45,"stem":46,"icon":49},"i-lucide-list-checks",{"title":51,"path":52,"stem":53,"icon":54},"Register users","\u002Fguides\u002Fregistration","2.guides\u002F02.registration","i-lucide-user-plus",{"title":56,"path":57,"stem":58,"icon":59},"Sign users in","\u002Fguides\u002Fsign-in","2.guides\u002F03.sign-in","i-lucide-log-in",{"title":61,"path":62,"stem":63,"icon":64},"Sign users out","\u002Fguides\u002Fsign-out","2.guides\u002F04.sign-out","i-lucide-log-out",{"title":66,"path":67,"stem":68,"icon":69},"Turn on two-factor authentication","\u002Fguides\u002Ftwo-factor","2.guides\u002F05.two-factor","i-lucide-smartphone",{"title":71,"path":72,"stem":73,"icon":36},"Reset a forgotten password","\u002Fguides\u002Freset-password","2.guides\u002F06.reset-password",{"title":75,"path":76,"stem":77,"icon":78},"Change a user's email or password","\u002Fguides\u002Fmanage-account","2.guides\u002F07.manage-account","i-lucide-user-cog",{"title":80,"path":81,"stem":82,"icon":83},"Add, rename, and remove passkeys","\u002Fguides\u002Fmanage-passkeys","2.guides\u002F08.manage-passkeys","i-lucide-scan-face",{"title":85,"path":86,"stem":87,"icon":88},"Link and unlink GitHub or Google accounts","\u002Fguides\u002Flink-external-accounts","2.guides\u002F09.link-external-accounts","i-lucide-link",{"title":90,"path":91,"stem":92,"icon":93},"Require step-up before sensitive actions","\u002Fguides\u002Fstep-up","2.guides\u002F10.step-up","i-lucide-shield-check",{"title":95,"path":96,"stem":97,"icon":98},"Call the API from a browser","\u002Fguides\u002Fbrowser-clients","2.guides\u002F11.browser-clients","i-lucide-globe",{"title":100,"path":101,"stem":102,"icon":103},"Prepare for production","\u002Fguides\u002Fproduction","2.guides\u002F12.production","i-lucide-factory",{"title":105,"path":106,"stem":107,"icon":108},"Sign in with an emailed code","\u002Fguides\u002Femail-code","2.guides\u002F13.email-code","i-lucide-mail",{"title":110,"path":111,"stem":112,"icon":113},"Upgrade to 4.0","\u002Fguides\u002Fupgrading-to-4","2.guides\u002F14.upgrading-to-4","i-lucide-arrow-up-right",{"title":115,"path":116,"stem":117,"icon":118},"Run an app with no public sign-up","\u002Fguides\u002Finternal-app","2.guides\u002F15.internal-app","i-lucide-building-2","i-lucide-waypoints",{"title":121,"path":122,"stem":123,"children":124,"icon":142},"Composable endpoints","\u002Fcomposables","3.composables\u002F1.index",[125,128,132,137],{"title":126,"path":122,"stem":123,"icon":127},"How composition works","i-lucide-layout-grid",{"title":129,"path":130,"stem":131,"icon":49},"Composition requirements","\u002Fcomposables\u002Frequirements","3.composables\u002F2.requirements",{"title":133,"path":134,"stem":135,"icon":136},"Compose a custom auth stack","\u002Fcomposables\u002Frecipes","3.composables\u002F3.recipes","i-lucide-book-marked",{"title":138,"path":139,"stem":140,"icon":141},"Composition","\u002Fcomposables\u002Fcomposition","3.composables\u002F4.composition","i-lucide-table","i-lucide-blocks",{"title":144,"icon":145,"path":146,"stem":147,"children":148,"page":218},"Reference","i-lucide-book-open","\u002Fmodules","4.modules",[149,154,158,163,168,173,177,182,186,191,195,200,205,209,213],{"title":150,"path":151,"stem":152,"icon":153},"Endpoint reference","\u002Fmodules\u002Fendpoints","4.modules\u002F01.endpoints","i-lucide-route",{"title":155,"path":156,"stem":157,"icon":78},"Identity management module","\u002Fmodules\u002Fidentity-management","4.modules\u002F02.identity-management",{"title":159,"path":160,"stem":161,"icon":162},"Cookie sign-in module","\u002Fmodules\u002Fcookie-auth","4.modules\u002F03.cookie-auth","i-lucide-cookie",{"title":164,"path":165,"stem":166,"icon":167},"Identity bearer sign-in module","\u002Fmodules\u002Fbearer-auth","4.modules\u002F04.bearer-auth","i-lucide-key",{"title":169,"path":170,"stem":171,"icon":172},"JWT module","\u002Fmodules\u002Fjwt","4.modules\u002F05.jwt","i-lucide-fingerprint",{"title":174,"path":175,"stem":176,"icon":83},"Passkeys module","\u002Fmodules\u002Fpasskeys","4.modules\u002F06.passkeys",{"title":178,"path":179,"stem":180,"icon":181},"ReAuth module","\u002Fmodules\u002Freauth","4.modules\u002F07.reauth","i-lucide-shield-alert",{"title":183,"path":184,"stem":185,"icon":59},"External OAuth packages","\u002Fmodules\u002Fexternal-oauth","4.modules\u002F08.external-oauth",{"title":187,"path":188,"stem":189,"icon":190},"Configuration options","\u002Fmodules\u002Fconfiguration","4.modules\u002F09.configuration","i-lucide-settings",{"title":192,"path":193,"stem":194,"icon":93},"Antiforgery (CSRF) rules","\u002Fmodules\u002Fcsrf","4.modules\u002F10.csrf",{"title":196,"path":197,"stem":198,"icon":199},"Responses and errors","\u002Fmodules\u002Ferrors","4.modules\u002F11.errors","i-lucide-circle-alert",{"title":201,"path":202,"stem":203,"icon":204},"Rate-limit policies","\u002Fmodules\u002Frate-limits","4.modules\u002F12.rate-limits","i-lucide-gauge",{"title":206,"path":207,"stem":208,"icon":108},"Email-code module","\u002Fmodules\u002Femail-code","4.modules\u002F13.email-code",{"title":210,"path":211,"stem":212,"icon":59},"Sign-in completer","\u002Fmodules\u002Fsign-in-completer","4.modules\u002F14.sign-in-completer",{"title":214,"path":215,"stem":216,"icon":217},"Enumeration-safe responses","\u002Fmodules\u002Fenumeration","4.modules\u002F15.enumeration","i-lucide-eye-off",false,{"title":220,"icon":221,"path":222,"stem":223,"children":224,"page":218},"Concepts","i-lucide-lightbulb","\u002Fconcepts","5.concepts",[225,230,235,240,245],{"title":226,"path":227,"stem":228,"icon":229},"AuthEndpoints compared with other options","\u002Fconcepts\u002Fcompare","5.concepts\u002F1.compare","i-lucide-git-compare",{"title":231,"path":232,"stem":233,"icon":234},"Stock Identity endpoints vs AuthEndpoints","\u002Fconcepts\u002Fstock-identity-vs-authendpoints","5.concepts\u002F2.stock-identity-vs-authendpoints","i-lucide-columns-2",{"title":236,"path":237,"stem":238,"icon":239},"MapIdentityApi alternative","\u002Fconcepts\u002Fmapidentityapi-alternative","5.concepts\u002F3.mapidentityapi-alternative","i-lucide-arrow-left-right",{"title":241,"path":242,"stem":243,"icon":244},"Security model","\u002Fconcepts\u002Fsecurity-model","5.concepts\u002F4.security-model","i-lucide-shield",{"title":246,"path":247,"stem":248,"icon":249},"FAQ","\u002Fconcepts\u002Ffaq","5.concepts\u002F5.faq","i-lucide-circle-help",{"id":251,"title":115,"body":252,"description":1460,"extension":1461,"faq":218,"links":1462,"meta":1463,"navigation":1464,"path":116,"seo":1465,"stem":117,"__hash__":1466},"docs\u002F2.guides\u002F15.internal-app.md",{"type":253,"value":254,"toc":1454},"minimark",[255,259,270,275,315,1110,1128,1138,1141,1148,1187,1321,1330,1334,1422,1426,1450],[256,257,258],"p",{},"Create accounts in your own admin code. Do not map a public register route.",[256,260,261,265,266,269],{},[262,263,264],"code",{},"AddPasswordAuth"," always maps ",[262,267,268],{},"POST \u002Fregister",". There is no option to turn that route off. Compose sign-in instead.",[271,272,274],"h2",{"id":273},"map-sign-in-without-register","Map sign-in without register",[276,277,278,294,301,307],"ol",{},[279,280,281,282,285,286,289,290,293],"li",{},"Call ",[262,283,284],{},"AddAuthEndpointsIdentity",". It sets ",[262,287,288],{},"RequireConfirmedAccount"," to ",[262,291,292],{},"true",", then runs your callback.",[279,295,296,297,300],{},"Register password sign-in, recovery, account management, and the cookie session. Do not call ",[262,298,299],{},"AddPasswordSignUpEndpoints",".",[279,302,303,304,300],{},"Map those four groups on one prefix. Do not call ",[262,305,306],{},"MapPasswordSignUpEndpoints",[279,308,309,310,300],{},"Invite each user from your admin code. A confirmation link confirms the email and sets no password. See ",[311,312,314],"a",{"href":313},"#invite-a-user","Invite a user",[316,317,323],"pre",{"className":318,"code":319,"language":320,"meta":321,"style":322},"language-cs shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","using AuthEndpoints;\nusing AuthEndpoints.Identity;\nusing Microsoft.AspNetCore.Identity;\nusing Microsoft.AspNetCore.Identity.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore;\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddDbContext\u003CAppDbContext>(options =>\n    options.UseSqlite(\"Data Source=app.db\"));\n\nbuilder.Services.AddAuthEndpointsIdentity\u003CAppUser, AppDbContext>(options =>\n{\n    options.User.RequireUniqueEmail = true;\n});\nbuilder.Services.AddPasswordSignInEndpoints();\nbuilder.Services.AddPasswordRecoveryEndpoints();\nbuilder.Services.AddAccountManagementEndpoints();\nbuilder.Services.AddCookieSessionEndpoints();\nbuilder.Services.AddTransient\u003CIEmailSender\u003CAppUser>, QueuedIdentityEmailSender>();\n\nvar app = builder.Build();\napp.UseAuthEndpoints();\n\nvar auth = app.MapGroup(\"\u002Fauth\");\nauth.MapPasswordSignInEndpoints\u003CAppUser>(AuthEndpointsSession.Cookie);\nauth.MapPasswordRecoveryEndpoints\u003CAppUser>();\nauth.MapCookieSessionEndpoints\u003CAppUser>();\nauth.MapAccountManagementEndpoints\u003CAppUser>();\n\napp.Run();\n\npublic class AppUser : IdentityUser { }\n\npublic class AppDbContext(DbContextOptions\u003CAppDbContext> options) : IdentityDbContext\u003CAppUser>(options) { }\n\npublic sealed class QueuedIdentityEmailSender : IEmailSender\u003CAppUser>\n{\n    public Task SendConfirmationLinkAsync(AppUser user, string email, string confirmationLink)\n        => Task.CompletedTask;\n\n    public Task SendPasswordResetLinkAsync(AppUser user, string email, string resetLink)\n        => Task.CompletedTask;\n\n    public Task SendPasswordResetCodeAsync(AppUser user, string email, string resetCode)\n        => Task.CompletedTask;\n}\n","cs","recipe","",[262,324,325,342,356,375,397,410,417,448,453,484,509,514,544,550,574,580,597,613,629,645,677,682,701,714,719,747,774,790,806,822,827,839,844,869,874,920,925,949,954,991,1006,1011,1042,1055,1060,1091,1104],{"__ignoreMap":322},[326,327,330,334,338],"span",{"class":328,"line":329},"line",1,[326,331,333],{"class":332},"sbssI","using",[326,335,337],{"class":336},"sTEyZ"," AuthEndpoints",[326,339,341],{"class":340},"sMK4o",";\n",[326,343,345,347,349,351,354],{"class":328,"line":344},2,[326,346,333],{"class":332},[326,348,337],{"class":336},[326,350,300],{"class":340},[326,352,353],{"class":336},"Identity",[326,355,341],{"class":340},[326,357,359,361,364,366,369,371,373],{"class":328,"line":358},3,[326,360,333],{"class":332},[326,362,363],{"class":336}," Microsoft",[326,365,300],{"class":340},[326,367,368],{"class":336},"AspNetCore",[326,370,300],{"class":340},[326,372,353],{"class":336},[326,374,341],{"class":340},[326,376,378,380,382,384,386,388,390,392,395],{"class":328,"line":377},4,[326,379,333],{"class":332},[326,381,363],{"class":336},[326,383,300],{"class":340},[326,385,368],{"class":336},[326,387,300],{"class":340},[326,389,353],{"class":336},[326,391,300],{"class":340},[326,393,394],{"class":336},"EntityFrameworkCore",[326,396,341],{"class":340},[326,398,400,402,404,406,408],{"class":328,"line":399},5,[326,401,333],{"class":332},[326,403,363],{"class":336},[326,405,300],{"class":340},[326,407,394],{"class":336},[326,409,341],{"class":340},[326,411,413],{"class":328,"line":412},6,[326,414,416],{"emptyLinePlaceholder":415},true,"\n",[326,418,420,424,427,430,433,435,439,442,445],{"class":328,"line":419},7,[326,421,423],{"class":422},"sBMFI","var",[326,425,426],{"class":422}," builder",[326,428,429],{"class":340}," =",[326,431,432],{"class":336}," WebApplication",[326,434,300],{"class":340},[326,436,438],{"class":437},"s2Zo4","CreateBuilder",[326,440,441],{"class":340},"(",[326,443,444],{"class":336},"args",[326,446,447],{"class":340},");\n",[326,449,451],{"class":328,"line":450},8,[326,452,416],{"emptyLinePlaceholder":415},[326,454,456,459,461,464,466,469,472,475,478,481],{"class":328,"line":455},9,[326,457,458],{"class":336},"builder",[326,460,300],{"class":340},[326,462,463],{"class":336},"Services",[326,465,300],{"class":340},[326,467,468],{"class":437},"AddDbContext",[326,470,471],{"class":340},"\u003C",[326,473,474],{"class":422},"AppDbContext",[326,476,477],{"class":340},">(",[326,479,480],{"class":422},"options",[326,482,483],{"class":340}," =>\n",[326,485,487,490,492,495,497,500,504,506],{"class":328,"line":486},10,[326,488,489],{"class":336},"    options",[326,491,300],{"class":340},[326,493,494],{"class":437},"UseSqlite",[326,496,441],{"class":340},[326,498,499],{"class":340},"\"",[326,501,503],{"class":502},"sfazB","Data Source=app.db",[326,505,499],{"class":340},[326,507,508],{"class":340},"));\n",[326,510,512],{"class":328,"line":511},11,[326,513,416],{"emptyLinePlaceholder":415},[326,515,517,519,521,523,525,527,529,532,535,538,540,542],{"class":328,"line":516},12,[326,518,458],{"class":336},[326,520,300],{"class":340},[326,522,463],{"class":336},[326,524,300],{"class":340},[326,526,284],{"class":437},[326,528,471],{"class":340},[326,530,531],{"class":422},"AppUser",[326,533,534],{"class":340},",",[326,536,537],{"class":422}," AppDbContext",[326,539,477],{"class":340},[326,541,480],{"class":422},[326,543,483],{"class":340},[326,545,547],{"class":328,"line":546},13,[326,548,549],{"class":340},"{\n",[326,551,553,555,557,560,562,565,568,572],{"class":328,"line":552},14,[326,554,489],{"class":336},[326,556,300],{"class":340},[326,558,559],{"class":336},"User",[326,561,300],{"class":340},[326,563,564],{"class":336},"RequireUniqueEmail ",[326,566,567],{"class":340},"=",[326,569,571],{"class":570},"sfNiH"," true",[326,573,341],{"class":340},[326,575,577],{"class":328,"line":576},15,[326,578,579],{"class":340},"});\n",[326,581,583,585,587,589,591,594],{"class":328,"line":582},16,[326,584,458],{"class":336},[326,586,300],{"class":340},[326,588,463],{"class":336},[326,590,300],{"class":340},[326,592,593],{"class":437},"AddPasswordSignInEndpoints",[326,595,596],{"class":340},"();\n",[326,598,600,602,604,606,608,611],{"class":328,"line":599},17,[326,601,458],{"class":336},[326,603,300],{"class":340},[326,605,463],{"class":336},[326,607,300],{"class":340},[326,609,610],{"class":437},"AddPasswordRecoveryEndpoints",[326,612,596],{"class":340},[326,614,616,618,620,622,624,627],{"class":328,"line":615},18,[326,617,458],{"class":336},[326,619,300],{"class":340},[326,621,463],{"class":336},[326,623,300],{"class":340},[326,625,626],{"class":437},"AddAccountManagementEndpoints",[326,628,596],{"class":340},[326,630,632,634,636,638,640,643],{"class":328,"line":631},19,[326,633,458],{"class":336},[326,635,300],{"class":340},[326,637,463],{"class":336},[326,639,300],{"class":340},[326,641,642],{"class":437},"AddCookieSessionEndpoints",[326,644,596],{"class":340},[326,646,648,650,652,654,656,659,661,664,666,668,671,674],{"class":328,"line":647},20,[326,649,458],{"class":336},[326,651,300],{"class":340},[326,653,463],{"class":336},[326,655,300],{"class":340},[326,657,658],{"class":437},"AddTransient",[326,660,471],{"class":340},[326,662,663],{"class":422},"IEmailSender",[326,665,471],{"class":340},[326,667,531],{"class":422},[326,669,670],{"class":340},">,",[326,672,673],{"class":422}," QueuedIdentityEmailSender",[326,675,676],{"class":340},">();\n",[326,678,680],{"class":328,"line":679},21,[326,681,416],{"emptyLinePlaceholder":415},[326,683,685,687,690,692,694,696,699],{"class":328,"line":684},22,[326,686,423],{"class":422},[326,688,689],{"class":422}," app",[326,691,429],{"class":340},[326,693,426],{"class":336},[326,695,300],{"class":340},[326,697,698],{"class":437},"Build",[326,700,596],{"class":340},[326,702,704,707,709,712],{"class":328,"line":703},23,[326,705,706],{"class":336},"app",[326,708,300],{"class":340},[326,710,711],{"class":437},"UseAuthEndpoints",[326,713,596],{"class":340},[326,715,717],{"class":328,"line":716},24,[326,718,416],{"emptyLinePlaceholder":415},[326,720,722,724,727,729,731,733,736,738,740,743,745],{"class":328,"line":721},25,[326,723,423],{"class":422},[326,725,726],{"class":422}," auth",[326,728,429],{"class":340},[326,730,689],{"class":336},[326,732,300],{"class":340},[326,734,735],{"class":437},"MapGroup",[326,737,441],{"class":340},[326,739,499],{"class":340},[326,741,742],{"class":502},"\u002Fauth",[326,744,499],{"class":340},[326,746,447],{"class":340},[326,748,750,753,755,758,760,762,764,767,769,772],{"class":328,"line":749},26,[326,751,752],{"class":336},"auth",[326,754,300],{"class":340},[326,756,757],{"class":437},"MapPasswordSignInEndpoints",[326,759,471],{"class":340},[326,761,531],{"class":422},[326,763,477],{"class":340},[326,765,766],{"class":336},"AuthEndpointsSession",[326,768,300],{"class":340},[326,770,771],{"class":336},"Cookie",[326,773,447],{"class":340},[326,775,777,779,781,784,786,788],{"class":328,"line":776},27,[326,778,752],{"class":336},[326,780,300],{"class":340},[326,782,783],{"class":437},"MapPasswordRecoveryEndpoints",[326,785,471],{"class":340},[326,787,531],{"class":422},[326,789,676],{"class":340},[326,791,793,795,797,800,802,804],{"class":328,"line":792},28,[326,794,752],{"class":336},[326,796,300],{"class":340},[326,798,799],{"class":437},"MapCookieSessionEndpoints",[326,801,471],{"class":340},[326,803,531],{"class":422},[326,805,676],{"class":340},[326,807,809,811,813,816,818,820],{"class":328,"line":808},29,[326,810,752],{"class":336},[326,812,300],{"class":340},[326,814,815],{"class":437},"MapAccountManagementEndpoints",[326,817,471],{"class":340},[326,819,531],{"class":422},[326,821,676],{"class":340},[326,823,825],{"class":328,"line":824},30,[326,826,416],{"emptyLinePlaceholder":415},[326,828,830,832,834,837],{"class":328,"line":829},31,[326,831,706],{"class":336},[326,833,300],{"class":340},[326,835,836],{"class":437},"Run",[326,838,596],{"class":340},[326,840,842],{"class":328,"line":841},32,[326,843,416],{"emptyLinePlaceholder":415},[326,845,847,851,854,857,860,863,866],{"class":328,"line":846},33,[326,848,850],{"class":849},"spNyl","public",[326,852,853],{"class":422}," class",[326,855,856],{"class":422}," AppUser",[326,858,859],{"class":340}," :",[326,861,862],{"class":422}," IdentityUser",[326,864,865],{"class":340}," {",[326,867,868],{"class":340}," }\n",[326,870,872],{"class":328,"line":871},34,[326,873,416],{"emptyLinePlaceholder":415},[326,875,877,879,881,883,885,888,890,892,895,898,901,903,906,908,910,912,914,916,918],{"class":328,"line":876},35,[326,878,850],{"class":849},[326,880,853],{"class":422},[326,882,537],{"class":422},[326,884,441],{"class":340},[326,886,887],{"class":422},"DbContextOptions",[326,889,471],{"class":340},[326,891,474],{"class":422},[326,893,894],{"class":340},">",[326,896,897],{"class":422}," options",[326,899,900],{"class":340},")",[326,902,859],{"class":340},[326,904,905],{"class":422}," IdentityDbContext",[326,907,471],{"class":340},[326,909,531],{"class":422},[326,911,477],{"class":340},[326,913,480],{"class":336},[326,915,900],{"class":340},[326,917,865],{"class":340},[326,919,868],{"class":340},[326,921,923],{"class":328,"line":922},36,[326,924,416],{"emptyLinePlaceholder":415},[326,926,928,930,933,935,937,939,942,944,946],{"class":328,"line":927},37,[326,929,850],{"class":849},[326,931,932],{"class":849}," sealed",[326,934,853],{"class":422},[326,936,673],{"class":422},[326,938,859],{"class":340},[326,940,941],{"class":422}," IEmailSender",[326,943,471],{"class":340},[326,945,531],{"class":422},[326,947,948],{"class":340},">\n",[326,950,952],{"class":328,"line":951},38,[326,953,549],{"class":340},[326,955,957,960,963,966,968,970,973,975,978,981,983,985,988],{"class":328,"line":956},39,[326,958,959],{"class":849},"    public",[326,961,962],{"class":422}," Task",[326,964,965],{"class":437}," SendConfirmationLinkAsync",[326,967,441],{"class":340},[326,969,531],{"class":422},[326,971,972],{"class":422}," user",[326,974,534],{"class":340},[326,976,977],{"class":340}," string",[326,979,980],{"class":422}," email",[326,982,534],{"class":340},[326,984,977],{"class":340},[326,986,987],{"class":422}," confirmationLink",[326,989,990],{"class":340},")\n",[326,992,994,997,999,1001,1004],{"class":328,"line":993},40,[326,995,996],{"class":340},"        =>",[326,998,962],{"class":336},[326,1000,300],{"class":340},[326,1002,1003],{"class":336},"CompletedTask",[326,1005,341],{"class":340},[326,1007,1009],{"class":328,"line":1008},41,[326,1010,416],{"emptyLinePlaceholder":415},[326,1012,1014,1016,1018,1021,1023,1025,1027,1029,1031,1033,1035,1037,1040],{"class":328,"line":1013},42,[326,1015,959],{"class":849},[326,1017,962],{"class":422},[326,1019,1020],{"class":437}," SendPasswordResetLinkAsync",[326,1022,441],{"class":340},[326,1024,531],{"class":422},[326,1026,972],{"class":422},[326,1028,534],{"class":340},[326,1030,977],{"class":340},[326,1032,980],{"class":422},[326,1034,534],{"class":340},[326,1036,977],{"class":340},[326,1038,1039],{"class":422}," resetLink",[326,1041,990],{"class":340},[326,1043,1045,1047,1049,1051,1053],{"class":328,"line":1044},43,[326,1046,996],{"class":340},[326,1048,962],{"class":336},[326,1050,300],{"class":340},[326,1052,1003],{"class":336},[326,1054,341],{"class":340},[326,1056,1058],{"class":328,"line":1057},44,[326,1059,416],{"emptyLinePlaceholder":415},[326,1061,1063,1065,1067,1070,1072,1074,1076,1078,1080,1082,1084,1086,1089],{"class":328,"line":1062},45,[326,1064,959],{"class":849},[326,1066,962],{"class":422},[326,1068,1069],{"class":437}," SendPasswordResetCodeAsync",[326,1071,441],{"class":340},[326,1073,531],{"class":422},[326,1075,972],{"class":422},[326,1077,534],{"class":340},[326,1079,977],{"class":340},[326,1081,980],{"class":422},[326,1083,534],{"class":340},[326,1085,977],{"class":340},[326,1087,1088],{"class":422}," resetCode",[326,1090,990],{"class":340},[326,1092,1094,1096,1098,1100,1102],{"class":328,"line":1093},46,[326,1095,996],{"class":340},[326,1097,962],{"class":336},[326,1099,300],{"class":340},[326,1101,1003],{"class":336},[326,1103,341],{"class":340},[326,1105,1107],{"class":328,"line":1106},47,[326,1108,1109],{"class":340},"}\n",[256,1111,1112,1115,1116,1119,1120,1123,1124,1127],{},[262,1113,1114],{},"POST \u002Fauth\u002Flogin"," signs an existing user in. ",[262,1117,1118],{},"POST \u002Fauth\u002FforgotPassword"," and ",[262,1121,1122],{},"POST \u002Fauth\u002FresetPassword"," stay available. ",[262,1125,1126],{},"POST \u002Fauth\u002Fregister"," is not mapped.",[256,1129,1130,1133,1134,1137],{},[262,1131,1132],{},"POST \u002Fauth\u002Fmanage\u002Fpassword"," can set a first password after sign-in and step-up. It returns ",[262,1135,1136],{},"404"," when password sign-in is not mapped. This host maps password sign-in, so the route is present.",[271,1139,314],{"id":1140},"invite-a-user",[256,1142,1143,1144,1147],{},"Create the account with no password, then send your own set-password link. ",[262,1145,1146],{},"GET \u002Fauth\u002FconfirmEmail"," confirms the email. It does not set a password.",[276,1149,1150,1162,1179],{},[279,1151,281,1152,1155,1156,289,1159,1161],{},[262,1153,1154],{},"UserManager\u003CTUser>.CreateAsync(user)"," with no password. Set ",[262,1157,1158],{},"EmailConfirmed",[262,1160,292],{}," before that call. An unconfirmed account cannot sign in, and it cannot reset a password.",[279,1163,281,1164,1167,1168,1171,1172,1174,1175,1178],{},[262,1165,1166],{},"GeneratePasswordResetTokenAsync",". Encode the token with ",[262,1169,1170],{},"WebEncoders.Base64UrlEncode"," of the UTF-8 bytes. ",[262,1173,1122],{}," decodes ",[262,1176,1177],{},"resetCode"," that way.",[279,1180,1181,1182,289,1185,300],{},"Send the encoded value to your own set-password screen. That screen posts ",[262,1183,1184],{},"{ \"email\", \"resetCode\", \"newPassword\" }",[262,1186,1122],{},[316,1188,1190],{"className":318,"code":1189,"language":320,"meta":322,"style":322},"var user = new AppUser { UserName = email, Email = email, EmailConfirmed = true };\nawait userManager.CreateAsync(user);\n\nvar token = await userManager.GeneratePasswordResetTokenAsync(user);\nvar resetCode = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token));\n",[262,1191,1192,1235,1255,1259,1283],{"__ignoreMap":322},[326,1193,1194,1196,1198,1200,1203,1205,1207,1210,1212,1214,1216,1219,1221,1223,1225,1228,1230,1232],{"class":328,"line":329},[326,1195,423],{"class":422},[326,1197,972],{"class":422},[326,1199,429],{"class":340},[326,1201,1202],{"class":340}," new",[326,1204,856],{"class":422},[326,1206,865],{"class":340},[326,1208,1209],{"class":336}," UserName ",[326,1211,567],{"class":340},[326,1213,980],{"class":336},[326,1215,534],{"class":340},[326,1217,1218],{"class":336}," Email ",[326,1220,567],{"class":340},[326,1222,980],{"class":336},[326,1224,534],{"class":340},[326,1226,1227],{"class":336}," EmailConfirmed ",[326,1229,567],{"class":340},[326,1231,571],{"class":570},[326,1233,1234],{"class":340}," };\n",[326,1236,1237,1240,1243,1245,1248,1250,1253],{"class":328,"line":344},[326,1238,1239],{"class":340},"await",[326,1241,1242],{"class":336}," userManager",[326,1244,300],{"class":340},[326,1246,1247],{"class":437},"CreateAsync",[326,1249,441],{"class":340},[326,1251,1252],{"class":336},"user",[326,1254,447],{"class":340},[326,1256,1257],{"class":328,"line":358},[326,1258,416],{"emptyLinePlaceholder":415},[326,1260,1261,1263,1266,1268,1271,1273,1275,1277,1279,1281],{"class":328,"line":377},[326,1262,423],{"class":422},[326,1264,1265],{"class":422}," token",[326,1267,429],{"class":340},[326,1269,1270],{"class":340}," await",[326,1272,1242],{"class":336},[326,1274,300],{"class":340},[326,1276,1166],{"class":437},[326,1278,441],{"class":340},[326,1280,1252],{"class":336},[326,1282,447],{"class":340},[326,1284,1285,1287,1289,1291,1294,1296,1299,1301,1304,1306,1309,1311,1314,1316,1319],{"class":328,"line":399},[326,1286,423],{"class":422},[326,1288,1088],{"class":422},[326,1290,429],{"class":340},[326,1292,1293],{"class":336}," WebEncoders",[326,1295,300],{"class":340},[326,1297,1298],{"class":437},"Base64UrlEncode",[326,1300,441],{"class":340},[326,1302,1303],{"class":336},"Encoding",[326,1305,300],{"class":340},[326,1307,1308],{"class":336},"UTF8",[326,1310,300],{"class":340},[326,1312,1313],{"class":437},"GetBytes",[326,1315,441],{"class":340},[326,1317,1318],{"class":336},"token",[326,1320,508],{"class":340},[256,1322,1323,1326,1327,300],{},[262,1324,1325],{},"WebEncoders"," is in ",[262,1328,1329],{},"Microsoft.AspNetCore.WebUtilities",[271,1331,1333],{"id":1332},"leave-these-maps-off","Leave these maps off",[1335,1336,1337,1364,1379],"ul",{},[279,1338,1339,1340,1343,1344,1347,1348,1352,1353,1356,1357,1360,1361,300],{},"External sign-in. ",[262,1341,1342],{},"AutoLinkByEmail"," defaults to ",[262,1345,1346],{},"false",". Leaving it off does not stop user creation. External sign-in still creates an account for a verified email when no local user has that email. See ",[311,1349,1351],{"href":1350},"\u002Fmodules\u002Fexternal-oauth\u002F#security-behavior","External OAuth",". ",[262,1354,1355],{},"MapExternalAccountEndpoints"," alone never creates a user. That linked login cannot sign the user in until you also map ",[262,1358,1359],{},"MapExternalAuthProvider"," or ",[262,1362,1363],{},"MapExternalAuthEndpoints",[279,1365,1366,1367,1343,1370,1372,1373,1375,1376,300],{},"Email-code sign-up. ",[262,1368,1369],{},"AllowSignUp",[262,1371,1346],{},". Leave it ",[262,1374,1346],{}," if you map email-code sign-in. See ",[311,1377,105],{"href":1378},"\u002Fguides\u002Femail-code\u002F",[279,1380,1381,1382,1119,1385,1388,1389,1360,1392,1395,1396,1119,1399,1352,1402,265,1405,1408,1409,1412,1413,1119,1415,1417,1418,300],{},"Passkey register. For passkey login and management without that register route, call ",[262,1383,1384],{},"AddPasskeySignInEndpoints\u003CAppUser>()",[262,1386,1387],{},"AddPasskeyManagementEndpoints()",". Do not call ",[262,1390,1391],{},"AddPasskeyEndpoints",[262,1393,1394],{},"AddPasskeySignUpEndpoints",". Map ",[262,1397,1398],{},"MapSignInEndpoints\u003CAppUser>(AuthEndpointsSession.Cookie)",[262,1400,1401],{},"MapPasskeyManagementEndpoints\u003CAppUser>()",[262,1403,1404],{},"MapPasskeySignInEndpoints",[262,1406,1407],{},"POST \u002Fpasskeys\u002Fregister",". Do not call it. In this recipe, ",[262,1410,1411],{},"MapSignInEndpoints"," replaces ",[262,1414,757],{},[262,1416,799],{},". Do not map those two as well. See ",[311,1419,1421],{"href":1420},"\u002Fmodules\u002Fpasskeys\u002F#map","Passkeys",[271,1423,1425],{"id":1424},"related","Related",[1335,1427,1428,1433,1439,1445],{},[279,1429,1430],{},[311,1431,23],{"href":1432},"\u002Fgetting-started\u002Fchoose-a-sign-in-stack\u002F",[279,1434,1435],{},[311,1436,1438],{"href":1437},"\u002Fcomposables\u002Fcomposition\u002F","Composition table",[279,1440,1441],{},[311,1442,1444],{"href":1443},"\u002Fcomposables\u002Frecipes\u002F","Recipes",[279,1446,1447],{},[311,1448,33],{"href":1449},"\u002Fgetting-started\u002Fpassword-auth\u002F",[1451,1452,1453],"style",{},"html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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":322,"searchDepth":329,"depth":344,"links":1455},[1456,1457,1458,1459],{"id":273,"depth":344,"text":274},{"id":1140,"depth":344,"text":314},{"id":1332,"depth":344,"text":1333},{"id":1424,"depth":344,"text":1425},"Map password sign-in, recovery, and account management without a public register route.","md",null,{},{"icon":118},{"title":115,"description":1460},"zlfbBf1-ZNbzoixO5kB1i-b_JT-rla-Kl2O5t14ZIOE",[1468,1470],{"title":110,"path":111,"stem":112,"description":1469,"icon":113,"children":-1},"Breaking changes from AuthEndpoints 3.x to 4.0, starting with the unified sign-in completer.",{"title":126,"path":122,"stem":123,"description":1471,"icon":127,"children":-1},"A facade is one fixed composition. A custom host calls the same Add and Map pairs on its own prefixes.",1792054256638]