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:
| Domain | Org Type |
|---|---|
portal.theonemission.com | mission |
portal.theonemission.app | mission |
| Everything else | generic (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:
- Add a Cloudflare CNAME pointing
portal.acme.com→app.theoneportal.app - Enable SSL — Cloudflare Full (Strict) mode recommended
- Configure the tenant — The Portal application must know which tenant maps to this domain. Contact support to register your custom domain → tenant mapping.
- Distribute the URL — Share
https://portal.acme.comwith 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:
| Field | Description |
|---|---|
| Portal name | Displayed in the browser tab and header when no logo is uploaded |
| Logo URL | Displayed in the portal header; replaces the portal name text |
| Favicon URL | Browser tab icon |
| Primary color | Used for active nav items, buttons, and accents |
| Accent color | Secondary accent; falls back to primary if not set |
| Welcome text | Shown below the user's name on the Dashboard |
| Login background URL | Optional background image on the login page |
| Powered by visible | Toggle the "Powered by The One Stack" footer |
| Custom CSS | Raw CSS injected into the portal for advanced customization |
Changes take effect immediately for new page loads — branding is fetched fresh on each session start.