Skip to content

Latest commit

 

History

History
1141 lines (910 loc) · 105 KB

File metadata and controls

1141 lines (910 loc) · 105 KB
document interface_mapping
version 1.0
last_updated 2026-04-24
legacy_sdk @forgerock/javascript-sdk
legacy_source .opensource/forgerock-javascript-sdk/packages/javascript-sdk/src
new_packages
journey oidc sdk-oidc device protect types utilities logger storage middleware iframe-manager
@forgerock/journey-client
@forgerock/oidc-client
@forgerock/sdk-oidc
@forgerock/device-client
@forgerock/protect
@forgerock/sdk-types
@forgerock/sdk-utilities
@forgerock/sdk-logger
@forgerock/storage
@forgerock/sdk-request-middleware
@forgerock/sdk-effects/iframe-manager

Interface Mapping: Legacy SDK → Ping SDK

This document maps every public interface from the legacy @forgerock/javascript-sdk to its equivalent in the new Ping SDK. It is designed for both human developers performing migrations and AI coding assistants needing structured context for automated refactoring.

Table of Contents

  1. Quick Reference
  2. Package Mapping
  3. Configuration
  4. Authentication Flow
  5. Step Types
  6. Callbacks
  7. Callback Type Enum
  8. Token Management
  9. OAuth2 Client
  10. User Management
  11. Session Management
  12. HTTP Client
  13. WebAuthn
  14. QR Code
  15. Recovery Codes
  16. Policy
  17. Device
  18. Protect
  19. Error Handling Patterns
  20. Type Exports
  21. Removed / Deprecated APIs

Import Principle

Consumers should only import from *-client packages. Internal packages like @forgerock/sdk-types, @forgerock/sdk-logger, @forgerock/sdk-request-middleware, and @forgerock/storage are implementation details. All consumer-facing types are re-exported through the client packages:

  • Journey types: import type { Step, Callback, ... } from '@forgerock/journey-client/types'
  • Journey values: import { journey, callbackType, PolicyKey } from '@forgerock/journey-client'
  • OIDC types: import type { OidcClient, ResponseType, ... } from '@forgerock/oidc-client/types'
  • OIDC client: import { oidc } from '@forgerock/oidc-client'
  • Device client: import { deviceClient } from '@forgerock/device-client'

If you find a type you need that isn't re-exported from a client package, file an issue - it should be.


0. Quick Reference

Flat lookup table for AI context injection. Every legacy symbol → new import in one line.

Legacy Symbol New SDK Equivalent
AuthResponse import type { AuthResponse } from '@forgerock/journey-client/types'
Callback import type { Callback } from '@forgerock/journey-client/types' — AM callback interface
ConfigOptions Removed — use factory params on journey() / oidc() instead
FailureDetail import type { FailureDetail } from '@forgerock/journey-client/types'
FRCallbackFactory Removed — custom callback factories not supported
FRStepHandler Removed — step handling is internal to JourneyClient
GetAuthorizationUrlOptions import type { GetAuthorizationUrlOptions } from '@forgerock/oidc-client/types'
GetOAuth2TokensOptions Removed — use oidcClient.token.get() params instead
GetTokensOptions Removed — use oidcClient.token.get() params instead
IdPValue import type { IdPValue } from '@forgerock/journey-client/types'
LoggerFunctions Removed — use CustomLogger from @forgerock/sdk-logger instead
MessageCreator import type { MessageCreator } from '@forgerock/journey-client/policy'
NameValue import type { NameValue } from '@forgerock/journey-client/types'
OAuth2Tokens import type { OauthTokens } from '@forgerock/oidc-client/types' — renamed to OauthTokens
PolicyRequirement import type { PolicyRequirement } from '@forgerock/journey-client/types'
ProcessedPropertyError import type { ProcessedPropertyError } from '@forgerock/journey-client/policy'
RelyingParty import type { RelyingParty } from '@forgerock/journey-client/webauthn'
Step import type { Step } from '@forgerock/journey-client/types' — AM step response interface
StepDetail import type { StepDetail } from '@forgerock/journey-client/types'
Tokens import type { Tokens } from '@forgerock/journey-client/types'
ValidConfigOptions Removed — config is encapsulated in client instances
WebAuthnAuthenticationMetadata import type { WebAuthnAuthenticationMetadata } from '@forgerock/journey-client/webauthn'
WebAuthnCallbacks import type { WebAuthnCallbacks } from '@forgerock/journey-client/webauthn'
WebAuthnRegistrationMetadata import type { WebAuthnRegistrationMetadata } from '@forgerock/journey-client/webauthn'
defaultMessageCreator Not exported — internal to @forgerock/journey-client/policy
AttributeInputCallback import { AttributeInputCallback } from '@forgerock/journey-client/types'
Auth Removed — no replacement needed
CallbackType import { callbackType } from '@forgerock/journey-client'
ChoiceCallback import { ChoiceCallback } from '@forgerock/journey-client/types'
Config Removed — pass config to journey() / oidc() factory params
ConfirmationCallback import { ConfirmationCallback } from '@forgerock/journey-client/types'
Deferred Removed — use native Promise constructor
deviceClient import { deviceClient } from '@forgerock/device-client'
DeviceProfileCallback import { DeviceProfileCallback } from '@forgerock/journey-client/types'
ErrorCode Removed — use GenericError.type instead
FRAuth import { journey } from '@forgerock/journey-client' — factory returns JourneyClient
FRCallback import { BaseCallback } from '@forgerock/journey-client/types'
FRDevice import { deviceClient } from '@forgerock/device-client'
FRLoginFailure import type { JourneyLoginFailure } from '@forgerock/journey-client/types'
FRLoginSuccess import type { JourneyLoginSuccess } from '@forgerock/journey-client/types'
FRPolicy import { Policy } from '@forgerock/journey-client/policy'
FRQRCode import { QRCode } from '@forgerock/journey-client/qr-code'
FRRecoveryCodes import { RecoveryCodes } from '@forgerock/journey-client/recovery-codes'
FRStep import type { JourneyStep } from '@forgerock/journey-client/types'
FRUser import { oidc } from '@forgerock/oidc-client'oidcClient.user.logout()
FRWebAuthn import { WebAuthn } from '@forgerock/journey-client/webauthn'
HiddenValueCallback import { HiddenValueCallback } from '@forgerock/journey-client/webauthn'
HttpClient Removed — use fetch + manual Authorization header
KbaCreateCallback import { KbaCreateCallback } from '@forgerock/journey-client/types'
LocalStorage Removed — use @forgerock/storage or native APIs
MetadataCallback import { MetadataCallback } from '@forgerock/journey-client/webauthn'
NameCallback import { NameCallback } from '@forgerock/journey-client/types'
OAuth2Client import { oidc } from '@forgerock/oidc-client'oidcClient.authorize.* / oidcClient.token.*
PasswordCallback import { PasswordCallback } from '@forgerock/journey-client/types'
PingOneProtectEvaluationCallback import { PingOneProtectEvaluationCallback } from '@forgerock/journey-client/types'
PingOneProtectInitializeCallback import { PingOneProtectInitializeCallback } from '@forgerock/journey-client/types'
PKCE Removed — handled internally by @forgerock/oidc-client
PolicyKey import { PolicyKey } from '@forgerock/journey-client'
PollingWaitCallback import { PollingWaitCallback } from '@forgerock/journey-client/types'
ReCaptchaCallback import { ReCaptchaCallback } from '@forgerock/journey-client/types'
ReCaptchaEnterpriseCallback import { ReCaptchaEnterpriseCallback } from '@forgerock/journey-client/types'
RedirectCallback import { RedirectCallback } from '@forgerock/journey-client/types'
ResponseType import type { ResponseType } from '@forgerock/oidc-client/types'
SelectIdPCallback import { SelectIdPCallback } from '@forgerock/journey-client/types'
SessionManager journeyClient.terminate() — method on JourneyClient, not a standalone import
StepOptions Removed — per-call config overrides removed; use factory params
StepType import type { StepType } from '@forgerock/journey-client/types'
SuspendedTextOutputCallback import { SuspendedTextOutputCallback } from '@forgerock/journey-client/types'
TermsAndConditionsCallback import { TermsAndConditionsCallback } from '@forgerock/journey-client/types'
TextInputCallback import { TextInputCallback } from '@forgerock/journey-client/types'
TextOutputCallback import { TextOutputCallback } from '@forgerock/journey-client/webauthn'
TokenManager import { oidc } from '@forgerock/oidc-client'oidcClient.token.*
TokenStorage import { oidc } from '@forgerock/oidc-client'oidcClient.token.*
UserManager import { oidc } from '@forgerock/oidc-client'oidcClient.user.info()
ValidatedCreatePasswordCallback import { ValidatedCreatePasswordCallback } from '@forgerock/journey-client/types'
ValidatedCreateUsernameCallback import { ValidatedCreateUsernameCallback } from '@forgerock/journey-client/types'
WebAuthnOutcome Not exported — internal to webauthn module
WebAuthnOutcomeType Not exported — internal to webauthn module
WebAuthnStepType import { WebAuthnStepType } from '@forgerock/journey-client/webauthn'
@forgerock/ping-protect @forgerock/protect — PingOne Protect/Signals integration

