Skip to content

Account Access

Who this is for: support staff answering login questions, new hires.

A patient’s account is created automatically the first time they check out through onboarding (see Onboarding & signup). From then on, signing in works the same way every time:

  1. The patient enters their email on the sign-in page.
  2. The system emails them a one-time “magic link.”
  3. Clicking the link verifies the one-time link, creates a signed session token, and sets it as a cookie in the patient’s browser.
  4. The magic link itself expires quickly (about 15 minutes) if unused. The resulting session cookie lasts roughly a week before the patient has to sign in again.

If the email doesn’t match an existing account, sign-in fails — there is no separate “forgot password” flow on the patient side, because there is no password to forget.

If the patient portal and a marketing/WordPress site sit on the same root web domain, the session cookie is deliberately made readable by every subdomain on that domain (not just the patient portal), so the marketing site can check “is this visitor already signed in?” without asking twice. Locally, or when that shared domain isn’t configured, the cookie stays scoped to just the patient portal. See System overview for how this cross-site behavior fits into the two apps’ overall connection.

Staff sign-in (care portal) is a separate system

Section titled “Staff sign-in (care portal) is a separate system”

Care-portal staff (doctors, admins, care-team, print-station) log in through a completely separate, unrelated login system from the patient portal’s magic-link flow:

  • Staff accounts use a traditional email/password login, with a “forgot password” reset-link flow available if they lose access.
  • After logging in, the system checks the staff member’s role (admin, provider, or an “outsider” bucket covering care-team/print-station) and, for finer-grained access, a sub-role (doctor, super admin, care-team member, consent coordinator, dispute handler, printer). Every internal page checks this before showing anything.
  • There is no shared login between a patient’s account and a staff account, even if they use the same email address — they are entirely separate user tables and sessions.

Some calls between the patient portal and the care portal don’t involve any person logging in at all — the patient portal calls into the care portal directly using a pre-shared internal key (a different key for “public” vs. “internal” call paths) to do things like the pre-signup eligibility check, look up patient files, or upload documents on the patient’s behalf. This is invisible to the patient and unrelated to their own session cookie.

Patients can view and update their own contact/profile details (name, email, phone, etc.) from a profile page in their dashboard.

  • Whether a patient can be logged out of all devices/sessions at once (e.g. by support staff, for security reasons) was not confirmed in the code reviewed.
  • parkingmd-patient-portal/documentation/cross-site-auth-cookie.md
  • parkingmd-patient-portal/src/auth/handlers/ (login.ts, verify-token.ts, signup.ts, logout.ts, me.ts)
  • parkingmd-patient-portal/src/auth/tokens.ts, src/auth/config.ts
  • parkingmd-patient-portal/src/config.ts (auth.cookieDomain)
  • parkingmd-care-portal/src/lib/auth/index.ts, validate-request.ts, actions.ts
  • parkingmd-care-portal/src/app/(auth)/reset-password/
  • parkingmd-care-portal/src/app/api/v1/external/_helpers.ts (validateS2SToken, validateInternalApiKey)
  • parkingmd-patient-portal/src/app/(dashboard)/profile/page.tsx, ProfileContent.tsx, parkingmd-patient-portal/src/trpc/routers/profile.ts