Skip to main content

Multi-Org Routing

The One Portal serves two distinct organizations types — MSP client portals and Mission (nonprofit/church) member portals — from the same application. The correct mode is selected automatically based on the visitor's domain and JWT claims.


How Org Type Is Detected

The Portal uses a two-pass detection system:

Pass 1: Domain-based (pre-auth, for branding)

When the page loads, the frontend checks window.location.hostname against a known map:

DomainOrg Type
portal.theonemission.commission
portal.theonemission.appmission
Everything elsegeneric (MSP assumed)

This is used to apply the correct accent color and show the appropriate login page before the user authenticates.

Pass 2: JWT claim (post-auth, authoritative)

After login, the session JWT may contain an org_type claim set by the admin SSO flow. If present, it overrides the domain-based hint.

The resolved orgType then determines:

  • Which navigation items appear in the sidebar
  • Which module routes are active
  • Which accent color is applied (rose for Mission, branded color for MSP)

MSP Portal Mode

Triggered by: Any domain not listed in the Mission map, or org_type: 'msp' in JWT.

Active navigation:

  • Dashboard
  • Tickets
  • Service Catalog
  • Invoices
  • Documents
  • Announcements
  • Team
  • Profile

Accent color: Configured per tenant in Branding settings (defaults to violet #8b5cf6).

Default route after login: /portal/dashboard


Mission Portal Mode

Triggered by: portal.theonemission.com or portal.theonemission.app, or org_type: 'mission' in JWT.

Active navigation:

  • Dashboard
  • Giving
  • Events
  • Groups
  • Directory
  • Prayer Wall

Accent color: Rose #e11d48 (fixed for Mission, not tenant-configurable).

Default route after login: /portal/mission/dashboard

All Mission routes are under /portal/mission/*. Mission data is fetched through the mission-proxy API function, which forwards requests to The One Mission API.


Tenant Identification

For MSP portals, the tenant is identified by the tenant query parameter or localStorage:

https://app.theoneportal.app/?tenant=acme-msp

The tenant slug is stored in localStorage as portal_tenant after first use, so subsequent visits to the same origin remember the tenant. Branding (colors, logo, portal name) is fetched from /api/portal/branding?tenant=SLUG before login.


White-Label Custom Domain Setup

MSPs can serve the Portal from their own domain (e.g., portal.acme.com) instead of the default app.theoneportal.app.

Steps:

  1. Add a Cloudflare CNAME pointing portal.acme.comapp.theoneportal.app
  2. Enable SSL — Cloudflare Full (Strict) mode recommended
  3. Configure the tenant — The Portal application must know which tenant maps to this domain. Contact support to register your custom domain → tenant mapping.
  4. Distribute the URL — Share https://portal.acme.com with your clients. No ?tenant= parameter is needed when the domain is registered.
ℹ️

Custom domain registration is a server-side configuration step. The Portal frontend reads the Host header to resolve the tenant when no ?tenant= param is present.


Branded Portal Configuration

Branding is configured per tenant in Admin → Branding:

FieldDescription
Portal nameDisplayed in the browser tab and header when no logo is uploaded
Logo URLDisplayed in the portal header; replaces the portal name text
Favicon URLBrowser tab icon
Primary colorUsed for active nav items, buttons, and accents
Accent colorSecondary accent; falls back to primary if not set
Welcome textShown below the user's name on the Dashboard
Login background URLOptional background image on the login page
Powered by visibleToggle the "Powered by The One Stack" footer
Custom CSSRaw CSS injected into the portal for advanced customization

Changes take effect immediately for new page loads — branding is fetched fresh on each session start.