yao/openapi/otp/README.md
Max 37ab2bc84b Enhance user login functionality with options for customization
- Introduce `LoginWithOptions` method to allow for customizable login flows, enabling overrides for scopes, token expiration, and refresh token issuance.
- Add `LoginOptions` struct to encapsulate optional parameters for login, improving flexibility in user authentication.
- Update token handling in `issueTokens` to accommodate new options, ensuring proper management of access and refresh tokens based on user preferences.
- Integrate OTP service initialization into the OpenAPI server setup for enhanced authentication capabilities.
2026-02-21 21:38:39 +08:00

3.2 KiB

OTP — Passwordless Authentication

One-time password (OTP) module for passwordless login. An authorized caller generates a short-lived code bound to a user/member and a redirect URL. The recipient opens /v/<code> in a browser to authenticate without credentials.

Process

Process Args Returns Description
otp.Create params (map) code (string) Generate an OTP code
otp.Verify code payload (map) Look up a code without consuming it
otp.Login code, locale? LoginResult Verify code, issue access token, optionally consume
otp.Revoke code nil Delete a code immediately

otp.Create

yao run otp.Create '::{"team_id":"T1","member_id":"M1","redirect":"/dashboard"}'

Parameters:

Field Type Required Default Description
team_id string When member_id set Team context
member_id string Either this or user_id Target member (resolved to user_id at login)
user_id string Either this or member_id Target user
redirect string Yes Post-login redirect URL
expires_in int No 86400 Code TTL in seconds
token_expires_in int No system default Access token lifetime override (seconds)
scope string No Space-separated scopes for the issued token
consume bool No true Revoke code after first login

otp.Verify

yao run otp.Verify abc123def456

Returns the stored payload without consuming the code.

otp.Login

yao run otp.Login abc123def456 en-US

Verifies the code, resolves identity (member_iduser_id if needed), issues an access token (no refresh token), and returns LoginResult. Consumes the code if consume is true.

otp.Revoke

yao run otp.Revoke abc123def456

Deletes the code. Silent if the code does not exist.

HTTP API

Method Path Auth Description
POST /otp/create Bearer token (team context) Create an OTP code
POST /otp/login Public Verify code, set session cookies

POST /otp/create

Requires a valid access token with team context. The team_id is forced from the caller's identity. Validates that the target user/member belongs to the same team.

Request:

{"member_id": "M1", "redirect": "/agents/keeper/entry/xxx"}

Response:

{"code": "abc123def456"}

POST /otp/login

Public endpoint. Checks for an existing valid session first — if found, returns already_logged_in without issuing new tokens. Otherwise performs login and sets access_token cookie (no refresh_token).

Request:

{"code": "abc123def456", "locale": "en-US"}

Response:

{"status": "success", "redirect": "/agents/keeper/entry/xxx"}

Status is either success (new session) or already_logged_in (existing session).

Security

  • Codes are 12-char NanoID ([2-9a-hjkmnp-z]), ~62 bits of entropy
  • Default TTL: 24 hours
  • Codes are single-use by default (consume: true)
  • No refresh token issued — access token only
  • POST /otp/create enforces team membership validation
  • team_id is always derived from the caller's token, not the request body