Phone app sign-in and two-factor authentication (2FA)
The EquipDash phone app signs in with an email and password, or with Google, and gets a bearer token back. These endpoints are for the phone app. API keys are not affected by two-factor authentication (2FA): a key is not a person signing in, so it keeps working exactly as before.
When a person has 2FA on, a correct password returns a challenge instead of a token. The app swaps the challenge plus a code for the token.
Sign in with a passwordโ
POST /api/v1/mobile/auth/login
| Field | Type | Required | Notes |
|---|---|---|---|
email | string | yes | |
password | string | yes | |
device_name | string | yes | Shown to the person as the trusted device name. |
trusted_device_token | string | no | The token this phone got the last time the person ticked Trust this device. A valid one skips the code for 30 days. |
2FA off, or a trusted phone: the same response as always.
{
"data": {
"token": "12|q8F...",
"user": { "id": 1, "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@example.test" },
"suppliers": [ ... ],
"active_supplier": { ... }
}
}
2FA on: no token yet.
{
"data": {
"two_factor_required": true,
"challenge_token": "Xk2...",
"expires_in": 600,
"email_hint": "j***@example.test"
}
}
The challenge lasts 10 minutes.
The person's team requires 2FA and they have not set it up: 403 with
two_factor_setup_required. They set it up by signing in on the website first, then sign in on
the phone.
Swap the challenge and a code for the tokenโ
POST /api/v1/mobile/auth/two-factor
| Field | Type | Required | Notes |
|---|---|---|---|
challenge_token | string | yes | From the login response. |
code | string | yes | Any of the three: the 6 digits from their authenticator app, the 6 digits from the emailed code, or one of their backup codes (with or without the dash). |
trust_device | boolean | no | true returns a trusted_device_token to store on the phone. |
Success returns the normal sign-in response, plus trusted_device_token when trust_device was
true. Store it in the phone's secure storage and send it with the next login.
Email a code insteadโ
POST /api/v1/mobile/auth/two-factor/email
| Field | Type | Required |
|---|---|---|
challenge_token | string | yes |
Emails 6 digits to the person, good for 10 minutes and once. At most one email a minute.
{ "data": { "sent": true, "email_hint": "j***@example.test" } }
Google sign-inโ
POST /api/v1/mobile/auth/google-login is unchanged. Google checks it is the person, so no
code is asked.
Errorsโ
| Error code | HTTP status | Meaning |
|---|---|---|
invalid_code | 422 | The code did not match. |
too_many_attempts | 429 | 5 wrong codes in a row. Wait 5 minutes. Also returned when an emailed code was sent less than a minute ago. |
challenge_expired | 401 | The challenge is older than 10 minutes, or was already used. Sign in again. |
two_factor_setup_required | 403 | The person's team requires 2FA and they have not set it up yet. |