@forgerock/login-widget 1.0.0-alpha.1 → 1.0.0-alpha.10
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/CHANGELOG.md +22 -0
- package/LICENSE +28 -0
- package/README.md +693 -0
- package/inline.cjs +27528 -0
- package/inline.cjs.map +1 -0
- package/inline.d.ts +2022 -0
- package/inline.js +27521 -0
- package/inline.js.map +1 -0
- package/modal.cjs +28247 -0
- package/modal.cjs.map +1 -0
- package/modal.d.ts +2052 -0
- package/modal.js +28239 -0
- package/modal.js.map +1 -0
- package/package.json +20 -7
- package/widget.css +1611 -0
package/README.md
ADDED
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
# ForgeRock Web Login Framework
|
|
2
|
+
|
|
3
|
+
[](http://commitizen.github.io/cz-cli/)
|
|
4
|
+
[](https://github.com/semantic-release/semantic-release)
|
|
5
|
+
|
|
6
|
+
## WARNING: VAPORWARE
|
|
7
|
+
|
|
8
|
+
**This is a prototype of a development framework for generating a ForgeRock Login App for self-hosting or JavaScript Widget into an existing self-hosted SPA (React, Vue, Angular, etc.). This project is not officially supported and is not recommended for any project development. If you use this, you accept all the risks that come with completely unsupported software.**
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Overview](#overview)
|
|
13
|
+
- [Quick Start: Using the Widget in Your App](#quick-start-using-the-widget-in-your-app)
|
|
14
|
+
- [Adding the Widget's CSS](#adding-the-widgets-css)
|
|
15
|
+
- [Using the Modal component](#using-the-modal-component)
|
|
16
|
+
- [Using the Inline component](#using-the-inline-component)
|
|
17
|
+
- [Complete Widget API](#complete-widget-api)
|
|
18
|
+
- [Widget](#widget)
|
|
19
|
+
- [Journey](#journey)
|
|
20
|
+
- [User](#user)
|
|
21
|
+
- [Request](#request)
|
|
22
|
+
- [Modal](#modal)
|
|
23
|
+
- [Inline](#inline)
|
|
24
|
+
- [Styling API](#styling-api)
|
|
25
|
+
- [Future APIs (not implemented)](#future-apis-not-implemented)
|
|
26
|
+
- [Currently unsupported](#currently-unsupported)
|
|
27
|
+
- [Widget customization (future)](#widget-customization-future)
|
|
28
|
+
- [Additional modal events (future)](#additional-modal-events-future)
|
|
29
|
+
- [Quick Start: Internal Login Framework Development](#quick-start-internal-login-framework-development)
|
|
30
|
+
- [Technical requirements](#technical-requirements)
|
|
31
|
+
- [Knowledge requirements](#knowledge-requirements)
|
|
32
|
+
- [Instal, build & run](#instal-build--run)
|
|
33
|
+
- [Disclaimer](#disclaimer)
|
|
34
|
+
- [License](#license)
|
|
35
|
+
|
|
36
|
+
## Overview
|
|
37
|
+
|
|
38
|
+
The Login Widget produced by this framework is intended to be an all-inclusive, UI component that can be used within any modern JavaScript app for handling the default login, registration and related user flows. It can be used within a React, Vue, Angular or any other modern JavaScript framework (does not currently support Node.js or server-rendering (SSR)).
|
|
39
|
+
|
|
40
|
+
This Widget uses the ForgeRock JavaScript SDK internally. It adds a UI rendering layer on top of the SDK to help eliminate the need to develop and maintain the UI components necessary for providing complex authentication flows. Although this rendering layer is developed with Svelte and Tailwind, it is "compiled away" and has no runtime dependencies. It is library and framework agnostic.
|
|
41
|
+
|
|
42
|
+
This Widget can be used in two different ways (or "form factors"):
|
|
43
|
+
|
|
44
|
+
1. **Modal** component: this renders the form elements inside a modal dialog that can be opened and closed. This component is mounted outside of your app's controlled DOM.
|
|
45
|
+
2. **Inline** component: this is just the form elements themselves, no container. This component is intended to be rendered inside your app's controlled DOM.
|
|
46
|
+
|
|
47
|
+
Both components provide the same authentication, token and user features. The only difference is how the component is rendered within your app.
|
|
48
|
+
|
|
49
|
+
The Modal component is recommended as it provides the quickest development experience for providing login and registration flows into your app with the least disruption to your codebase. The Modal will be controlled within your app, but rendered in its own DOM root node and visual layer.
|
|
50
|
+
|
|
51
|
+
For example:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<!DOCTYPE html>
|
|
55
|
+
<html lang="en">
|
|
56
|
+
<head></head>
|
|
57
|
+
<body>
|
|
58
|
+
<div id="react-root">
|
|
59
|
+
<!--
|
|
60
|
+
Contents of this div are controlled by React or Vue via the Virtual DOM
|
|
61
|
+
-->
|
|
62
|
+
</div>
|
|
63
|
+
<!--
|
|
64
|
+
Outside of React or Vue's controlled DOM
|
|
65
|
+
-->
|
|
66
|
+
<div id="widget-root"></div>
|
|
67
|
+
</body>
|
|
68
|
+
</html>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The Inline component, on the other hand, allows you to render the resulting form within your app's controlled DOM and visual layer (rather than on top of it) in whatever way is best for you, but there are some caveats to understand.
|
|
72
|
+
|
|
73
|
+
For example:
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<!DOCTYPE html>
|
|
77
|
+
<html lang="en">
|
|
78
|
+
<head></head>
|
|
79
|
+
<body>
|
|
80
|
+
<div id="react-root">
|
|
81
|
+
<!--
|
|
82
|
+
Contents of this div are controlled by React or Vue via the Virtual DOM
|
|
83
|
+
|
|
84
|
+
Widget's root will need to be _mounted_ inside this "controlled" div by
|
|
85
|
+
React or Vue **before** instantiating Widget
|
|
86
|
+
-->
|
|
87
|
+
</div>
|
|
88
|
+
</body>
|
|
89
|
+
</html>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
More details will be discussed below in the [Inline section](#using-the-inline-component).
|
|
93
|
+
|
|
94
|
+
## Quick Start: Using the Widget in Your App
|
|
95
|
+
|
|
96
|
+
Note: This project is currently in Beta, so this is not available via public npm. Because of this, it's worth noting what's not [currently supported](#currently-unsupported).
|
|
97
|
+
|
|
98
|
+
1. `git clone https://github.com/cerebrl/forgerock-web-login-framework`
|
|
99
|
+
2. `cd forgerock-web-login-framework`
|
|
100
|
+
3. `npm install` (or simply `npm i`)
|
|
101
|
+
4. `npm run build:widget`
|
|
102
|
+
5. Copy the built `package/` directory with its contents and paste (or drag-n-drop) it into your project
|
|
103
|
+
6. Import the Widget by directory reference, since it's local to your project; e.g. `import Widget from '../path/to/package/modal';`
|
|
104
|
+
|
|
105
|
+
### Adding the Widget's CSS
|
|
106
|
+
|
|
107
|
+
There are a few ways to add the Widget's CSS to your product:
|
|
108
|
+
|
|
109
|
+
1. Import it into your JavaScript project as a module
|
|
110
|
+
2. Import it using a CSS preprocessor, like Sass, Less or PostCSS
|
|
111
|
+
3. Copy and paste the CSS file from the Widget and link it into your HTML
|
|
112
|
+
|
|
113
|
+
If you decide to import the CSS into your JavaScript, make sure your bundler knows how to import and process the CSS as a module. If using a CSS preprocessor, ensure you configure your preprocessor to access files from within your `package/` directory.
|
|
114
|
+
|
|
115
|
+
Copying the file and pasting it into your project for linking in the HTML is the easiest.
|
|
116
|
+
|
|
117
|
+
Importing into your JavaScript:
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
import '../path/to/package/widget.css';
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Importing into your CSS:
|
|
124
|
+
|
|
125
|
+
```css
|
|
126
|
+
@import '../path/to/package/widget.css';
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Linking CSS in HTML example:
|
|
130
|
+
|
|
131
|
+
```html
|
|
132
|
+
<!DOCTYPE html>
|
|
133
|
+
<html lang="en">
|
|
134
|
+
<head>
|
|
135
|
+
<!-- ... -->
|
|
136
|
+
<link rel="stylesheet" href="/path/to/package/widget.css" />
|
|
137
|
+
</head>
|
|
138
|
+
<body>
|
|
139
|
+
<!-- ... -->
|
|
140
|
+
</body>
|
|
141
|
+
</html>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Controlling the CSS cascade
|
|
145
|
+
|
|
146
|
+
To ensure the proper CSS cascade, you can use `@layer` to ensure the browser applies the CSS in the way you intend regardless of the order you import or declare the CSS in your project. You can [read more about this new browser feature in the Mozilla docs](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer).
|
|
147
|
+
|
|
148
|
+
Steps recommended:
|
|
149
|
+
|
|
150
|
+
1. Wrap your current CSS in a layer called `app`:
|
|
151
|
+
|
|
152
|
+
```css
|
|
153
|
+
@layer app {
|
|
154
|
+
/* Your app's CSS */
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Widget layers are already declared within the Widget's CSS.
|
|
159
|
+
|
|
160
|
+
2. Declare the order of layers in your index HTML file before any CSS is loaded:
|
|
161
|
+
|
|
162
|
+
```html
|
|
163
|
+
<style type="text/css">
|
|
164
|
+
@layer app;
|
|
165
|
+
/* List the Widget layers last */
|
|
166
|
+
@layer 'fr-widget.base';
|
|
167
|
+
@layer 'fr-widget.utilities';
|
|
168
|
+
@layer 'fr-widget.components';
|
|
169
|
+
@layer 'fr-widget.variants';
|
|
170
|
+
</style>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
It's important to note that none of the CSS imported for the Widget will overwrite any of your app's CSS. It's all namespaced to ensure there are no collisions. Unless, that is, you use the exact same selector naming convention we use.
|
|
174
|
+
|
|
175
|
+
### Using the Modal component
|
|
176
|
+
|
|
177
|
+
#### Add element to your HTML file
|
|
178
|
+
|
|
179
|
+
We recommend you add a new element on which you will mount the Widget to your static HTML file. For most SPAs (Single Page Applications), this will be your `index.html`. This new element should be a direct child element of the body, and not without the element you mount your SPA.
|
|
180
|
+
|
|
181
|
+
Example:
|
|
182
|
+
|
|
183
|
+
```html
|
|
184
|
+
<!DOCTYPE html>
|
|
185
|
+
<html lang="en">
|
|
186
|
+
<head>
|
|
187
|
+
<!-- ... -->
|
|
188
|
+
</head>
|
|
189
|
+
<body>
|
|
190
|
+
<!-- Root element for main app -->
|
|
191
|
+
<div id="root"></div>
|
|
192
|
+
<!-- Root element for Widget -->
|
|
193
|
+
<div id="widget-root"></div>
|
|
194
|
+
<!-- scripts ... -->
|
|
195
|
+
</body>
|
|
196
|
+
</html>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
NOTE: We do not recommend injecting the element on which you will mount the widget within your main application. This can cause Virtual DOM issues, so manually adding it within your static HTML file is best.
|
|
200
|
+
|
|
201
|
+
#### Instantiate the Widget (Modal)
|
|
202
|
+
|
|
203
|
+
Now, you can import the Widget into your app wherever you would like as a modal dialog (aka "lightbox"), or as an embedded component. Once the Widget is imported, you will need to instantiate it.
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
// As modal dialog
|
|
207
|
+
import Widget from 'forgerock-web-login-widget/modal';
|
|
208
|
+
|
|
209
|
+
// ...
|
|
210
|
+
|
|
211
|
+
new Widget({
|
|
212
|
+
target: document.getElementById('widget-root'), // Any existing element from static HTML file
|
|
213
|
+
props: {
|
|
214
|
+
config: {}, // Your JS SDK configuration; see below
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
This mounts your Widget into the DOM. If you choose the modal version, it will be hidden at first.
|
|
220
|
+
|
|
221
|
+
Note: [See additional documentation about configuring the JS SDK](https://backstage.forgerock.com/docs/sdks/3.3/javascript/configuring/configuring-forgerock-sdk-settings-for-your-javascript-app.html).
|
|
222
|
+
|
|
223
|
+
#### Starting a journey (Modal)
|
|
224
|
+
|
|
225
|
+
The Widget will be mounted to the DOM, but it will not display the first step of the journey. To render the first step, you'll need to import the `journey` object and call the `journey.start` method. This makes the initial request to the ForgeRock server for the initial step.
|
|
226
|
+
|
|
227
|
+
```js
|
|
228
|
+
import Widget, { journey } from 'forgerock-web-login-widget/modal';
|
|
229
|
+
|
|
230
|
+
new Widget({
|
|
231
|
+
target: document.getElementById('login-widget'), // Any existing element in the DOM
|
|
232
|
+
props: {
|
|
233
|
+
config: {}, // Your JS SDK configuration; see below
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Be sure to call after instantiating the Widget
|
|
238
|
+
journey.start();
|
|
239
|
+
|
|
240
|
+
// OR, call on button click
|
|
241
|
+
buttonElement.addEventListener('click', (event) => {
|
|
242
|
+
journey.start();
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
This `journey.start` method can be called anywhere in your application, or anytime as long as it's _after_ the Widget being mounted to the DOM.
|
|
247
|
+
|
|
248
|
+
#### Listening for journey completion (Modal)
|
|
249
|
+
|
|
250
|
+
Use the `journey.onSuccess` method to know when a user has completed their journey. Pass a callback function into this method to run when the journey successfully completes.
|
|
251
|
+
|
|
252
|
+
```js
|
|
253
|
+
journey.onSuccess((response) => {
|
|
254
|
+
console.log(response);
|
|
255
|
+
});
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
And, that's it. You now can mount, display, and authenticate users through the ForgeRock Login Widget. There are addition features documented below for a more complete implementation. For more about Widget events, [see the Widget Events section](#widget-events).
|
|
259
|
+
|
|
260
|
+
#### Controlling the modal dialog
|
|
261
|
+
|
|
262
|
+
To show the modal, you will need to import the `modal` object, and use the `modal.open` method. It's common to execute this within a button's click handler.
|
|
263
|
+
|
|
264
|
+
```js
|
|
265
|
+
import Widget, { modal } from 'forgerock-web-login-widget/modal';
|
|
266
|
+
|
|
267
|
+
// ...
|
|
268
|
+
|
|
269
|
+
const loginButton = document.getElementById('loginButton');
|
|
270
|
+
loginButton.addEventListener('click', () => {
|
|
271
|
+
modal.open();
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Opening the modal will display the Widget in a "Lightbox" or modal dialog and make a request to your ID Cloud (or AM) instance. When the Widget gets the response, it will display the required fields for authenticating the user. When the user successfully authenticates, the modal will close itself. If you'd like to close the widget programmatically, you can call the `modal.close` method.
|
|
276
|
+
|
|
277
|
+
### Using the Inline component
|
|
278
|
+
|
|
279
|
+
#### Element for mounting
|
|
280
|
+
|
|
281
|
+
The Widget requires a real DOM element on which to mount. Since the Inline component will be mounted within your application's controlled DOM, it's important to understand the lifecycle of how your framework mounts elements to the DOM.
|
|
282
|
+
|
|
283
|
+
React, for example, uses the Virtual DOM, and the Inline component cannot mount to a Virtual DOM element. So, you will need to wait until the element has been property mounted to the real DOM before instantiating the Widget.
|
|
284
|
+
|
|
285
|
+
#### Instantiate the Widget (Inline)
|
|
286
|
+
|
|
287
|
+
Now, import the Widget where you'd like to mount it. In whatever way your framework requires, provide a reference to the element mounted in the actual DOM as the target of the Widget instantiation.
|
|
288
|
+
|
|
289
|
+
```js
|
|
290
|
+
// As inline
|
|
291
|
+
import Widget from 'forgerock-web-login-widget/inline';
|
|
292
|
+
|
|
293
|
+
// ...
|
|
294
|
+
|
|
295
|
+
new Widget({
|
|
296
|
+
target: mountedDomElement, // ensure this is a reference to a real DOM element
|
|
297
|
+
props: {
|
|
298
|
+
config: {}, // Your JS SDK configuration; see below
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
This mounts your Widget into the DOM. If you choose the modal version, it will be hidden at first.
|
|
304
|
+
|
|
305
|
+
Note: [See additional documentation about configuring the JS SDK](https://backstage.forgerock.com/docs/sdks/3.3/javascript/configuring/configuring-forgerock-sdk-settings-for-your-javascript-app.html).
|
|
306
|
+
|
|
307
|
+
#### Starting a journey (Inline)
|
|
308
|
+
|
|
309
|
+
The Widget will be mounted to the DOM, but it will not display the first step of the journey. To render the first step, you'll need to import the `journey` object and call the `journey.start` method. This makes the initial request to the ForgeRock server for the initial step.
|
|
310
|
+
|
|
311
|
+
```js
|
|
312
|
+
import Widget, { journey } from 'forgerock-web-login-widget/inline';
|
|
313
|
+
|
|
314
|
+
// Call after instantiating the Widget
|
|
315
|
+
new Widget({
|
|
316
|
+
target: actualDomElement, // ensure this is a reference to a real DOM element
|
|
317
|
+
props: {
|
|
318
|
+
config: {}, // Your JS SDK configuration; see below
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
journey.start();
|
|
322
|
+
|
|
323
|
+
// OR, call on button click
|
|
324
|
+
buttonElement.addEventListener('click', (event) => {
|
|
325
|
+
journey.start();
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
This `journey.start` method can be called anywhere in your application, or anytime as long as it's _after_ the Widget being mounted to the DOM.
|
|
330
|
+
|
|
331
|
+
#### Listening for journey completion (Inline)
|
|
332
|
+
|
|
333
|
+
Use the `journey.onSuccess` method to know when a user has completed their journey. Pass a callback function into this method to run when the journey successfully completes.
|
|
334
|
+
|
|
335
|
+
```js
|
|
336
|
+
journey.onSuccess((response) => {
|
|
337
|
+
console.log(response);
|
|
338
|
+
});
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
And, that's it. You now can mount, display, and authenticate users through the ForgeRock Login Widget. There are addition features documented below for a more complete implementation. For more about Widget events, [see the Widget Events section](#widget-events).
|
|
342
|
+
|
|
343
|
+
## Complete Widget API
|
|
344
|
+
|
|
345
|
+
The Widget comes with methods and event handlers used to control the lifecycle of user journeys/authentication.
|
|
346
|
+
|
|
347
|
+
### Widget
|
|
348
|
+
|
|
349
|
+
```js
|
|
350
|
+
// As modal dialog
|
|
351
|
+
import Widget from 'forgerock-web-login-widget/modal';
|
|
352
|
+
|
|
353
|
+
// OR, as embedded
|
|
354
|
+
import Widget from 'forgerock-web-login-widget/inline';
|
|
355
|
+
|
|
356
|
+
// Instantiate Widget
|
|
357
|
+
const widget = new Widget({
|
|
358
|
+
target: document.getElementById('widget-root'), // REQUIRED; Element available in DOM
|
|
359
|
+
props: {
|
|
360
|
+
/**
|
|
361
|
+
* REQUIRED; SDK configuration object
|
|
362
|
+
*/
|
|
363
|
+
config: {
|
|
364
|
+
serverConfig: {
|
|
365
|
+
baseUrl: 'https://customer.forgeblocks.com/am', // REQUIRED; URL to ForgeRock AM
|
|
366
|
+
},
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* OPTIONAL, *BUT ENCOURAGED*, CONFIGURATION
|
|
370
|
+
* Remaining config is optional with fallback values shown
|
|
371
|
+
*/
|
|
372
|
+
clientId: 'WebLoginWidgetClient', // OPTIONAL; Uses 'WebLoginWidgetClient', if not provided
|
|
373
|
+
realmPath: 'alpha', // OPTIONAL; Uses 'alpha', if not provided
|
|
374
|
+
redirectUri: window.location.href, // OPTIONAL; falls back to `window.location.href`
|
|
375
|
+
scope: 'openid email', // OPTIONAL; falls back to minimal 'openid email'
|
|
376
|
+
tree: 'Login', // OPTIONAL; falls back to default Login journey provided in ForgeRock
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* OPTIONAL; See below for the content object schema
|
|
381
|
+
*/
|
|
382
|
+
content: {},
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* OPTIONAL; See below for Styling section
|
|
386
|
+
*/
|
|
387
|
+
style: {},
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
// OPTIONAL; Remove widget from DOM and destroy all listeners
|
|
392
|
+
widget.$destroy();
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
NOTE: For more SDK configuration options, please [see our SDK's configuration document](https://backstage.forgerock.com/docs/sdks/3.3/javascript/configuring/configuring-forgerock-sdk-settings-for-your-javascript-app.html), or you can [see our API docs for more developer detail](https://backstage.forgerock.com/docs/sdks/3.3/_attachments/javascript/api-reference-core/interfaces/configoptions.html).
|
|
396
|
+
|
|
397
|
+
NOTE: For content schema, please [use the example en-US locale file](/src/locales/us/en/index.ts).
|
|
398
|
+
|
|
399
|
+
### Journey
|
|
400
|
+
|
|
401
|
+
The `journey` object:
|
|
402
|
+
|
|
403
|
+
```js
|
|
404
|
+
import { journey } from 'forgerock-web-login-widget/modal';
|
|
405
|
+
// OR, import { journey } from 'forgerock-web-login-widget/inline';
|
|
406
|
+
|
|
407
|
+
// Call to start the journey
|
|
408
|
+
// Optional config can be passed in, see below for more details
|
|
409
|
+
journey.start();
|
|
410
|
+
|
|
411
|
+
// Listeners for journey events
|
|
412
|
+
// See below for more details on `response`
|
|
413
|
+
journey.onSuccess((response) => {
|
|
414
|
+
/* Run anything you want */
|
|
415
|
+
});
|
|
416
|
+
journey.onFailure((error) => {
|
|
417
|
+
/* Run anything you want */
|
|
418
|
+
});
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
NOTE: Optional `start` config:
|
|
422
|
+
|
|
423
|
+
```js
|
|
424
|
+
journey.start({
|
|
425
|
+
config: undefined, // OPTIONAL; defaults to undefined, mechanism to override base SDK config object
|
|
426
|
+
oauth: true, // OPTIONAL; defaults to true and uses OAuth flow for acquiring tokens
|
|
427
|
+
user: true, // OPTIONAL; default to true and returns user information from `userinfo` endpoint
|
|
428
|
+
});
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
NOTE: Schema for `response`
|
|
432
|
+
|
|
433
|
+
```js
|
|
434
|
+
// response
|
|
435
|
+
{
|
|
436
|
+
journey: {
|
|
437
|
+
completed: false, // boolean
|
|
438
|
+
error: null, // null or object with `code`, `message` and `step` that failed
|
|
439
|
+
loading: false, // boolean
|
|
440
|
+
step: null, // null or object with the last step object from ForgeRock AM
|
|
441
|
+
successful: false, // boolean
|
|
442
|
+
response: null, // null or object, if successful, it will contain the success response from AM
|
|
443
|
+
},
|
|
444
|
+
oauth: {
|
|
445
|
+
completed: false, // boolean
|
|
446
|
+
error: null, // null or object with `code` and `message` properties
|
|
447
|
+
loading: false, // boolean
|
|
448
|
+
successful: false, // boolean
|
|
449
|
+
response: null, // null or object with OAuth/OIDC tokens
|
|
450
|
+
},
|
|
451
|
+
user: {
|
|
452
|
+
completed: false, // boolean
|
|
453
|
+
error: null, // null or object with `code` and `message` properties
|
|
454
|
+
loading: false, // boolean
|
|
455
|
+
successful: false, // boolean
|
|
456
|
+
response: null, // null or object with user information driven by OAuth scope config
|
|
457
|
+
},
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### User
|
|
462
|
+
|
|
463
|
+
The `user` object:
|
|
464
|
+
|
|
465
|
+
```js
|
|
466
|
+
import { user } from 'forgerock-web-login-widget/modal';
|
|
467
|
+
// OR, import { user } from 'forgerock-web-login-widget/inline';
|
|
468
|
+
|
|
469
|
+
// Is user currently authorized
|
|
470
|
+
await user.authorized(); // do they have OAuth tokens (local)?
|
|
471
|
+
await user.authorized({ remote: true }); // do we have valid tokens (remote)?
|
|
472
|
+
|
|
473
|
+
// Get user information
|
|
474
|
+
await user.info(); // what we have locally in-memory
|
|
475
|
+
await user.info({ remote: true }); // request user info from server
|
|
476
|
+
|
|
477
|
+
// Log user out
|
|
478
|
+
await user.logout();
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Request
|
|
482
|
+
|
|
483
|
+
The Widget has an alias to the JavaScript SDK's `HttpClient.request`, which is a convenience wrapper around the native `fetch`. All this does is auto-inject the Access Token into the `Authorization` header and manage some of the lifecycle around the token.
|
|
484
|
+
|
|
485
|
+
```js
|
|
486
|
+
import { request } from 'forgerock-web-login-widget/modal';
|
|
487
|
+
// OR, import { request } from 'forgerock-web-login-widget/inline';
|
|
488
|
+
|
|
489
|
+
// See below for more details on the options
|
|
490
|
+
request({ init: { method: 'GET' }, url: 'https://protected.resource.com' });
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
The full `options` object:
|
|
494
|
+
|
|
495
|
+
```js
|
|
496
|
+
{
|
|
497
|
+
bypassAuthentication: false, // Boolean; if true, Access Token is not injected into Authorization header
|
|
498
|
+
init: {
|
|
499
|
+
// Options object for `fetch` API: https://developer.mozilla.org/en-US/docs/Web/API/fetch
|
|
500
|
+
},
|
|
501
|
+
timeout: 3000, // Fetch timeout in milliseconds
|
|
502
|
+
url: 'https://protected.resource.com', // String; the URL of the resource
|
|
503
|
+
|
|
504
|
+
// Unsupported properties
|
|
505
|
+
authorization: {},
|
|
506
|
+
requiresNewToken: () => {},
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
For the full type definition of this, please [view our SDK API documentation](https://backstage.forgerock.com/docs/sdks/3.3/_attachments/javascript/api-reference-core/interfaces/httpclientrequestoptions.html).
|
|
511
|
+
|
|
512
|
+
### Modal
|
|
513
|
+
|
|
514
|
+
The named `modal` import provides controls of the modal component.
|
|
515
|
+
|
|
516
|
+
```js
|
|
517
|
+
import { modal } from 'forgerock-web-login-widget/modal';
|
|
518
|
+
|
|
519
|
+
// Know when the modal auto-closes, not when the modal is
|
|
520
|
+
// The property `reason` will be either "auto", "external", or "user" (see below)
|
|
521
|
+
modal.onClose(({ reason }) => {
|
|
522
|
+
/* Run anything you want */
|
|
523
|
+
});
|
|
524
|
+
// Know when the modal has mounted
|
|
525
|
+
modal.onMount((dialogElement, formElement) => {
|
|
526
|
+
/* Run anything you want */
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
// "Open" the modal (this implicitly calls `journey.start()`)
|
|
530
|
+
modal.open();
|
|
531
|
+
|
|
532
|
+
// "Close" the modal
|
|
533
|
+
modal.close();
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
It's worth noting that if the Widget has already mounted before the `onMount` statement, it will never run. It won't retroactively run the callback function.
|
|
537
|
+
|
|
538
|
+
`onClose` and the `reason` value:
|
|
539
|
+
|
|
540
|
+
1. `"user"`: user closed the dialog via UI
|
|
541
|
+
2. `"auto"`: the modal was closed because user successfully authenticated
|
|
542
|
+
3. `"external"`: the application itself called the `modal.close` function
|
|
543
|
+
|
|
544
|
+
### Inline
|
|
545
|
+
|
|
546
|
+
The named `form` import provides a simple `onMount` event.
|
|
547
|
+
|
|
548
|
+
```js
|
|
549
|
+
import { form } from 'forgerock-web-login-widget/inline';
|
|
550
|
+
|
|
551
|
+
// Know when the inline form has mounted
|
|
552
|
+
form.onMount((formElement) => {
|
|
553
|
+
/* Run anything you want */
|
|
554
|
+
});
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
It's worth noting that if the Widget has already mounted before the `onMount` statement, it will never run. It won't retroactively run the callback function.
|
|
558
|
+
|
|
559
|
+
### Styling API
|
|
560
|
+
|
|
561
|
+
The Widget can be configured for styling purposes via the JavaScript API. This allows you to choose the type of labels used or providing a logo for the modal.
|
|
562
|
+
|
|
563
|
+
Example:
|
|
564
|
+
|
|
565
|
+
```js
|
|
566
|
+
const widget = new Widget({
|
|
567
|
+
target: document.getElementById('widget-root'),
|
|
568
|
+
props: {
|
|
569
|
+
config: {
|
|
570
|
+
/* ... */
|
|
571
|
+
},
|
|
572
|
+
content: {
|
|
573
|
+
/* ... */
|
|
574
|
+
},
|
|
575
|
+
/**
|
|
576
|
+
* OPTIONAL
|
|
577
|
+
*/
|
|
578
|
+
style: {
|
|
579
|
+
checksAndRadios: 'animated', // OPTIONAL; choices are 'animated' or 'standard'
|
|
580
|
+
labels: 'floating', // OPTIONAL; choices are 'floating' or 'stacked'
|
|
581
|
+
logo: {
|
|
582
|
+
// OPTIONAL; only used with modal form factor
|
|
583
|
+
dark: 'https://example.com/img/white-logo.png', // OPTIONAL; used if theme has a dark variant
|
|
584
|
+
light: 'https://example.com/img/black-logo.png', // REQUIRED if logo property is provided; full URL
|
|
585
|
+
height: '300px', // OPTIONAL; provides additional controls to logo display
|
|
586
|
+
width: '400px', // OPTIONAL; provides additional controls to logo display
|
|
587
|
+
},
|
|
588
|
+
sections: {
|
|
589
|
+
// OPTIONAL; only used with modal form factor
|
|
590
|
+
header: false, // OPTIONAL; uses a modal "header" section that displays logo
|
|
591
|
+
},
|
|
592
|
+
stage: {
|
|
593
|
+
icon: true, // OPTIONAL; displays generic icons for the provided stages
|
|
594
|
+
},
|
|
595
|
+
},
|
|
596
|
+
},
|
|
597
|
+
});
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
Note that the `logo` and `section` property only apply to the "modal" form factor, and not the "inline".
|
|
601
|
+
|
|
602
|
+
## Future APIs (not implemented)
|
|
603
|
+
|
|
604
|
+
### Currently **unsupported**
|
|
605
|
+
|
|
606
|
+
1. WebAuthn
|
|
607
|
+
2. Push Authentication
|
|
608
|
+
3. Recaptcha
|
|
609
|
+
4. QR Code display
|
|
610
|
+
5. TextOutputCallback with scripts
|
|
611
|
+
6. Device Profile
|
|
612
|
+
7. Email Suspend (Forgot Password/Username flows)
|
|
613
|
+
8. Social Login
|
|
614
|
+
9. Central Login
|
|
615
|
+
10. SAML
|
|
616
|
+
|
|
617
|
+
### Widget customization (future)
|
|
618
|
+
|
|
619
|
+
```js
|
|
620
|
+
new Widget({
|
|
621
|
+
// ... previous config properties ...
|
|
622
|
+
|
|
623
|
+
// All optional; default value is assigned below
|
|
624
|
+
customization: {
|
|
625
|
+
labels: 'floating', // "floating" or "stacked"
|
|
626
|
+
modalBackdrop: true, // boolean; display modal backdrop
|
|
627
|
+
modalAutoClose: true, // boolean; automatically close modal on success
|
|
628
|
+
},
|
|
629
|
+
});
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### Additional modal events (future)
|
|
633
|
+
|
|
634
|
+
```js
|
|
635
|
+
modal.onClose((event) => {
|
|
636
|
+
/* anything you want */
|
|
637
|
+
});
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
## Quick Start: Internal Login Framework Development
|
|
641
|
+
|
|
642
|
+
### Technical requirements
|
|
643
|
+
|
|
644
|
+
1. Node.js v16
|
|
645
|
+
2. npm v8
|
|
646
|
+
|
|
647
|
+
### Knowledge requirements
|
|
648
|
+
|
|
649
|
+
1. JavaScript & TypeScript
|
|
650
|
+
2. Svelte
|
|
651
|
+
3. Tailwind
|
|
652
|
+
4. ES Modules
|
|
653
|
+
|
|
654
|
+
### Install, build & run
|
|
655
|
+
|
|
656
|
+
1. `npm install` (or simply `npm i`)
|
|
657
|
+
2. `npm run build`
|
|
658
|
+
3. `npm run dev` (leave running)
|
|
659
|
+
|
|
660
|
+
This will install all the necessary dependencies, build the project and run it in `dev` mode, providing you with Hot Module Reloading. This will also produce the Widget package for use in external applications.
|
|
661
|
+
|
|
662
|
+
## Notes
|
|
663
|
+
|
|
664
|
+
### Re-syncing with Chromatic
|
|
665
|
+
|
|
666
|
+
Rebuilds and syncs with Chromatic:
|
|
667
|
+
|
|
668
|
+
```sh
|
|
669
|
+
npx chromatic --project-token=e10acf0c74f9 --patch-build=<current-branch>...main
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
Make sure upstream is set on all branches:
|
|
673
|
+
|
|
674
|
+
```sh
|
|
675
|
+
git push -u origin <branch>
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
## Disclaimer
|
|
679
|
+
|
|
680
|
+
> **This code is provided by ForgeRock on an “as is” basis, without warranty of any kind, to the fullest extent permitted by law. ForgeRock does not represent or warrant or make any guarantee regarding the use of this code or the accuracy, timeliness or completeness of any data or information relating to this code, and ForgeRock hereby disclaims all warranties whether express, or implied or statutory, including without limitation the implied warranties of merchantability, fitness for a particular purpose, and any warranty of non-infringement. ForgeRock shall not have any liability arising out of or related to any use, implementation or configuration of this code, including but not limited to use for any commercial purpose. Any action or suit relating to the use of the code may be brought only in the courts of a jurisdiction wherein ForgeRock resides or in which ForgeRock conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions.**
|
|
681
|
+
|
|
682
|
+
<!---------------------------------------------------------------------------------------------------------->
|
|
683
|
+
<!-- LICENSE - Links to the MIT LICENSE file in each repo. -->
|
|
684
|
+
|
|
685
|
+
## License
|
|
686
|
+
|
|
687
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
691
|
+
© Copyright 2020 ForgeRock AS. All Rights Reserved.
|
|
692
|
+
|
|
693
|
+
[forgerock-logo]: https://www.forgerock.com/themes/custom/forgerock/images/fr-logo-horz-color.svg 'ForgeRock Logo'
|