@axa-fr/react-oidc 7.22.17 → 7.22.19-alpha.1516
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 +91 -112
- package/bin/copy-service-worker-files.mjs +24 -17
- package/dist/FetchToken.d.ts.map +1 -1
- package/dist/OidcProvider.d.ts +1 -1
- package/dist/OidcProvider.d.ts.map +1 -1
- package/dist/OidcSecure.d.ts.map +1 -1
- package/dist/OidcTrustedDomains.js +13 -10
- package/dist/ReactOidc.d.ts.map +1 -1
- package/dist/User.d.ts.map +1 -1
- package/dist/core/default-component/Authenticating.component.d.ts.map +1 -1
- package/dist/core/default-component/Callback.component.d.ts.map +1 -1
- package/dist/core/default-component/Loading.component.d.ts.map +1 -1
- package/dist/core/default-component/ServiceWorkerNotSupported.component.d.ts.map +1 -1
- package/dist/core/default-component/SilentCallback.component.d.ts +5 -2
- package/dist/core/default-component/SilentCallback.component.d.ts.map +1 -1
- package/dist/core/routes/OidcRoutes.d.ts.map +1 -1
- package/dist/core/routes/withRouter.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +165 -72
- package/dist/index.umd.cjs +1 -1
- package/package.json +3 -3
- package/src/FetchToken.tsx +36 -13
- package/src/OidcProvider.tsx +222 -176
- package/src/OidcSecure.tsx +34 -23
- package/src/ReactOidc.tsx +181 -142
- package/src/User.ts +60 -50
- package/src/core/default-component/Authenticating.component.tsx +1 -1
- package/src/core/default-component/Callback.component.tsx +18 -11
- package/src/core/default-component/Loading.component.tsx +1 -5
- package/src/core/default-component/ServiceWorkerNotSupported.component.tsx +5 -2
- package/src/core/default-component/SessionLost.component.tsx +1 -1
- package/src/core/default-component/SilentCallback.component.tsx +17 -11
- package/src/core/default-component/SilentLogin.component.tsx +18 -18
- package/src/core/routes/OidcRoutes.spec.tsx +2 -2
- package/src/core/routes/OidcRoutes.tsx +12 -5
- package/src/core/routes/withRouter.spec.tsx +5 -6
- package/src/core/routes/withRouter.tsx +21 -19
- package/src/index.ts +8 -3
package/README.md
CHANGED
|
@@ -11,7 +11,6 @@ We provide a wrapper **@axa-fr/react-oidc** for **React** (compatible next.js) a
|
|
|
11
11
|
- Try the React demo at https://black-rock-0dc6b0d03.1.azurestaticapps.net/ (most advanced)
|
|
12
12
|
- Try the pure javascript demo at https://icy-glacier-004ab4303.2.azurestaticapps.net/
|
|
13
13
|
|
|
14
|
-
|
|
15
14
|
<img src="https://raw.githubusercontent.com/AxaFrance/oidc-client/main/docs/img/introduction.gif" alt="Sample React Oicd"/>
|
|
16
15
|
|
|
17
16
|
- [About](#about)
|
|
@@ -60,12 +59,14 @@ node ./node_modules/@axa-fr/react-oidc/bin/copy-service-worker-files.mjs public
|
|
|
60
59
|
```
|
|
61
60
|
|
|
62
61
|
WARNING : If you use Service Worker mode, the OidcServiceWorker.js file should always be up to date with the version of the library. You may setup a postinstall script in your package.json file to update it at each npm install. For example :
|
|
62
|
+
|
|
63
63
|
```sh
|
|
64
64
|
"scripts": {
|
|
65
65
|
...
|
|
66
66
|
"postinstall": "node ./node_modules/@axa-fr/react-oidc/bin/copy-service-worker-files.mjs public"
|
|
67
67
|
},
|
|
68
68
|
```
|
|
69
|
+
|
|
69
70
|
If you need a very secure mode where refresh_token and access_token will be hide behind a service worker that will proxify requests.
|
|
70
71
|
The only file you should edit is "OidcTrustedDomains.js".
|
|
71
72
|
|
|
@@ -79,25 +80,25 @@ The only file you should edit is "OidcTrustedDomains.js".
|
|
|
79
80
|
// Domains used by OIDC server must be also declared here
|
|
80
81
|
const trustedDomains = {
|
|
81
82
|
default: {
|
|
82
|
-
oidcDomains
|
|
83
|
-
accessTokenDomains
|
|
83
|
+
oidcDomains: ['https://demo.duendesoftware.com'],
|
|
84
|
+
accessTokenDomains: ['https://www.myapi.com/users'],
|
|
84
85
|
},
|
|
85
86
|
};
|
|
86
87
|
|
|
87
88
|
// Service worker will continue to give access token to the JavaScript client
|
|
88
89
|
// Ideal to hide refresh token from client JavaScript, but to retrieve access_token for some
|
|
89
90
|
// scenarios which require it. For example, to send it via websocket connection.
|
|
90
|
-
trustedDomains.config_show_access_token = {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
trustedDomains.config_show_access_token = {
|
|
92
|
+
oidcDomains: ['https://demo.duendesoftware.com'],
|
|
93
|
+
accessTokenDomains: ['https://www.myapi.com/users'],
|
|
94
|
+
showAccessToken: true,
|
|
94
95
|
// convertAllRequestsToCorsExceptNavigate: false, // default value is false
|
|
95
96
|
// setAccessTokenToNavigateRequests: true, // default value is true
|
|
96
97
|
};
|
|
97
98
|
|
|
98
99
|
// DPoP (Demonstrating Proof of Possession) will be activated for the following domains
|
|
99
100
|
trustedDomains.config_with_dpop = {
|
|
100
|
-
domains: [
|
|
101
|
+
domains: ['https://demo.duendesoftware.com'],
|
|
101
102
|
demonstratingProofOfPossession: true,
|
|
102
103
|
demonstratingProofOfPossessionOnlyWhenDpopHeaderPresent: true, // default value is false, inject DPOP token only when DPOP header is present
|
|
103
104
|
// Optional, more details bellow
|
|
@@ -117,7 +118,12 @@ trustedDomains.config_with_dpop = {
|
|
|
117
118
|
}*/
|
|
118
119
|
};
|
|
119
120
|
|
|
120
|
-
|
|
121
|
+
// Setting allowMultiTabLogin to true will enable storing login-specific parameters (state, nonce, code verifier)
|
|
122
|
+
// separately for each tab. This will prevent errors when logins are initiated from multiple tabs.
|
|
123
|
+
trustedDomains.config_multi_tab_login = {
|
|
124
|
+
domains: ['https://demo.duendesoftware.com'],
|
|
125
|
+
allowMultiTabLogin: true,
|
|
126
|
+
};
|
|
121
127
|
```
|
|
122
128
|
|
|
123
129
|
## Run The Demo
|
|
@@ -143,26 +149,25 @@ The default routes used internally :
|
|
|
143
149
|
- www.your-app.fr/authentication/callback
|
|
144
150
|
|
|
145
151
|
```javascript
|
|
146
|
-
import React from
|
|
147
|
-
import { render } from
|
|
148
|
-
import { BrowserRouter as Router } from
|
|
149
|
-
import { OidcProvider } from
|
|
150
|
-
import Header from
|
|
151
|
-
import Routes from
|
|
152
|
+
import React from 'react';
|
|
153
|
+
import { render } from 'react-dom';
|
|
154
|
+
import { BrowserRouter as Router } from 'react-router-dom';
|
|
155
|
+
import { OidcProvider } from '@axa-fr/react-oidc';
|
|
156
|
+
import Header from './Layout/Header';
|
|
157
|
+
import Routes from './Router';
|
|
152
158
|
|
|
153
159
|
// This configuration use hybrid mode
|
|
154
160
|
// ServiceWorker are used if available (more secure) else tokens are given to the client
|
|
155
161
|
// You need to give inside your code the "access_token" when using fetch
|
|
156
162
|
const configuration = {
|
|
157
|
-
client_id:
|
|
158
|
-
redirect_uri: window.location.origin +
|
|
159
|
-
silent_redirect_uri:
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
service_worker_relative_url: "/OidcServiceWorker.js", // just comment that line to disable service worker mode
|
|
163
|
+
client_id: 'interactive.public.short',
|
|
164
|
+
redirect_uri: window.location.origin + '/authentication/callback',
|
|
165
|
+
silent_redirect_uri: window.location.origin + '/authentication/silent-callback',
|
|
166
|
+
scope: 'openid profile email api offline_access', // offline_access scope allow your client to retrieve the refresh_token
|
|
167
|
+
authority: 'https://demo.duendesoftware.com',
|
|
168
|
+
service_worker_relative_url: '/OidcServiceWorker.js', // just comment that line to disable service worker mode
|
|
164
169
|
service_worker_only: false,
|
|
165
|
-
demonstrating_proof_of_possession: false,
|
|
170
|
+
demonstrating_proof_of_possession: false,
|
|
166
171
|
};
|
|
167
172
|
|
|
168
173
|
const App = () => (
|
|
@@ -174,7 +179,7 @@ const App = () => (
|
|
|
174
179
|
</OidcProvider>
|
|
175
180
|
);
|
|
176
181
|
|
|
177
|
-
render(<App />, document.getElementById(
|
|
182
|
+
render(<App />, document.getElementById('root'));
|
|
178
183
|
```
|
|
179
184
|
|
|
180
185
|
```javascript
|
|
@@ -208,7 +213,7 @@ const configuration = {
|
|
|
208
213
|
refresh_time_before_tokens_expiration_in_second: Number, // default is 120 seconds
|
|
209
214
|
service_worker_relative_url: String,
|
|
210
215
|
service_worker_keep_alive_path: String, // default is "/"
|
|
211
|
-
service_worker_only: Boolean, // default false
|
|
216
|
+
service_worker_only: Boolean, // default false
|
|
212
217
|
service_worker_activate: () => boolean, // you can take the control of the service worker default activation which use user agent string
|
|
213
218
|
service_worker_update_require_callback: (registration:any, stopKeepAlive:Function) => Promise<void>, // callback called when service worker need to be updated, you can take the control of the update process
|
|
214
219
|
service_worker_register: (url: string) => Promise<ServiceWorkerRegistration>, // Optional, you can take the control of the service worker registration
|
|
@@ -235,7 +240,7 @@ const configuration = {
|
|
|
235
240
|
demonstrating_proof_of_possession_configuration: DemonstratingProofOfPossessionConfiguration // Optional, more details bellow
|
|
236
241
|
};
|
|
237
242
|
|
|
238
|
-
interface DemonstratingProofOfPossessionConfiguration
|
|
243
|
+
interface DemonstratingProofOfPossessionConfiguration
|
|
239
244
|
{
|
|
240
245
|
generateKeyAlgorithm: RsaHashedKeyGenParams | EcKeyGenParams,
|
|
241
246
|
digestAlgorithm: AlgorithmIdentifier,
|
|
@@ -268,8 +273,8 @@ const defaultDemonstratingProofOfPossessionConfiguration: DemonstratingProofOfPo
|
|
|
268
273
|
"useOidc" returns all props from the Hook :
|
|
269
274
|
|
|
270
275
|
```javascript
|
|
271
|
-
import React from
|
|
272
|
-
import { useOidc } from
|
|
276
|
+
import React from 'react';
|
|
277
|
+
import { useOidc } from './oidc';
|
|
273
278
|
|
|
274
279
|
export const Home = () => {
|
|
275
280
|
const { login, logout, renewTokens, isAuthenticated } = useOidc();
|
|
@@ -279,33 +284,19 @@ export const Home = () => {
|
|
|
279
284
|
<div className="card">
|
|
280
285
|
<div className="card-body">
|
|
281
286
|
<h5 className="card-title">Welcome !!!</h5>
|
|
282
|
-
<p className="card-text">
|
|
283
|
-
React Demo Application protected by OpenId Connect
|
|
284
|
-
</p>
|
|
287
|
+
<p className="card-text">React Demo Application protected by OpenId Connect</p>
|
|
285
288
|
{!isAuthenticated && (
|
|
286
|
-
<button
|
|
287
|
-
type="button"
|
|
288
|
-
className="btn btn-primary"
|
|
289
|
-
onClick={() => login("/profile")}
|
|
290
|
-
>
|
|
289
|
+
<button type="button" className="btn btn-primary" onClick={() => login('/profile')}>
|
|
291
290
|
Login
|
|
292
291
|
</button>
|
|
293
292
|
)}
|
|
294
293
|
{isAuthenticated && (
|
|
295
|
-
<button
|
|
296
|
-
type="button"
|
|
297
|
-
className="btn btn-primary"
|
|
298
|
-
onClick={() => logout()}
|
|
299
|
-
>
|
|
294
|
+
<button type="button" className="btn btn-primary" onClick={() => logout()}>
|
|
300
295
|
logout
|
|
301
296
|
</button>
|
|
302
297
|
)}
|
|
303
298
|
{isAuthenticated && (
|
|
304
|
-
<button
|
|
305
|
-
type="button"
|
|
306
|
-
className="btn btn-primary"
|
|
307
|
-
onClick={() => renewTokens()}
|
|
308
|
-
>
|
|
299
|
+
<button type="button" className="btn btn-primary" onClick={() => renewTokens()}>
|
|
309
300
|
renewTokens
|
|
310
301
|
</button>
|
|
311
302
|
)}
|
|
@@ -328,8 +319,8 @@ The Hook method exposes :
|
|
|
328
319
|
`OidcSecure` component trigger authentication in case user is not authenticated. So, the children of that component can be accessible only once you are connected.
|
|
329
320
|
|
|
330
321
|
```javascript
|
|
331
|
-
import React from
|
|
332
|
-
import { OidcSecure } from
|
|
322
|
+
import React from 'react';
|
|
323
|
+
import { OidcSecure } from '@axa-fr/react-oidc';
|
|
333
324
|
|
|
334
325
|
const AdminSecure = () => (
|
|
335
326
|
<OidcSecure>
|
|
@@ -346,12 +337,12 @@ export default AdminSecure;
|
|
|
346
337
|
`withOidcSecure` will act the same as `OidcSecure`,it will also trigger authentication in case the user is not authenticated.
|
|
347
338
|
|
|
348
339
|
```javascript
|
|
349
|
-
import React from
|
|
350
|
-
import { Switch, Route } from
|
|
351
|
-
import { withOidcSecure } from
|
|
352
|
-
import Home from
|
|
353
|
-
import Dashboard from
|
|
354
|
-
import Admin from
|
|
340
|
+
import React from 'react';
|
|
341
|
+
import { Switch, Route } from 'react-router-dom';
|
|
342
|
+
import { withOidcSecure } from '@axa-fr/react-oidc';
|
|
343
|
+
import Home from '../Pages/Home';
|
|
344
|
+
import Dashboard from '../Pages/Dashboard';
|
|
345
|
+
import Admin from '../Pages/Admin';
|
|
355
346
|
|
|
356
347
|
const Routes = () => (
|
|
357
348
|
<Switch>
|
|
@@ -368,7 +359,7 @@ export default Routes;
|
|
|
368
359
|
## How to get "Access Token": Hook method
|
|
369
360
|
|
|
370
361
|
```javascript
|
|
371
|
-
import { useOidcAccessToken } from
|
|
362
|
+
import { useOidcAccessToken } from '@axa-fr/react-oidc';
|
|
372
363
|
|
|
373
364
|
const DisplayAccessToken = () => {
|
|
374
365
|
const { accessToken, accessTokenPayload } = useOidcAccessToken();
|
|
@@ -380,11 +371,10 @@ const DisplayAccessToken = () => {
|
|
|
380
371
|
<div className="card text-white bg-info mb-3">
|
|
381
372
|
<div className="card-body">
|
|
382
373
|
<h5 className="card-title">Access Token</h5>
|
|
383
|
-
<p style={{ color:
|
|
384
|
-
Please consider to configure the ServiceWorker in order to protect
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
javascript.
|
|
374
|
+
<p style={{ color: 'red', backgroundColor: 'white' }}>
|
|
375
|
+
Please consider to configure the ServiceWorker in order to protect your application from
|
|
376
|
+
XSRF attacks. ""access_token" and "refresh_token" will never be accessible from your
|
|
377
|
+
client side javascript.
|
|
388
378
|
</p>
|
|
389
379
|
{<p className="card-text">{JSON.stringify(accessToken)}</p>}
|
|
390
380
|
{accessTokenPayload != null && (
|
|
@@ -399,7 +389,7 @@ const DisplayAccessToken = () => {
|
|
|
399
389
|
## How to get IDToken: Hook method
|
|
400
390
|
|
|
401
391
|
```javascript
|
|
402
|
-
import { useOidcIdToken } from
|
|
392
|
+
import { useOidcIdToken } from '@axa-fr/react-oidc';
|
|
403
393
|
|
|
404
394
|
const DisplayIdToken = () => {
|
|
405
395
|
const { idToken, idTokenPayload } = useOidcIdToken();
|
|
@@ -413,9 +403,7 @@ const DisplayIdToken = () => {
|
|
|
413
403
|
<div className="card-body">
|
|
414
404
|
<h5 className="card-title">ID Token</h5>
|
|
415
405
|
{<p className="card-text">{JSON.stringify(idToken)}</p>}
|
|
416
|
-
{idTokenPayload != null && (
|
|
417
|
-
<p className="card-text">{JSON.stringify(idTokenPayload)}</p>
|
|
418
|
-
)}
|
|
406
|
+
{idTokenPayload != null && <p className="card-text">{JSON.stringify(idTokenPayload)}</p>}
|
|
419
407
|
</div>
|
|
420
408
|
</div>
|
|
421
409
|
);
|
|
@@ -425,7 +413,7 @@ const DisplayIdToken = () => {
|
|
|
425
413
|
## How to get User Information: Hook method
|
|
426
414
|
|
|
427
415
|
```javascript
|
|
428
|
-
import { useOidcUser, UserStatus } from
|
|
416
|
+
import { useOidcUser, UserStatus } from '@axa-fr/react-oidc';
|
|
429
417
|
|
|
430
418
|
const DisplayUserInfo = () => {
|
|
431
419
|
const { oidcUser, oidcUserLoadingState } = useOidcUser();
|
|
@@ -456,8 +444,8 @@ If you are not using the service worker. The Fetch function needs to send Access
|
|
|
456
444
|
This hook will give you a wrapped fetch that adds the access token for you.
|
|
457
445
|
|
|
458
446
|
```javascript
|
|
459
|
-
import React, { useEffect, useState } from
|
|
460
|
-
import { useOidcFetch, OidcSecure } from
|
|
447
|
+
import React, { useEffect, useState } from 'react';
|
|
448
|
+
import { useOidcFetch, OidcSecure } from '@axa-fr/react-oidc';
|
|
461
449
|
|
|
462
450
|
const DisplayUserInfo = ({ fetch }) => {
|
|
463
451
|
const [oidcUser, setOidcUser] = useState(null);
|
|
@@ -465,16 +453,14 @@ const DisplayUserInfo = ({ fetch }) => {
|
|
|
465
453
|
|
|
466
454
|
useEffect(() => {
|
|
467
455
|
const fetchUserInfoAsync = async () => {
|
|
468
|
-
const res = await fetch(
|
|
469
|
-
"https://demo.duendesoftware.com/connect/userinfo",
|
|
470
|
-
);
|
|
456
|
+
const res = await fetch('https://demo.duendesoftware.com/connect/userinfo');
|
|
471
457
|
if (res.status != 200) {
|
|
472
458
|
return null;
|
|
473
459
|
}
|
|
474
460
|
return res.json();
|
|
475
461
|
};
|
|
476
462
|
let isMounted = true;
|
|
477
|
-
fetchUserInfoAsync().then(
|
|
463
|
+
fetchUserInfoAsync().then(userInfo => {
|
|
478
464
|
if (isMounted) {
|
|
479
465
|
setLoading(false);
|
|
480
466
|
setOidcUser(userInfo);
|
|
@@ -494,9 +480,7 @@ const DisplayUserInfo = ({ fetch }) => {
|
|
|
494
480
|
<div className="card text-white bg-success mb-3">
|
|
495
481
|
<div className="card-body">
|
|
496
482
|
<h5 className="card-title">User information</h5>
|
|
497
|
-
{oidcUser != null && (
|
|
498
|
-
<p className="card-text">{JSON.stringify(oidcUser)}</p>
|
|
499
|
-
)}
|
|
483
|
+
{oidcUser != null && <p className="card-text">{JSON.stringify(oidcUser)}</p>}
|
|
500
484
|
</div>
|
|
501
485
|
</div>
|
|
502
486
|
</div>
|
|
@@ -519,8 +503,8 @@ If your are not using the service worker. Fetch function need to send AccessToke
|
|
|
519
503
|
This HOC give you a wrapped fetch that add the access token for you.
|
|
520
504
|
|
|
521
505
|
```javascript
|
|
522
|
-
import React, { useEffect, useState } from
|
|
523
|
-
import { useOidcFetch, OidcSecure } from
|
|
506
|
+
import React, { useEffect, useState } from 'react';
|
|
507
|
+
import { useOidcFetch, OidcSecure } from '@axa-fr/react-oidc';
|
|
524
508
|
|
|
525
509
|
const DisplayUserInfo = ({ fetch }) => {
|
|
526
510
|
const [oidcUser, setOidcUser] = useState(null);
|
|
@@ -528,16 +512,14 @@ const DisplayUserInfo = ({ fetch }) => {
|
|
|
528
512
|
|
|
529
513
|
useEffect(() => {
|
|
530
514
|
const fetchUserInfoAsync = async () => {
|
|
531
|
-
const res = await fetch(
|
|
532
|
-
"https://demo.duendesoftware.com/connect/userinfo",
|
|
533
|
-
);
|
|
515
|
+
const res = await fetch('https://demo.duendesoftware.com/connect/userinfo');
|
|
534
516
|
if (res.status != 200) {
|
|
535
517
|
return null;
|
|
536
518
|
}
|
|
537
519
|
return res.json();
|
|
538
520
|
};
|
|
539
521
|
let isMounted = true;
|
|
540
|
-
fetchUserInfoAsync().then(
|
|
522
|
+
fetchUserInfoAsync().then(userInfo => {
|
|
541
523
|
if (isMounted) {
|
|
542
524
|
setLoading(false);
|
|
543
525
|
setOidcUser(userInfo);
|
|
@@ -557,9 +539,7 @@ const DisplayUserInfo = ({ fetch }) => {
|
|
|
557
539
|
<div className="card text-white bg-success mb-3">
|
|
558
540
|
<div className="card-body">
|
|
559
541
|
<h5 className="card-title">User information</h5>
|
|
560
|
-
{oidcUser != null && (
|
|
561
|
-
<p className="card-text">{JSON.stringify(oidcUser)}</p>
|
|
562
|
-
)}
|
|
542
|
+
{oidcUser != null && <p className="card-text">{JSON.stringify(oidcUser)}</p>}
|
|
563
543
|
</div>
|
|
564
544
|
</div>
|
|
565
545
|
</div>
|
|
@@ -580,23 +560,23 @@ You can inject your own components.
|
|
|
580
560
|
All components definition receive props `configurationName`. Please checkout the demo for more complete example.
|
|
581
561
|
|
|
582
562
|
```javascript
|
|
583
|
-
import React from
|
|
584
|
-
import { render } from
|
|
585
|
-
import { BrowserRouter as Router } from
|
|
586
|
-
import { OidcProvider } from
|
|
587
|
-
import Header from
|
|
588
|
-
import Routes from
|
|
563
|
+
import React from 'react';
|
|
564
|
+
import { render } from 'react-dom';
|
|
565
|
+
import { BrowserRouter as Router } from 'react-router-dom';
|
|
566
|
+
import { OidcProvider } from '@axa-fr/react-oidc';
|
|
567
|
+
import Header from './Layout/Header';
|
|
568
|
+
import Routes from './Router';
|
|
589
569
|
|
|
590
570
|
// This configuration use hybrid mode
|
|
591
571
|
// ServiceWorker are used if available (more secure) else tokens are given to the client
|
|
592
572
|
// You need to give inside your code the "access_token" when using fetch
|
|
593
573
|
const configuration = {
|
|
594
|
-
client_id:
|
|
595
|
-
redirect_uri:
|
|
596
|
-
silent_redirect_uri:
|
|
597
|
-
scope:
|
|
598
|
-
authority:
|
|
599
|
-
service_worker_relative_url:
|
|
574
|
+
client_id: 'interactive.public.short',
|
|
575
|
+
redirect_uri: 'http://localhost:4200/authentication/callback',
|
|
576
|
+
silent_redirect_uri: 'http://localhost:4200/authentication/silent-callback',
|
|
577
|
+
scope: 'openid profile email api offline_access',
|
|
578
|
+
authority: 'https://demo.identityserver.io',
|
|
579
|
+
service_worker_relative_url: '/OidcServiceWorker.js',
|
|
600
580
|
service_worker_only: false,
|
|
601
581
|
};
|
|
602
582
|
|
|
@@ -632,7 +612,7 @@ const App = () => (
|
|
|
632
612
|
</OidcProvider>
|
|
633
613
|
);
|
|
634
614
|
|
|
635
|
-
render(<App />, document.getElementById(
|
|
615
|
+
render(<App />, document.getElementById('root'));
|
|
636
616
|
```
|
|
637
617
|
|
|
638
618
|
## How It Works
|
|
@@ -654,15 +634,15 @@ To work with NextJS you need to inject your own history surcharge like the sampl
|
|
|
654
634
|
**component/layout.js**
|
|
655
635
|
|
|
656
636
|
```javascript
|
|
657
|
-
import { OidcProvider } from
|
|
658
|
-
import { useRouter } from
|
|
637
|
+
import { OidcProvider } from '@axa-fr/react-oidc';
|
|
638
|
+
import { useRouter } from 'next/router';
|
|
659
639
|
|
|
660
640
|
const configuration = {
|
|
661
|
-
client_id:
|
|
662
|
-
redirect_uri:
|
|
663
|
-
silent_redirect_uri:
|
|
664
|
-
scope:
|
|
665
|
-
authority:
|
|
641
|
+
client_id: 'interactive.public.short',
|
|
642
|
+
redirect_uri: 'http://localhost:3001/#authentication/callback',
|
|
643
|
+
silent_redirect_uri: 'http://localhost:3001/#authentication/silent-callback', // Optional activate silent-login that use cookies between OIDC server and client javascript to restore the session
|
|
644
|
+
scope: 'openid profile email api offline_access',
|
|
645
|
+
authority: 'https://demo.duendesoftware.com',
|
|
666
646
|
};
|
|
667
647
|
|
|
668
648
|
const onEvent = (configurationName, eventName, data) => {
|
|
@@ -673,13 +653,13 @@ export default function Layout({ children }) {
|
|
|
673
653
|
const router = useRouter();
|
|
674
654
|
const withCustomHistory = () => {
|
|
675
655
|
return {
|
|
676
|
-
replaceState:
|
|
656
|
+
replaceState: url => {
|
|
677
657
|
router
|
|
678
658
|
.replace({
|
|
679
659
|
pathname: url,
|
|
680
660
|
})
|
|
681
661
|
.then(() => {
|
|
682
|
-
window.dispatchEvent(new Event(
|
|
662
|
+
window.dispatchEvent(new Event('popstate'));
|
|
683
663
|
});
|
|
684
664
|
},
|
|
685
665
|
};
|
|
@@ -707,14 +687,13 @@ For more information checkout the [NextJS React OIDC demo](https://github.com/Ax
|
|
|
707
687
|
|
|
708
688
|
```javascript
|
|
709
689
|
export const configurationIdentityServerWithHash = {
|
|
710
|
-
client_id:
|
|
711
|
-
redirect_uri: window.location.origin +
|
|
712
|
-
silent_redirect_uri:
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
authority: "https://demo.duendesoftware.com",
|
|
690
|
+
client_id: 'interactive.public.short',
|
|
691
|
+
redirect_uri: window.location.origin + '#authentication-callback',
|
|
692
|
+
silent_redirect_uri: window.location.origin + '#authentication-silent-callback',
|
|
693
|
+
scope: 'openid profile email api offline_access',
|
|
694
|
+
authority: 'https://demo.duendesoftware.com',
|
|
716
695
|
refresh_time_before_tokens_expiration_in_second: 70,
|
|
717
|
-
service_worker_relative_url:
|
|
696
|
+
service_worker_relative_url: '/OidcServiceWorker.js',
|
|
718
697
|
service_worker_only: false,
|
|
719
698
|
};
|
|
720
699
|
```
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
/* global console, process */
|
|
2
|
+
/* eslint no-console: "off" */
|
|
2
3
|
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
3
5
|
import { fileURLToPath } from 'url';
|
|
4
6
|
|
|
5
7
|
try {
|
|
6
|
-
|
|
7
8
|
/**
|
|
8
9
|
* Script to run after npm install
|
|
9
10
|
*
|
|
10
11
|
* Copy selected files to user's directory
|
|
11
12
|
*/
|
|
12
|
-
const script_prefix= 'react-oidc';
|
|
13
|
+
const script_prefix = 'react-oidc';
|
|
13
14
|
|
|
14
15
|
const copyFile = async (src, dest, overwrite) => {
|
|
15
|
-
if(!fileExists(src)) {
|
|
16
|
+
if (!fileExists(src)) {
|
|
16
17
|
console.log(`[${script_prefix}:skip] file does not exist ${src}`);
|
|
17
18
|
return false;
|
|
18
19
|
}
|
|
@@ -24,17 +25,24 @@ try {
|
|
|
24
25
|
}
|
|
25
26
|
await fs.promises.copyFile(src, dest);
|
|
26
27
|
console.log(`[${script_prefix}:copy] ${dest}`);
|
|
27
|
-
return true
|
|
28
|
+
return true;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
|
-
const fileExists =
|
|
31
|
+
const fileExists = path => {
|
|
31
32
|
return !!fs.existsSync(path);
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
const initPath = process.cwd();
|
|
35
36
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
36
|
-
const srcDir = path.join(__dirname,
|
|
37
|
-
const srcDirFallback = path.join(
|
|
37
|
+
const srcDir = path.join(__dirname, '..', '..', 'oidc-client-service-worker', 'dist');
|
|
38
|
+
const srcDirFallback = path.join(
|
|
39
|
+
__dirname,
|
|
40
|
+
'..',
|
|
41
|
+
'node_modules',
|
|
42
|
+
'@axa-fr',
|
|
43
|
+
'oidc-client-service-worker',
|
|
44
|
+
'dist',
|
|
45
|
+
);
|
|
38
46
|
const destinationFolder = process.argv.length >= 3 ? process.argv[2] : 'public';
|
|
39
47
|
const destinationDir = path.join(initPath, destinationFolder);
|
|
40
48
|
|
|
@@ -51,19 +59,18 @@ try {
|
|
|
51
59
|
|
|
52
60
|
for await (const file of files) {
|
|
53
61
|
const success = await copyFile(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
path.join(srcDir, file.fileName),
|
|
63
|
+
path.join(destinationDir, file.fileName),
|
|
64
|
+
file.overwrite,
|
|
57
65
|
);
|
|
58
|
-
if(!success){
|
|
66
|
+
if (!success) {
|
|
59
67
|
await copyFile(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
path.join(srcDirFallback, file.fileName),
|
|
69
|
+
path.join(destinationDir, file.fileName),
|
|
70
|
+
file.overwrite,
|
|
63
71
|
);
|
|
64
72
|
}
|
|
65
73
|
}
|
|
66
|
-
|
|
67
74
|
} catch (err) {
|
|
68
75
|
console.warn(err);
|
|
69
|
-
}
|
|
76
|
+
}
|
package/dist/FetchToken.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FetchToken.d.ts","sourceRoot":"","sources":["../src/FetchToken.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAc,MAAM,qBAAqB,CAAC;AAGxD,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"FetchToken.d.ts","sourceRoot":"","sources":["../src/FetchToken.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAc,MAAM,qBAAqB,CAAC;AAGxD,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAgBD,eAAO,MAAM,aAAa,WAEf,KAAK,kEAEuB,OAAO,wCAGpC,2BAA2B,4CAOlC,CAAC;AAEJ,eAAO,MAAM,YAAY,WAChB,KAAK,kEAEuB,OAAO;mBAMhC,WAAW,GAAG,GAAG,SAAS,WAAW;CAYhD,CAAC"}
|
package/dist/OidcProvider.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Fetch,
|
|
1
|
+
import { Fetch, ILOidcLocation, OidcClient, OidcConfiguration } from '@axa-fr/oidc-client';
|
|
2
2
|
import { ComponentType, FC, PropsWithChildren } from 'react';
|
|
3
3
|
import { CustomHistory } from './core/routes/withRouter.js';
|
|
4
4
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcProvider.d.ts","sourceRoot":"","sources":["../src/OidcProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"OidcProvider.d.ts","sourceRoot":"","sources":["../src/OidcProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EAEL,cAAc,EACd,UAAU,EACV,iBAAiB,EAElB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,iBAAiB,EAAuB,MAAM,OAAO,CAAC;AAWlF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;CAC7B,CAAC;AAIF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wBAAwB,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC9C,oBAAoB,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC1C,uBAAuB,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7C,4BAA4B,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAClD,gBAAgB,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IACtC,kCAAkC,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IACxD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,QAAQ,EAAE,GAAG,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IACpC,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,aAAa,CAAC;IACxC,OAAO,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IACnE,QAAQ,CAAC,EAAE,MAAM,KAAK,CAAC;IACvB,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC;CAC1C,CAAC;AAqCF,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAuKjE,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
package/dist/OidcSecure.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcSecure.d.ts","sourceRoot":"","sources":["../src/OidcSecure.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"OidcSecure.d.ts","sourceRoot":"","sources":["../src/OidcSecure.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAa,MAAM,OAAO,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAkB7D,CAAC;AAEF,eAAO,MAAM,cAAc,qBAEL,GAAG,kBAAkB,eAAe,CAAC,CAAC,0HAWzD,CAAC"}
|
|
@@ -5,22 +5,25 @@
|
|
|
5
5
|
// Domains used by OIDC server must be also declared here
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
7
7
|
const trustedDomains = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
default: ['https://demo.duendesoftware.com', 'https://kdhttps.auth0.com'],
|
|
9
|
+
config_classic: ['https://demo.duendesoftware.com'],
|
|
10
|
+
config_without_silent_login: ['https://demo.duendesoftware.com'],
|
|
11
|
+
config_without_refresh_token: ['https://demo.duendesoftware.com'],
|
|
12
|
+
config_without_refresh_token_silent_login: ['https://demo.duendesoftware.com'],
|
|
13
|
+
config_google: ['https://oauth2.googleapis.com', 'https://openidconnect.googleapis.com'],
|
|
14
|
+
config_with_hash: ['https://demo.duendesoftware.com'],
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
// Service worker will continue to give access token to the JavaScript client
|
|
18
18
|
// Ideal to hide refresh token from client JavaScript, but to retrieve access_token for some
|
|
19
19
|
// scenarios which require it. For example, to send it via websocket connection.
|
|
20
|
-
trustedDomains.config_show_access_token = {
|
|
20
|
+
trustedDomains.config_show_access_token = {
|
|
21
|
+
domains: ['https://demo.duendesoftware.com'],
|
|
22
|
+
showAccessToken: true,
|
|
23
|
+
};
|
|
21
24
|
|
|
22
25
|
// This example defines domains used by OIDC server separately from domains to which access tokens will be injected.
|
|
23
26
|
trustedDomains.config_separate_oidc_access_token_domains = {
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
oidcDomains: ['https://demo.duendesoftware.com'],
|
|
28
|
+
accessTokenDomains: ['https://myapi'],
|
|
26
29
|
};
|
package/dist/ReactOidc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactOidc.d.ts","sourceRoot":"","sources":["../src/ReactOidc.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ReactOidc.d.ts","sourceRoot":"","sources":["../src/ReactOidc.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAU,MAAM,qBAAqB,CAAC;AAkBpE,eAAO,MAAM,OAAO;2BA6BF,MAAM,GAAG,SAAS,WACxB,SAAS;4BAYH,MAAM,GAAG,IAAI,GAAG,SAAS,WAC/B,SAAS;2BAIgB,SAAS,KAAU,QAAQ,eAAe,GAAG,WAAW,CAAC;;CAe7F,CAAC;AAsBF,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,kBAAkB,CAAC,EAAE,GAAG,CAAC;IACzB,6CAA6C,CAAC,EAAE,GAAG,CAAC;CACrD,CAAC;AASF,eAAO,MAAM,kBAAkB,iDA6C9B,CAAC;AAeF,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,cAAc,CAAC,EAAE,GAAG,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,cAAc,6CAqC1B,CAAC"}
|
package/dist/User.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"User.d.ts","sourceRoot":"","sources":["../src/User.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"User.d.ts","sourceRoot":"","sources":["../src/User.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGpE,oBAAY,cAAc;IACxB,eAAe,oBAAoB;IACnC,OAAO,iBAAiB;IACxB,MAAM,gBAAgB;IACtB,YAAY,uBAAuB;CACpC;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,IAAI;IAC5D,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,WAAW;;;;CAwDvB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Authenticating.component.d.ts","sourceRoot":"","sources":["../../../src/core/default-component/Authenticating.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,QAAA,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"Authenticating.component.d.ts","sourceRoot":"","sources":["../../../src/core/default-component/Authenticating.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,QAAA,MAAM,cAAc,EAAE,aAAa,CAAC,GAAG,CAOtC,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Callback.component.d.ts","sourceRoot":"","sources":["../../../src/core/default-component/Callback.component.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAuB,MAAM,OAAO,CAAC;AAK3D,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"Callback.component.d.ts","sourceRoot":"","sources":["../../../src/core/default-component/Callback.component.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAuB,MAAM,OAAO,CAAC;AAK3D,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,GAAG,CAO9C,CAAC;AAEF,QAAA,MAAM,eAAe,EAAE,aAAa,CAAC,GAAG,CAoCvC,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Loading.component.d.ts","sourceRoot":"","sources":["../../../src/core/default-component/Loading.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,QAAA,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"Loading.component.d.ts","sourceRoot":"","sources":["../../../src/core/default-component/Loading.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,QAAA,MAAM,OAAO,EAAE,aAAa,CAAC,GAAG,CAAuD,CAAC;AAExF,eAAe,OAAO,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceWorkerNotSupported.component.d.ts","sourceRoot":"","sources":["../../../src/core/default-component/ServiceWorkerNotSupported.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,QAAA,MAAM,yBAAyB,
|
|
1
|
+
{"version":3,"file":"ServiceWorkerNotSupported.component.d.ts","sourceRoot":"","sources":["../../../src/core/default-component/ServiceWorkerNotSupported.component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,QAAA,MAAM,yBAAyB,EAAE,aAAa,CAAC,GAAG,CAUjD,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
|