1. Package Mapping

The legacy SDK is a single package. The new SDK splits concerns across multiple focused packages.

Legacy Import New Import Notes
import type { AuthResponse } from '@forgerock/javascript-sdk' import type { AuthResponse } from '@forgerock/journey-client/types' AuthResponse
import type { Callback } from '@forgerock/javascript-sdk' import type { Callback } from '@forgerock/journey-client/types' Callback
import type { FailureDetail } from '@forgerock/javascript-sdk' import type { FailureDetail } from '@forgerock/journey-client/types' FailureDetail
import type { GetAuthorizationUrlOptions } from '@forgerock/javascript-sdk' import type { GetAuthorizationUrlOptions } from '@forgerock/oidc-client/types' GetAuthorizationUrlOptions
import type { IdPValue } from '@forgerock/javascript-sdk' import type { IdPValue } from '@forgerock/journey-client/types' IdPValue
import type { MessageCreator } from '@forgerock/javascript-sdk' import type { MessageCreator } from '@forgerock/journey-client/policy' MessageCreator
import type { NameValue } from '@forgerock/javascript-sdk' import type { NameValue } from '@forgerock/journey-client/types' NameValue
import type { OAuth2Tokens } from '@forgerock/javascript-sdk' import type { OauthTokens } from '@forgerock/oidc-client/types' OAuth2Tokens
import type { PolicyRequirement } from '@forgerock/javascript-sdk' import type { PolicyRequirement } from '@forgerock/journey-client/types' PolicyRequirement
import type { ProcessedPropertyError } from '@forgerock/javascript-sdk' import type { ProcessedPropertyError } from '@forgerock/journey-client/policy' ProcessedPropertyError
import type { RelyingParty } from '@forgerock/javascript-sdk' import type { RelyingParty } from '@forgerock/journey-client/webauthn' RelyingParty
import type { Step } from '@forgerock/javascript-sdk' import type { Step } from '@forgerock/journey-client/types' Step
import type { StepDetail } from '@forgerock/javascript-sdk' import type { StepDetail } from '@forgerock/journey-client/types' StepDetail
import type { Tokens } from '@forgerock/javascript-sdk' import type { Tokens } from '@forgerock/journey-client/types' Tokens
import type { WebAuthnAuthenticationMetadata } from '@forgerock/javascript-sdk' import type { WebAuthnAuthenticationMetadata } from '@forgerock/journey-client/webauthn' WebAuthnAuthenticationMetadata
import type { WebAuthnCallbacks } from '@forgerock/javascript-sdk' import type { WebAuthnCallbacks } from '@forgerock/journey-client/webauthn' WebAuthnCallbacks
import type { WebAuthnRegistrationMetadata } from '@forgerock/javascript-sdk' import type { WebAuthnRegistrationMetadata } from '@forgerock/journey-client/webauthn' WebAuthnRegistrationMetadata
import { CallbackType } from '@forgerock/javascript-sdk' import { callbackType } from '@forgerock/journey-client' CallbackType
import { deviceClient } from '@forgerock/javascript-sdk' import { deviceClient } from '@forgerock/device-client' deviceClient
import { FRAuth } from '@forgerock/javascript-sdk' import { journey } from '@forgerock/journey-client' FRAuth
import { FRCallback } from '@forgerock/javascript-sdk' import { BaseCallback } from '@forgerock/journey-client/types' FRCallback
import { FRDevice } from '@forgerock/javascript-sdk' import { deviceClient } from '@forgerock/device-client' FRDevice
import type { FRLoginFailure } from '@forgerock/javascript-sdk' import type { JourneyLoginFailure } from '@forgerock/journey-client/types' FRLoginFailure
import type { FRLoginSuccess } from '@forgerock/javascript-sdk' import type { JourneyLoginSuccess } from '@forgerock/journey-client/types' FRLoginSuccess
import { FRPolicy } from '@forgerock/javascript-sdk' import { Policy } from '@forgerock/journey-client/policy' FRPolicy
import { FRQRCode } from '@forgerock/javascript-sdk' import { QRCode } from '@forgerock/journey-client/qr-code' FRQRCode
import { FRRecoveryCodes } from '@forgerock/javascript-sdk' import { RecoveryCodes } from '@forgerock/journey-client/recovery-codes' FRRecoveryCodes
import type { FRStep } from '@forgerock/javascript-sdk' import type { JourneyStep } from '@forgerock/journey-client/types' FRStep
import { FRUser } from '@forgerock/javascript-sdk' import { oidc } from '@forgerock/oidc-client' FRUser
import { FRWebAuthn } from '@forgerock/javascript-sdk' import { WebAuthn } from '@forgerock/journey-client/webauthn' FRWebAuthn
import { OAuth2Client } from '@forgerock/javascript-sdk' import { oidc } from '@forgerock/oidc-client' OAuth2Client
import { PolicyKey } from '@forgerock/javascript-sdk' import { PolicyKey } from '@forgerock/journey-client' PolicyKey
import type { ResponseType } from '@forgerock/javascript-sdk' import type { ResponseType } from '@forgerock/oidc-client/types' ResponseType
import type { StepType } from '@forgerock/javascript-sdk' import type { StepType } from '@forgerock/journey-client/types' StepType
import { TokenManager } from '@forgerock/javascript-sdk' import { oidc } from '@forgerock/oidc-client' TokenManager
import { TokenStorage } from '@forgerock/javascript-sdk' import { oidc } from '@forgerock/oidc-client' TokenStorage
import { UserManager } from '@forgerock/javascript-sdk' import { oidc } from '@forgerock/oidc-client' UserManager
import { WebAuthnStepType } from '@forgerock/javascript-sdk' import { WebAuthnStepType } from '@forgerock/journey-client/webauthn' WebAuthnStepType

