What happens if…
Sign-in cases: what Gemmein does and what you do.
| If… | What happens | What you do |
|---|---|---|
| The code email does not arrive | The code is sent the moment it is asked for. Until you add a domain for email, it comes from Gemmein's shared address as <App name> (via Gemmein). If your own domain's sender is refused, the same code goes out from the shared address instead | Ask the person to check spam and wait a minute before asking again |
| A person asks for another code | Once the new code’s email has been sent, the new code replaces the earlier one. The earlier code then stops working, even if its email arrives later | Tell people to use the newest email |
| A person asks for a fourth code within 15 minutes | Sending is capped at 3 per email address (the original plus two resends) and 20 per IP per app (an IPv6 address counts by its /64), each per 15 minutes. The fourth answers 429 with resetAt | Show the wait from resetAt, and disable the resend button between attempts |
| The code email cannot be sent (the email provider refuses or fails the send, or cannot be reached) | The start answers 503 email_send_failed, the same for every address. The person’s earlier code, if they have one, still works. The code in any email from this try that does arrive won’t work. The try does not count toward the 3 per 15 minutes when the provider was down, busy or unreachable, or the time ran out before the email was handed over | Show "Try again in a moment" and let them retry |
| The email provider takes the code email but does not answer in time | The start answers 202, the same as a sent code. The email may still arrive, and its code works. The try counts toward the 3 per 15 minutes | Tell people to check their inbox, and to ask for a new code if none arrives |
| A person types a wrong code | 400 invalid_code. An expired code and a code already used get the same answer | Let them type it again |
| A person types three wrong codes | That code stops working, even the right one. Checking codes is also capped at 3 per email address per 15 minutes, so the next try answers 429 with resetAt | After resetAt, send a new code |
| A code is older than 10 minutes | It is refused with invalid_code | Send a new code |
| A person signs in on a second device | Both stay signed in. g.auth.devices() lists them (see Devices) | Nothing |
| A person signs in on an 11th device | The oldest of their ten sessions is signed out. That device's next call throws auth_expired, and onSignedOut fires there with "revoked" | Nothing. They sign in again on that device |
| A stored session stopped working | currentUser() answers authenticated: false with ended: "expired" (its 30 days ran out) or ended: "revoked" (signed out from this device or another, or by you). No ended means no session was held | Say which on the sign-in screen: "Your session expired" or "You were signed out" |
| A person types their email with different capitals | It is one person: addresses are matched in lower case | Nothing |
| A suspended person enters a correct code | Sign-in is refused with 403 user_suspended, and their existing sessions stop working | Unsuspend them on the Customers page to let them back in |
| A session is older than 30 days | It expires, and currentUser() answers authenticated: false | Show the sign-in screen |
| An earlier code email to the address bounced for good (the mailbox does not exist) | The start answers 202 like any other. Your app sends that address one code attempt every 24 hours, and a new bounce restarts the wait. A code that does not bounce within an hour turns the address's email back on. You can turn its email back on from the person's page | Ask the person to check the address |
| The person marked your app's mail as spam | Sign-in codes are still sent. Only your app's other mail stops | Nothing |
Was this page helpful?
Thanks for telling us.
Thanks for telling us.
Last updated