Passwordless Authentication#
Agenta uses SuperTokens to implement a passwordless, OTP-based login flow. Users receive a 6-digit code via email, enter it to authenticate, and are issued a session via the SuperTokens session recipe. This flow is only active in demo mode (isDemo() === true); self-hosted (non-demo) deployments use the EmailPassword recipe instead .
SuperTokens Recipe Configuration#
The passwordless recipe is initialized in frontendConfig.ts with contactMethod: "EMAIL". The full recipe list also includes ThirdPartyReact (GitHub, Google), EmailPassword, and SessionReact . SuperTokens is bootstrapped at app startup by AuthProvider (web/oss/src/lib/helpers/auth/AuthProvider.tsx), which calls SuperTokensReact.init(frontendConfig()).
Authentication Flow#
The three-step flow maps directly to three SuperTokens SDK functions, each handled in a dedicated component:
1. createCode — Email submission#
Component: PasswordlessAuth
The user submits their email. createCode({ email }) is called. On success (status !== "SIGN_IN_UP_NOT_ALLOWED"), isLoginCodeVisible is set to true, switching the UI to the OTP entry screen . A SIGN_IN_UP_NOT_ALLOWED response surfaces the reason string directly as a user-facing error .
2. consumeCode — OTP verification#
Component: SendOTP
The user enters the 6-digit code. consumeCode({ userInputCode }) is called and handles four response statuses:
| Status | Behavior |
|---|---|
OK | Clears login attempt info, resets profile/org/project context, redirects to /apps (or /post-signup / /workspaces/accept for new/invited users) |
INCORRECT_USER_INPUT_CODE_ERROR | Shows remaining attempts (maximumCodeInputAttempts - failedCodeInputAttemptCount) |
EXPIRED_USER_INPUT_CODE_ERROR | Prompts user to request a new code |
Other / RESTART_FLOW_ERROR | Clears attempt info and returns to email entry screen |
3. resendCode — Re-sending the OTP#
Still in SendOTP, the resendOTP handler calls resendCode(). On RESTART_FLOW_ERROR, it clears the attempt and resets to the email screen. On success, the "Resend" button is disabled for 60 seconds to prevent spam .
Auth Page Orchestration#
pages/auth/[[...path]].tsx is the entry point for all auth flows. On mount, it calls getLoginAttemptInfo() to detect an in-progress OTP session and pre-show the SendOTP component if one exists (e.g., after a page refresh). The isLoginCodeVisible boolean drives which component is rendered .
Invite-flow detection reads query params (token, org_id, project_id, workspace_id, email) and persists them to localStorage; this isInvitedUser flag is passed down to SendOTP to control the post-login redirect .
Key Files#
| File | Purpose |
|---|---|
web/oss/src/config/frontendConfig.ts | SuperTokens recipe initialization |
web/oss/src/pages/auth/[[...path]].tsx | Auth page entry point and flow orchestration |
web/oss/src/components/pages/auth/PasswordlessAuth/index.tsx | Email input + createCode |
web/oss/src/components/pages/auth/SendOTP/index.tsx | OTP input + consumeCode + resendCode |