2. Configuration

Architecture Change

Aspect Legacy New
Pattern Global static Config.set(options) Per-client config via factory function params
Discovery Manual serverConfig.baseUrl + optional paths Automatic via serverConfig.wellknown endpoint
Scope Shared global state Each client instance independently configured
Async Config.set() is sync; Config.setAsync() is async Factory functions (journey(), oidc()) are always async

Config Class Methods

Legacy API New API Return Type Change Behavioral Notes
Config.set(options: ConfigOptions): void journey({ config }) / oidc({ config }) voidPromise<JourneyClient> / Promise<OidcClient> Config is passed as factory param, not set globally. OidcClient type available from @forgerock/oidc-client
Config.setAsync(options: AsyncConfigOptions): Promise<void> journey({ config }) / oidc({ config }) Same Wellknown is now the default and only discovery path
Config.get(options?: ConfigOptions): ValidConfigOptions No equivalent Config is encapsulated in the client instance; not retrievable externally

ConfigOptions Property Mapping

Legacy Property Journey Client OIDC Client Notes
serverConfig.baseUrl: string Derived from serverConfig.wellknown Derived from serverConfig.wellknown No longer manually specified
serverConfig.paths?: CustomPathConfig Removed Removed Option removed; paths are discovered automatically via wellknown
serverConfig.timeout?: number Accepted but ignored (warning logged) serverConfig.timeout?: number Only used by oidc-client
serverConfig.wellknown?: string (AsyncServerConfig) serverConfig.wellknown: string (required) serverConfig.wellknown: string (required) Now the primary and only server config
clientId?: string Accepted but ignored (warning logged) clientId: string (required) Only needed for OIDC operations
redirectUri?: string Accepted but ignored (warning logged) redirectUri: string (required) Only needed for OIDC operations
scope?: string Accepted but ignored (warning logged) scope: string (required) Only needed for OIDC operations
realmPath?: string Derived from wellknown URL Derived from wellknown URL No longer manually specified
tree?: string Passed to journeyClient.start({ journey: 'treeName' }) N/A Tree specified per-call, not in config
tokenStore?: TokenStoreObject | 'sessionStorage' | 'localStorage' Accepted but ignored storage?: Partial<StorageConfig> param on oidc() Storage config is a separate factory param
middleware?: RequestMiddleware[] requestMiddleware?: RequestMiddleware[] param on journey() requestMiddleware?: RequestMiddleware[] param on oidc() Separate factory param, not in config object
callbackFactory?: FRCallbackFactory Accepted but ignored (warning logged) N/A Custom callback factories not supported
oauthThreshold?: number Accepted but ignored oauthThreshold?: number in OidcConfig Default: 30000ms (30 seconds)
logLevel?: LogLevel logger?: { level: LogLevel } param on journey() logger?: { level: LogLevel } param on oidc() Separate factory param with custom logger support
logger?: LoggerFunctions logger?: { custom?: CustomLogger } param on journey() logger?: { custom?: CustomLogger } param on oidc() Interface changed
platformHeader?: boolean Accepted but ignored (warning logged) N/A Removed
prefix?: string Accepted but ignored (warning logged) storage?.prefix on oidc() Moved to storage config
type?: string Accepted but ignored (warning logged) N/A Removed
responseType?: ResponseType N/A responseType?: ResponseType in OidcConfig Defaults to 'code'

Before/After: Configuration

Legacy:

import { Config } from '@forgerock/javascript-sdk';

Config.set({
  clientId: 'my-app',
  redirectUri: `${window.location.origin}/callback`,
  scope: 'openid profile',
  serverConfig: {
    baseUrl: 'https://am.example.com/am',
    timeout: 5000,
  },
  realmPath: 'alpha',
  tree: 'Login',
});

New:

import { journey } from '@forgerock/journey-client';
import { oidc } from '@forgerock/oidc-client';

// Shared config — both clients can use the same base config
const config = {
  serverConfig: {
    wellknown: 'https://am.example.com/am/oauth2/alpha/.well-known/openid-configuration',
  },
  clientId: 'my-app',
  redirectUri: `${window.location.origin}/callback`,
  scope: 'openid profile',
};

// Journey client accepts but ignores clientId, redirectUri, scope (warns in console)
const journeyClient = await journey({ config });

// OIDC client requires clientId, redirectUri, scope
const oidcClient = await oidc({ config });

3. Authentication Flow

FRAuth → JourneyClient

Legacy API New API Return Type Change Behavioral Notes
FRAuth.start(options?: StepOptions): Promise<FRStep | FRLoginSuccess | FRLoginFailure> journeyClient.start(options?: StartParam): Promise<JourneyResult> Return type now includes GenericError in union Tree name passed via options.journey instead of Config.set({ tree }) or options.tree
FRAuth.next(step?: FRStep, options?: StepOptions): Promise<FRStep | FRLoginSuccess | FRLoginFailure> journeyClient.next(step: JourneyStep, options?: NextOptions): Promise<JourneyResult> Return type now includes GenericError in union step param is now required (not optional). options simplified to { query?: Record<string, string> }
FRAuth.redirect(step: FRStep): void journeyClient.redirect(step: JourneyStep): Promise<void> voidPromise<void> Now async. Step stored in sessionStorage (was localStorage)
FRAuth.resume(url: string, options?: StepOptions): Promise<FRStep | FRLoginSuccess | FRLoginFailure> journeyClient.resume(url: string, options?: ResumeOptions): Promise<JourneyResult> Return type now includes GenericError in union Previous step retrieved from sessionStorage (was localStorage)
No equivalent journeyClient.terminate(options?: { query?: Record<string, string> }): Promise<void | GenericError> New method. Ends the authentication session via /sessions endpoint

StartParam (replaces StepOptions for start)

Legacy Property New Property Notes
options.tree or Config.set({ tree }) options.journey: string Renamed. Passed per-call, not in global config
options.query?: StringDict<string> options.query?: Record<string, string> Type changed from StringDict to Record
All other ConfigOptions properties Not applicable Per-call config overrides removed

Per-Call Config Override Removal

Breaking Change: In the legacy SDK, every call to FRAuth.next() accepted a full StepOptions (extending ConfigOptions), allowing per-call overrides of tree, serverConfig, middleware, etc. In the new SDK, config is fixed at client creation time. Only query parameters can vary per-call via NextOptions or ResumeOptions. Apps that dynamically switch trees or servers mid-flow must create separate JourneyClient instances.

resume() URL Parameter Parsing

The legacy FRAuth.resume() automatically parses 10+ URL parameters from the redirect URL and conditionally adjusts behavior. The new journeyClient.resume() continues to parse these URL parameters and forwards them through as options.query values.

URL Parameter Legacy Behavior New Behavior
code Extracted, passed as query param to next() Same — extracted and passed through
state Extracted, passed as query param Same
form_post_entry Extracted, triggers previous step retrieval Same
responsekey Extracted, triggers previous step retrieval Same
error, errorCode, errorMessage Extracted, passed as query params Same
suspendedId Extracted, passed as query params Same
RelayState Extracted for SAML flows Same
nonce, scope Extracted, passed as query params Same
authIndexValue Extracted, used as fallback journey name Same

Before/After: Start and Next

Legacy:

import { FRAuth, StepType } from '@forgerock/javascript-sdk';

// Start a journey
let step = await FRAuth.start({ tree: 'Login' });

