@forgerock/login-widget 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -36,7 +36,6 @@
36
36
  - [Journey](#journey)
37
37
  - [Component](#component)
38
38
  - [User](#user)
39
- - [Request](#request)
40
39
  - [Styling Configuration](#styling-configuration)
41
40
  - [Links Configuration](#links-configuration)
42
41
  - [Content Configuration](#content-configuration)
@@ -48,7 +47,7 @@
48
47
 
49
48
  The Login Widget is an all-inclusive UI component for handling login, registration, and related user flows in any modern JavaScript app. It works with React, Vue, Angular, Svelte, or vanilla JavaScript — it does not currently support Node.js or server-side rendering (SSR).
50
49
 
51
- The widget uses [Journey Client](https://developer.pingidentity.com/orchsdks/journey/usage/javascript/index.html) for journey execution, and the [ForgeRock SDK for JavaScript](https://docs.pingidentity.com/sdks/latest/sdks/tutorials/javascript/index.html) for OAuth/OIDC tokens, user info, and request utilities. It adds a UI rendering layer on top of these SDKs to eliminate the need to develop and maintain UI components for complex authentication flows. Although this rendering layer is developed with Svelte and Tailwind, both are "compiled away" and have no runtime dependencies. The resulting widget is library- and framework-agnostic.
50
+ The widget uses [Journey Client](https://developer.pingidentity.com/orchsdks/journey/usage/javascript/index.html) for journey execution, and [OIDC Client](https://developer.pingidentity.com/orchsdks/oidc/usage/javascript-centralized-login.html) for OAuth/OIDC tokens and user info. It adds a UI rendering layer on top of these SDKs to eliminate the need to develop and maintain UI components for complex authentication flows. Although this rendering layer is developed with Svelte and Tailwind, both are "compiled away" and have no runtime dependencies. The resulting widget is library- and framework-agnostic.
52
51
 
53
52
  The widget can be rendered in two form factors:
54
53
 
@@ -139,12 +138,15 @@ import Widget, { configure, journey } from '@forgerock/login-widget';
139
138
  // 1. Configure — async; awaiting it ensures both clients are ready before use
140
139
  await configure({
141
140
  // REQUIRED — the well-known URL, shared by the journey and OIDC clients
142
- wellknown: 'https://your-tenant.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration',
141
+ serverConfig: {
142
+ wellknown:
143
+ 'https://your-tenant.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration',
144
+ },
143
145
  // REQUIRED if you use OAuth/OIDC tokens, user info, or logout
144
146
  oidcClient: {
145
147
  clientId: 'YourOauthClient',
146
148
  redirectUri: `${window.location.origin}/callback`,
147
- scope: 'openid profile email',
149
+ scope: 'openid profile email', // OPTIONAL — defaults to 'openid'
148
150
  },
149
151
  });
150
152
 
@@ -259,14 +261,23 @@ import { configure } from '@forgerock/login-widget';
259
261
  // configure() is async — await it before calling any other Widget API
260
262
  await configure({
261
263
  // REQUIRED — the well-known URL, shared by the journey and OIDC clients
262
- wellknown:
263
- 'https://your-tenant.forgeblocks.com/am/oauth2/realms/root/realms/alpha/.well-known/openid-configuration',
264
+ serverConfig: {
265
+ wellknown:
266
+ 'https://your-tenant.forgeblocks.com/am/oauth2/realms/root/realms/alpha/.well-known/openid-configuration',
267
+ },
264
268
  // REQUIRED if you use OAuth/OIDC tokens, user info, or logout
265
269
  oidcClient: {
266
270
  clientId: 'WebOAuthClient',
267
271
  redirectUri: `${window.location.origin}/callback`,
268
272
  scope: 'openid profile email',
269
273
  },
274
+ // OPTIONAL — logger for both clients; `level` gates verbosity and `custom`
275
+ // redirects SDK log output to your own sink. See the full example below.
276
+ logger: { level: 'warn' },
277
+ // OPTIONAL — request middleware for both clients; see the full example below
278
+ middleware: [],
279
+ // OPTIONAL — token storage config; see Storage section below
280
+ storage: { type: 'sessionStorage', name: 'tokens' },
270
281
  // OPTIONAL — see dedicated sections below
271
282
  content: {},
272
283
  links: {},
@@ -275,9 +286,115 @@ await configure({
275
286
  ```
276
287
 
277
288
  > **Migration note (2.0.0):** The `forgerock` config object has been replaced by `oidcClient`.
278
- > Endpoint discovery is now driven by a single top-level `wellknown` URL, shared by the
279
- > journey and OIDC clients — `baseUrl`, `realmPath`, `timeout`, and `support` are no longer
280
- > used. `clientId`, `redirectUri`, and `scope` are now required when configuring `oidcClient`.
289
+ > Endpoint discovery is now driven by `serverConfig.wellknown`, shared by the journey and OIDC
290
+ > clients — `baseUrl`, `realmPath`, `timeout`, and `support` are no longer used. `clientId` and
291
+ > `redirectUri` are required when configuring `oidcClient`; `scope` defaults to `'openid'`. `tokenStore` has
292
+ > moved to a top-level `storage` option.
293
+
294
+ #### Logger
295
+
296
+ The top-level `logger` option is forwarded to both the journey and OIDC clients.
297
+
298
+ | Property | Type | Default | Description |
299
+ | -------- | -------------------------------------------------- | --------- | --------------------------------------------------------------------------------------- |
300
+ | `level` | `'none' \| 'error' \| 'warn' \| 'info' \| 'debug'` | `'error'` | Gates SDK log verbosity. `'none'` silences all SDK logs. |
301
+ | `custom` | `{ error, warn, info, debug }` | — | Sink for SDK log output. When set, the SDK calls your methods instead of the `console`. |
302
+
303
+ ```js
304
+ await configure({
305
+ serverConfig: {
306
+ wellknown:
307
+ 'https://your-tenant.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration',
308
+ },
309
+ logger: {
310
+ level: 'debug',
311
+ // OPTIONAL — route SDK logs to your own sink instead of the console.
312
+ custom: {
313
+ error: (...args) => myLogger.error(...args),
314
+ warn: (...args) => myLogger.warn(...args),
315
+ info: (...args) => myLogger.info(...args),
316
+ debug: (...args) => myLogger.debug(...args),
317
+ },
318
+ },
319
+ oidcClient: {
320
+ clientId: 'WebOAuthClient',
321
+ redirectUri: `${window.location.origin}/callback`,
322
+ scope: 'openid profile email',
323
+ },
324
+ });
325
+ ```
326
+
327
+ #### OIDC Client Options
328
+
329
+ All properties are nested inside `oidcClient`.
330
+
331
+ | Property | Type | Default | Description |
332
+ | ---------------- | ------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
333
+ | `clientId` | `string` | — | **Required.** OAuth 2.0 client ID. |
334
+ | `redirectUri` | `string` | — | **Required.** URI AM redirects to after authorization. |
335
+ | `scope` | `string` | `'openid'` | OAuth 2.0 scopes. |
336
+ | `oauthThreshold` | `number` | `30000` | Milliseconds before expiry to trigger background renewal. |
337
+ | `par` | `boolean` | auto | Use Pushed Authorization Requests. When omitted, the SDK auto-detects from the authorization server's `require_pushed_authorization_requests` metadata. Setting `false` while the server requires PAR is an error. |
338
+ | `loginHint` | `string` | — | Pre-fills the login identifier; bridged onto silent token renewal. |
339
+ | `acrValues` | `string` | — | Requested ACR values; bridged onto silent token renewal. |
340
+ | `query` | `Record<string, string>` | — | Extra authorize query params; bridged onto silent token renewal. |
341
+
342
+ Example with all optional OIDC options:
343
+
344
+ ```js
345
+ await configure({
346
+ serverConfig: {
347
+ wellknown:
348
+ 'https://your-tenant.forgeblocks.com/am/oauth2/alpha/.well-known/openid-configuration',
349
+ },
350
+ logger: { level: 'debug' },
351
+ middleware: [
352
+ (req, action, next) => {
353
+ console.log('[middleware]', action.type, req.url);
354
+ next();
355
+ },
356
+ ],
357
+ storage: { type: 'sessionStorage', name: 'tokens', prefix: 'myapp' },
358
+ oidcClient: {
359
+ clientId: 'WebOAuthClient',
360
+ redirectUri: `${window.location.origin}/callback`,
361
+ scope: 'openid profile email',
362
+ oauthThreshold: 60000,
363
+ par: true,
364
+ loginHint: 'user@example.com',
365
+ acrValues: 'urn:acr:2fa',
366
+ query: { ui_locales: 'en-US' },
367
+ },
368
+ });
369
+ ```
370
+
371
+ #### Storage
372
+
373
+ The top-level `storage` option configures where the OIDC client persists tokens. It mirrors
374
+ the SDK's `StorageConfig` union — `type` selects a browser store or a custom sink.
375
+
376
+ | Property | Type | Default | Description |
377
+ | -------- | ------------------------------------------------ | ---------------- | ----------------------------------------------------------------------- |
378
+ | `type` | `'localStorage' \| 'sessionStorage' \| 'custom'` | `'localStorage'` | Storage backend. `'custom'` requires a `custom` sink. |
379
+ | `name` | `string` | — | **Required.** Storage key name. |
380
+ | `prefix` | `string` | `'pic'` | Key prefix for storage entries. |
381
+ | `custom` | `{ get, set, remove }` | — | **Required when `type: 'custom'`.** Async functions for your own store. |
382
+
383
+ ```js
384
+ // Browser store
385
+ storage: { type: 'sessionStorage', name: 'tokens', prefix: 'myapp' },
386
+
387
+ // Custom store
388
+ storage: {
389
+ type: 'custom',
390
+ name: 'tokens',
391
+ custom: {
392
+ get: async (key) => myStore.read(key),
393
+ set: async (key, value) => myStore.write(key, value),
394
+ remove: async (key) => myStore.delete(key),
395
+ },
396
+ },
397
+ ```
281
398
 
282
399
  ### Journey
283
400
 
@@ -6,10 +6,13 @@
6
6
  * of the MIT license. See the LICENSE file for details.
7
7
  *
8
8
  **/
9
- import type { GetTokensOptions, OauthTokens, OidcClient } from '@forgerock/oidc-client/types';
9
+ import type { GetAuthorizationUrlOptions, GetTokensOptions, OauthTokens, OidcClient, StorageConfig } from '@forgerock/oidc-client/types';
10
10
  import type { Readable, Writable } from 'svelte/store';
11
11
  import type { Maybe } from '../interfaces';
12
+ import type { OidcClientConfig } from '../oidc/oidc.store';
12
13
  export interface OAuthStore extends Pick<Writable<OAuthTokenStoreValue>, 'subscribe'> {
14
+ background: (options?: GetAuthorizationUrlOptions) => void;
15
+ exchange: (options?: Partial<StorageConfig>) => void;
13
16
  get: (getOptions?: GetTokensOptions) => Promise<OAuthTokenStoreValue>;
14
17
  reset: () => void;
15
18
  }
@@ -22,12 +25,14 @@ export interface OAuthTokenStoreValue {
22
25
  }>;
23
26
  loading: boolean;
24
27
  successful: boolean;
28
+ code: Maybe<string>;
29
+ state: Maybe<string>;
25
30
  response: Maybe<OauthTokens> | void;
26
31
  }
27
32
  /**
28
33
  * @function initialize - Initializes the OAuth store with a get function and a reset function
29
34
  * @param {Readable<OidcClient | null>} oidcClientStore - The OIDC client store to read the client from
30
- * @param {GetTokensOptions} initOptions - Default options to pass to `token.get`
35
+ * @param {OidcClientConfig} oidcConfig - The OIDC client config; used to build authorizeOptions for token.get
31
36
  * @returns {OAuthStore} - The OAuth store
32
37
  */
33
- export declare function initialize(oidcClientStore: Readable<OidcClient | null> | undefined, initOptions?: GetTokensOptions): OAuthStore;
38
+ export declare function initialize(oidcClientStore: Readable<OidcClient | null> | undefined, oidcConfig?: Omit<OidcClientConfig, 'serverConfig'>): OAuthStore;
@@ -7,10 +7,12 @@
7
7
  *
8
8
  **/
9
9
  import { z } from 'zod';
10
- import type { OidcClient } from '@forgerock/oidc-client/types';
10
+ import type { CustomLogger, LogLevel, OidcClient, RequestMiddleware, StorageConfig } from '@forgerock/oidc-client/types';
11
11
  import type { Readable } from 'svelte/store';
12
12
  /**
13
- * Configure the OIDC Client.
13
+ * Validates the OIDC client config passed to the widget. Accepts the fields from
14
+ * OidcConfig that have a clear consumer use case. serverConfig is injected by the
15
+ * widget from its own wellknown; log is omitted in favour of the top-level logger option.
14
16
  */
15
17
  export declare const oidcClientConfigSchema: z.ZodObject<{
16
18
  clientId: z.ZodString;
@@ -19,6 +21,11 @@ export declare const oidcClientConfigSchema: z.ZodObject<{
19
21
  serverConfig: z.ZodObject<{
20
22
  wellknown: z.ZodString;
21
23
  }, z.core.$strict>;
24
+ par: z.ZodOptional<z.ZodBoolean>;
25
+ loginHint: z.ZodOptional<z.ZodString>;
26
+ acrValues: z.ZodOptional<z.ZodString>;
27
+ query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
28
+ oauthThreshold: z.ZodOptional<z.ZodNumber>;
22
29
  }, z.core.$strict>;
23
30
  export type OidcClientConfig = z.infer<typeof oidcClientConfigSchema>;
24
31
  export type OidcClientStore = Readable<OidcClient | null> & {
@@ -40,6 +47,12 @@ export type OidcClientStore = Readable<OidcClient | null> & {
40
47
  * client instance without module-level state.
41
48
  *
42
49
  * @param {OidcClientConfig} config — OIDC client configuration (validated by Zod).
50
+ * @param {RequestMiddleware[]} [requestMiddleware] — optional request middleware forwarded to `oidc()`.
51
+ * @param {{ level: LogLevel; custom?: CustomLogger }} [logger] — optional logger (level + custom sink) forwarded to `oidc()`.
52
+ * @param {StorageConfig} [storage] — optional token storage config forwarded to `oidc()`.
43
53
  * @returns {OidcClientStore}
44
54
  */
45
- export declare function createOidcClientStore(config: OidcClientConfig): OidcClientStore;
55
+ export declare function createOidcClientStore(config: OidcClientConfig, requestMiddleware?: RequestMiddleware[], logger?: {
56
+ level: LogLevel;
57
+ custom?: CustomLogger;
58
+ }, storage?: StorageConfig): OidcClientStore;