Skip to main content
POST
/
api
/
auth
/
login
Login
curl --request POST \
  --url https://api.example.com/api/auth/login \
  --header 'Content-Type: application/json' \
  --data '
{
  "email": "<string>",
  "password": "<string>"
}
'
{
  "success": true,
  "user": {
    "id": "<string>",
    "email": "<string>",
    "name": "<string>",
    "email_verified": true,
    "created_at": "<string>",
    "updated_at": "<string>"
  },
  "key_salt": "<string>",
  "verification_blob": {},
  "encrypted_keys": [
    {
      "account_id": "<string>",
      "encrypted_key": "<string>",
      "key_version": 123
    }
  ],
  "csrfToken": "<string>",
  "error": "<string>",
  "code": "<string>"
}
Authenticates a user with their email and password. Returns JWT tokens in httpOnly cookies and encryption keys for client-side decryption.

Request

email
string
required
User’s email address. Must be a valid email format.
password
string
required
User’s password. Minimum 6 characters.

Response

success
boolean
Indicates if the login was successful.
user
object
User information.
key_salt
string
Hex-encoded salt used for key derivation. Required for client-side encryption.
verification_blob
string | null
Encrypted verification data for PIN validation. Null if not configured.
encrypted_keys
array
Array of encrypted account keys.
csrfToken
string
CSRF token for subsequent authenticated requests.

Cookies Set

The endpoint sets the following httpOnly cookies:
  • accessToken: JWT access token (15 minute expiry)
  • refreshToken: JWT refresh token (8 hour expiry)
  • csrfToken: CSRF protection token
All cookies are:
  • httpOnly: true (not accessible via JavaScript)
  • secure: true in production
  • sameSite: 'none' in production, 'lax' in development

Example Request

curl -X POST https://api.homeaccount.app/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "SecurePass123!"
  }'

Example Response

{
  "success": true,
  "user": {
    "id": "usr_1a2b3c4d5e6f",
    "email": "[email protected]",
    "name": "John Doe",
    "email_verified": true,
    "created_at": "2024-01-15T10:30:00.000Z",
    "updated_at": "2024-03-05T14:20:00.000Z"
  },
  "key_salt": "a1b2c3d4e5f6789...",
  "verification_blob": "ZW5jcnlwdGVkX3Zlcml...",
  "encrypted_keys": [
    {
      "account_id": "acc_9z8y7x6w5v4u",
      "encrypted_key": "U2FsdGVkX1+abcdef...",
      "key_version": 1
    }
  ],
  "csrfToken": "csrf_abc123xyz..."
}

Error Responses

error
string
Error message describing what went wrong.
code
string
Machine-readable error code.

400 Bad Request

{
  "success": false,
  "error": "Email inválido"
}
Returned when:
  • Email is missing or invalid format
  • Password is missing
  • Request body validation fails

401 Unauthorized

{
  "success": false,
  "error": "Invalid email or password"
}
Returned when:
  • Email doesn’t exist in the system
  • Password is incorrect

403 Forbidden - Email Not Verified

{
  "success": false,
  "error": "Debes verificar tu email antes de iniciar sesión.",
  "code": "EMAIL_NOT_VERIFIED",
  "email": "[email protected]"
}
Returned when the user hasn’t verified their email address. The client should redirect to the email verification flow.

429 Too Many Requests

Returned when rate limit is exceeded. Login endpoint has rate limiting protection.

Implementation Details

  • Rate Limiting: The login endpoint is protected by rate limiting middleware (loginRateLimiter)
  • Password Hashing: Passwords are hashed using bcrypt with configurable salt rounds
  • Token Generation: JWT tokens are generated using the tokenService
  • Email Verification: Users must verify their email before they can log in
  • Session Management: Sessions are managed via httpOnly cookies for security

Security Considerations

  1. Never send tokens in response body: Access and refresh tokens are only set as httpOnly cookies
  2. CSRF Protection: All authenticated requests must include the CSRF token
  3. Email Verification Required: Users cannot log in until they verify their email
  4. Rate Limiting: Prevents brute force attacks
  5. Secure Cookies: In production, all cookies use secure: true and sameSite: 'none'

Source Code

Controller: backend/controllers/auth/auth-controller.ts:95 Route: backend/routes/auth/auth-routes.ts:47

Build docs developers (and LLMs) love