while (step.type === StepType.Step) {
  // ... handle callbacks ...
  step = await FRAuth.next(step, { tree: 'Login' });
}

if (step.type === StepType.LoginSuccess) {
  const token = step.getSessionToken();
}

New:

import { journey } from '@forgerock/journey-client';

const journeyClient = await journey({
  config: {
    serverConfig: {
      wellknown: 'https://am.example.com/am/oauth2/alpha/.well-known/openid-configuration',
    },
  },
});

let result = await journeyClient.start({ journey: 'Login' });

while (result.type === 'Step') {
  // ... handle callbacks ...
  result = await journeyClient.next(result);
}

if ('error' in result) {
  console.error('Journey error:', result);
} else if (result.type === 'LoginSuccess') {
  const token = result.getSessionToken();
}

Before/After: Redirect and Resume

Legacy:

import { FRAuth } from '@forgerock/javascript-sdk';

// Redirect to AM for social login / external IdP
FRAuth.redirect(step);

// On callback page, resume the journey
const result = await FRAuth.resume(window.location.href);

New:

// Redirect to AM for social login / external IdP
await journeyClient.redirect(step);

// On callback page, resume the journey
const result = await journeyClient.resume(window.location.href);

4. Step Types

Class → Object Type Change

The legacy SDK uses class instances created via new FRStep(payload). The new SDK uses plain objects with methods, created internally by createJourneyObject(). This means instanceof checks no longer work — use the type discriminant instead.

Legacy API New API Return Type Change Behavioral Notes
new FRStep(payload: Step) class instance JourneyStep object type Class → plain object with methods Cannot use instanceof FRStep; use result.type === 'Step'
new FRLoginSuccess(payload: Step) class instance JourneyLoginSuccess object type Class → plain object with methods Cannot use instanceof; use result.type === 'LoginSuccess'
new FRLoginFailure(payload: Step) class instance JourneyLoginFailure object type Class → plain object with methods Cannot use instanceof; use result.type === 'LoginFailure'

JourneyStep Methods (unchanged signatures)

Method Legacy (FRStep) New (JourneyStep) Notes
callbacks FRCallback[] BaseCallback[] Base class renamed
payload Step Step Same interface
getCallbackOfType<T>(type) getCallbackOfType<T extends FRCallback>(type: CallbackType): T getCallbackOfType<T extends BaseCallback>(type: CallbackType): T Generic constraint changed
getCallbacksOfType<T>(type) getCallbacksOfType<T extends FRCallback>(type: CallbackType): T[] getCallbacksOfType<T extends BaseCallback>(type: CallbackType): T[] Generic constraint changed
setCallbackValue(type, value) Same Same No change
getDescription() Same Same No change
getHeader() Same Same No change
getStage() Same Same No change

JourneyLoginSuccess Methods (unchanged signatures)

Method Notes
getRealm(): string | undefined No change
getSessionToken(): string | undefined No change
getSuccessUrl(): string | undefined No change

JourneyLoginFailure Methods (unchanged signatures)

Method Notes
getCode(): number No change
getDetail(): FailureDetail | undefined No change
getMessage(): string | undefined No change
getReason(): string | undefined No change
getProcessedMessage(messageCreator?: MessageCreator): ProcessedPropertyError[] No change

StepType Enum

Legacy New Notes
StepType.Step ('Step') 'Step' Same values, re-exported from @forgerock/journey-client/types
StepType.LoginSuccess ('LoginSuccess') 'LoginSuccess' Same
StepType.LoginFailure ('LoginFailure') 'LoginFailure' Same

5. Callbacks

Base Class Change

Legacy New Notes
import FRCallback from '@forgerock/javascript-sdk' import { BaseCallback } from '@forgerock/journey-client/types' Renamed: FRCallbackBaseCallback

BaseCallback Methods (identical to FRCallback)

Method Signature Notes
getType() (): CallbackType No change
getInputValue(selector?) (selector: number | string = 0): unknown No change
setInputValue(value, selector?) (value: unknown, selector: number | string | RegExp = 0): void No change
getOutputValue(selector?) (selector: number | string = 0): unknown No change
getOutputByName<T>(name, defaultValue) (name: string, defaultValue: T): T No change

Callback Type Mapping

All callback classes retain the same name and method signatures. Only the import path and base class change.

Legacy Import New Import Notes
import { Callback } from '@forgerock/javascript-sdk' import { Callback } from '@forgerock/journey-client/types' None
import { AttributeInputCallback } from '@forgerock/javascript-sdk' import { AttributeInputCallback } from '@forgerock/journey-client/types' None
import { BaseCallback } from '@forgerock/javascript-sdk' import { BaseCallback } from '@forgerock/journey-client/types' None
import { ChoiceCallback } from '@forgerock/javascript-sdk' import { ChoiceCallback } from '@forgerock/journey-client/types' None
import { ConfirmationCallback } from '@forgerock/javascript-sdk' import { ConfirmationCallback } from '@forgerock/journey-client/types' None
import { DeviceProfileCallback } from '@forgerock/javascript-sdk' import { DeviceProfileCallback } from '@forgerock/journey-client/types' None
import { createCallback } from '@forgerock/javascript-sdk' import { createCallback } from '@forgerock/journey-client/types' None
import { HiddenValueCallback } from '@forgerock/javascript-sdk' import { HiddenValueCallback } from '@forgerock/journey-client/types' None
import { KbaCreateCallback } from '@forgerock/javascript-sdk' import { KbaCreateCallback } from '@forgerock/journey-client/types' None
import { MetadataCallback } from '@forgerock/javascript-sdk' import { MetadataCallback } from '@forgerock/journey-client/types' None
import { NameCallback } from '@forgerock/javascript-sdk' import { NameCallback } from '@forgerock/journey-client/types' None
import { PasswordCallback } from '@forgerock/javascript-sdk' import { PasswordCallback } from '@forgerock/journey-client/types' None
import { PingOneProtectEvaluationCallback } from '@forgerock/javascript-sdk' import { PingOneProtectEvaluationCallback } from '@forgerock/journey-client/types' None
import { PingOneProtectInitializeCallback } from '@forgerock/javascript-sdk' import { PingOneProtectInitializeCallback } from '@forgerock/journey-client/types' None
import { PollingWaitCallback } from '@forgerock/javascript-sdk' import { PollingWaitCallback } from '@forgerock/journey-client/types' None
import { ReCaptchaCallback } from '@forgerock/javascript-sdk' import { ReCaptchaCallback } from '@forgerock/journey-client/types' None
import { ReCaptchaEnterpriseCallback } from '@forgerock/javascript-sdk' import { ReCaptchaEnterpriseCallback } from '@forgerock/journey-client/types' None
import { RedirectCallback } from '@forgerock/javascript-sdk' import { RedirectCallback } from '@forgerock/journey-client/types' None
import { SelectIdPCallback } from '@forgerock/javascript-sdk' import { SelectIdPCallback } from '@forgerock/journey-client/types' None
import { SuspendedTextOutputCallback } from '@forgerock/javascript-sdk' import { SuspendedTextOutputCallback } from '@forgerock/journey-client/types' None
import { TextInputCallback } from '@forgerock/javascript-sdk' import { TextInputCallback } from '@forgerock/journey-client/types' None
import { TextOutputCallback } from '@forgerock/javascript-sdk' import { TextOutputCallback } from '@forgerock/journey-client/types' None
import { TermsAndConditionsCallback } from '@forgerock/javascript-sdk' import { TermsAndConditionsCallback } from '@forgerock/journey-client/types' None
import { ValidatedCreatePasswordCallback } from '@forgerock/javascript-sdk' import { ValidatedCreatePasswordCallback } from '@forgerock/journey-client/types' None
import { ValidatedCreateUsernameCallback } from '@forgerock/javascript-sdk' import { ValidatedCreateUsernameCallback } from '@forgerock/journey-client/types' None

