Session

Loading…

Start a login

or
Test options
Rides the Auth0 redirect flow only (password, Google, Facebook). The magic link ("Email me a login link instead") posts to the API inline, so this guard does not apply to it.
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 carries client_id/site_id.
  • Verified identity, no account — with a site_id declared 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 a site_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/
Featurestaging.flowyogatx.comThis system
Email + password✔✔
Google / Facebook✔✔
Passwordless email code✔✔
Magic link (one click, any device)✖✔
Passkeyshosted 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 signupsocial, passwordsocial, password, magic link
Stay-logged-inPHP session + remember-device rows400-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).