implement password reset on login screen and MFA management for users

Agent-Logs-Url: https://github.com/christianlouis/dmarq/sessions/0419399d-3a03-4f02-a3a8-fc75da7172bc

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-30 19:58:40 +00:00
parent 6805ae301a
commit c81173e417
5 changed files with 252 additions and 0 deletions
+49
View File
@@ -7,6 +7,8 @@ GET /sign-in Initiate the Logto sign-in flow.
GET /callback Handle the Logto authorization-code callback.
GET /sign-out Sign the user out (clears session + redirects to Logto).
GET /me Return the currently authenticated user's profile.
GET /forgot-password Redirect to Logto's forgot-password screen.
GET /account-portal Redirect to the Logto account portal (MFA management).
"""
from __future__ import annotations
@@ -197,6 +199,53 @@ async def sign_out(request: Request) -> RedirectResponse:
return response
@router.get("/forgot-password")
async def forgot_password(request: Request) -> RedirectResponse:
"""
Redirect the user to Logto's forgot-password screen.
Builds a standard Logto authorization URL and appends the
``first_screen=forgot_password`` parameter so that Logto shows the
password-reset form immediately instead of the normal sign-in form.
After the user resets their password they are returned via the normal
callback flow and land on the app dashboard.
"""
if not settings.logto_configured:
raise _logto_not_configured()
storage = CookieStorage(request)
client = make_logto_client(storage)
sign_in_url: str = await client.signIn(redirectUri=_get_redirect_uri(request))
# Append the Logto-specific first_screen parameter so the password-reset
# form is shown directly. The sign-in URL normally already contains a "?"
# but we defensively detect the right separator in case the structure varies.
separator = "&" if "?" in sign_in_url else "?"
forgot_url = f"{sign_in_url}{separator}first_screen=forgot_password"
response = RedirectResponse(url=forgot_url, status_code=302)
storage.apply_to_response(response)
return response
@router.get("/account-portal")
async def account_portal(request: Request) -> RedirectResponse:
"""
Redirect an authenticated user to the Logto account portal.
The Logto account portal (``{LOGTO_ENDPOINT}/account``) lets users manage
their profile, linked identities, and multi-factor authentication settings
without leaving the Logto-hosted UI. After updating their settings, users
can simply navigate back to the app.
"""
if not settings.logto_configured:
raise _logto_not_configured()
portal_url = f"{settings.LOGTO_ENDPOINT.rstrip('/')}/account"
return RedirectResponse(url=portal_url, status_code=302)
@router.get("/me", response_model=None)
async def get_current_user(
request: Request,