Callback Factory

Legacy New Notes
import type { FRCallbackFactory } from '@forgerock/javascript-sdk' import type { CallbackFactory } from '@forgerock/journey-client/types' Type renamed: FRCallbackFactoryCallbackFactory
createCallback(callback: Callback): FRCallback createCallback(callback: Callback): BaseCallback Return type changed from FRCallback to BaseCallback

6. Callback Type Enum

The legacy SDK uses a TypeScript enum. The new SDK uses a plain object (const assertion).

Legacy New Notes
import { CallbackType } from '@forgerock/javascript-sdk' import { callbackType } from '@forgerock/journey-client' PascalCase enum → camelCase object

Value Mapping

All values remain the same strings. Only the access pattern changes:

Legacy New
CallbackType.NameCallback callbackType.NameCallback
CallbackType.PasswordCallback callbackType.PasswordCallback
CallbackType.ChoiceCallback callbackType.ChoiceCallback
CallbackType.TextInputCallback callbackType.TextInputCallback
CallbackType.TextOutputCallback callbackType.TextOutputCallback
CallbackType.ConfirmationCallback callbackType.ConfirmationCallback
CallbackType.HiddenValueCallback callbackType.HiddenValueCallback
CallbackType.RedirectCallback callbackType.RedirectCallback
CallbackType.MetadataCallback callbackType.MetadataCallback
CallbackType.BooleanAttributeInputCallback callbackType.BooleanAttributeInputCallback
CallbackType.NumberAttributeInputCallback callbackType.NumberAttributeInputCallback
CallbackType.StringAttributeInputCallback callbackType.StringAttributeInputCallback
CallbackType.ValidatedCreateUsernameCallback callbackType.ValidatedCreateUsernameCallback
CallbackType.ValidatedCreatePasswordCallback callbackType.ValidatedCreatePasswordCallback
CallbackType.SelectIdPCallback callbackType.SelectIdPCallback
CallbackType.TermsAndConditionsCallback callbackType.TermsAndConditionsCallback
CallbackType.KbaCreateCallback callbackType.KbaCreateCallback
CallbackType.DeviceProfileCallback callbackType.DeviceProfileCallback
CallbackType.ReCaptchaCallback callbackType.ReCaptchaCallback
CallbackType.ReCaptchaEnterpriseCallback callbackType.ReCaptchaEnterpriseCallback
CallbackType.PingOneProtectInitializeCallback callbackType.PingOneProtectInitializeCallback
CallbackType.PingOneProtectEvaluationCallback callbackType.PingOneProtectEvaluationCallback
CallbackType.PollingWaitCallback callbackType.PollingWaitCallback
CallbackType.SuspendedTextOutputCallback callbackType.SuspendedTextOutputCallback

Before/After: Callback Handling

Legacy:

import { CallbackType, FRStep } from '@forgerock/javascript-sdk';
import type { FRCallback } from '@forgerock/javascript-sdk';

if (step.type === 'Step') {
  const nameCb = step.getCallbackOfType<NameCallback>(CallbackType.NameCallback);
  nameCb.setName('demo');
}

New:

import { callbackType } from '@forgerock/journey-client';
import type { NameCallback } from '@forgerock/journey-client/types';

if (result.type === 'Step') {
  const nameCb = result.getCallbackOfType<NameCallback>(callbackType.NameCallback);
  nameCb.setName('demo');
}

7. Token Management

TokenManager

Legacy API New API Return Type Change Behavioral Notes
TokenManager.getTokens(options?: GetTokensOptions): Promise<OAuth2Tokens | void> oidcClient.token.get(options?: GetTokensOptions): Promise<OauthTokens | GenericError | ...> OAuth2Tokens | voidOauthTokens | TokenExchangeErrorResponse | AuthorizationError | GenericError Returns error objects instead of throwing. Check with 'error' in result
TokenManager.deleteTokens(): Promise<void> oidcClient.token.revoke(): Promise<GenericError | RevokeSuccessResult | RevokeErrorResult> void → result object Revokes remotely AND deletes locally. Returns result instead of throwing

TokenManager.getTokens Options

Legacy Option New Option Notes
forceRenew?: boolean forceRenew?: boolean Same behavior
login?: 'embedded' | 'redirect' Removed Legacy login: 'redirect' skipped background token request (equivalent to skipBackgroundRequest: true). In the new SDK, use backgroundRenew: false instead
skipBackgroundRequest?: boolean backgroundRenew?: boolean Inverted semantics: legacy skipBackgroundRequest: true = new backgroundRenew: false
query?: StringDict<string> authorizeOptions?: { query?: Record<string, string> } Moved to authorizeOptions.query (nested inside GetAuthorizationUrlOptions)

TokenStorage

Legacy API New API Return Type Change Behavioral Notes
TokenStorage.get(): Promise<Tokens | void> oidcClient.token.get() Tokens | voidOauthTokens | GenericError | ... Retrieves from storage with optional auto-renewal
TokenStorage.set(tokens: Tokens): Promise<void> Handled internally by oidcClient.token.exchange() Tokens are stored automatically after exchange
TokenStorage.remove(): Promise<void> oidcClient.token.revoke() void → result object Revokes remotely and removes locally

Token Type Change

Legacy Type New Type Changes
Tokens { accessToken?, idToken?, refreshToken?, tokenExpiry? } OauthTokens { accessToken, idToken, refreshToken?, expiresAt?, expiryTimestamp? } accessToken and idToken now required. tokenExpiryexpiryTimestamp

Token Refresh Flow Comparison

The token refresh behavior changed significantly between SDKs:

Legacy flow (TokenManager.getTokens()):

  1. Check if tokens exist in storage
  2. If forceRenew: false and tokens are not expired → return stored tokens
  3. If tokens will expire within oauthThreshold (default: 30s) → attempt silent refresh
  4. If skipBackgroundRequest: false (default) → attempt iframe-based silent auth (prompt=none)
  5. If iframe fails with "allowed error" (consent required, CORS, timeout) → fall back to redirect
  6. If skipBackgroundRequest: true → skip iframe, go straight to redirect-based auth

New flow (oidcClient.token.get()):

  1. Check if tokens exist in storage
  2. If error in stored tokens → return state_error
  3. If forceRenew: false and tokens are not within oauthThreshold → return stored tokens
  4. If backgroundRenew: false and forceRenew: false → return tokens (even if expired) or state_error
  5. If backgroundRenew: true or forceRenew: true → attempt iframe-based silent auth
  6. On success → revoke old tokens, store new tokens, return new tokens
  7. On failure → return AuthorizationError or GenericError

Key differences:

  • Legacy throws errors; new SDK returns them as objects
  • Legacy has redirect fallback built in; new SDK does not auto-redirect
  • skipBackgroundRequest: true (legacy) = backgroundRenew: false (new) — inverted boolean
  • New SDK auto-revokes old tokens before storing new ones during background renewal

Before/After: Token Management

Legacy:

import { TokenManager, TokenStorage } from '@forgerock/javascript-sdk';

try {
  const tokens = await TokenManager.getTokens({ forceRenew: true });
  console.log(tokens?.accessToken);
} catch (err) {
  console.error('Token error:', err);
}

// Direct storage access
const stored = await TokenStorage.get();

New:

// Tokens managed through oidcClient
const tokens = await oidcClient.token.get({ forceRenew: true, backgroundRenew: true });

if ('error' in tokens) {
  console.error('Token error:', tokens);
} else {
  console.log(tokens.accessToken);
}

8. OAuth2 Client

Legacy API New API Return Type Change Behavioral Notes
OAuth2Client.createAuthorizeUrl(options: GetAuthorizationUrlOptions): Promise<string> oidcClient.authorize.url(options?: GetAuthorizationUrlOptions): Promise<string | GenericError> stringstring | GenericError Returns error instead of throwing. PKCE handled internally
OAuth2Client.getAuthCodeByIframe(options: GetAuthorizationUrlOptions): Promise<string> oidcClient.authorize.background(options?: GetAuthorizationUrlOptions): Promise<AuthorizationSuccess | AuthorizationError> string (URL) → { code, state } or error object Returns parsed code+state instead of raw URL. Uses prompt: 'none' internally
OAuth2Client.getOAuth2Tokens(options: GetOAuth2TokensOptions): Promise<OAuth2Tokens> oidcClient.token.exchange(code: string, state: string, options?: Partial<StorageConfig>): Promise<OauthTokens | GenericError | TokenExchangeErrorResponse> OAuth2Tokens → union with error types Separate code and state params (not in options object). Auto-stores tokens
OAuth2Client.getUserInfo(options?: ConfigOptions): Promise<unknown> oidcClient.user.info(): Promise<GenericError | UserInfoResponse> unknownGenericError | UserInfoResponse No config param needed. Token retrieved from storage automatically
OAuth2Client.endSession(options?: LogoutOptions): Promise<Response | void> oidcClient.user.logout(): Promise<GenericError | LogoutSuccessResult | LogoutErrorResult> Response | void → structured result Revokes tokens, clears storage, and ends session in one call
OAuth2Client.revokeToken(options?: ConfigOptions): Promise<Response> oidcClient.token.revoke(): Promise<GenericError | RevokeSuccessResult | RevokeErrorResult> Response → structured result Also removes tokens from local storage
ResponseType enum ResponseType from @forgerock/oidc-client/types Same values Import path changed

Before/After: OAuth2 Flow

Legacy:

import { OAuth2Client, TokenStorage } from '@forgerock/javascript-sdk';

try {
  const urlWithCode = await OAuth2Client.getAuthCodeByIframe({ ...options });
  const url = new URL(urlWithCode);
  const code = url.searchParams.get('code');
  const tokens = await OAuth2Client.getOAuth2Tokens({
    authorizationCode: code,
    verifier,
  });
  await TokenStorage.set(tokens);
} catch (err) {
  console.error(err);
}

New:

const authResult = await oidcClient.authorize.background();
if ('error' in authResult) {
  console.error(authResult);
} else {
  const tokens = await oidcClient.token.exchange(authResult.code, authResult.state);
  if ('error' in tokens) {
    console.error(tokens);
  }
  // Tokens are auto-stored
}

9. User Management

Legacy API New API Return Type Change Behavioral Notes
UserManager.getCurrentUser(options?: ConfigOptions): Promise<unknown> oidcClient.user.info(): Promise<GenericError | UserInfoResponse> unknown → typed response No config param. Returns error object instead of throwing
FRUser.logout(options?: LogoutOptions): Promise<void> oidcClient.user.logout(): Promise<GenericError | LogoutSuccessResult | LogoutErrorResult> void → structured result Combines revoke + delete + end session. Returns result instead of throwing
FRUser.login(handler, options) No equivalent Was never implemented in legacy SDK (throw new Error('not implemented'))

Logout Orchestration Comparison

Legacy FRUser.logout() flow:

  1. Call SessionManager.logout() to destroy AM session (if sessions endpoint configured)
  2. Call OAuth2Client.revokeToken() to revoke the access token
  3. Call TokenStorage.remove() to clear local tokens
  4. Call OAuth2Client.endSession() with idToken to end the OIDC session
  5. Each step is "best effort" — errors are logged but not thrown, so logout continues even if individual steps fail
  6. logoutRedirectUri controls post-logout redirect; redirect: false explicitly disables the end-session redirect

New oidcClient.user.logout() flow:

  1. Revoke access token via revocation endpoint
  2. End OIDC session via end-session endpoint
  3. Remove tokens from local storage
  4. Returns structured LogoutSuccessResult or LogoutErrorResult

Key differences:

  • Legacy has separate logoutRedirectUri and redirect options; new SDK does not expose redirect control on logout
  • Legacy silently swallows per-step errors; new SDK returns detailed error results for each sub-operation
  • AM session destruction (SessionManager.logout()) is NOT part of oidcClient.user.logout() — combine with journeyClient.terminate() for full logout

Before/After: User Info & Logout

Legacy:

import { UserManager, FRUser } from '@forgerock/javascript-sdk';

try {
  const user = await UserManager.getCurrentUser();
  console.log(user);
} catch (err) {
  console.error('Error getting user:', err);
}

try {
  await FRUser.logout({ logoutRedirectUri: '/signoff' });
} catch (err) {
  console.error('Logout error:', err);
}

New:

const user = await oidcClient.user.info();
if ('error' in user) {
  console.error('Error getting user:', user);
} else {
  console.log(user);
}

const logoutResult = await oidcClient.user.logout();
if ('error' in logoutResult) {
  console.error('Logout error:', logoutResult);
}

10. Session Management

Legacy API New API Return Type Change Behavioral Notes
SessionManager.logout(options?: ConfigOptions): Promise<Response> journeyClient.terminate(options?: { query?: Record<string, string> }): Promise<void | GenericError> Responsevoid | GenericError Calls /sessions endpoint. Returns error object instead of throwing

Note: SessionManager.logout() in the legacy SDK destroys the AM session. journeyClient.terminate() serves the same purpose. For full logout (revoke tokens + end OIDC session + destroy AM session), combine oidcClient.user.logout() with journeyClient.terminate().


11. HTTP Client

Legacy API New API Return Type Change Behavioral Notes
HttpClient.request(options: HttpClientRequestOptions): Promise<Response> No direct equivalent Must manually manage tokens and fetch

Migration Pattern

The legacy HttpClient provided several advanced features that have no equivalent in the new SDK. You must implement these yourself:

Capabilities Lost

Legacy HttpClient Feature Migration Approach
Auto bearer token injection — Automatically added Authorization: Bearer header Manually call oidcClient.token.get() and set the header
401 token refresh — On 401 response, auto-refreshed tokens and retried the request Implement retry logic: on 401, call oidcClient.token.get({ forceRenew: true }) and retry
Policy advice parsing (IG) — Parsed Advices from Identity Gateway 401/redirect responses Not supported. If using IG-protected resources, parse advice manually
Policy advice parsing (REST) — Parsed AuthenticateToServiceConditionAdvice and TransactionConditionAdvice from AM REST responses Not supported. Parse AM authorization advice manually
Automatic authorization tree execution — Ran additional auth trees to satisfy policy advice Must implement the full advice → auth tree → retry flow manually
Request timeout — Configurable via serverConfig.timeout Use native fetch timeout options or AbortController if needed
Middleware integration — Request middleware received ActionTypes context Apply your own middleware pattern to fetch calls

