airqo-platform / airqo-platform/AirQo-frontend
Frontend integration guide — secure sign-in link email (self-hosted, no Firebase)
- Vorherrschende Sprache
- TypeScript
- Sterne
- 23
- Forks
- 48
- Ø Merge
- 15 Std. 24 Min.
- Gemergte PRs (30 T.)
- 57
Beschreibung
## Context
auth-service's email-based sign-in flow sends a clickable "Sign in" link (magic-link style) instead of a bare numeric code. The link generation was originally built on Firebase, but has since been reworked to be fully self-hosted (no third-party SDK dependency). **This changes what the link is and what needs to intercept/complete it — read this even if you saw an earlier version of this issue.**
## Background
- Trigger: user submits their email to start passwordless sign-in.
- auth-service emails a secure, single-use, time-limited token embedded in a link, inside a styled "Sign in" button.
- The link is a plain URL (`/user/emailLogin?token=...&email=...`) — **not** a Firebase dynamic/action link, and it does **not** automatically open a mobile app the way a Firebase App Link/Universal Link would.
- Clicking the link alone does nothing by itself — a client must read `token` and `email` from it and call the completion endpoint below to actually finish signing in.
## Endpoints
**POST `/api/v3/users/emailLogin`**
Body: `{ "email": "user@example.com" }`
Requires an existing account for that email (returns 400 otherwise). Sends the sign-in email.
**POST `/api/v3/users/completeEmailLogin`** — new
Body: `{ "email": "user@example.com", "token": "" }`
Validates the token (single-use, ~15 minute expiry) and, if valid, returns a normal login session — same response shape as a regular password login (`_id`, `token` as `"JWT <...>"`, `email`, profile fields, `authMethods`, etc.). This is the call that actually completes sign-in.
**POST `/api/v3/users/emailAuth/:purpose?`** (`purpose`: `auth` | `mobileAccountDelete` | `login`)
Used for re-authentication and account-deletion confirmation flows. The `auth`/`mobileAccountDelete` emails themselves (numeric code) are unchanged, but this endpoint now also requires an existing account for the email (same 400 behavior as `emailLogin`) and no longer depends on Firebase under the hood.
Legacy equivalents exist under `/api/v2/users/...` for older clients.
**`emailLogin` response (200):**
```json
{
"success": true,
"message": "process successful, check your email for token",
"data": {
"link": "/user/emailLogin?token=...&email=...",
"token": "<5-digit numeric code, unrelated to the link token>",
"email": "user@example.com",
"emailLinkCode": ""
}
}
```
## What each app needs to do
### nexus (web platform) — primary target now
- Needs a route matching the link, e.g. `/user/emailLogin`, that reads `token` and `email` from the query string and calls `POST /completeEmailLogin` with them.
- On success, store the returned session the same way a normal password login response is handled today.
- On failure (invalid/expired token), show a clear "this link has expired, request a new one" message and a way to re-trigger `/emailLogin`.
### mobile
- No more automatic deep-link interception — that was a Firebase App Link/Universal Link behavior that no longer applies.
- If mobile should support completing sign-in without going through the web page, it needs its own universal-link (iOS) / app-link (Android) association set up for the link's domain, then call `POST /completeEmailLogin` with the parsed `token`/`email` itself.
- If that's more than you want to take on right now, the simplest path is: the link opens the nexus web page, which completes sign-in there — mobile users would just be sent to a browser. Flag if that's not acceptable UX.
### vertex / vertex-desktop / vertex-template
- Vertex is in maintenance mode (no new features) — out of scope unless explicitly requested by its maintainer.
### website / docs-website / beacon / calibrate
- Not applicable — these apps don't handle user authentication.
## Open questions for the frontend team
- [ ] Does mobile want native deep-link handling (own universal links + direct `/completeEmailLogin` call), or is "link opens in browser, completes on nexus" acceptable for now?
- [ ] Should the numeric `token` (`data.token`, separate from the link) still be offered as a fallback manual-entry option anywhere?
## Acceptance criteria
- [ ] nexus has a working `/user/emailLogin`-style completion page wired to `POST /completeEmailLogin`
- [ ] Expired/invalid-token error state is handled with a clear retry path
- [ ] Decision made and documented on mobile's deep-link approach
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.