Orchestration SDKs

Step 2. Authenticating with external IdPs

PingOne JavaScript

Your app must handle the relevant node types your server returns when a user attempts to authenticate using an external IdP.

A DaVinci flow returns an IdpCollector to the client, which contains details about the external IdP the user chose for authentication.

Handling external IdP nodes in DaVinci flows

When encountering a IdpCollector collector in a DaVinci flow, use the externalIdp() method to obtain the details from the collector:

Calling externalIdp to authenticate users with an external IdP
const collectors = davinciClient.getCollectors();

collectors.forEach((collector) => {
  if (collector.type === 'IdpCollector') {
    socialLoginButtonComponent(formEl, collector, davinciClient.externalIdp());
  }
}

In this example, a socialLoginButtonComponent handles rendering the button and redirecting the user to the selected identity provider:

Example social-login-button.ts file to render social sign-on buttons
import type { IdpCollector } from "@forgerock/davinci-client/types";

export default function socialLoginButtonComponent(
  formEl: HTMLFormElement,
  collector: IdpCollector,
  updater: () => void
) {
  const button = document.createElement("button");

  button.value = collector.output.label;
  button.innerHTML = collector.output.label;

  if (collector.output.label.toLowerCase().includes('google')) {
    button.style.background = 'white'
    button.style.borderColor = 'grey'
  } else if (collector.output.label.toLowerCase().includes('facebook')) {
    button.style.color = 'white'
    button.style.background = 'royalblue'
    button.style.borderColor = 'royalblue'
  } else if (collector.output.label.toLowerCase().includes('apple')) {
    button.style.color = 'white'
    button.style.background = 'black'
    button.style.borderColor = 'black'
  }

  button.onclick = async () => {
    await updater();
    window.location.assign(collector.output.url);
  };

  formEl?.appendChild(button);
}

After authenticating with the external IdP, they return to PingOne. PingOne generates a continueToken and attaches it as a query parameter to the URL that redirects back to the JavaScript client.

You must configure your JavaScript app to continue a flow on receipt of the continueToken.

Use the resume() method to continue an existing flow, rather than start a new one:

Continuing an existing DaVinci flow by using a continueToken
const davinciClient = await davinci({ config });
const urlParams = new URLSearchParams(window.location.search);
const continueToken = urlParams.get('continueToken');
let resumeNode;

if (continueToken) {
  // Continue an existing flow
  resumeNode = await davinciClient.resume({ continueToken });
} else {
  // Setup configuration for a new flow
  await Config.setAsync(config);
}