Skip to content

appwrite login --mfa/--code never creates the MFA challenge (self-hosted TOTP)Β #363

Description

@lucydjo

πŸ‘Ÿ Reproduction steps

Self-hosted Appwrite 1.9.6, CLI 27.3.0 (Homebrew, darwin/arm64). Console account has TOTP enabled as its only MFA factor (GET /v1/account/mfa/factors β†’ {"totp":true,"phone":false,"email":false,"recoveryCode":false}).

$ appwrite login --endpoint "https://appwrite.example.com/v1" \
    --email me@example.com --password '<password>' --mfa totp --code 130705
βœ— Error: More factors are required to complete the sign in process.

Same result with a fresh code every time, and with --code alone or --mfa alone.

πŸ‘ Expected behavior

After POST /v1/account/sessions/email returns user_more_factors_required, the CLI should create an MFA challenge for the factor given in --mfa (POST /v1/account/mfa/challenge) and verify it with --code (PUT /v1/account/mfa/challenge), then store the elevated session.

πŸ‘Ž Actual Behavior

The CLI never creates the challenge. --verbose shows the request sequence stops right after the email session call:

Β· GET /v1/health/version 200
Β· GET /v1/account 200
Β· POST /v1/account/sessions/email 401

No POST /v1/account/mfa/challenge is ever issued, so --mfa / --code are effectively ignored and the error from step 1 is surfaced as-is.

Worse, the partial (unelevated) session cookie appears to be written to ~/.appwrite/prefs.json anyway. Subsequent commands then fail confusingly:

$ appwrite pull all
βœ— Error: you are not authenticated. Run `appwrite login` to authenticate and try again

Doing the three calls by hand against the same server works fine and produces a usable session:

curl -c c.txt -X POST "$EP/account/sessions/email" -H "X-Appwrite-Project: console" \
  -H 'Content-Type: application/json' -d '{"email":"...","password":"..."}'
CH=$(curl -b c.txt -X POST "$EP/account/mfa/challenge" -H "X-Appwrite-Project: console" \
  -H 'Content-Type: application/json' -d '{"factor":"totp"}')   # β†’ challengeId
curl -b c.txt -c c.txt -X PUT "$EP/account/mfa/challenge" -H "X-Appwrite-Project: console" \
  -H 'Content-Type: application/json' -d '{"challengeId":"'"$ID"'","otp":"123456"}'

Writing that cookie into ~/.appwrite/prefs.json makes the CLI work normally, which confirms the server side is fine and the gap is in the CLI's login flow.

Note: --mfa also has a misleading UX β€” --mfa 123456 fails with flag needs an argument guidance that doesn't hint the value is a factor name, not the code.

🎲 Appwrite version

Different version (specify in environment)

πŸ’» Operating system

MacOS

🧱 Your Environment

Appwrite server 1.9.6 (self-hosted, behind HTTPS). appwrite-cli 27.3.0 installed via Homebrew, macOS 15 / arm64.

πŸ‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏒 Have you read the Code of Conduct?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions