Skip to content

Auth Verify (Magic Link Token Verification)

A user clicks the magic link delivered to their email; the app extracts the token and session, submits them to the verify endpoint, and receives a short-lived handoff code in return.

Flow

  1. Deep link opens the app — The mobile app intercepts the magic-link URL and parses email, token, and session from the query string.

  2. Client submits verification — A POST request is sent to the auth-verify Lambda with { "email", "token", "session" }.

  3. Input validation — The Lambda normalizes and validates the email. Missing token or session values return HTTP 400 with a specific error code.

  4. Cognito challenge responseadmin_respond_to_auth_challenge is called with ChallengeName=CUSTOM_CHALLENGE and ANSWER=<token>. On success, Cognito returns an AuthenticationResult containing AccessToken, IdToken, RefreshToken, and ExpiresIn.

  5. Email verified flagadmin_update_user_attributes sets email_verified=true on the Cognito user.

  6. Handoff code creation — The create_handoff_code ORM helper stores the Cognito tokens in the shared PostgreSQL database with a short TTL and returns a single opaque code.

  7. Response — The API returns { "handoffCode": "<code>", "expiresIn": <seconds> }. The mobile app immediately exchanges this code via the handoff endpoint to obtain tokens natively.

Entry Point

  • Lambda: main/server/api/auth/verify/app.pylambda_handler
  • HTTP method: POST /auth/verify (API Gateway)

Dependencies

  • AWS Cognito (COGNITO_USER_POOL_ID, COGNITO_APP_CLIENT_ID)
  • PostgreSQL via shared.orm.create_handoff_code

Error Cases

Condition Response
Invalid email format 400 AUTH_EMAIL_INVALID
Missing token 400 AUTH_TOKEN_REQUIRED
Missing session 400 AUTH_SESSION_REQUIRED
Wrong or expired token 400 AUTH_TOKEN_INVALID