Skip to main content

B2B Quick Start with React

Use this guide to build a React application where each company that signs up becomes its own organization in ThunderID. You set up the Wayfinder Enterprise platform from the model, then write a small application that shows each signed-in person which company they are working in.

What You Will Learn

  • Create a platform organization that every customer company joins
  • Let a company and its first admin sign up in one step
  • Read the organization from the token with @thunderid/react

Prerequisites

  • About 30 minutes
  • Docker installed on your system
  • Node.js installed on your system
  • npm, Yarn, or pnpm
  • Your preferred code editor
Building your own application?

The names here (Wayfinder Enterprise, Wayfinder Admin, northstar) come from the running example of this section. Swap in your own product and role names as you go.

Set Up the Platform​

The platform side is everything your team defines once: the platform organization, the account schema, the roles, the two flows, and the application. Every company that signs up later uses these without any further setup.

1

Run ThunderID

Run the quickstart image. ThunderID splits into two planes: the Control Plane, where your team authors configuration, and the Data Plane, which serves sign-ins and holds the people who sign in. The image starts both, already wired together. You configure the platform in the Control Plane console, and your application signs people in on the Data Plane:

bash
docker run --name thunderid-quickstart \
-p 8090:8090 -p 8091:8091 -p 8095:8095 \
-e ADMIN_PASSWORD='<admin-password>' \
-v thunderid-quickstart:/opt/thunderid-quickstart \
ghcr.io/thunder-id/thunderid:latest
EndpointURL
Control Plane console, where you build the platformhttps://localhost:8095/console
Data Plane, where your application signs people inhttps://localhost:8090

Open the Control Plane console and sign in as admin with the password you set. Every change you make there is applied to the Data Plane automatically. See Run the Control Plane and Data Plane together with Docker for the other settings.

The console opens in the Default project. Applications, roles, and flows you create in a project belong to the project's own organization unit, also named Default. This guide therefore creates the platform organization beneath Default, and shares the application, roles, and flows with every organization unit below Default, which includes every company that signs up.

2

Create the Platform Organization

The platform organization holds the accounts and the customer companies: each company that signs up becomes a child of it.

  1. Navigate to Organization units.
  2. On the Default row, click Add child organization unit.
  3. Set Name to Wayfinder Enterprise and Handle to wayfinder-enterprise.
  4. Click Create.

Open Wayfinder Enterprise and copy its ID. The sign-in flow needs it later.

3

Define the Account

A user type defines what an account looks like. Because it belongs to the platform organization, every company beneath it can use it. User types are set for the whole deployment, so they sit under Organization settings rather than in the project.

  1. In the sidebar, click Organization settings, navigate to User types, and click Create user type.

  2. On the Organization unit step, select Wayfinder Enterprise.

  3. On the Details step, set User type name to Wayfinder User, keep the suggested Handle, wayfinder-user, and turn on Allow self registration, so people can create accounts through sign-up.

  4. On the Properties step, define the schema:

    AttributeTypeProperties
    usernamestringRequired, unique
    emailstringUnique
    passwordstringCredential
  5. Finish the wizard to create the user type.

The company sign-up asks only for a username and a password, so email stays optional. Invitations find people by email, so an account needs one before it can be invited into another company.

When you are done, select the Default project again. The steps that follow work inside it.

4

Create the Shared Roles

The two roles mean the same thing in every company, so you define them once and share them with every company, including the ones that sign up later.

  1. Navigate to Roles and click Add role.
  2. Set Role name to Wayfinder Admin, then click Continue until the role is created. The role needs no permissions in this guide.
  3. Open the role and select the Organization Access tab.
  4. Select Default and chosen organization units, then select All child organization units.
  5. Click Save changes.
  6. Repeat these steps for a second role named Wayfinder Member.

All child organization units means every organization unit below Default, now and later, so each company gets both roles the moment it signs up. Copy the ID of the Wayfinder Admin role: the sign-up flow assigns it to each company's first user. See Share a Role With Other Organization Units for the sharing options.

