mcpField
P
ping-orchestration-reactjs-journey-sdk

ping-orchestration-reactjs-journey-sdk

github.com/pingidentitySecurity146 installsUpdated 13w ago
Repository

About ping-orchestration-reactjs-journey-sdk

A skill for building Ping Orchestration JavaScript SDK authentication flows in React single-page apps. It can scaffold a full sample app or generate integration files for an existing app, including Journey handling and protected routes.

Key features

  1. 01Scaffold React sample apps
  2. 02Generate integration files for existing apps
  3. 03Manage Journey steps with a custom hook
  4. 04Render callback-specific components
  5. 05Handle OIDC state and protected routes

Use cases

  1. 01Demonstrate PingAM or AIC authentication
  2. 02Add Journey login or registration to a React SPA
  3. 03Integrate step-up authentication in an existing app

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/pingidentity/ping-sdk-agent-skills --skill ping-orchestration-reactjs-journey-sdk

After installing, type/ping-orchestration-reactjs-journey-sdkin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

assets/
.env.template
.gitignore.template
boolean.jsx.template
callback.html.template
choice.jsx.template
confirmation.jsx.template
constants.js.template
device-profile.jsx.template
form.jsx.template
hidden-value.jsx.template
home.jsx.template
index.html.template
index.jsx.template
journey.hook.js.template
kba.jsx.template
login.jsx.template
logout.jsx.template
metadata.jsx.template
number.jsx.template
oidc.context.js.template
package.json.template
password.jsx.template
polling-wait.jsx.template
protect-evaluation.jsx.template
protect-initialize.jsx.template
recaptcha-enterprise.jsx.template
recaptcha.jsx.template
redirect.jsx.template
register.jsx.template
route.jsx.template

Details

From the project README

ReactJS Authentication with Ping Orchestration JavaScript SDK

Scaffold a complete authentication flow in a ReactJS single-page application using the Ping Orchestration JavaScript SDK (Journey).


Metadata

FieldValue
LanguageJavaScript (JSX)
FrameworkReact 18+, React Router 6+, Vite
SDKPing Orchestration JavaScript SDK (@forgerock/journey-client, @forgerock/oidc-client)
PatternFunctional Components, Custom Hooks, Context API
Node.js>= 18.12.0

Overview

This skill adds a complete authentication flow to a ReactJS single-page application. It uses the Ping Identity Orchestration JavaScript SDK (Journey client) to authenticate users against PingOne Advanced Identity Cloud (AIC) or PingAM.

The implementation covers:

  • Journey client configuration via OIDC well-known endpoint discovery
  • OIDC client setup for OAuth 2.0 token exchange, renewal, and revocation
  • Custom React hook (useJourney) for managing the step-by-step authentication flow
  • Dynamic callback rendering with dedicated React components for each callback type
  • Protected route handling with React Router
  • Context-based authentication state management
  • Login, registration, and logout flows
  • User profile display via oidcClient.user.info() with optional edit UI
  • Success, error, and failure handling
Use Cases
  1. Sample Application — Build a complete, themed ReactJS app from scratch to demonstrate how the Ping Orchestration JavaScript SDK works with PingAM and AIC. This includes all SDK integration files plus a full UI with navigation, styled views, a user profile page, and protected content. The agent should generate package.json, vite.config.js, index.html, a CSS stylesheet, and all views/components.
  2. Existing Application Integration — Integrate the Ping Orchestration JavaScript SDK into an existing ReactJS SPA to add authentication, step-up authentication, or any Journey/Tree-based flow supported by the SDK. The agent should generate only the SDK integration files (constants, context, hook, form, callbacks, protected route) and guide the user on wiring them into their existing router and layout.

Prerequisites

1. npm Dependencies

Install the following packages in your React project:

npm install @forgerock/journey-client @forgerock/oidc-client react react-dom react-router-dom

Optional dependencies for additional features:

# PingOne Protect integration (threat signals / risk evaluation)
npm install @forgerock/protect

See package.json template for a complete example.

2. Vite Configuration

