Session
Loading…
Start a login
or
Test options
How this system works
This is the login system for fvmgt.com apps, served by the Datastream API on its
own Auth0 tenant (fvmgt / login.fvmgt.com).
Auth0 is only the identity verifier — after the code exchange the API verifies
the RS256 ID token against the tenant JWKS (signature, issuer, audience, expiry, nonce), applies
the business guards below, then issues its own first-party session cookie on
.fvmgt.com and discards the Auth0 session. Every outcome, success or refusal,
returns as ?outcome= on the caller's page. It provides everything the Auth0 login
at staging.flowyogatx.com/auth-login/ provides, plus a few things beyond it —
true cross-device magic links, automatic passkey enrollment, and inline signup.
Two ways in: (a) this page's login card, which drives the
individual endpoints, and (b) the bare hosted entry — a plain link or redirect to
https://datastream.fvmgt.com/v1/auth/login (optional query:
connection=password|google|facebook|email, login_hint,
checkout_email, site_id, return_to) sends the browser
straight to the hosted Auth0 chooser and lands back on return_to with the
outcome — zero page code needed by the installing site.
Login methods: email + password, Google, Facebook, passwordless
email — as both a 6-digit code and a true cross-device magic link (redeemed
server-side via the OTP grant, since Auth0's native links only work on Classic Universal
Login) — and passkeys (autofill detection on the hosted identifier screen, plus automatic
enrollment on this page after login via the My Account API, RP scoped to
fvmgt.com).
Business guards — every scenario the auth-login flow handles is handled here, same verdicts:
- Connection allow-list — anything but the four known connections is rejected
(same behavior as auth-login's "Bad Gateway" exit) →
bad_connection. - Social identity without an email (e.g. Facebook with email permission declined) —
no session, Auth0 session dropped (same behavior as auth-login's social-error page) →
no_email. - Checkout email mismatch — a flow started with a checkout email refuses a login
under a different address (same as auth-login: social-error plus an audit log) →
email_mismatch. - Account existence — checked live against the Mindbody mirror by email (the same
check auth-login runs as
checkUserExistsForSocialLogin). Existing client → logged in, session carriesclient_id/site_id. - Verified identity, no account — with a
site_iddeclared by the installing site, the user is handed a signed 15-minute signup token and finishes registration on this page; the API creates the Mindbody client (AddClient at that studio) and logs them in (auth-login routes this through its social-signup form to the same MBO registration). Without asite_id, the same dead ends auth-login uses — social →signup_required, passwordless →passwordless_blocked. - Passkey/MFA (amr) return with no account — hard dead end, never a signup, the same
verdict as auth-login's AMR guard and its blocked-landing log →
amr_blocked. - Unverified database user — login deferred until the email address is verified
(same behavior as auth-login's pending-verification flags) →
pending_verification.
Feature comparison vs staging.flowyogatx.com/auth-login/
| Feature | staging.flowyogatx.com | This system |
|---|---|---|
| Email + password | ✔ | ✔ |
| Google / Facebook | ✔ | ✔ |
| Passwordless email code | ✔ | ✔ |
| Magic link (one click, any device) | ✖ | ✔ |
| Passkeys | hosted button + enroll-after-password screen | ✔ autofill detection + automatic inline enrollment, no extra screen |
| Callback guards (allow-list, no-email, checkout mismatch, account existence, passwordless/AMR blocks, unverified deferral) | ✔ | ✔ |
| Unknown-user signup | social, password | social, password, magic link |
| Stay-logged-in | PHP session + remember-device rows | 400-day rolling signed cookie, self-contained |
| Account-page workflows (activate social, set password) | ✔ | ✔ |
Sessions: HMAC-signed, HttpOnly, 400-day expiry (browser cap)
with rolling renewal on every visit — the durable-login role auth-login's remember-device
cookies play. The Auth0 refresh token is AES-256-GCM-encrypted inside the cookie solely to
power passkey enrollment; /me never exposes it.
Account management is part of the login layer: the Session card lets a logged-in user link or unlink Google and Facebook (linking requires the same email — a mismatch is refused), set or change a password via an emailed link, and manage passkeys. Provider-link state lives in Auth0 itself, so there are no separate status records to drift. The one piece that intentionally remains the consuming site's job is the email-change workflow (adopting a different social email as the account email). Every branch above is pinned by the API's automated test suite (576 tests).