[{"data":1,"prerenderedAt":521},["ShallowReactive",2],{"navigation":3,"\u002Fgetting-started\u002Fregister-confirmed-account":114,"\u002Fgetting-started\u002Fregister-confirmed-account-surround":516},[4,53,72],{"title":5,"path":6,"stem":7,"children":8,"icon":52},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17,22,27,32,37,42,47],{"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},"AI agents","\u002Fgetting-started\u002Fai-agents","1.getting-started\u002F3.ai-agents","i-lucide-bot",{"title":23,"path":24,"stem":25,"icon":26},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F4.quick-start","i-lucide-play",{"title":28,"path":29,"stem":30,"icon":31},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F5.configuration","i-lucide-settings",{"title":33,"path":34,"stem":35,"icon":36},"Production","\u002Fgetting-started\u002Fproduction","1.getting-started\u002F6.production","i-lucide-shield-check",{"title":38,"path":39,"stem":40,"icon":41},"Compare","\u002Fgetting-started\u002Fcompare","1.getting-started\u002F7.compare","i-lucide-git-compare",{"title":43,"path":44,"stem":45,"icon":46},"FAQ","\u002Fgetting-started\u002Ffaq","1.getting-started\u002F8.faq","i-lucide-circle-help",{"title":48,"path":49,"stem":50,"icon":51},"Register a confirmed account","\u002Fgetting-started\u002Fregister-confirmed-account","1.getting-started\u002F9.register-confirmed-account","i-lucide-mail-check","i-lucide-rocket",{"title":54,"path":55,"stem":56,"children":57,"icon":71},"Composable Endpoints","\u002Fcomposables","2.composables\u002F1.index",[58,61,66],{"title":59,"path":55,"stem":56,"icon":60},"Overview","i-lucide-layout-grid",{"title":62,"path":63,"stem":64,"icon":65},"Requirements","\u002Fcomposables\u002Frequirements","2.composables\u002F2.requirements","i-lucide-list-checks",{"title":67,"path":68,"stem":69,"icon":70},"Recipes","\u002Fcomposables\u002Frecipes","2.composables\u002F3.recipes","i-lucide-book-marked","i-lucide-blocks",{"title":73,"icon":74,"path":75,"stem":76,"children":77,"page":113},"Modules","i-lucide-package","\u002Fmodules","3.modules",[78,83,88,93,98,103,108],{"title":79,"path":80,"stem":81,"icon":82},"Identity management","\u002Fmodules\u002Fidentity-management","3.modules\u002F1.identity-management","i-lucide-user-cog",{"title":84,"path":85,"stem":86,"icon":87},"Cookie auth","\u002Fmodules\u002Fcookie-auth","3.modules\u002F2.cookie-auth","i-lucide-cookie",{"title":89,"path":90,"stem":91,"icon":92},"Bearer auth","\u002Fmodules\u002Fbearer-auth","3.modules\u002F3.bearer-auth","i-lucide-key",{"title":94,"path":95,"stem":96,"icon":97},"JWT","\u002Fmodules\u002Fjwt","3.modules\u002F4.jwt","i-lucide-fingerprint",{"title":99,"path":100,"stem":101,"icon":102},"Passkeys","\u002Fmodules\u002Fpasskeys","3.modules\u002F5.passkeys","i-lucide-scan-face",{"title":104,"path":105,"stem":106,"icon":107},"ReAuth","\u002Fmodules\u002Freauth","3.modules\u002F6.reauth","i-lucide-shield-alert",{"title":109,"path":110,"stem":111,"icon":112},"External OAuth","\u002Fmodules\u002Fexternal-oauth","3.modules\u002F7.external-oauth","i-lucide-log-in",false,{"id":115,"title":48,"body":116,"description":509,"extension":510,"links":511,"meta":512,"navigation":513,"path":49,"seo":514,"stem":50,"__hash__":515},"docs\u002F1.getting-started\u002F9.register-confirmed-account.md",{"type":117,"value":118,"toc":498},"minimark",[119,132,150,155,197,201,304,308,402,414,418,465,469,476,480],[120,121,122,123,127,128,131],"p",{},"Build a first-party SPA signup that stays logged out until the user confirms email, then signs in. Use this when ",[124,125,126],"code",{},"RequireConfirmedAccount"," is ",[124,129,130],{},"true"," (the facade default).",[120,133,134,135,138,139,142,143,146,147,149],{},"Assume the cookie facade: management and cookie login under ",[124,136,137],{},"\u002Fidentity",", passkeys under ",[124,140,141],{},"\u002Faccount",". See ",[144,145,23],"a",{"href":24}," and ",[144,148,67],{"href":68},".",[151,152,154],"h2",{"id":153},"shared-setup","Shared setup",[156,157,158,170,180,194],"ol",{},[159,160,161,162,146,166,169],"li",{},"Offer ",[163,164,165],"strong",{},"Password",[163,167,168],{},"Passkey"," on the same signup screen.",[159,171,172,173,176,177,149],{},"Call ",[124,174,175],{},"GET \u002Fidentity\u002FcsrfToken"," before unsafe POSTs that require antiforgery. Send the value as header ",[124,178,179],{},"RequestVerificationToken",[159,181,182,183,186,187,190,191,193],{},"After a successful register (",[124,184,185],{},"200","), show the same ",[163,188,189],{},"Check your email"," screen for both methods. Do not treat that ",[124,192,185],{}," as signed in.",[159,195,196],{},"Do not tell the user the email is already registered. Duplicate-email paths return generic success or a generic failure (see below).",[151,198,200],{"id":199},"password-register","Password register",[156,202,203,206,216,228,235,284,297],{},[159,204,205],{},"Collect email and password.",[159,207,208,211,212,215],{},[124,209,210],{},"POST \u002Fidentity\u002Fregister"," with body ",[124,213,214],{},"{ \"email\", \"password\" }"," and CSRF.",[159,217,218,219,221,222,224,225,227],{},"On ",[124,220,185],{},", show ",[163,223,189],{},". Stay logged out. Duplicate email also returns ",[124,226,185],{}," (anti-enumeration). Use the same copy.",[159,229,230,231,234],{},"On validation failure, show the ",[124,232,233],{},"400"," problem details.",[159,236,237,238,241,242],{},"The mail link calls ",[124,239,240],{},"GET \u002Fidentity\u002FconfirmEmail?userId=…&code=…",".\n",[243,244,245,258],"ul",{},[159,246,247,248,251,252,254,255,149],{},"With ",[124,249,250],{},"EmailConfirmation.ConfirmEmailRedirectUri"," unset: success is plain-text thank-you (",[124,253,185],{},"); failure is ",[124,256,257],{},"401",[159,259,260,261,264,265,146,268,271,272,275,276,279,280,149],{},"With the URI set: success and failure return ",[124,262,263],{},"302"," to that URI with ",[124,266,267],{},"status=confirmed|failed",[124,269,270],{},"flow=confirm"," (or ",[124,273,274],{},"flow=change-email"," when ",[124,277,278],{},"changedEmail"," is present). Configure the option under ",[144,281,283],{"href":282},"\u002Fgetting-started\u002Fconfiguration#email-confirmation","Email confirmation",[159,285,286,287,290,291,294,295,149],{},"After confirm, sign in: ",[124,288,289],{},"POST \u002Fidentity\u002Flogin"," with email and password. Use ",[124,292,293],{},"?useSessionCookies=false"," only when you need a persistent cookie. See ",[144,296,84],{"href":85},[159,298,299,300,303],{},"On login success, enter the app with the session cookie (",[124,301,302],{},"credentials: \"include\"",").",[151,305,307],{"id":306},"passkey-register","Passkey register",[156,309,310,313,323,330,338,354,364,371,396],{},[159,311,312],{},"Collect email only.",[159,314,315,318,319,322],{},[124,316,317],{},"POST \u002Faccount\u002Fpasskeys\u002Fregister\u002Foptions"," with ",[124,320,321],{},"{ \"email\" }"," and CSRF. Creation options are returned even when the email is already taken.",[159,324,325,326,329],{},"Run ",[124,327,328],{},"navigator.credentials.create(…)",". If the user cancels, show a soft UI error. Do not call register.",[159,331,332,318,335,215],{},[124,333,334],{},"POST \u002Faccount\u002Fpasskeys\u002Fregister?useCookies=true",[124,336,337],{},"{ \"email\", \"credentialJson\" }",[159,339,340,341,318,343,346,347,350,351,353],{},"New email success: ",[124,342,185],{},[124,344,345],{},"{ \"credentialId\" }"," (or equivalent ",[124,348,349],{},"PasskeyCredentialResponse","). No Identity application cookie while the account is unconfirmed. Show the same ",[163,352,189],{}," screen. You may add a short note that they registered with a passkey.",[159,355,356,357,359,360,363],{},"Email taken, bad ceremony, or an attempt to attach to an existing user id: generic ",[124,358,233],{}," ",[163,361,362],{},"\"Unable to complete registration.\""," Use that copy. Do not invent a more specific reason.",[159,365,366,367,370],{},"Confirm with the same mail link and ",[124,368,369],{},"GET \u002Fidentity\u002FconfirmEmail"," behavior as password register. The passkey is already stored on the unconfirmed user.",[159,372,373,374],{},"After confirm, sign in with passkey:\n",[156,375,376,385,390],{},[159,377,378,381,382,303],{},[124,379,380],{},"POST \u002Faccount\u002Fpasskeys\u002FrequestOptions"," (optional ",[124,383,384],{},"?username=",[159,386,387,149],{},[124,388,389],{},"navigator.credentials.get(…)",[159,391,392,395],{},[124,393,394],{},"POST \u002Faccount\u002Fpasskeys\u002Flogin?useCookies=true"," with the assertion payload and CSRF.",[159,397,398,399,401],{},"Login succeeds only after confirm. Unconfirmed login returns ",[124,400,257],{}," Invalid credentials.",[120,403,404,405,408,409,142,412,149],{},"Default passkey completer cookie flags follow Identity ",[124,406,407],{},"Login",", not facade ",[124,410,411],{},"LoginCookie",[144,413,99],{"href":100},[151,415,417],{"id":416},"host-checklist","Host checklist",[419,420,421,434],"table",{},[422,423,424],"thead",{},[425,426,427,431],"tr",{},[428,429,430],"th",{},"Do",[428,432,433],{},"Do not",[435,436,437,449,457],"tbody",{},[425,438,439,443],{},[440,441,442],"td",{},"Same check-email screen for password and passkey",[440,444,445,446,448],{},"Treat register ",[124,447,185],{}," as logged in",[425,450,451,454],{},[440,452,453],{},"Generic copy on duplicate email",[440,455,456],{},"Say \"email already registered\"",[425,458,459,462],{},[440,460,461],{},"Sign in only after confirm",[440,463,464],{},"Expect a session from unconfirmed passkey register",[151,466,468],{"id":467},"out-of-scope","Out of scope",[120,470,471,472,475],{},"This page does not cover sign-in inside ",[124,473,474],{},"confirmEmail",", public resend without a session, or OAuth.",[151,477,479],{"id":478},"related","Related",[243,481,482,486,490,494],{},[159,483,484],{},[144,485,79],{"href":80},[159,487,488],{},[144,489,99],{"href":100},[159,491,492],{},[144,493,84],{"href":85},[159,495,496],{},[144,497,28],{"href":282},{"title":499,"searchDepth":500,"depth":501,"links":502},"",1,2,[503,504,505,506,507,508],{"id":153,"depth":501,"text":154},{"id":199,"depth":501,"text":200},{"id":306,"depth":501,"text":307},{"id":416,"depth":501,"text":417},{"id":467,"depth":501,"text":468},{"id":478,"depth":501,"text":479},"SPA password and passkey signup when RequireConfirmedAccount is true.","md",null,{},{"icon":51},{"title":48,"description":509},"vd09bx_E19JM1_NscRjcJIwxaOv-0vzyh_FOWZUmyNM",[517,519],{"title":43,"path":44,"stem":45,"description":518,"icon":46,"children":-1},"Does AuthEndpoints replace Identity? Cookie or JWT? Passkeys, 2FA, composing routes, and Sign in with Google as a provider.",{"title":59,"path":55,"stem":56,"description":520,"icon":60,"children":-1},"Compose Identity management, sign-in stacks, and passkeys on the prefixes your host needs.",1788834582933]