This skill uses Vite as the build tool. See vite.config.js template for the recommended configuration.

npm install --save-dev vite @vitejs/plugin-react
3. CORS Configuration (PingAM / AIC)

Configure CORS in your PingAM or AIC tenant:

SettingValue
Allowed Originshttps://localhost:8443 (or your app URL)
Allowed MethodsGET, POST
Allowed HeadersContent-Type, X-Requested-With, X-Requested-Platform, Accept-API-Version, Authorization
Allow CredentialsEnabled
4. OAuth 2.0 Client Registration

Create a public (SPA) OAuth client in PingAM / AIC:

SettingValue
Client TypePublic
Grant TypesAuthorization Code
Token Endpoint Auth Methodnone
Scopesopenid profile email (minimum)
Redirect URIsYour app's callback URL (e.g., https://localhost:8443/callback.html)
Implicit ConsentEnabled

Required Configuration

Agent instruction: Before generating any file, collect the values below from the user.

Step 0 — Determine use case: Ask the user whether they want a sample app (full scaffold including package.json, vite.config.js, index.html, CSS, navigation, and styled views) or existing app integration (only SDK integration files: constants, context, hook, form, callbacks, protected route). This affects what files are generated in later steps.

Ask for all required parameters up front in a single prompt. For optional parameters, show the default and ask whether the user wants to override it. Do not proceed to Step 1 until every required parameter has a non-empty value.

