@forgerock/login-widget 0.0.0-beta-20260330171021
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/LICENSE +21 -0
- package/README.md +517 -0
- package/dist/core/component.store.d.ts +40 -0
- package/dist/core/interfaces.d.ts +12 -0
- package/dist/core/journey/config.store.d.ts +114 -0
- package/dist/core/journey/journey.interfaces.d.ts +83 -0
- package/dist/core/links.store.d.ts +34 -0
- package/dist/core/locale.store.d.ts +966 -0
- package/dist/core/oauth/oauth.store.d.ts +38 -0
- package/dist/core/sdk.config.d.ts +257 -0
- package/dist/core/style.store.d.ts +184 -0
- package/dist/core/user/user.store.d.ts +37 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +11726 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +61 -0
- package/dist/types.d.ts +79 -0
- package/dist/widget.css +1 -0
- package/dist/widget.iife.js +32 -0
- package/dist/widget.iife.js.map +1 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 - 2025 Ping Identity Corporation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
[](https://www.npmjs.com/package/@forgerock/login-widget)
|
|
2
|
+
[](http://commitizen.github.io/cz-cli/)
|
|
3
|
+
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="https://github.com/ForgeRock">
|
|
6
|
+
<img src="https://www.forgerock.com/themes/custom/forgerock/images/fr-logo-horz-color.svg" alt="ForgeRock Logo">
|
|
7
|
+
</a>
|
|
8
|
+
<h2 align="center">ForgeRock Login Widget</h2>
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://www.npmjs.com/package/@forgerock/login-widget">npm</a>
|
|
11
|
+
·
|
|
12
|
+
<a href="#support">Support</a>
|
|
13
|
+
·
|
|
14
|
+
<a href="https://backstage.forgerock.com/docs/sdks/latest/javascript/webloginframework.html">Docs</a>
|
|
15
|
+
</p>
|
|
16
|
+
<hr/>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
## Table of Contents
|
|
20
|
+
|
|
21
|
+
- [Overview](#overview)
|
|
22
|
+
- [Requirements](#requirements)
|
|
23
|
+
- [Quick Start](#quick-start)
|
|
24
|
+
- [Install](#install)
|
|
25
|
+
- [Add CSS](#add-css)
|
|
26
|
+
- [Mount the Widget](#mount-the-widget)
|
|
27
|
+
- [Observables Pattern](#observables-pattern)
|
|
28
|
+
- [Subscribe to Events](#subscribe-to-events)
|
|
29
|
+
- [Unsubscribe](#unsubscribe)
|
|
30
|
+
- [Get Current Values](#get-current-values)
|
|
31
|
+
- [Request Fresh Values](#request-fresh-values)
|
|
32
|
+
- [Use Promises](#use-promises)
|
|
33
|
+
- [Complete Widget API](#complete-widget-api)
|
|
34
|
+
- [Widget](#widget)
|
|
35
|
+
- [Configuration](#configuration)
|
|
36
|
+
- [Journey](#journey)
|
|
37
|
+
- [Component](#component)
|
|
38
|
+
- [User](#user)
|
|
39
|
+
- [Request](#request)
|
|
40
|
+
- [Styling Configuration](#styling-configuration)
|
|
41
|
+
- [Links Configuration](#links-configuration)
|
|
42
|
+
- [Content Configuration](#content-configuration)
|
|
43
|
+
- [Supported Callbacks](#supported-callbacks)
|
|
44
|
+
- [Disclaimer](#disclaimer)
|
|
45
|
+
- [License](#license)
|
|
46
|
+
|
|
47
|
+
## Overview
|
|
48
|
+
|
|
49
|
+
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
|
+
|
|
51
|
+
The widget uses the ForgeRock JavaScript SDK internally. It adds a UI rendering layer on top of the SDK 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
|
+
|
|
53
|
+
The widget can be rendered in two form factors:
|
|
54
|
+
|
|
55
|
+
1. **Modal** (default): Renders form elements inside a modal dialog that opens and closes. Mounted _outside_ your app's controlled DOM.
|
|
56
|
+
2. **Inline**: Just the form elements with no container. Mounted _inside_ your app's controlled DOM.
|
|
57
|
+
|
|
58
|
+
Both form factors provide the same authentication, OAuth/OIDC, and user features. Start with Modal — it provides the quickest path to adding login/registration with minimal disruption to your existing codebase.
|
|
59
|
+
|
|
60
|
+
## Requirements
|
|
61
|
+
|
|
62
|
+
- An ECMAScript module or CommonJS enabled client-side JavaScript app
|
|
63
|
+
- A modern, fully-supported browser: Chrome, Firefox, Safari, or Chromium Edge
|
|
64
|
+
|
|
65
|
+
**Not supported**: Internet Explorer, Legacy Edge, WebView, Electron, and other modified browser-like environments.
|
|
66
|
+
|
|
67
|
+
## Quick Start
|
|
68
|
+
|
|
69
|
+
### Install
|
|
70
|
+
|
|
71
|
+
```shell
|
|
72
|
+
npm install @forgerock/login-widget
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Add CSS
|
|
76
|
+
|
|
77
|
+
Import into your JavaScript:
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
import '@forgerock/login-widget/widget.css';
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Import into your CSS:
|
|
84
|
+
|
|
85
|
+
```css
|
|
86
|
+
@import '@forgerock/login-widget/widget.css';
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Or link in HTML (copy the CSS file from the npm module into your static files):
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<link rel="stylesheet" href="/path/to/file/widget.css" />
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Controlling the CSS Cascade
|
|
96
|
+
|
|
97
|
+
Though not required, using `@layer` ensures the browser applies CSS in the intended order regardless of import order. [Read more about @layer](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer).
|
|
98
|
+
|
|
99
|
+
1. Wrap your CSS in a layer:
|
|
100
|
+
|
|
101
|
+
```css
|
|
102
|
+
@layer app {
|
|
103
|
+
/* Your app's CSS */
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
2. Declare layer order in your HTML before any CSS loads:
|
|
108
|
+
|
|
109
|
+
```html
|
|
110
|
+
<style type="text/css">
|
|
111
|
+
@layer app;
|
|
112
|
+
@layer 'fr-widget.base';
|
|
113
|
+
@layer 'fr-widget.utilities';
|
|
114
|
+
@layer 'fr-widget.components';
|
|
115
|
+
@layer 'fr-widget.variants';
|
|
116
|
+
</style>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Widget CSS is fully namespaced — it will not overwrite your app's CSS unless you use the same selector naming convention.
|
|
120
|
+
|
|
121
|
+
### Mount the Widget
|
|
122
|
+
|
|
123
|
+
Add a dedicated element to your HTML file as a direct child of `<body>`, separate from your main app root:
|
|
124
|
+
|
|
125
|
+
```html
|
|
126
|
+
<body>
|
|
127
|
+
<div id="root"></div>
|
|
128
|
+
<div id="widget-root"></div>
|
|
129
|
+
</body>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
> **Tip**: Do not mount the modal form factor on a dynamic element inside your app's Virtual DOM. Hard-code it in your static HTML file.
|
|
133
|
+
|
|
134
|
+
Import, configure, and instantiate:
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
import Widget, { configuration, journey } from '@forgerock/login-widget';
|
|
138
|
+
|
|
139
|
+
// 1. Configure
|
|
140
|
+
const config = configuration();
|
|
141
|
+
config.set({
|
|
142
|
+
forgerock: {
|
|
143
|
+
serverConfig: {
|
|
144
|
+
baseUrl: 'https://your-tenant.forgeblocks.com/am/',
|
|
145
|
+
timeout: 3000,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// 2. Instantiate
|
|
151
|
+
const widgetRootEl = document.getElementById('widget-root');
|
|
152
|
+
new Widget({ target: widgetRootEl });
|
|
153
|
+
|
|
154
|
+
// 3. Start a journey
|
|
155
|
+
const journeyEvents = journey();
|
|
156
|
+
journeyEvents.start();
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
> **Tip**: Set configuration at the top level of your application (`index.js` or `app.js`) to ensure it is available before calling `journeyEvents.start()` or any other Widget API.
|
|
160
|
+
|
|
161
|
+
## Observables Pattern
|
|
162
|
+
|
|
163
|
+
Most Widget APIs are asynchronous and use an event-centric observable pattern. The widget uses Svelte's simplified, standard observable implementation called a "store" — these are embedded in the widget and are not a dependency your app needs to manage.
|
|
164
|
+
|
|
165
|
+
[Read more about the Svelte store contract](https://svelte.dev/docs#component-format-script-4-prefix-stores-with-$-to-access-their-values-store-contract).
|
|
166
|
+
|
|
167
|
+
### Subscribe to Events
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
import { user } from '@forgerock/login-widget';
|
|
171
|
+
|
|
172
|
+
const userInfoEvents = user.info();
|
|
173
|
+
|
|
174
|
+
userInfoEvents.subscribe((event) => {
|
|
175
|
+
if (event.loading) {
|
|
176
|
+
console.log('User info is being requested from server');
|
|
177
|
+
} else if (event.successful) {
|
|
178
|
+
console.log('User info request was successful');
|
|
179
|
+
console.log(event.response);
|
|
180
|
+
} else if (event.error) {
|
|
181
|
+
console.error('User info request failed');
|
|
182
|
+
console.error(event.error.message);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Unsubscribe
|
|
188
|
+
|
|
189
|
+
Observables are not like Promises — they don't resolve and get cleaned up. You must unsubscribe when no longer needed, especially in components that are created and destroyed frequently:
|
|
190
|
+
|
|
191
|
+
```js
|
|
192
|
+
const unsubscribe = userInfoEvents.subscribe((event) => console.log(event));
|
|
193
|
+
|
|
194
|
+
// Later, when no longer needed:
|
|
195
|
+
unsubscribe();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
> **Note**: If subscribing at a top-level component that persists over the lifetime of your app, unsubscribing is not needed.
|
|
199
|
+
|
|
200
|
+
### Get Current Values
|
|
201
|
+
|
|
202
|
+
To get the current value stored within the Widget without subscribing to future events, call `subscribe` and immediately call the returned unsubscribe function:
|
|
203
|
+
|
|
204
|
+
```js
|
|
205
|
+
let userInfo;
|
|
206
|
+
userInfoEvents.subscribe((event) => (userInfo = event.response))();
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Request Fresh Values
|
|
210
|
+
|
|
211
|
+
Call action methods like `get` to request new values from the server. Any active `subscribe` callbacks will receive the resulting events:
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
userInfoEvents.get();
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Use Promises
|
|
218
|
+
|
|
219
|
+
All Widget APIs that involve network calls also support Promises:
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
// async/await
|
|
223
|
+
const userInfo = await userInfoEvents.get();
|
|
224
|
+
|
|
225
|
+
// Promise chain
|
|
226
|
+
userInfoEvents
|
|
227
|
+
.get()
|
|
228
|
+
.then((data) => console.log(data))
|
|
229
|
+
.catch((err) => console.error(err));
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Complete Widget API
|
|
233
|
+
|
|
234
|
+
### Widget
|
|
235
|
+
|
|
236
|
+
```js
|
|
237
|
+
import Widget from '@forgerock/login-widget';
|
|
238
|
+
|
|
239
|
+
// Instantiate
|
|
240
|
+
const widget = new Widget({
|
|
241
|
+
target: widgetRootEl, // REQUIRED; a real DOM element
|
|
242
|
+
props: {
|
|
243
|
+
type: 'modal', // OPTIONAL; "modal" (default) or "inline"
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
// Remove widget from DOM and destroy listeners
|
|
248
|
+
widget.$destroy();
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
> **Note**: Call `$destroy()` if instantiating the Widget in a component that is frequently created and destroyed. We recommend instantiating higher in your application tree, in a component created once and preserved.
|
|
252
|
+
|
|
253
|
+
### Configuration
|
|
254
|
+
|
|
255
|
+
```js
|
|
256
|
+
import { configuration } from '@forgerock/login-widget';
|
|
257
|
+
|
|
258
|
+
const config = configuration();
|
|
259
|
+
config.set({
|
|
260
|
+
forgerock: {
|
|
261
|
+
// REQUIRED
|
|
262
|
+
serverConfig: {
|
|
263
|
+
baseUrl: 'https://your-tenant.forgeblocks.com/am',
|
|
264
|
+
timeout: 3000,
|
|
265
|
+
},
|
|
266
|
+
// OPTIONAL (defaults shown)
|
|
267
|
+
clientId: 'WebLoginWidgetClient',
|
|
268
|
+
realmPath: 'alpha',
|
|
269
|
+
redirectUri: window.location.href,
|
|
270
|
+
scope: 'openid email',
|
|
271
|
+
},
|
|
272
|
+
// OPTIONAL — see dedicated sections below
|
|
273
|
+
content: {},
|
|
274
|
+
links: {},
|
|
275
|
+
style: {},
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
For more SDK configuration options, see the [SDK configuration documentation](https://backstage.forgerock.com/docs/sdks/latest/javascript/webloginframework/04-configure-sdk.html#sdk_configuration_properties).
|
|
280
|
+
|
|
281
|
+
### Journey
|
|
282
|
+
|
|
283
|
+
```js
|
|
284
|
+
import { journey } from '@forgerock/login-widget';
|
|
285
|
+
|
|
286
|
+
const journeyEvents = journey({
|
|
287
|
+
oauth: true, // OPTIONAL; default true; use OAuth flow for tokens
|
|
288
|
+
user: true, // OPTIONAL; default true; fetch user info from /userinfo
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
// Start a journey
|
|
292
|
+
journeyEvents.start({
|
|
293
|
+
forgerock: {}, // OPTIONAL; configuration overrides
|
|
294
|
+
journey: 'Login', // OPTIONAL; journey/tree name (defaults to server default)
|
|
295
|
+
resumeUrl: window.location.href, // OPTIONAL; URL for resuming a suspended journey
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Change to a different journey
|
|
299
|
+
journeyEvents.change({
|
|
300
|
+
forgerock: {},
|
|
301
|
+
journey: 'Registration',
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// Listen for events
|
|
305
|
+
journeyEvents.subscribe((event) => {
|
|
306
|
+
if (event.journey.successful) {
|
|
307
|
+
console.log('Authentication succeeded', event);
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
**Journey event schema:**
|
|
313
|
+
|
|
314
|
+
```js
|
|
315
|
+
{
|
|
316
|
+
journey: {
|
|
317
|
+
completed: false, // boolean
|
|
318
|
+
error: null, // null or { code, message, step }
|
|
319
|
+
loading: false, // boolean
|
|
320
|
+
step: null, // null or step object from ForgeRock AM
|
|
321
|
+
successful: false, // boolean
|
|
322
|
+
response: null, // null or success response from AM
|
|
323
|
+
},
|
|
324
|
+
oauth: {
|
|
325
|
+
completed: false, // boolean
|
|
326
|
+
error: null, // null or { code, message }
|
|
327
|
+
loading: false, // boolean
|
|
328
|
+
successful: false, // boolean
|
|
329
|
+
response: null, // null or OAuth/OIDC tokens
|
|
330
|
+
},
|
|
331
|
+
user: {
|
|
332
|
+
completed: false, // boolean
|
|
333
|
+
error: null, // null or { code, message }
|
|
334
|
+
loading: false, // boolean
|
|
335
|
+
successful: false, // boolean
|
|
336
|
+
response: null, // null or user info (driven by OAuth scope)
|
|
337
|
+
},
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Component
|
|
342
|
+
|
|
343
|
+
The `component` API controls the widget's lifecycle. For the modal form factor, it provides `open` and `close` methods.
|
|
344
|
+
|
|
345
|
+
```js
|
|
346
|
+
import { component } from '@forgerock/login-widget';
|
|
347
|
+
|
|
348
|
+
const componentEvents = component();
|
|
349
|
+
|
|
350
|
+
// Open/close the modal
|
|
351
|
+
componentEvents.open();
|
|
352
|
+
componentEvents.close();
|
|
353
|
+
|
|
354
|
+
// Listen for lifecycle events
|
|
355
|
+
componentEvents.subscribe((event) => {
|
|
356
|
+
if (event.mounted) console.log('Widget is mounted');
|
|
357
|
+
if (event.open === false) console.log('Modal closed:', event.reason);
|
|
358
|
+
});
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Component event schema:**
|
|
362
|
+
|
|
363
|
+
```js
|
|
364
|
+
{
|
|
365
|
+
error: null, // null or { code, message, step }
|
|
366
|
+
mounted: false, // boolean
|
|
367
|
+
open: null, // boolean or null (null for inline type)
|
|
368
|
+
reason: null, // "user" | "auto" | "external"
|
|
369
|
+
type: null, // "modal" | "inline"
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Close reasons:**
|
|
374
|
+
|
|
375
|
+
| Reason | Description |
|
|
376
|
+
| ------------ | -------------------------------------------- |
|
|
377
|
+
| `"user"` | User closed the dialog via UI |
|
|
378
|
+
| `"auto"` | Modal closed after successful authentication |
|
|
379
|
+
| `"external"` | Application called `componentEvents.close()` |
|
|
380
|
+
|
|
381
|
+
### User
|
|
382
|
+
|
|
383
|
+
```js
|
|
384
|
+
import { user } from '@forgerock/login-widget';
|
|
385
|
+
|
|
386
|
+
// User info
|
|
387
|
+
const userEvents = user.info();
|
|
388
|
+
userEvents.subscribe((event) => console.log(event));
|
|
389
|
+
userEvents.get(); // Fetch fresh user info from server
|
|
390
|
+
|
|
391
|
+
// User tokens
|
|
392
|
+
const tokenEvents = user.tokens();
|
|
393
|
+
tokenEvents.subscribe((event) => console.log(event));
|
|
394
|
+
tokenEvents.get(); // Fetch fresh tokens from server
|
|
395
|
+
|
|
396
|
+
// Logout
|
|
397
|
+
user.logout(); // Clears user data and emits events to subscribers
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**User info / token event schema:**
|
|
401
|
+
|
|
402
|
+
```js
|
|
403
|
+
{
|
|
404
|
+
completed: false, // boolean
|
|
405
|
+
error: null, // null or { code, message }
|
|
406
|
+
loading: false, // boolean
|
|
407
|
+
successful: false, // boolean
|
|
408
|
+
response: null, // object from /userinfo or /access_token endpoint
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Request
|
|
413
|
+
|
|
414
|
+
An alias to the JavaScript SDK's `HttpClient.request` — a convenience wrapper around `fetch` that auto-injects the Access Token into the `Authorization` header.
|
|
415
|
+
|
|
416
|
+
```js
|
|
417
|
+
import { request } from '@forgerock/login-widget';
|
|
418
|
+
|
|
419
|
+
const response = await request({
|
|
420
|
+
url: 'https://protected.resource.com',
|
|
421
|
+
init: { method: 'GET' },
|
|
422
|
+
});
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
**Options:**
|
|
426
|
+
|
|
427
|
+
```js
|
|
428
|
+
{
|
|
429
|
+
bypassAuthentication: false, // Boolean; skip token injection
|
|
430
|
+
init: {}, // fetch() options
|
|
431
|
+
timeout: 3000, // Fetch timeout in milliseconds
|
|
432
|
+
url: '', // Resource URL
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
> **Note**: The response is a native [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object and is not persisted in the widget.
|
|
437
|
+
|
|
438
|
+
### Styling Configuration
|
|
439
|
+
|
|
440
|
+
Configure the widget's visual appearance:
|
|
441
|
+
|
|
442
|
+
```js
|
|
443
|
+
config.set({
|
|
444
|
+
style: {
|
|
445
|
+
checksAndRadios: 'animated', // OPTIONAL; 'animated' or 'standard'
|
|
446
|
+
labels: 'floating', // OPTIONAL; 'floating' or 'stacked'
|
|
447
|
+
logo: {
|
|
448
|
+
// OPTIONAL; modal only
|
|
449
|
+
dark: 'https://example.com/img/white-logo.png',
|
|
450
|
+
light: 'https://example.com/img/black-logo.png', // REQUIRED if logo provided
|
|
451
|
+
height: 300,
|
|
452
|
+
width: 400,
|
|
453
|
+
},
|
|
454
|
+
sections: {
|
|
455
|
+
// OPTIONAL; modal only
|
|
456
|
+
header: false, // Display a header section with logo
|
|
457
|
+
},
|
|
458
|
+
stage: {
|
|
459
|
+
icon: true, // OPTIONAL; display generic stage icons
|
|
460
|
+
},
|
|
461
|
+
},
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
> **Note**: The `logo` and `sections` properties only apply to the modal form factor.
|
|
466
|
+
|
|
467
|
+
### Links Configuration
|
|
468
|
+
|
|
469
|
+
Set the URL for your Terms & Conditions page (used by `TermsAndConditionsCallback`):
|
|
470
|
+
|
|
471
|
+
```js
|
|
472
|
+
config.set({
|
|
473
|
+
links: {
|
|
474
|
+
termsAndConditions: 'https://example.com/terms',
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Content Configuration
|
|
480
|
+
|
|
481
|
+
Override the widget's default content with custom text. For the full schema, see the [en-US locale file](https://github.com/ForgeRock/forgerock-web-login-framework/tree/main/core/locales).
|
|
482
|
+
|
|
483
|
+
```js
|
|
484
|
+
config.set({
|
|
485
|
+
content: {
|
|
486
|
+
// Custom content that overrides Widget defaults
|
|
487
|
+
},
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## Supported Callbacks
|
|
492
|
+
|
|
493
|
+
The widget supports the following ForgeRock callbacks:
|
|
494
|
+
|
|
495
|
+
- Page node
|
|
496
|
+
- Username, Password
|
|
497
|
+
- WebAuthn (registration and login)
|
|
498
|
+
- Push authentication
|
|
499
|
+
- One-time password verification
|
|
500
|
+
- Social login (Apple, Facebook, Google)
|
|
501
|
+
- Email suspend ("magic links")
|
|
502
|
+
- Device profile
|
|
503
|
+
- reCAPTCHA / hCaptcha
|
|
504
|
+
- QR codes
|
|
505
|
+
- Ping Protect
|
|
506
|
+
|
|
507
|
+
## Disclaimer
|
|
508
|
+
|
|
509
|
+
> **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.**
|
|
510
|
+
|
|
511
|
+
## License
|
|
512
|
+
|
|
513
|
+
This project is licensed under the MIT License — see the [LICENSE](https://github.com/ForgeRock/forgerock-web-login-framework/blob/main/LICENSE) file for details.
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
© Copyright 2022-2025 Ping Identity Corporation. All Rights Reserved.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Copyright © 2025 Ping Identity Corporation. All right reserved.
|
|
4
|
+
*
|
|
5
|
+
* This software may be modified and distributed under the terms
|
|
6
|
+
* of the MIT license. See the LICENSE file for details.
|
|
7
|
+
*
|
|
8
|
+
**/
|
|
9
|
+
import { type Writable } from 'svelte/store';
|
|
10
|
+
import type { SvelteComponent } from 'svelte';
|
|
11
|
+
export interface ComponentStoreValue {
|
|
12
|
+
lastAction: 'close' | 'open' | 'mount' | null;
|
|
13
|
+
error: {
|
|
14
|
+
code: string;
|
|
15
|
+
message: string;
|
|
16
|
+
} | null;
|
|
17
|
+
modal: {
|
|
18
|
+
component: SvelteComponent;
|
|
19
|
+
element: HTMLDialogElement;
|
|
20
|
+
} | null;
|
|
21
|
+
mounted: boolean;
|
|
22
|
+
open: boolean | null;
|
|
23
|
+
reason: 'auto' | 'external' | 'user' | null;
|
|
24
|
+
type: 'inline' | 'modal' | null;
|
|
25
|
+
}
|
|
26
|
+
export declare const componentStore: Writable<ComponentStoreValue>;
|
|
27
|
+
/**
|
|
28
|
+
* @function closeComponent - this is a widget internal function not to be exposed to user
|
|
29
|
+
* @param {object} args - object containing the reason for closing component
|
|
30
|
+
* @param {boolean} shouldCloseDialog - if true, the close command comes from outside of dialog component
|
|
31
|
+
*/
|
|
32
|
+
export declare function closeComponent(args?: {
|
|
33
|
+
reason: ComponentStoreValue['reason'];
|
|
34
|
+
}, shouldCloseDialog?: boolean): void;
|
|
35
|
+
/**
|
|
36
|
+
* @function mount - this is a widget internal function not to be exposed to user
|
|
37
|
+
* @param {object} component - actual Svelte component representing the dialog
|
|
38
|
+
* @param {object} element - actual DOM element representing the dialog
|
|
39
|
+
*/
|
|
40
|
+
export declare function mount(component: SvelteComponent, element: HTMLDialogElement): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Copyright © 2025 Ping Identity Corporation. All right reserved.
|
|
4
|
+
*
|
|
5
|
+
* This software may be modified and distributed under the terms
|
|
6
|
+
* of the MIT license. See the LICENSE file for details.
|
|
7
|
+
*
|
|
8
|
+
**/
|
|
9
|
+
export type Maybe<T> = T | null | undefined;
|
|
10
|
+
export interface StringDict<T> {
|
|
11
|
+
[name: string]: T;
|
|
12
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Copyright © 2025 Ping Identity Corporation. All right reserved.
|
|
4
|
+
*
|
|
5
|
+
* This software may be modified and distributed under the terms
|
|
6
|
+
* of the MIT license. See the LICENSE file for details.
|
|
7
|
+
*
|
|
8
|
+
**/
|
|
9
|
+
import { type Writable } from 'svelte/store';
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
export declare const journeyConfigItemSchema: z.ZodOptional<z.ZodObject<{
|
|
12
|
+
journey: z.ZodOptional<z.ZodString>;
|
|
13
|
+
match: z.ZodArray<z.ZodString, "many">;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
match: string[];
|
|
16
|
+
journey?: string | undefined;
|
|
17
|
+
}, {
|
|
18
|
+
match: string[];
|
|
19
|
+
journey?: string | undefined;
|
|
20
|
+
}>>;
|
|
21
|
+
export declare const journeyConfigSchema: z.ZodObject<{
|
|
22
|
+
forgotPassword: z.ZodOptional<z.ZodObject<{
|
|
23
|
+
journey: z.ZodOptional<z.ZodString>;
|
|
24
|
+
match: z.ZodArray<z.ZodString, "many">;
|
|
25
|
+
}, "strip", z.ZodTypeAny, {
|
|
26
|
+
match: string[];
|
|
27
|
+
journey?: string | undefined;
|
|
28
|
+
}, {
|
|
29
|
+
match: string[];
|
|
30
|
+
journey?: string | undefined;
|
|
31
|
+
}>>;
|
|
32
|
+
forgotUsername: z.ZodOptional<z.ZodObject<{
|
|
33
|
+
journey: z.ZodOptional<z.ZodString>;
|
|
34
|
+
match: z.ZodArray<z.ZodString, "many">;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
match: string[];
|
|
37
|
+
journey?: string | undefined;
|
|
38
|
+
}, {
|
|
39
|
+
match: string[];
|
|
40
|
+
journey?: string | undefined;
|
|
41
|
+
}>>;
|
|
42
|
+
login: z.ZodOptional<z.ZodObject<{
|
|
43
|
+
journey: z.ZodOptional<z.ZodString>;
|
|
44
|
+
match: z.ZodArray<z.ZodString, "many">;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
match: string[];
|
|
47
|
+
journey?: string | undefined;
|
|
48
|
+
}, {
|
|
49
|
+
match: string[];
|
|
50
|
+
journey?: string | undefined;
|
|
51
|
+
}>>;
|
|
52
|
+
register: z.ZodOptional<z.ZodObject<{
|
|
53
|
+
journey: z.ZodOptional<z.ZodString>;
|
|
54
|
+
match: z.ZodArray<z.ZodString, "many">;
|
|
55
|
+
}, "strip", z.ZodTypeAny, {
|
|
56
|
+
match: string[];
|
|
57
|
+
journey?: string | undefined;
|
|
58
|
+
}, {
|
|
59
|
+
match: string[];
|
|
60
|
+
journey?: string | undefined;
|
|
61
|
+
}>>;
|
|
62
|
+
}, "strip", z.ZodTypeAny, {
|
|
63
|
+
forgotPassword?: {
|
|
64
|
+
match: string[];
|
|
65
|
+
journey?: string | undefined;
|
|
66
|
+
} | undefined;
|
|
67
|
+
forgotUsername?: {
|
|
68
|
+
match: string[];
|
|
69
|
+
journey?: string | undefined;
|
|
70
|
+
} | undefined;
|
|
71
|
+
login?: {
|
|
72
|
+
match: string[];
|
|
73
|
+
journey?: string | undefined;
|
|
74
|
+
} | undefined;
|
|
75
|
+
register?: {
|
|
76
|
+
match: string[];
|
|
77
|
+
journey?: string | undefined;
|
|
78
|
+
} | undefined;
|
|
79
|
+
}, {
|
|
80
|
+
forgotPassword?: {
|
|
81
|
+
match: string[];
|
|
82
|
+
journey?: string | undefined;
|
|
83
|
+
} | undefined;
|
|
84
|
+
forgotUsername?: {
|
|
85
|
+
match: string[];
|
|
86
|
+
journey?: string | undefined;
|
|
87
|
+
} | undefined;
|
|
88
|
+
login?: {
|
|
89
|
+
match: string[];
|
|
90
|
+
journey?: string | undefined;
|
|
91
|
+
} | undefined;
|
|
92
|
+
register?: {
|
|
93
|
+
match: string[];
|
|
94
|
+
journey?: string | undefined;
|
|
95
|
+
} | undefined;
|
|
96
|
+
}>;
|
|
97
|
+
type ConfigItem = z.infer<typeof journeyConfigItemSchema>;
|
|
98
|
+
export type StoreItem = {
|
|
99
|
+
key: string;
|
|
100
|
+
} & ConfigItem;
|
|
101
|
+
export declare const configuredJourneysStore: Writable<StoreItem[]>;
|
|
102
|
+
/**
|
|
103
|
+
* @function initialize - Initialize the configured journeys store
|
|
104
|
+
* @param {object} customJourneys - An object of custom journeys to merge with the default
|
|
105
|
+
* @returns {object} - The configured journeys store
|
|
106
|
+
* @example initialize({ login: { journey: 'Login', match: ['?journey=Login'] } })
|
|
107
|
+
*/
|
|
108
|
+
export declare function initialize(customJourneys?: z.infer<typeof journeyConfigSchema> | null): Writable<({
|
|
109
|
+
key: string;
|
|
110
|
+
} & {
|
|
111
|
+
match: string[];
|
|
112
|
+
journey?: string | undefined;
|
|
113
|
+
})[]>;
|
|
114
|
+
export {};
|