Advanced Identity Cloud/PingAM Login Widget

Breaking changes

This page summarizes breaking changes to the Advanced Identity Cloud/PingAM Login Widget, and how to migrate an existing integration past each one.

Advanced Identity Cloud/PingAM Login Widget 2.x

Advanced Identity Cloud/PingAM Login Widget 2.x introduces breaking changes to configuration, module dependencies, and the public API. This section summarizes what changed, why it changed, and how to migrate an existing 1.x integration.

Summary of changes

  • Configuration is now driven by a single async configure() function; the synchronous configuration() + .set() pattern is removed.

  • Endpoint discovery is now driven by the serverConfig.wellknown property, that is shared by the Journey and OIDC clients.

  • The nested forgerock config object is replaced by a flat, top-level shape with an oidcClient sub-object.

  • The request export, an alias to the legacy HttpClient.request, is removed.

  • Underlying dependencies have moved: OAuth/OIDC is now backed by @forgerock/oidc-client, PingOne Protect is backed by @forgerock/protect, and @forgerock/javascript-sdk is no longer a dependency of the widget.

Migration checklist

  1. Rename the configuration import to configure.

  2. Replace calls to configuration() and .set() with a single await configure({...}).

  3. Ensure your endpoint discovery URL property wellknown is inside the serverConfig property.

    1. Remove any other properties from serverConfig, such as baseUrl, timeout, realmPath, tree, and any paths overrides.

  4. Wrap clientId, redirectUri, and scope in a new oidcClient sub-object.

    1. Add the oidcClient sub-object if you use OAuth/OIDC tokens, user info, or logout.

  5. Remove any calls to the request export. Fetch tokens from user.tokens().get() and call fetch yourself.

  6. Remove platformHeader, which has no replacement.

  7. await the returned promise before calling any other Widget API. journey().start(), user.info().get(), and user.tokens().get() all fail if called before configure() resolves.

Before and after

Configuration

Before (1.x)
import Widget, { configuration } from '@forgerock/login-widget';

const myConfig = configuration();

myConfig.set({
  forgerock: {
    serverConfig: {
      baseUrl: 'https://openam-forgerock-sdks.forgeblocks.com/am/',
      timeout: 3000,
    },
    clientId: 'sdkPublicClient',
    realmPath: 'alpha',
    redirectUri: window.location.href,
    scope: 'openid profile email address',
  },
});
After (2.x)
import '@forgerock/login-widget/widget.css';
import Widget, { configure } from '@forgerock/login-widget';

// configure() is async, so await it before any other Widget API
await configure({
  serverConfig: {
    wellknown: 'https://openam-forgerock-sdks.forgeblocks.com/am/oauth2/realms/root/realms/alpha/.well-known/openid-configuration',
  },
  oidcClient: {
    clientId: 'sdkPublicClient',
    redirectUri: `${window.location.origin}/callback`,
    scope: 'openid profile email address',
  },
});

Starting a journey after configuration

Before (1.x)
import Widget, { configuration, journey } from '@forgerock/login-widget';

const myConfig = configuration();
myConfig.set({ forgerock: { /* ... */ } });

new Widget({ target: document.getElementById('widget-root') });

const journeyEvents = journey();
journeyEvents.start();
After (2.x)
import Widget, { configure, journey } from '@forgerock/login-widget';

await configure({
  serverConfig: {
    wellknown: 'https://openam-forgerock-sdks.forgeblocks.com/am/oauth2/realms/root/realms/alpha/.well-known/openid-configuration',
  },
  oidcClient: { /* ... */ },
});

new Widget({ target: document.getElementById('widget-root') });

journey().start();

Calling a protected resource

Before (1.x)
import { request } from '@forgerock/login-widget';

const response = await request({
  init: { method: 'GET' },
  url: 'https://protected.resource.com',
});
After (2.x)
import { user } from '@forgerock/login-widget';

const { response: tokens } = await user.tokens().get();

const response = await fetch('https://protected.resource.com', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${tokens.accessToken}`,
  },
});

The legacy request alias automatically refreshed the access token on a 401 response and parsed Identity Gateway policy advice.

Neither behavior is provided by the Advanced Identity Cloud/PingAM Login Widget 2.x or @forgerock/oidc-client.

If your app depends on these, you must implement them at the consumer level.

Custom endpoint paths

The following properties are all removed in 2.x. Every endpoint is now discovered from serverConfig.wellknown.

  • serverConfig.paths.authenticate

  • serverConfig.paths.authorize

  • serverConfig.paths.accessToken

  • serverConfig.paths.revoke

  • serverConfig.paths.userInfo

  • serverConfig.paths.sessions

  • serverConfig.paths.endSession

If your deployment does not expose a standard .well-known/openid-configuration document, you must add one before upgrading to 2.x.

Important changes

The following table highlights some important differences between 1.x and 2.x.

Changes between Advanced Identity Cloud/PingAM Login Widget 1.x and 2.x
Property Notes

request (module export)

Use user.tokens().get() plus a manual fetch call.

serverConfig.paths.*

All seven per-endpoint overrides are gone.

realmPath, tree

The realm is encoded in the wellknown URL path.

The tree option was inherited from the Ping Orchestration SDK for JavaScript and is not a widget concept.

tokenStore, prefix

Changed in 2.x to be the top-level storage option (storage.type, storage.name, storage.prefix).

logLevel

Changed in 2.x to be the top-level logger option (logger.level, logger.custom).

platformHeader

Not currently configurable in the widget.

pingProtect (as a journey().start() parameter)

Initialize PingOne Signals separately via protect.start().

Tutorial

Updated for 2.x.

API reference

Updated for 2.x.