Parameters to collect
ParameterRequiredDefaultDescription
wellknownUrlYes—Full OIDC well-known endpoint URL (e.g., https://your-tenant.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration)
clientIdYes—OAuth 2.0 Client ID registered in PingAM / AIC for this web app
scopeYesopenid profile emailSpace-separated OAuth 2.0 scopes to request
redirectUriNohttp://localhost:<appPort>/callback.htmlOAuth 2.0 redirect URI registered in PingAM / AIC
journeyLoginNoLoginName of the login Journey/Tree to invoke
journeyRegisterNoRegistrationName of the registration Journey/Tree to invoke
appPortNo8443Local development server port
Suggested prompts
Before I get started, I want to confirm — are you wanting me to help you create a sample app or
integrate with your existing single-page app?

Before I generate the files, I need a few details about your PingAM / AIC setup:

1. Well-known URL     — What is your OIDC well-known endpoint URL?
                        e.g. https://your-tenant.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration
2. Client ID          — What is the OAuth 2.0 Client ID for this web app?
3. Scopes             — Which OAuth 2.0 scopes? (default: openid profile email)
4. Redirect URI       — What is the redirect URI? (default: http://localhost:8443/callback.html)
5. Login Journey      — Which Journey/Tree for login? (default: Login)
6. Register Journey   — Which Journey/Tree for registration? (default: Registration)
7. App Port           — Which port for local dev? (default: 8443)
Validation rules
  • wellknownUrl must start with https:// and end with /.well-known/openid-configuration.
  • clientId must be non-empty.
  • If scope does not include openid, prepend it automatically and warn the user.
  • redirectUri must be a valid URL starting with https:// or http://localhost.
  • If the user provides redirectUri with a port that differs from appPort, warn the user — they likely need to match.
Well-known URL construction guidance

Agent instruction: Users often provide a base AM URL (e.g., https://your-tenant.forgeblocks.com/am) instead of the full well-known URL. If the provided URL does not end with /.well-known/openid-configuration:

  1. Ask the user which realm they are using (commonly alpha or bravo for AIC).
  2. Construct the well-known URL as: <baseUrl>/oauth2/<realm>/.well-known/openid-configuration
  3. Strip any trailing / from the base URL before construction.
  4. Confirm the constructed URL with the user before proceeding.

Example:

  • User provides: https://openam-myco.forgeblocks.com/am
  • Agent asks: "Which realm? (commonly alpha or bravo)"
  • User says: alpha
  • Agent constructs: https://openam-myco.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration
  • Agent confirms: "I'll use this as your well-known URL — does that look correct?"

Implementation Steps

Step 1 — Configure Environment Variables

Create a .env file in the project root. See .env template.

Also add a .gitignore to keep secrets and build artifacts out of version control. See .gitignore template.

Agent instruction: Substitute all <parameter> placeholders with values collected above.

VITE_WELLKNOWN_URL=<wellknownUrl>
VITE_WEB_OAUTH_CLIENT=<clientId>
VITE_SCOPE=<scope>
VITE_PORT=<appPort>
VITE_JOURNEY_LOGIN=<journeyLogin>
VITE_JOURNEY_REGISTER=<journeyRegister>
VITE_REDIRECT_URI=<redirectUri>
VITE_DEBUGGER_OFF=true

Step 2 — Create the Configuration Constants

Create constants.js to centralize SDK configuration. See constants.js template.

The SDK configuration requires only the wellknown URL — the Journey client automatically derives the baseUrl, authenticate, and sessions endpoints from the well-known document.

export const WELLKNOWN_URL = import.meta.env.VITE_WELLKNOWN_URL;
export const WEB_OAUTH_CLIENT = import.meta.env.VITE_WEB_OAUTH_CLIENT;
export const SCOPE = import.meta.env.VITE_SCOPE;
export const REDIRECT_URI = import.meta.env.VITE_REDIRECT_URI || `${window.location.origin}/callback.html`;

export const CONFIG = {
  clientId: WEB_OAUTH_CLIENT,
  redirectUri: REDIRECT_URI,
  scope: SCOPE,
  serverConfig: {
    wellknown: WELLKNOWN_URL,
  },
};

Note: VITE_REDIRECT_URI allows the redirect URI to be configured via environment variable. If omitted, it defaults to ${window.location.origin}/callback.html. This is important because local development may use http:// while production uses https://, and the redirect URI must exactly match what is registered in PingAM / AIC.

See the @forgerock/journey-client section in SDK Package Reference for all configuration options.


Step 3 — Create the OIDC Context Provider

Create oidc.context.js to manage authentication state across the application. See oidc.context.js template.

The OIDC context:

  • Initializes the OIDC client on app mount
  • Checks for existing tokens (session persistence)
  • Provides isAuthenticated, oidcClient, and user info to all components
  • Handles logout by revoking tokens and clearing state
import { createContext } from 'react';
import { oidc } from '@forgerock/oidc-client';

export const OidcContext = createContext();

export function useInitOidcState(config) {
  // Initialize OIDC client and check for existing session
  // Returns [state, methods] for context consumption
}

See the @forgerock/oidc-client section in SDK Package Reference and the full OIDC Centralized Reference for API documentation.


Step 4 — Create the Journey Hook

Create journey.hook.js — the core custom hook that manages the Journey authentication flow. See journey.hook.js template.

Key responsibilities:

  • Initializes the Journey client with the shared CONFIG
  • Starts a new Journey (or resumes after redirect)
  • Handles step submission and advances to the next node
  • On LoginSuccess, exchanges the session for OAuth tokens via the OIDC client
  • On LoginFailure, extracts the error message and restarts the Journey
  • Returns the current step for rendering and methods for form submission
import { journey, callbackType } from '@forgerock/journey-client';

export default function useJourney({ formMetadata, resumeUrl }) {
  // Returns [state, methods]
  // state: { formFailureMessage, renderStep, submittingForm, user }
  // methods: { setSubmissionStep, setSubmittingForm, redirect }
}

See the @forgerock/journey-client section in SDK Package Reference for client API details.


Step 5 — Create the Journey Form Component

Create form.jsx — the main form component that renders the current Journey step's callbacks. See form.jsx template.

The form:

  • Uses useJourney to obtain the current step and submission methods
  • Maps each callback in the step to its corresponding React component
  • Handles form submission by setting the submission step
  • Navigates away on LoginSuccess
import { callbackType } from '@forgerock/journey-client';

export default function Form({ action, followUp, topMessage }) {
  // Maps callbacks to components and handles form lifecycle
}

See the callback assets in this skill's assets/ directory for the full list of supported callback implementations.


Step 6 — Create Callback Components

Create individual React components for each callback type. See callback component templates.

All callback types supported by @forgerock/journey-client:

Callback TypeComponentDescription
NameCallbackTextText input for username
ValidatedCreateUsernameCallbackTextValidated username input with policy enforcement
StringAttributeInputCallbackTextGeneric string attribute (email, name, etc.)
TextInputCallbackTextInputGeneric text input field
PasswordCallbackPasswordPassword input with visibility toggle
ValidatedCreatePasswordCallbackPasswordValidated password input with policy enforcement
BooleanAttributeInputCallbackBooleanCheckbox toggle for boolean attributes
NumberAttributeInputCallbackNumberInputNumeric input for number attributes
ChoiceCallbackChoiceSingle-selection dropdown
ConfirmationCallbackConfirmationAction options (Submit / Cancel)
SelectIdPCallbackSelectIdPSocial / external Identity Provider selection
KbaCreateCallbackKbaSecurity question & answer
TermsAndConditionsCallbackTermsConditionsTerms acceptance checkbox
TextOutputCallbackTextOutputDisplay server messages (info, warning, error)
SuspendedTextOutputCallbackSuspendedTextOutputSuspended journey message (magic link / email verification)
PollingWaitCallbackPollingWaitAuto-advancing wait step (no user interaction)
RedirectCallbackRedirectBrowser redirect for external auth (social login, SAML)
DeviceProfileCallbackDeviceProfileAuto-collects device metadata and submits
HiddenValueCallbackHiddenValueNon-visual — carries internal state between client/server
MetadataCallbackMetadataNon-visual — carries server metadata to client
ReCaptchaCallbackReCaptchaGoogle reCAPTCHA v2 widget
ReCaptchaEnterpriseCallbackReCaptchaEnterpriseGoogle reCAPTCHA Enterprise widget
PingOneProtectInitializeCallbackProtectInitializeInitializes PingOne Protect threat signal collection
PingOneProtectEvaluationCallbackProtectEvaluationCollects and submits PingOne Protect threat signals
WebAuthn (FIDO2)WebAuthnComponentFIDO2/Passkey registration & authentication

Each component follows this pattern:

  1. Get display values from the callback (e.g., callback.getPrompt())
  2. Render an appropriate form element
  3. Set user input back on the callback (e.g., callback.setInputValue(value))

Note: Auto-advancing callbacks (PollingWaitCallback, DeviceProfileCallback, RedirectCallback, ReCaptchaCallback, ReCaptchaEnterpriseCallback, PingOneProtectInitializeCallback, PingOneProtectEvaluationCallback) do not require user interaction — they automatically submit the step after completing their operation.


Step 7 — Create the Login and Register Views

Create login.jsx and register.jsx views. See login.jsx template and register.jsx template.

// login.jsx — Renders the Form component with the login journey
export default function Login() {
  return <Form action={{ type: 'login' }} />;
}

// register.jsx — Renders the Form component with the registration journey
export default function Register() {
  return <Form action={{ type: 'register' }} />;
}

Step 8 — Create the Logout View

Create logout.jsx. See logout.jsx template.

Logout uses the OIDC context to revoke tokens and clear the session:

import { useContext, useEffect } from 'react';
import { OidcContext } from '../context/oidc.context';

export default function Logout() {
  const [, { setAuthentication }] = useContext(OidcContext);
  useEffect(() => { setAuthentication(false); }, []);
  return <p>Logging out...</p>;
}

Step 9 — Create Protected Route and Router

Create a ProtectedRoute component and the app router. See route.jsx template and router.jsx template.

// Protected route — redirects to /login if not authenticated
export function ProtectedRoute({ children }) {
  const [{ isAuthenticated }] = useContext(OidcContext);
  return isAuthenticated ? children : <Navigate to="/login" />;
}

Step 10 — Create the Application Entry Point

Create index.jsx to bootstrap the app with context providers. See index.jsx template.

import { OidcContext, useInitOidcState } from './context/oidc.context';
import { CONFIG } from './constants';

function App() {
  const oidcState = useInitOidcState(CONFIG);
  return (
    <OidcContext.Provider value={oidcState}>
      <Router />
    </OidcContext.Provider>
  );
}

Step 11 — Create the OAuth Callback Page

Create callback.html in the public/ directory to handle OAuth redirect responses. See callback.html template.

This static HTML page captures the code and state parameters from the OAuth redirect and passes them back to the SPA.


Steps 12–14 — Sample App Only (Profile, Navigation, Router)

Agent instruction: Only execute these steps when the user chose Sample Application mode or explicitly requests a profile page, navbar, or full router wiring.

Follow the full instructions in references/sample-app-guide.md:

  • Step 12 — Create profile.jsx using oidcClient.user.info(), userinfo claims table, edit modal pattern
  • Step 13 — Create Navbar component, CSS stylesheet, themed Home view
  • Step 14 — Wire router.jsx with all protected and public routes

Scaffolding Script

For quick setup, use the scaffolding script to copy all template files into your project:

chmod +x scripts/scaffold_auth.sh
./scripts/scaffold_auth.sh \
    --project-dir ./my-react-app \
    --journey Login

See scaffold_auth.sh for details.


Common Mistakes

MistakeFix
CORS not configuredEnsure your PingAM / AIC tenant allows your app origin, methods, and headers
Missing openid scopeAlways include openid — required for OIDC token exchange
Wrong well-known URLMust end with /.well-known/openid-configuration and include the correct realm. Users often provide just the base AM URL — ask for the realm and construct the full URL.
Using base AM URL instead of well-known URLIf the user provides https://tenant.forgeblocks.com/am, ask which realm (alpha/bravo) and construct: <baseUrl>/oauth2/<realm>/.well-known/openid-configuration
Unhandled callback typeAdd a case in the mapCallbacksToComponents function for every callback your Journey uses
Not calling callback.setInputValue()Always set callback values before submitting the step — the SDK sends the values you set
Redirect URI mismatchThe redirectUri in your config must exactly match the one registered in PingAM / AIC — including protocol (http vs https) and port number
Redirect URI port vs app port mismatchIf the user specifies redirectUri on port 8443 but appPort on 8444 (or vice versa), warn them — these must match for the OAuth flow to work
Mixed HTTP/HTTPSThe SDK requires HTTPS in production; for local dev, http://localhost is acceptable if the OAuth client in AIC is configured with an http://localhost redirect URI
Token exchange before LoginSuccessOnly call oidcClient.authorize.background() after the Journey returns a LoginSuccess step
Not handling LoginFailureAlways check for LoginFailure after client.next() — restart the journey and display the error
Calling client.next() without setting callbacksAlways populate callback values before advancing to the next step
Importing oidc in constants.jsThe constants file only exports configuration — it does not import or use @forgerock/oidc-client directly. The OIDC client is initialized in oidc.context.js.
Not generating styles.css for sample appsSample apps need a stylesheet for form fields, buttons, layouts, and modals. Always create client/styles.css and import it in index.jsx.
Forgetting callback.html in public/The OAuth callback page must be a static HTML file in the public/ directory, not a React route. Without it, the OAuth redirect will fail with a blank page.

Reference Documentation

  • SDK Package Reference — Package selection guide for @forgerock/journey-client, @forgerock/oidc-client, and optional add-ons
  • OIDC Centralized Reference — Full @forgerock/oidc-client API: authorize, token exchange, user info, logout, storage
  • Callback implementations — see template files in assets/ (e.g. text.jsx.template, password.jsx.template, boolean.jsx.template, webauthn.jsx.template)

Related Skills

  • ping-orchestration-javascript-sdk — JavaScript umbrella skill (routes Journey/DaVinci/OIDC, delegates here for Journey flows)
  • ping-orchestration-android-sdk — Android (Kotlin/Jetpack Compose) equivalent
  • ping-orchestration-ios-sdk — iOS (Swift/SwiftUI) equivalent

Comments

Markdown supported