Legacy:

import { HttpClient } from '@forgerock/javascript-sdk';

const response = await HttpClient.request({
  url: 'https://api.example.com/resource',
  init: { method: 'GET' },
  authorization: { handleStep: myStepHandler },
});

New:

const tokens = await oidcClient.token.get({ backgroundRenew: true });

if ('error' in tokens) {
  throw new Error('No valid tokens');
}

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

12. WebAuthn

Legacy API New API Return Type Change Behavioral Notes
import { FRWebAuthn, WebAuthnStepType } from '@forgerock/javascript-sdk' import { WebAuthn, WebAuthnStepType } from '@forgerock/journey-client/webauthn' Class renamed FRWebAuthnWebAuthn. Import path changed to submodule
FRWebAuthn.getWebAuthnStepType(step: FRStep): WebAuthnStepType WebAuthn.getWebAuthnStepType(step: JourneyStep): WebAuthnStepType Same Step type changed to JourneyStep
FRWebAuthn.authenticate(step: FRStep, optionsTransformer?): Promise<FRStep> WebAuthn.authenticate(step: JourneyStep): Promise<void> FRStepvoid Mutates step in-place instead of returning it
FRWebAuthn.register(step: FRStep, deviceName?): Promise<FRStep> WebAuthn.register(step: JourneyStep): Promise<void> FRStepvoid Mutates step in-place instead of returning it. Device name not passed here
FRWebAuthn.isWebAuthnSupported(): boolean No equivalent exported Check window.PublicKeyCredential directly
FRWebAuthn.isConditionalMediationSupported(): Promise<boolean> No equivalent exported Check PublicKeyCredential.isConditionalMediationAvailable() directly
FRWebAuthn.getCallbacks(step): WebAuthnCallbacks Not exported as public API Internal to WebAuthn.authenticate/register
FRWebAuthn.getMetadataCallback(step) Not exported as public API Internal
FRWebAuthn.getOutcomeCallback(step) Not exported as public API Internal
FRWebAuthn.getTextOutputCallback(step) Not exported as public API Internal
FRWebAuthn.getAuthenticationCredential(options) Not exported as public API Internal
FRWebAuthn.getAuthenticationOutcome(credential) Not exported as public API Internal
FRWebAuthn.getRegistrationCredential(options) Not exported as public API Internal
FRWebAuthn.getRegistrationOutcome(credential) Not exported as public API Internal
FRWebAuthn.createAuthenticationPublicKey(metadata) Not exported as public API Internal
FRWebAuthn.createRegistrationPublicKey(metadata) Not exported as public API Internal

WebAuthn Enums

Legacy New Notes
WebAuthnStepType.None WebAuthnStepType.None Same
WebAuthnStepType.Registration WebAuthnStepType.Registration Same
WebAuthnStepType.Authentication WebAuthnStepType.Authentication Same
WebAuthnOutcome Not exported Internal to WebAuthn module
WebAuthnOutcomeType Not exported Internal to WebAuthn module

Before/After: WebAuthn

Legacy:

import { FRWebAuthn, WebAuthnStepType } from '@forgerock/javascript-sdk';

const type = FRWebAuthn.getWebAuthnStepType(step);
if (type === WebAuthnStepType.Authentication) {
  step = await FRWebAuthn.authenticate(step);
} else if (type === WebAuthnStepType.Registration) {
  step = await FRWebAuthn.register(step, 'My Device');
}

New:

import { WebAuthn, WebAuthnStepType } from '@forgerock/journey-client/webauthn';

const type = WebAuthn.getWebAuthnStepType(step);
if (type === WebAuthnStepType.Authentication) {
  await WebAuthn.authenticate(step); // Mutates step in place
} else if (type === WebAuthnStepType.Registration) {
  await WebAuthn.register(step); // Mutates step in place
}

13. QR Code

Legacy API New API Return Type Change Behavioral Notes
import { FRQRCode } from '@forgerock/javascript-sdk' import { QRCode } from '@forgerock/journey-client/qr-code' Class renamed FRQRCodeQRCode. Subpath import required
FRQRCode.isQRCodeStep(step: FRStep): boolean QRCode.isQRCodeStep(step: JourneyStep): boolean Same Step param type changed
FRQRCode.getQRCodeData(step: FRStep): QRCodeData QRCode.getQRCodeData(step: JourneyStep): QRCodeData Same Step param type changed

14. Recovery Codes

Legacy API New API Return Type Change Behavioral Notes
import { FRRecoveryCodes } from '@forgerock/javascript-sdk' import { RecoveryCodes } from '@forgerock/journey-client/recovery-codes' Class renamed FRRecoveryCodesRecoveryCodes. Subpath import required
FRRecoveryCodes.isDisplayStep(step: FRStep): boolean RecoveryCodes.isDisplayStep(step: JourneyStep): boolean Same Step param type changed
FRRecoveryCodes.getCodes(step: FRStep): string[] RecoveryCodes.getCodes(step: JourneyStep): string[] Same Step param type changed
FRRecoveryCodes.getDeviceName(step: FRStep): string RecoveryCodes.getDeviceName(step: JourneyStep): string Same Step param type changed

15. Policy

Legacy API New API Return Type Change Behavioral Notes
import { FRPolicy, PolicyKey } from '@forgerock/javascript-sdk' import { Policy } from '@forgerock/journey-client/policy' + import { PolicyKey } from '@forgerock/journey-client' Class renamed FRPolicyPolicy. Subpath import required. In legacy, config was passed to FRPolicy methods; in new SDK, config is set at client creation time
FRPolicy.parseErrors(err, messageCreator?) Policy.parseErrors(err, messageCreator?) Same Same signature
FRPolicy.parseFailedPolicyRequirement(failedPolicy, messageCreator?) Policy.parseFailedPolicyRequirement(failedPolicy, messageCreator?) Same Same signature
FRPolicy.parsePolicyRequirement(property, policy, messageCreator?) Policy.parsePolicyRequirement(property, policy, messageCreator?) Same Same signature. Note: legacy threw on errors; new SDK returns error objects
import { defaultMessageCreator } from '@forgerock/javascript-sdk' Internal to @forgerock/journey-client/policy module Same Not publicly re-exported. Policy class uses it internally. To provide custom messages, pass a MessageCreator to Policy.parseErrors()

16. Device

FRDevice (Device Profile Collection)

Legacy API New API Return Type Change Behavioral Notes
import { FRDevice } from '@forgerock/javascript-sdk' Device profile functionality via @forgerock/device-client Class-based → factory function
new FRDevice(config?).getProfile({ location, metadata }) deviceClient(config).profile.get(query) DeviceProfileDataProfileDevice[] | { error } Returns error object instead of throwing

deviceClient (Device CRUD Operations)

Legacy API New API Return Type Change Behavioral Notes
import { deviceClient } from '@forgerock/javascript-sdk' import { deviceClient } from '@forgerock/device-client' Same factory pattern, different package
deviceClient(config).oath.get(query) deviceClient(config).oath.get(query) Same
deviceClient(config).oath.delete(query) deviceClient(config).oath.delete(query) Same
deviceClient(config).push.get(query) deviceClient(config).push.get(query) Same
deviceClient(config).push.delete(query) deviceClient(config).push.delete(query) Same
deviceClient(config).webAuthn.get(query) deviceClient(config).webAuthn.get(query) Same
deviceClient(config).webAuthn.update(query) deviceClient(config).webAuthn.update(query) Same
deviceClient(config).webAuthn.delete(query) deviceClient(config).webAuthn.delete(query) Same
deviceClient(config).bound.get(query) deviceClient(config).bound.get(query) Same
deviceClient(config).bound.delete(query) deviceClient(config).bound.delete(query) Same
deviceClient(config).profile.get(query) deviceClient(config).profile.get(query) Same
deviceClient(config).profile.delete(query) deviceClient(config).profile.delete(query) Same

