Skip to content

Commit 5a9ea40

Browse files
committed
chore: update readmes, fix types and comments
1 parent 4933f55 commit 5a9ea40

16 files changed

Lines changed: 228 additions & 124 deletions

File tree

.changeset/sour-jobs-count.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@forgerock/sdk-request-middleware': patch
3+
'@forgerock/iframe-manager': patch
4+
'@forgerock/storage': patch
5+
'@forgerock/sdk-logger': patch
6+
'@forgerock/davinci-client': patch
7+
'@forgerock/device-client': patch
8+
'@forgerock/sdk-utilities': patch
9+
'@forgerock/oidc-client': patch
10+
'@forgerock/sdk-types': patch
11+
'@forgerock/protect': patch
12+
---
13+
14+
Update READMES. Fix types and comments.

e2e/davinci-suites/src/fido.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,7 @@ test.describe('FIDO/WebAuthn Tests', () => {
8787
await expect(page.getByText('FIDO2 Test Form')).toBeVisible();
8888
});
8989

90-
// Note: This test is currently not working due to a DaVinci issue where the authentication options
91-
// are not included in the response.
92-
test.skip('Register and authenticate with usernameless', async ({ page }) => {
90+
test('Register and authenticate with usernameless', async ({ page }) => {
9391
const { navigate } = asyncEvents(page);
9492

9593
await navigate(

packages/davinci-client/src/lib/fido/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
The `fido` API provides an interface for registering and authenticating with the WebAuthn API and transforming data to and from DaVinci. These methods transform options from DaVinci into WebAuthn compatible options, then call `navigator.credentials.create` or `navigator.credentials.get`, and finally transform the output of the WebAuthn API into a valid payload to send back to DaVinci.
66

7+
**Note**: To use this module, browser support is required for `navigator.credentials.create` and `navigator.credentials.get`
8+
79
## Installation and Initialization
810

911
The `fido` module is exported as a member of the `@forgerock/davinci-client` package and is intended to be used alongside the `davinciClient` to progress through a flow. To install the necessary dependencies, run:

packages/device-client/README.md

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ The `deviceClient` API provides a structured interface for managing various type
88
2. [Installation](#installation)
99
3. [Configuration](#configuration)
1010
4. [API Methods](#api-methods)
11-
1211
- [OATH Management](#oath-management)
1312
- [PUSH Management](#push-management)
1413
- [WebAuthn Management](#webauthn-management)
@@ -36,8 +35,7 @@ npm install @forgerock/device-client --save
3635
To configure the `deviceClient`, you need to provide a `ConfigOptions` object that includes the base URL for the server and the realm path.
3736

3837
```typescript
39-
import { deviceClient } from '@forgerock/device-client';
40-
import { type ConfigOptions } from '@forgerock/javascript-sdk';
38+
import { deviceClient, type ConfigOptions } from '@forgerock/device-client';
4139

4240
const config: ConfigOptions = {
4341
serverConfig: {
@@ -59,59 +57,59 @@ const apiClient = deviceClient(config);
5957

6058
#### Methods
6159

62-
- **get(query: RetrieveOathQuery): Promise<OathDevice[]>**
60+
- **get(query: RetrieveOathQuery): Promise<OathDevice[] | { error: unknown }>**
6361
- Retrieves Oath devices based on the specified query.
6462

65-
- **delete(query: RetrieveOathQuery & { device: OathDevice }): Promise\<null>**
63+
- **delete(query: RetrieveOathQuery & { device: OathDevice }): Promise<null | { error: unknown }>**
6664
- Deletes an Oath device based on the provided query and device information.
6765

6866
### PUSH Management
6967

7068
#### Methods
7169

72-
- **get(query: PushDeviceQuery): Promise<PushDevice[]>**
70+
- **get(query: PushDeviceQuery): Promise<PushDevice[] | { error: unknown }>**
7371
- Retrieves Push devices based on the specified query.
7472

75-
- **delete(query: DeleteDeviceQuery): Promise\<null>**
73+
- **delete(query: DeleteDeviceQuery): Promise<null | { error: unknown }>**
7674
- Deletes a Push device based on the provided query.
7775

7876
### WebAuthn Management
7977

8078
#### Methods
8179

82-
- **get(query: WebAuthnQuery): Promise<WebAuthnDevice[]>**
80+
- **get(query: WebAuthnQuery): Promise<WebAuthnDevice[] | { error: unknown }>**
8381
- Retrieves WebAuthn devices based on the specified query.
8482

85-
- **update(query: WebAuthnQuery & { device: WebAuthnDevice }): Promise\<UpdatedWebAuthnDevice>**
83+
- **update(query: WebAuthnQuery & { device: WebAuthnDevice }): Promise<UpdatedWebAuthnDevice | { error: unknown }>**
8684
- Updates the name of a WebAuthn device based on the provided query and body.
8785

88-
- **delete(query: WebAuthnQuery & { device: WebAuthnDevice | UpdatedWebAuthnDevice }): Promise\<null>**
86+
- **delete(query: WebAuthnQuery & { device: WebAuthnDevice | UpdatedWebAuthnDevice }): Promise<null | { error: unknown }>**
8987
- Deletes a WebAuthn device based on the provided query and body.
9088

9189
### Bound Devices Management
9290

9391
#### Methods
9492

95-
- **get(query: GetBoundDevicesQuery): Promise\<Device[]>**
93+
- **get(query: GetBoundDevicesQuery): Promise<Device[] | { error: unknown }>**
9694
- Retrieves bound devices based on the specified query.
9795

98-
- **update(query: BoundDeviceQuery): Promise\<Device>**
96+
- **update(query: BoundDeviceQuery): Promise<Device | { error: unknown }>**
9997
- Updates the name of a bound device based on the provided query.
10098

101-
- **delete(query: BoundDeviceQuery): Promise\<null>**
99+
- **delete(query: BoundDeviceQuery): Promise<null | { error: unknown }>**
102100
- Deletes a bound device based on the provided query.
103101

104102
### Device Profiling Management
105103

106104
#### Methods
107105

108-
- **get(query: GetProfileDevices): Promise\<ProfileDevice[]>**
106+
- **get(query: GetProfileDevices): Promise<ProfileDevice[] | { error: unknown }>**
109107
- Retrieves device profiles based on the specified query.
110108

111-
- **update(query: ProfileDevicesQuery): Promise\<ProfileDevice>**
109+
- **update(query: ProfileDevicesQuery): Promise<ProfileDevice | { error: unknown }>**
112110
- Updates the name of a device profile based on the provided query.
113111

114-
- **delete(query: ProfileDevicesQuery): Promise\<null>**
112+
- **delete(query: ProfileDevicesQuery): Promise<null | { error: unknown }>**
115113
- Deletes a device profile based on the provided query.
116114

117115
## Example Usage

packages/device-client/src/lib/device.store.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77
import { type ConfigOptions } from '@forgerock/javascript-sdk';
88
import { configureStore } from '@reduxjs/toolkit';
99
import { deviceService } from './services/index.js';
10-
import { OathDevice, RetrieveOathQuery } from './types/oath.types.js';
11-
import { DeleteDeviceQuery, PushDevice, PushDeviceQuery } from './types/push-device.types.js';
12-
import { UpdatedWebAuthnDevice, WebAuthnDevice, WebAuthnQuery } from './types/webauthn.types.js';
13-
import { BoundDeviceQuery, Device, GetBoundDevicesQuery } from './types/bound-device.types.js';
14-
import {
10+
import type { OathDevice, RetrieveOathQuery } from './types/oath.types.js';
11+
import type { DeleteDeviceQuery, PushDevice, PushDeviceQuery } from './types/push-device.types.js';
12+
import type {
13+
UpdatedWebAuthnDevice,
14+
WebAuthnDevice,
15+
WebAuthnQuery,
16+
} from './types/webauthn.types.js';
17+
import type { BoundDeviceQuery, Device, GetBoundDevicesQuery } from './types/bound-device.types.js';
18+
import type {
1519
GetProfileDevices,
1620
ProfileDevice,
1721
ProfileDevicesQuery,
@@ -290,7 +294,7 @@ export const deviceClient = (config: ConfigOptions) => {
290294
* Get profile devices
291295
*
292296
* @async
293-
* @function update
297+
* @function get
294298
* @param {GetProfileDevices} query - The query used to get profile devices
295299
* @returns {Promise<ProfileDevice[] | { error: unknown }>} - A promise that resolves to the response data or an error object if the response is not valid.
296300
*/
@@ -310,7 +314,7 @@ export const deviceClient = (config: ConfigOptions) => {
310314
}
311315
},
312316
/**
313-
* Get profile devices
317+
* Update profile devices
314318
*
315319
* @async
316320
* @function update
@@ -333,11 +337,11 @@ export const deviceClient = (config: ConfigOptions) => {
333337
}
334338
},
335339
/**
336-
* Get profile devices
340+
* Delete profile devices
337341
*
338342
* @async
339-
* @function update
340-
* @param {ProfileDevicesQuery} query - The query used to update a profile device
343+
* @function delete
344+
* @param {ProfileDevicesQuery} query - The query used to delete a profile device
341345
* @returns {Promise<null | { error: unknown }>} - A promise that resolves to null or an error object if the response is not valid.
342346
*/
343347
delete: async function (query: ProfileDevicesQuery): Promise<null | { error: unknown }> {

packages/oidc-client/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
# oidc-client
1+
# OIDC Client
22

3-
A generic OpenID Connect (OIDC) client library for JavaScript and TypeScript, designed to work with any OIDC-compliant identity provider.
3+
A generic OpenID Connect (OIDC) client library for JavaScript and TypeScript, designed to work with PingOne platforms.
4+
5+
The oidc module follows the [OIDC](https://openid.net/specs/openid-connect-core-1_0.html) specification and provides a simple and easy-to-use API to interact with the OIDC server. It allows you to authenticate, retrieve the access token, revoke the token, and sign out from the OIDC server.
46

57
```js
68
// Initialize OIDC Client

packages/protect/README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ resumeBehavioralData();
1414

1515
## Quickstart with a PingOne AIC or PingAM Authentication Journey
1616

17-
The Ping Protect module is intended to be used along with the ForgeRock JavaScript SDK to provide the Protect feature.
17+
The Ping Protect module is intended to be used along with the Journey client to provide the Protect feature.
1818

1919
### Requirements
2020

2121
1. PingOne Advanced Identity Cloud (aka PingOne AIC) platform or an up-to-date Ping Identity Access Management (aka PingAM)
2222
2. PingOne tenant with Protect enabled
2323
3. A Ping Protect Service configured in AIC or AM
2424
4. A journey/tree with the appropriate Protect Nodes
25-
5. A client application with the `@forgerock/javascript-sdk` and `@forgerock/protect` modules installed
25+
5. A client application with the `@forgerock/journey-client` and `@forgerock/protect` modules installed
2626

2727
### Integrate into a Client Application
2828

@@ -31,11 +31,11 @@ The Ping Protect module is intended to be used along with the ForgeRock JavaScri
3131
Install both modules and their latest versions:
3232

3333
```sh
34-
npm install @forgerock/javascript-sdk @forgerock/protect
34+
npm install @forgerock/journey-client @forgerock/protect
3535
```
3636

3737
```sh
38-
pnpm install @forgerock/javascript-sdk @forgerock/protect
38+
pnpm install @forgerock/journey-client @forgerock/protect
3939
```
4040

4141
#### Initialization (Recommended)
@@ -70,10 +70,10 @@ if (step.getCallbacksOfType('PingOneProtectInitializeCallback')) {
7070

7171
#### Data collection
7272

73-
You then call the `FRAuth.next` method after initialization to move the user forward in the journey.
73+
You then call the `next` method after initialization to move the user forward in the journey.
7474

7575
```js
76-
FRAuth.next(step);
76+
journeyClient.next(step);
7777
```
7878

7979
At some point in the journey, and as late as possible in order to collect as much data as you can, you will come across the `PingOneProtectEvaluationCallback`. This is when you call the `getData` method to package what's been collected for the server to evaluate.
@@ -92,12 +92,12 @@ Now that we have the data, set it on the callback in order to send it to the ser
9292
```js
9393
callback.setData(data);
9494

95-
FRAuth.next(step);
95+
journeyClient.next(step);
9696
```
9797

9898
### Error Handling
9999

100-
The Protect API methods will return an error object if they fail. When you encounter an error during initialization or evaluation, set the error message on the callback using the `setClientError` method. Setting the message on the callback is how it gets sent to the server on the `FRAuth.next` method call.
100+
The Protect API methods will return an error object if they fail. When you encounter an error during initialization or evaluation, set the error message on the callback using the `setClientError` method. Setting the message on the callback is how it gets sent to the server on the `next` method call.
101101

102102
```js
103103
if (step.getCallbacksOfType('PingOneProtectInitializeCallback')) {

packages/sdk-effects/iframe-manager/README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# IFrame Manager (`@pingidentity/sdk-effects/iframe-manager`)
1+
# IFrame Manager (`@forgerock/iframe-manager`)
22

33
## Overview
44

@@ -7,22 +7,20 @@ The IFrame Manager Effect provides a mechanism to perform operations within a hi
77
The core functionality involves:
88

99
1. Creating a hidden `<iframe>` dynamically.
10-
1. Navigating the iframe to a specified URL.
11-
1. Monitoring the iframe's `load` events to detect navigation changes.
12-
1. Once a navigation occurs back to the **same origin** as the parent application, parsing the query parameters from the iframe's URL.
13-
1. Resolving or rejecting a Promise based on the presence of predefined "success" or "error" query parameters.
14-
1. Handling timeouts and potential errors (like cross-origin access restrictions).
10+
2. Navigating the iframe to a specified URL.
11+
3. Monitoring the iframe's `load` events to detect navigation changes.
12+
4. Once a navigation occurs back to the **same origin** as the parent application, parsing the query parameters from the iframe's URL.
13+
5. Resolving or rejecting a Promise based on the presence of predefined "success" or "error" query parameters.
14+
6. Handling timeouts and potential errors (like cross-origin access restrictions).
1515

1616
**Key Constraint: Same-Origin Policy**
1717

1818
This utility fundamentally relies on the browser's **Same-Origin Policy**. The final URL that the iframe is redirected to (the one containing the expected `successParams` or `errorParams`) **MUST** be on the exact same origin (protocol, hostname, and port) as the main application window. Attempting to access the location (`contentWindow.location`) of an iframe pointing to a different origin will be blocked by the browser, causing the operation to fail.
1919

2020
## Installation
2121

22-
This effect is typically part of a larger SDK. Assume it's imported or available within your project structure like so (adjust path as necessary):
23-
2422
```typescript
25-
import iFrameManager from './path/to/iframe-manager.effects'; // Adjust path as needed
23+
import iFrameManager from '@forgerock/iframe-manager';
2624

2725
const iframeMgr = iFrameManager();
2826
```
@@ -40,19 +38,16 @@ This is the main factory function that initializes the effect.
4038
This method creates a hidden iframe, initiates navigation, and waits for a redirect back to the application's origin containing specific query parameters.
4139

4240
- **`options`**: `GetParamsFromIFrameOptions` - An object containing configuration for the iframe request.
43-
4441
- **`url: string`**: The initial URL to load within the hidden iframe. This URL is expected to eventually redirect back to the application's origin.
4542
- **`timeout: number`**: The maximum time in milliseconds to wait for the entire operation to complete successfully (i.e., for a redirect containing success or error parameters). If the timeout is reached before completion, the promise rejects.
46-
4743
* **`successParams: string[]`**: An array of query parameter _keys_. If the final redirect URL (on the same origin) contains **at least one** of these keys in its query string, the promise will **resolve**.
48-
* **`errorParams: string[]`**: An array of query parameter _keys_. If the final redirect URL (on the same origin) contains **any** of these keys in its query string, the promise will **reject**. Error parameters are checked _before_ success parameters.
44+
* **`errorParams: string[]`**: An array of query parameter _keys_. If the final redirect URL (on the same origin) contains **any** of these keys in its query string, the promise will **resolve** with all parsed parameters (including the error parameters). The caller must check the returned parameters for error keys. Error parameters are checked _before_ success parameters.
4945
- _Note:_ Both `successParams` and `errorParams` must be provided and contain at least one key.
5046

5147
- **Returns**: `Promise<ResolvedParams>`
52-
5348
- **On Success**: Resolves with `ResolvedParams`, an object containing _all_ query parameters parsed from the final redirect URL's query string. This occurs when the iframe redirects back to the same origin and its URL contains at least one key listed in `successParams` (and no keys listed in `errorParams`).
49+
- **On Error Params**: Resolves with `ResolvedParams` containing _all_ parsed query parameters if the final redirect URL contains any key listed in `errorParams`. The caller must inspect the result for error keys.
5450
- **On Failure**: Rejects with:
55-
- `ResolvedParams`: An object containing _all_ parsed query parameters if the final redirect URL contains any key listed in `errorParams`.
5651
- An object `{ type: 'internal_error', message: 'iframe timed out' }` if the specified `timeout` is reached before a success or error condition is met.
5752
- An object `{ type: 'internal_error', message: 'unexpected failure' }` if there's an error accessing the iframe's content window (most likely due to a cross-origin redirect that wasn't expected or handled).
5853
- An object `{ type: 'internal_error', message: 'error setting up iframe' }` if there was an issue creating or configuring the iframe initially.
@@ -63,7 +58,7 @@ This method creates a hidden iframe, initiates navigation, and waits for a redir
6358
## Usage Example
6459

6560
```typescript
66-
import iFrameManager from './path/to/iframe-manager.effects'; // Adjust path
61+
import iFrameManager from '@forgerock/iframe-manager';
6762

6863
const iframeMgr = iFrameManager();
6964

@@ -77,10 +72,15 @@ async function performSilentLogin(authUrl: string) {
7772

7873
try {
7974
console.log('Attempting silent login via iframe...');
80-
// The promise resolves/rejects when the iframe redirects back to *this* app's origin
81-
// with appropriate query parameters.
75+
// The promise resolves with all parsed params regardless of success/error.
8276
const resultParams = await iframeMgr.getParamsByRedirect(options);
8377

78+
// Check if the server returned an error
79+
if (resultParams.error || resultParams.error_description) {
80+
console.error('Silent login failed. Server returned error:', resultParams);
81+
return;
82+
}
83+
8484
// Success case: 'code', 'id_token', or 'session_state' was present
8585
console.log('Silent login successful. Received params:', resultParams);
8686
// Process the received parameters (e.g., exchange code for token)
@@ -117,4 +117,4 @@ performSilentLogin(authorizationUrl);
117117
1. **Timeout:** Choose a reasonable `timeout` value. If the external service is slow or the redirect chain is long, the operation might time out prematurely. Conversely, too long a timeout might delay feedback to the user if something goes wrong.
118118
1. **Intermediate Redirects:** The code handles intermediate redirects (pages loaded within the iframe that don't contain success or error parameters) by simply waiting for the next `load` event. The process only completes upon detecting success/error parameters or timing out.
119119
1. **Cleanup:** The utility ensures the iframe element is removed from the DOM and the timeout timer is cleared upon completion (resolve, reject, or timeout) to prevent memory leaks.
120-
1. **Error Parameter Precedence:** Error parameters (`errorParams`) are checked before success parameters (`successParams`). If a redirect URL contains both an error parameter and a success parameter, the promise will be **rejected**.
120+
1. **Error Parameter Precedence:** Error parameters (`errorParams`) are checked before success parameters (`successParams`). If a redirect URL contains both an error parameter and a success parameter, the promise will **resolve** with all parameters, and the caller must check for the error parameter keys to determine it's an error state.

packages/sdk-effects/iframe-manager/src/lib/iframe-manager.effects.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ export function iFrameManager() {
5858
* Accessing contentWindow.location of a cross-origin iframe will fail.
5959
*
6060
* @param options - The options for the iframe request (URL, timeout, success/error params).
61-
* @returns A Promise that resolves with the parsed query parameters on success,
62-
* or rejects on error, timeout, or if unable to access iframe content.
61+
* @returns A Promise that resolves with the parsed query parameters on success or
62+
* when error params are present; rejects on timeout or if unable to access iframe content.
6363
*/
6464
return {
6565
getParamsByRedirect: (options: GetParamsFromIFrameOptions): Promise<ResolvedParams> => {
@@ -116,7 +116,7 @@ export function iFrameManager() {
116116
// 1. Check for Error Parameters
117117
if (hasErrorParams(searchParams, errorParams)) {
118118
cleanup();
119-
resolve(parsedParams); // Reject with all parsed params for context
119+
resolve(parsedParams); // Resolve with all parsed params for context
120120
return;
121121
}
122122

0 commit comments

Comments
 (0)