5

Build the Company Sign-Up Flow

The sign-up flow asks for the first admin's account, then for the company. It creates the company as an organization beneath Wayfinder Enterprise, creates the account inside it, and makes that person the company's Wayfinder Admin.

  1. Navigate to Flows and click Create new flow.
  2. Select Self sign-up as the flow type and click Continue.
  3. Select the Organization Sign-up template.
  4. Name the flow Wayfinder Company Sign-up and click Create. The template opens in the designer unsaved, because it needs a role ID from your deployment.
  5. Select the Assign Roles step and set Roles to the Wayfinder Admin role ID you copied.
  6. Click Save.

See Let Companies Sign Up for what each step does, and for a sign-up where the account can join more companies later.

6

Build the Sign-In Flow

The sign-in flow offers a password sign-in and enterprise single sign-on (SSO). Both paths end with the person signed in to one company.

  1. Navigate to Flows and click Create new flow.
  2. Select Sign-in as the flow type and click Continue.
  3. Select the Basic + Enterprise SSO template.
  4. Name the flow Wayfinder Sign-in and click Create.
  5. The template has two Resolve OU steps. On each one, set Parent OU ID to the Wayfinder Enterprise ID you copied. On the SSO path, the step looks up the handle the person types. After a password sign-in, it picks the company the person belongs to.
  6. Click Save.
7

Add Company Registration to the Sign-In

A sign-up started on its own ends with the new admin signed out. Run it from the sign-in screen instead, so the new admin finishes sign-up already signed in to the application. Keep Wayfinder Sign-in open in the designer:

  1. In the Resources panel, open Components and drag a Button onto the first screen, the one that asks for a username and password. Set its label to Register your company.
  2. In the Resources panel, open Steps and drag a Flow step onto the canvas. Set Referenced flow to Wayfinder Company Sign-up.
  3. Connect the Register your company button to the Flow step.
  4. Connect the Flow step's success path to the Resolve OU step that follows the password sign-in. The new admin belongs to exactly one company, so that step picks it without asking.
  5. Click Save.

See Call Node for how a flow runs another flow.

8

Register the Application

One application serves every company. Like the roles, it is shared with every organization unit below Default.

  1. Navigate to Applications and create an application.
  2. Select React and name the application Wayfinder Enterprise Web.
  3. Turn off Allow all user types to sign up for this application and select Wayfinder User. Sign-up creates accounts of this type, and creates each company beneath the organization unit that owns it.
  4. Add http://localhost:5173 as an authorized redirect URI and allowed origin.
  5. Finish creating the application and copy its Client ID.

Then configure the application's tabs. Each tab saves on its own, so save before you move to the next one:

  1. On Flows, set Sign-in flow to Wayfinder Sign-in. Turn on Sign-up flow and select Wayfinder Company Sign-up.
  2. On Token, open the User sub-tab. Under Scopes & user attribute mappings, add a custom scope named ou and map it to ouId, ouHandle, and ouName. Turn on the roles scope.
  3. On the same sub-tab, make sure the ID token and the access token include roles, ouId, ouHandle, and ouName.
  4. On Organization Access, select Default and chosen organization units, then select All child organization units.

A scope is a name the application asks for at sign-in to receive a set of claims. The ou scope puts the organization into the ID token, which is where the React SDK reads it from. In a declarative resource, the same settings are these fields of the application:

applications/wayfinder-enterprise-web.yaml (excerpt)
yaml
inboundAuthConfig:
- type: oauth2
config:
token:
accessToken:
userConfig:
attributes: [roles, ouId, ouHandle, ouName]
idToken:
userAttributes: [roles, ouId, ouHandle, ouName]
scopeClaims:
ou: [ouId, ouHandle, ouName]
roles: [roles]
allowedUserTypes: [wayfinder-user]
sharingPolicies:
- id: wayfinder-enterprise-all-companies
childUnits:
mode: all