17. Protect

Legacy API New API Return Type Change Behavioral Notes
import { protect } from '@forgerock/ping-protect' import { protect } from '@forgerock/protect' Package renamed only
protect(options).start() protect(options).start() Promise<void | { error }> Same
protect(options).getData() protect(options).getData() Promise<string | { error }> Same
protect(options).pauseBehavioralData() protect(options).pauseBehavioralData() void | { error } Same
protect(options).resumeBehavioralData() protect(options).resumeBehavioralData() void | { error } Same

Protect Config Changes

Legacy Property New Property Notes
envId: string envId: string Same (required)
All other options Same No config changes

18. Error Handling Patterns

Fundamental Pattern Change

Aspect Legacy New
Error mechanism throw new Error(...) caught via try/catch Return GenericError object in union type
Detection catch (err) { ... } if ('error' in result) { ... }
Error info err.message: string result.error: string, result.message?: string, result.type: ErrorType, result.status?: number | string, result.code?: string | number

Caveat: While the new SDK primarily returns error objects, some journey-client methods may still throw in certain edge cases. This is known tech debt. Defensive code should handle both patterns: check for 'error' in result AND wrap calls in try/catch when working with journey-client methods.

GenericError Shape

interface GenericError {
  error: string; // Error identifier
  message?: string; // Human-readable description
  type: ErrorType; // Categorized error type
  status?: number | string; // HTTP status code (when applicable)
  code?: string | number; // Error code (when applicable)
}

Error Types

Error Type When Used
'argument_error' Invalid arguments passed to SDK methods
'auth_error' Authentication/authorization failures
'davinci_error' DaVinci-specific errors
'fido_error' WebAuthn/FIDO errors
'exchange_error' Token exchange failures
'internal_error' Internal SDK errors
'network_error' Network/fetch failures
'parse_error' Response parsing failures
'state_error' Invalid state (e.g., no tokens found)
'unknown_error' Unclassified errors
'wellknown_error' Wellknown endpoint errors

Before/After: Error Handling

Legacy:

try {
  const user = await UserManager.getCurrentUser();
  setUser(user);
} catch (err) {
  console.error(`Error: get current user; ${err}`);
  setUser({});
}

New:

const user = await oidcClient.user.info();
if ('error' in user) {
  console.error('Error getting user:', user.error, user.message);
  setUser({});
} else {
  setUser(user);
}

19. Type Exports

Legacy Type Export New Location Notes
AuthResponse @forgerock/journey-client/types Same interface
Callback @forgerock/journey-client/types Same interface
CallbackType (type) @forgerock/journey-client/types Same type
ConfigOptions No direct equivalent Config split across JourneyClientConfig and OidcConfig
FailureDetail @forgerock/journey-client/types Same interface
FRCallbackFactory CallbackFactory from @forgerock/journey-client/types Renamed
FRStepHandler No equivalent Removed
GetAuthorizationUrlOptions @forgerock/oidc-client/types Same interface
GetOAuth2TokensOptions No direct equivalent Replaced by token.exchange(code, state) params
GetTokensOptions @forgerock/oidc-client (from client.types.ts) Different shape: { authorizeOptions?, forceRenew?, backgroundRenew?, storageOptions? }
IdPValue @forgerock/journey-client/types (via SelectIdPCallback) Same interface
LoggerFunctions CustomLogger from @forgerock/sdk-logger Interface changed
MessageCreator @forgerock/journey-client/types Same interface
NameValue @forgerock/journey-client/types Same interface
OAuth2Tokens OauthTokens from @forgerock/oidc-client Renamed, shape changed (see Token section)
PolicyRequirement @forgerock/journey-client/types Same interface
ProcessedPropertyError @forgerock/journey-client/types Same interface
RelyingParty @forgerock/journey-client/webauthn (via interfaces) Same interface
Step @forgerock/journey-client/types Same interface
StepDetail @forgerock/journey-client/types Same interface
StepOptions No direct equivalent Replaced by StartParam, NextOptions, ResumeOptions
Tokens OauthTokens from @forgerock/oidc-client Renamed and restructured
ValidConfigOptions No equivalent Removed (config is encapsulated)
WebAuthnAuthenticationMetadata @forgerock/journey-client/webauthn (via interfaces) Same interface
WebAuthnCallbacks Not exported Internal to WebAuthn module
WebAuthnRegistrationMetadata @forgerock/journey-client/webauthn (via interfaces) Same interface

20. Removed / Deprecated APIs

These legacy exports have no equivalent in the new SDK:

Legacy Export Status Migration Path
Auth Removed Internal authentication logic. No public replacement needed
Deferred Removed Use native Promise constructor or equivalent
PKCE Removed PKCE is handled internally by @forgerock/oidc-client. Legacy utility methods (PKCE.createState(), PKCE.createVerifier(), PKCE.createChallenge(verifier)) have no public replacement — use crypto.randomUUID() for state and crypto.subtle for PKCE if needed
LocalStorage Removed Use @forgerock/storage package or native localStorage/sessionStorage
ErrorCode Removed Replaced by GenericError.type error classification (see Error Handling)
HttpClient Removed Use fetch + manual Authorization header (see HTTP Client)
Config (static class) Removed Config passed as params to factory functions
FRUser.login() Removed Was never implemented in legacy SDK
WebAuthnOutcome Not exported Internal to @forgerock/journey-client/webauthn
WebAuthnOutcomeType Not exported Internal to @forgerock/journey-client/webauthn
PolicyKey Available import { PolicyKey } from '@forgerock/journey-client'
defaultMessageCreator Internal Not publicly re-exported. Used internally by Policy class in @forgerock/journey-client/policy. Pass a custom MessageCreator to Policy.parseErrors() instead

Token Vault

The legacy @forgerock/token-vault package provided advanced token security via Service Worker interception and iframe-based origin isolation. It included:

  • client(config) — Main factory for creating a Token Vault client
  • register.interceptor() — Service Worker registration for transparent token injection
  • register.proxy(element, config) — iframe proxy for cross-origin token storage
  • register.store() — Custom token store implementation for SDK integration

Migration note: Token Vault is not yet available in the new SDK. If you depend on Service Worker-based token isolation, continue using the legacy @forgerock/token-vault or implement custom token security.

Key Behavioral Removals

Legacy Behavior New Approach
Global config via Config.set() Each client manages its own config independently
Automatic PKCE challenge generation in OAuth2Client @forgerock/oidc-client handles PKCE internally
HttpClient auto-injecting bearer tokens and refreshing on 401 Manually get tokens, add Authorization header, handle 401 yourself
Token stored in localStorage by default OIDC client uses localStorage by default; journey client step storage uses sessionStorage
Per-call config overrides via StepOptions Major change: Config is fixed at client creation time. Legacy apps that passed different tree, serverConfig, or middleware per-call must create separate client instances. Only query params can vary per-call
FRUser.logout() silently swallows errors per-step oidcClient.user.logout() returns structured LogoutErrorResult with per-operation error details