Build the React Application​

With the platform ready, the application only has to send people to sign in and read the organization from the token it gets back.

1

Create a React App

Create a React application with Vite:

bash
npm create vite@latest wayfinder-enterprise -- --template react
cd wayfinder-enterprise
npm install
2

Install @thunderid/react

bash
npm install @thunderid/react
3

Wrap the App in the Provider

Wrap the application in <ThunderIDProvider /> and ask for the ou and roles scopes, so the ID token names the organization and the roles held there.

Configuration

Replace <your-client-id> with the Client ID you copied when you registered the application.

src/main.jsx
jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { ThunderIDProvider } from '@thunderid/react'
import App from './App.jsx'
import './index.css'

createRoot(document.getElementById('root')).render(
<StrictMode>
<ThunderIDProvider
clientId="<your-client-id>"
baseUrl="https://localhost:8090"
scopes={['openid', 'profile', 'roles', 'ou']}
preferences={{ user: { fetchUserProfile: false } }}
>
<App />
</ThunderIDProvider>
</StrictMode>
)
ParameterDescription
baseUrlThe Data Plane, where people sign in.
scopesou releases the organization claims, and roles releases the roles held in that organization.
preferences.user.fetchUserProfilefalse reads the signed-in person from the ID token, which carries the organization and roles.
4

Show the Organization

Replace src/App.jsx with a page that shows the company the person signed in to, their role there, and a switcher for people who belong to more than one company:

src/App.jsx
jsx
import {
OrganizationUnitSwitcher,
SignedIn,
SignedOut,
SignInButton,
SignOutButton,
useThunderID,
} from '@thunderid/react'
import './App.css'

function Workspace() {
const { user, currentOrganizationUnit } = useThunderID()
const roles = Array.isArray(user?.roles) ? user.roles : []
const isAdmin = roles.includes('Wayfinder Admin')

return (
<>
<h1>{currentOrganizationUnit?.name}</h1>
<p>
Signed in to the organization with the handle <code>{currentOrganizationUnit?.handle}</code>
</p>
<p>{isAdmin ? 'You administer this company.' : 'You are a member of this company.'}</p>
<OrganizationUnitSwitcher />
<SignOutButton>Sign Out</SignOutButton>
</>
)
}

function App() {
return (
<section id="center">
<SignedIn>
<Workspace />
</SignedIn>
<SignedOut>
<h1>Wayfinder Enterprise</h1>
<SignInButton>Sign In or Register Your Company</SignInButton>
</SignedOut>
</section>
)
}

export default App
  • currentOrganizationUnit holds the id, handle, and name of the organization the sign-in landed in, read from the ID token. Treat it as display data. Your APIs read the organization from the access token they receive.
  • user.roles lists only the roles the person holds in that organization.
  • <OrganizationUnitSwitcher /> lists the companies the person belongs to, and signs them in to the one they pick. A person who belongs to one company sees only that one. With the sign-in flow in this guide, a switch asks for the password again. See Switch Organizations to switch without it.
5

Run Your Application

bash
npm run dev

Open http://localhost:5173 and register a company:

  1. Click Sign In or Register Your Company. The browser opens the ThunderID sign-in page.
  2. Click Register your company.
  3. Enter a username and a password.
  4. Enter Northstar Labs as the company name and northstar as its handle.
Success

The browser returns to your application signed in. The page shows Northstar Labs, the handle northstar, and You administer this company. Register a second company, such as Initech, in a private window with a different username: each person sees only their own company.

Before you go to production

This application runs entirely in the browser, so it can read the organization but cannot safely manage it. Letting a company's admin add people and assign roles needs a backend that holds a client secret. See Let Organization Admins Manage Teams.

What's Next​

Explore with AI

ThunderID LogoThunderID Logo

Product

DocsAPIsSDKs
© Copyright Linux Foundation Europe.For web site terms of use, trademark policy and other project policies please see https://linuxfoundation.eu/en/policies.