@axa-fr/react-oidc 6.9.4 → 6.9.6

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.
Files changed (2) hide show
  1. package/README.md +260 -219
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,16 +1,10 @@
1
- <H1> @axa-fr/react-oidc</H1>
1
+ # @axa-fr/react-oidc
2
2
 
3
- Try the demo at https://black-rock-0dc6b0d03.1.azurestaticapps.net/
3
+ Try the demo at <https://black-rock-0dc6b0d03.1.azurestaticapps.net/>
4
4
 
5
- <p align="center">
6
- <img src="https://github.com/AxaGuilDEv/react-oidc/blob/master/docs/img/introduction.gif?raw=true"
7
- alt="Sample React Oicd"
8
- />
9
- </p>
5
+ ![Sample React OIDC](https://github.com/AxaGuilDEv/react-oidc/blob/master/docs/img/introduction.gif?raw=true)
10
6
 
11
- <p align="center">
12
- A set of react components to make Oidc (OpenID Connect) client easy. It aim to simplify OAuth authentication between multiples providers.
13
- </p>
7
+ A set of react components to make OIDC (OpenID Connect) client easy. It aim to simplify OAuth authentication between multiples providers.
14
8
 
15
9
  - [About](#about)
16
10
  - [Getting Started](#getting-started)
@@ -21,16 +15,18 @@ Try the demo at https://black-rock-0dc6b0d03.1.azurestaticapps.net/
21
15
  - [Hash route](#Hash-route)
22
16
  - [Service Worker Support](#service-worker-support)
23
17
 
18
+ ## About
19
+
24
20
  Easy set up of OIDC for react.
25
- It use AppAuthJS behind the scene because it very lightweight and created by openid certification team. oidc-client use in V3 is heavy and not longer maintained.
21
+ It use AppAuthJS behind the scene because it very lightweight and created by OpenID certification team. `oidc-client` that was used in V3 was heavy and not longer maintained.
26
22
 
27
23
  - **Secure** :
28
- - With the use of Service Worker, your tokens (refresh_token and access_token) are not accessible to the javascript client code (big protection against XSRF attacks)
29
- - OIDC using client side Code Credential Grant with pkce only
24
+ - With the use of Service Worker, your tokens (refresh_token and access_token) are not accessible to the JavaScript client code (big protection against XSRF attacks)
25
+ - OIDC using client side Code Credential Grant with PKCE only
30
26
  - **Lightweight**
31
27
  - **Simple** :
32
28
  - refresh_token and access_token are auto refreshed in background
33
- - with the use of the Service Worker, you do not need to inject the access_token in every fetch, you have only to configure OidcTrustedDomains.js file
29
+ - with the use of the Service Worker, you do not need to inject the access_token in every fetch, you have only to configure `OidcTrustedDomains.js` file
34
30
  - **No cookies problem** : You can disable silent signin (that internally use an iframe). For your information, your OIDC server should be in the same domain of your website in order to be able to send OIDC server cookies from your website via an internal IFRAME, else, you may encounter COOKIES problem.
35
31
  - **Multiple Authentication** :
36
32
  - You can authenticate many times to the same provider with different scope (for example you can acquire a new 'payment' scope for a payment)
@@ -38,15 +34,11 @@ It use AppAuthJS behind the scene because it very lightweight and created by ope
38
34
  - **Flexible** :
39
35
  - Work with Service Worker (more secure) and without for older browser (less secure)
40
36
 
41
- <p align="center">
42
- <img src="https://github.com/AxaGuilDEv/react-oidc/blob/master/docs/img/schema_pcke_client_side_with_service_worker.png?raw=true"
43
- alt="Schema Authorization Code Grant with pcke flow on the using service worker"
44
- />
45
- <br>
46
- The service worker catch <b>access_token</b> and <b>refresh_token</b> that will never be accessible to the client.
47
- </p>
37
+ ![](https://github.com/AxaGuilDEv/react-oidc/blob/master/docs/img/schema_pcke_client_side_with_service_worker.png?raw=true)
38
+
39
+ The service worker catch **access_token** and **refresh_token** that will never be accessible to the client.
48
40
 
49
- # Getting Started
41
+ ## Getting Started
50
42
 
51
43
  ```sh
52
44
  npm install @axa-fr/react-oidc --save
@@ -63,17 +55,16 @@ The only file you should edit is "OidcTrustedDomains.js".
63
55
  // OidcTrustedDomains.js
64
56
 
65
57
  // Add bellow trusted domains, access tokens will automatically injected to be send to
66
- // trusted domain can also be a path like https://www.myapi.com/users,
58
+ // trusted domain can also be a path like https://www.myapi.com/users,
67
59
  // then all subroute like https://www.myapi.com/useers/1 will be authorized to send access_token to.
68
60
 
69
61
  // Domains used by OIDC server must be also declared here
70
62
  const trustedDomains = {
71
- default:["https://demo.duendesoftware.com", "https://www.myapi.com/users"]
63
+ default: ['https://demo.duendesoftware.com', 'https://www.myapi.com/users'],
72
64
  };
73
-
74
65
  ```
75
66
 
76
- # Run The Demo
67
+ ## Run The Demo
77
68
 
78
69
  ```sh
79
70
  git clone https://github.com/AxaGuilDEv/react-oidc.git
@@ -83,9 +74,9 @@ npm start
83
74
  # then navigate to http://localhost:4200
84
75
  ```
85
76
 
86
- # Examples
77
+ ## Examples
87
78
 
88
- ## Application startup
79
+ ### Application startup
89
80
 
90
81
  The library is router agnostic and use native History API.
91
82
 
@@ -107,26 +98,26 @@ import Routes from './Router';
107
98
  const configuration = {
108
99
  client_id: 'interactive.public.short',
109
100
  redirect_uri: window.location.origin + '/authentication/callback',
110
- silent_redirect_uri: window.location.origin + '/authentication/silent-callback',
101
+ silent_redirect_uri:
102
+ window.location.origin + '/authentication/silent-callback',
111
103
  scope: 'openid profile email api offline_access', // offline_access scope allow your client to retrieve the refresh_token
112
104
  authority: 'https://demo.duendesoftware.com',
113
- service_worker_relative_url:'/OidcServiceWorker.js',
114
- service_worker_only:false,
105
+ service_worker_relative_url: '/OidcServiceWorker.js',
106
+ service_worker_only: false,
115
107
  };
116
108
 
117
109
  const App = () => (
118
- <OidcProvider configuration={configuration} >
119
- <Router>
120
- <Header />
121
- <Routes />
122
- </Router>
123
- </OidcProvider>
110
+ <OidcProvider configuration={configuration}>
111
+ <Router>
112
+ <Header />
113
+ <Routes />
114
+ </Router>
115
+ </OidcProvider>
124
116
  );
125
117
 
126
118
  render(<App />, document.getElementById('root'));
127
119
  ```
128
120
 
129
-
130
121
  ```javascript
131
122
  const propTypes = {
132
123
  loadingComponent: PropTypes.elementType, // you can inject your own loading component
@@ -145,56 +136,84 @@ const propTypes = {
145
136
  scope: PropTypes.string.isRequired, // oidc scope (you need to set "offline_access")
146
137
  authority: PropTypes.string.isRequired,
147
138
  storage: Storage, // Default sessionStorage, you can set localStorage but it is less secure to XSS attacks
148
- authority_configuration: PropTypes.shape({ // Optional for providers that does not implement OIDC server auto discovery via a .wellknowurl
139
+ authority_configuration: PropTypes.shape({
140
+ // Optional for providers that does not implement OIDC server auto discovery via a .wellknowurl
149
141
  authorization_endpoint: PropTypes.string,
150
142
  token_endpoint: PropTypes.string,
151
143
  userinfo_endpoint: PropTypes.string,
152
144
  end_session_endpoint: PropTypes.string,
153
145
  revocation_endpoint: PropTypes.string,
154
- check_session_iframe: PropTypes.string
146
+ check_session_iframe: PropTypes.string,
155
147
  }),
156
148
  refresh_time_before_tokens_expiration_in_second: PropTypes.number,
157
149
  service_worker_relative_url: PropTypes.string,
158
150
  service_worker_only: PropTypes.boolean, // default false
159
- extras: StringMap|undefined, // ex: {'prompt': 'consent', 'access_type': 'offline'} list of key/value that are send to the oidc server (more info: https://github.com/openid/AppAuth-JS)
160
- withCustomHistory: PropTypes.function, // Override history modification, return instance with replaceState(url, stateHistory) implemented (like History.replaceState())
161
- authority_time_cache_wellknowurl_in_second: 60* 60, // Time to cache in second of openid wellknowurl, default is 1 hour
151
+ extras: StringMap | undefined, // ex: {'prompt': 'consent', 'access_type': 'offline'} list of key/value that are send to the oidc server (more info: https://github.com/openid/AppAuth-JS)
152
+ withCustomHistory: PropTypes.function, // Override history modification, return instance with replaceState(url, stateHistory) implemented (like History.replaceState())
153
+ authority_time_cache_wellknowurl_in_second: 60 * 60, // Time to cache in second of openid wellknowurl, default is 1 hour
162
154
  monitor_session: PropTypes.boolean, // Add OpenId monitor session, default is false (more information https://openid.net/specs/openid-connect-session-1_0.html), if you need to set it to true consider https://infi.nl/nieuws/spa-necromancy/
163
155
  onLogoutFromAnotherTab: Function, // Optional, can be set to override the default behavior, this function is triggered when user with the same subject is logged out from another tab when session_monitor is active
164
156
  onLogoutFromSameTab: Function, // Optional, can be set to override the default behavior, this function is triggered when user is logged out from same tab when session_monitor is active
165
- token_renew_mode: PropTypes.string // Optional, update tokens base on the selected token(s) lifetime: "access_token_or_id_token_invalid" (default), "access_token_invalid" , "id_token_invalid"
166
- }).isRequired
157
+ token_renew_mode: PropTypes.string, // Optional, update tokens base on the selected token(s) lifetime: "access_token_or_id_token_invalid" (default), "access_token_invalid" , "id_token_invalid"
158
+ }).isRequired,
167
159
  };
168
160
  ```
161
+
169
162
  ## How to consume
170
163
 
171
164
  "useOidc" returns all props from the Hook :
172
165
 
173
166
  ```javascript
174
167
  import React from 'react';
175
- import {useOidc} from "./oidc";
168
+ import { useOidc } from './oidc';
176
169
 
177
170
  export const Home = () => {
171
+ const { login, logout, renewTokens, isAuthenticated } = useOidc();
178
172
 
179
- const { login, logout, renewTokens, isAuthenticated} = useOidc();
180
-
181
- return (
182
- <div className="container-fluid mt-3">
183
- <div className="card">
184
- <div className="card-body">
185
- <h5 className="card-title">Welcome !!!</h5>
186
- <p className="card-text">React Demo Application protected by OpenId Connect</p>
187
- {!isAuthenticated && <button type="button" className="btn btn-primary" onClick={() => login('/profile')}>Login</button>}
188
- {isAuthenticated && <button type="button" className="btn btn-primary" onClick={() => logout()}>logout</button>}
189
- {isAuthenticated && <button type="button" className="btn btn-primary" onClick={() => renewTokens()}>renewTokens</button>}
190
- </div>
191
- </div>
173
+ return (
174
+ <div className='container-fluid mt-3'>
175
+ <div className='card'>
176
+ <div className='card-body'>
177
+ <h5 className='card-title'>Welcome !!!</h5>
178
+ <p className='card-text'>
179
+ React Demo Application protected by OpenId Connect
180
+ </p>
181
+ {!isAuthenticated && (
182
+ <button
183
+ type='button'
184
+ className='btn btn-primary'
185
+ onClick={() => login('/profile')}
186
+ >
187
+ Login
188
+ </button>
189
+ )}
190
+ {isAuthenticated && (
191
+ <button
192
+ type='button'
193
+ className='btn btn-primary'
194
+ onClick={() => logout()}
195
+ >
196
+ logout
197
+ </button>
198
+ )}
199
+ {isAuthenticated && (
200
+ <button
201
+ type='button'
202
+ className='btn btn-primary'
203
+ onClick={() => renewTokens()}
204
+ >
205
+ renewTokens
206
+ </button>
207
+ )}
192
208
  </div>
193
- )
209
+ </div>
210
+ </div>
211
+ );
194
212
  };
195
-
196
213
  ```
214
+
197
215
  The Hook method exposes :
216
+
198
217
  - isAuthenticated : if the user is logged in or not
199
218
  - logout: logout function (return a promise)
200
219
  - login: login function 'return a promise'
@@ -202,7 +221,7 @@ The Hook method exposes :
202
221
 
203
222
  ## How to secure a component
204
223
 
205
- "OidcSecure" component trigger authentication in case user is not authenticated. So, the children of that component can be accessible only once you are connected.
224
+ `OidcSecure` component trigger authentication in case user is not authenticated. So, the children of that component can be accessible only once you are connected.
206
225
 
207
226
  ```javascript
208
227
  import React from 'react';
@@ -232,10 +251,10 @@ import Admin from '../Pages/Admin';
232
251
 
233
252
  const Routes = () => (
234
253
  <Switch>
235
- <Route exact path="/" component={Home} />
236
- <Route path="/dashboard" component={withOidcSecure(Dashboard)} />
237
- <Route path="/admin" component={Admin} />
238
- <Route path="/home" component={Home} />
254
+ <Route exact path='/' component={Home} />
255
+ <Route path='/dashboard' component={withOidcSecure(Dashboard)} />
256
+ <Route path='/admin' component={Admin} />
257
+ <Route path='/home' component={Home} />
239
258
  </Switch>
240
259
  );
241
260
 
@@ -248,21 +267,28 @@ export default Routes;
248
267
  import { useOidcAccessToken } from '@axa-fr/react-oidc';
249
268
 
250
269
  const DisplayAccessToken = () => {
251
- const{ accessToken, accessTokenPayload } = useOidcAccessToken();
252
-
253
- if(!accessToken){
254
- return <p>you are not authentified</p>
255
- }
256
- return (
257
- <div className="card text-white bg-info mb-3">
258
- <div className="card-body">
259
- <h5 className="card-title">Access Token</h5>
260
- <p style={{color:'red', "backgroundColor": 'white'}}>Please consider to configure the ServiceWorker in order to protect your application from XSRF attacks. ""access_token" and "refresh_token" will never be accessible from your client side javascript.</p>
261
- {<p className="card-text">{JSON.stringify(accessToken)}</p>}
262
- {accessTokenPayload != null && <p className="card-text">{JSON.stringify(accessTokenPayload)}</p>}
263
- </div>
264
- </div>
265
- )
270
+ const { accessToken, accessTokenPayload } = useOidcAccessToken();
271
+
272
+ if (!accessToken) {
273
+ return <p>you are not authentified</p>;
274
+ }
275
+ return (
276
+ <div className='card text-white bg-info mb-3'>
277
+ <div className='card-body'>
278
+ <h5 className='card-title'>Access Token</h5>
279
+ <p style={{ color: 'red', backgroundColor: 'white' }}>
280
+ Please consider to configure the ServiceWorker in order to protect
281
+ your application from XSRF attacks. ""access_token" and
282
+ "refresh_token" will never be accessible from your client side
283
+ javascript.
284
+ </p>
285
+ {<p className='card-text'>{JSON.stringify(accessToken)}</p>}
286
+ {accessTokenPayload != null && (
287
+ <p className='card-text'>{JSON.stringify(accessTokenPayload)}</p>
288
+ )}
289
+ </div>
290
+ </div>
291
+ );
266
292
  };
267
293
  ```
268
294
 
@@ -271,26 +297,26 @@ const DisplayAccessToken = () => {
271
297
  ```javascript
272
298
  import { useOidcIdToken } from '@axa-fr/react-oidc';
273
299
 
274
- const DisplayIdToken =() => {
275
- const{ idToken, idTokenPayload } = useOidcIdToken();
276
-
277
- if(!idToken){
278
- return <p>you are not authentified</p>
279
- }
280
-
281
- return (
282
- <div className="card text-white bg-info mb-3">
283
- <div className="card-body">
284
- <h5 className="card-title">ID Token</h5>
285
- {<p className="card-text">{JSON.stringify(idToken)}</p>}
286
- {idTokenPayload != null && <p className="card-text">{JSON.stringify(idTokenPayload)}</p>}
287
- </div>
288
- </div>
289
- );
290
- }
300
+ const DisplayIdToken = () => {
301
+ const { idToken, idTokenPayload } = useOidcIdToken();
291
302
 
292
- ```
303
+ if (!idToken) {
304
+ return <p>you are not authentified</p>;
305
+ }
293
306
 
307
+ return (
308
+ <div className='card text-white bg-info mb-3'>
309
+ <div className='card-body'>
310
+ <h5 className='card-title'>ID Token</h5>
311
+ {<p className='card-text'>{JSON.stringify(idToken)}</p>}
312
+ {idTokenPayload != null && (
313
+ <p className='card-text'>{JSON.stringify(idTokenPayload)}</p>
314
+ )}
315
+ </div>
316
+ </div>
317
+ );
318
+ };
319
+ ```
294
320
 
295
321
  ## How to get User Information : Hook method
296
322
 
@@ -298,9 +324,9 @@ const DisplayIdToken =() => {
298
324
  import { useOidcUser, UserStatus } from '@axa-fr/react-oidc';
299
325
 
300
326
  const DisplayUserInfo = () => {
301
- const{ oidcUser, oidcUserLoadingState } = useOidcUser();
327
+ const { oidcUser, oidcUserLoadingState } = useOidcUser();
302
328
 
303
- switch (oidcUserLoadingState){
329
+ switch (oidcUserLoadingState) {
304
330
  case UserStatus.Loading:
305
331
  return <p>User Information are loading</p>;
306
332
  case UserStatus.Unauthenticated:
@@ -309,16 +335,15 @@ const DisplayUserInfo = () => {
309
335
  return <p>Fail to load user information</p>;
310
336
  default:
311
337
  return (
312
- <div className="card text-white bg-success mb-3">
313
- <div className="card-body">
314
- <h5 className="card-title">User information</h5>
315
- <p className="card-text">{JSON.stringify(oidcUser)}</p>
316
- </div>
317
- </div>
338
+ <div className='card text-white bg-success mb-3'>
339
+ <div className='card-body'>
340
+ <h5 className='card-title'>User information</h5>
341
+ <p className='card-text'>{JSON.stringify(oidcUser)}</p>
342
+ </div>
343
+ </div>
318
344
  );
319
345
  }
320
346
  };
321
-
322
347
  ```
323
348
 
324
349
  ## How to get a fetch that inject Access_Token : Hook method
@@ -327,7 +352,7 @@ If your are not using the service worker. Fetch function need to send AccessToke
327
352
  This Hook give you a wrapped fetch that add the access token for you.
328
353
 
329
354
  ```javascript
330
- import React, {useEffect, useState} from 'react';
355
+ import React, { useEffect, useState } from 'react';
331
356
  import { useOidcFetch, OidcSecure } from '@axa-fr/react-oidc';
332
357
 
333
358
  const DisplayUserInfo = ({ fetch }) => {
@@ -336,7 +361,9 @@ const DisplayUserInfo = ({ fetch }) => {
336
361
 
337
362
  useEffect(() => {
338
363
  const fetchUserInfoAsync = async () => {
339
- const res = await fetch("https://demo.duendesoftware.com/connect/userinfo");
364
+ const res = await fetch(
365
+ 'https://demo.duendesoftware.com/connect/userinfo'
366
+ );
340
367
  if (res.status != 200) {
341
368
  return null;
342
369
  }
@@ -344,37 +371,42 @@ const DisplayUserInfo = ({ fetch }) => {
344
371
  };
345
372
  let isMounted = true;
346
373
  fetchUserInfoAsync().then((userInfo) => {
347
- if(isMounted) {
374
+ if (isMounted) {
348
375
  setLoading(false);
349
- setOidcUser(userInfo)
376
+ setOidcUser(userInfo);
350
377
  }
351
- })
352
- return () => {
378
+ });
379
+ return () => {
353
380
  isMounted = false;
354
381
  };
355
- },[]);
382
+ }, []);
356
383
 
357
- if(isLoading){
384
+ if (isLoading) {
358
385
  return <>Loading</>;
359
386
  }
360
387
 
361
388
  return (
362
- <div className="container mt-3">
363
- <div className="card text-white bg-success mb-3">
364
- <div className="card-body">
365
- <h5 className="card-title">User information</h5>
366
- {oidcUser != null && <p className="card-text">{JSON.stringify(oidcUser)}</p>}
367
- </div>
368
- </div>
369
- </div>
370
- )
389
+ <div className='container mt-3'>
390
+ <div className='card text-white bg-success mb-3'>
391
+ <div className='card-body'>
392
+ <h5 className='card-title'>User information</h5>
393
+ {oidcUser != null && (
394
+ <p className='card-text'>{JSON.stringify(oidcUser)}</p>
395
+ )}
396
+ </div>
397
+ </div>
398
+ </div>
399
+ );
371
400
  };
372
401
 
373
- export const FetchUserHook= () => {
374
- const {fetch} = useOidcFetch();
375
- return <OidcSecure><DisplayUserInfo fetch={fetch} /></OidcSecure>
376
- }
377
-
402
+ export const FetchUserHook = () => {
403
+ const { fetch } = useOidcFetch();
404
+ return (
405
+ <OidcSecure>
406
+ <DisplayUserInfo fetch={fetch} />
407
+ </OidcSecure>
408
+ );
409
+ };
378
410
  ```
379
411
 
380
412
  ## How to get a fetch that inject Access_Token : HOC method
@@ -383,7 +415,7 @@ If your are not using the service worker. Fetch function need to send AccessToke
383
415
  This HOC give you a wrapped fetch that add the access token for you.
384
416
 
385
417
  ```javascript
386
- import React, {useEffect, useState} from 'react';
418
+ import React, { useEffect, useState } from 'react';
387
419
  import { useOidcFetch, OidcSecure } from '@axa-fr/react-oidc';
388
420
 
389
421
  const DisplayUserInfo = ({ fetch }) => {
@@ -392,7 +424,9 @@ const DisplayUserInfo = ({ fetch }) => {
392
424
 
393
425
  useEffect(() => {
394
426
  const fetchUserInfoAsync = async () => {
395
- const res = await fetch("https://demo.duendesoftware.com/connect/userinfo");
427
+ const res = await fetch(
428
+ 'https://demo.duendesoftware.com/connect/userinfo'
429
+ );
396
430
  if (res.status != 200) {
397
431
  return null;
398
432
  }
@@ -400,45 +434,48 @@ const DisplayUserInfo = ({ fetch }) => {
400
434
  };
401
435
  let isMounted = true;
402
436
  fetchUserInfoAsync().then((userInfo) => {
403
- if(isMounted) {
437
+ if (isMounted) {
404
438
  setLoading(false);
405
- setOidcUser(userInfo)
439
+ setOidcUser(userInfo);
406
440
  }
407
- })
408
- return () => {
441
+ });
442
+ return () => {
409
443
  isMounted = false;
410
444
  };
411
- },[]);
445
+ }, []);
412
446
 
413
- if(isLoading){
447
+ if (isLoading) {
414
448
  return <>Loading</>;
415
449
  }
416
450
 
417
451
  return (
418
- <div className="container mt-3">
419
- <div className="card text-white bg-success mb-3">
420
- <div className="card-body">
421
- <h5 className="card-title">User information</h5>
422
- {oidcUser != null && <p className="card-text">{JSON.stringify(oidcUser)}</p>}
423
- </div>
424
- </div>
425
- </div>
426
- )
452
+ <div className='container mt-3'>
453
+ <div className='card text-white bg-success mb-3'>
454
+ <div className='card-body'>
455
+ <h5 className='card-title'>User information</h5>
456
+ {oidcUser != null && (
457
+ <p className='card-text'>{JSON.stringify(oidcUser)}</p>
458
+ )}
459
+ </div>
460
+ </div>
461
+ </div>
462
+ );
427
463
  };
428
464
 
429
465
  const UserInfoWithFetchHoc = withOidcFetch(fetch)(DisplayUserInfo);
430
- export const FetchUserHoc= () => <OidcSecure><UserInfoWithFetchHoc/></OidcSecure>;
431
-
466
+ export const FetchUserHoc = () => (
467
+ <OidcSecure>
468
+ <UserInfoWithFetchHoc />
469
+ </OidcSecure>
470
+ );
432
471
  ```
433
472
 
434
-
435
473
  ## Components override
436
474
 
437
475
  You can inject your own components.
438
- All components definition receive props "configurationName". Please checkout and the the demo for more complexe exemple.
476
+ All components definition receive props `configurationName`. Please checkout the demo for more complete example.
439
477
 
440
478
  ```javascript
441
-
442
479
  import React from 'react';
443
480
  import { render } from 'react-dom';
444
481
  import { BrowserRouter as Router } from 'react-router-dom';
@@ -455,16 +492,16 @@ const configuration = {
455
492
  silent_redirect_uri: 'http://localhost:4200/authentication/silent-callback',
456
493
  scope: 'openid profile email api offline_access',
457
494
  authority: 'https://demo.identityserver.io',
458
- service_worker_relative_url:'/OidcServiceWorker.js',
459
- service_worker_only:false,
495
+ service_worker_relative_url: '/OidcServiceWorker.js',
496
+ service_worker_only: false,
460
497
  };
461
498
 
462
- const Loading = () => <p>Loading</p>
463
- const AuthenticatingError = () => <p>Authenticating error</p>
464
- const Authenticating = () => <p>Authenticating</p>
465
- const SessionLost = () => <p>Session Lost</p>
466
- const ServiceWorkerNotSupported = () => <p>Not supported</p>
467
- const CallBackSuccess = () => <p>Success</p>
499
+ const Loading = () => <p>Loading</p>;
500
+ const AuthenticatingError = () => <p>Authenticating error</p>;
501
+ const Authenticating = () => <p>Authenticating</p>;
502
+ const SessionLost = () => <p>Session Lost</p>;
503
+ const ServiceWorkerNotSupported = () => <p>Not supported</p>;
504
+ const CallBackSuccess = () => <p>Success</p>;
468
505
 
469
506
  //const [isSessionLost, setIsSessionLost] = useState(false);
470
507
 
@@ -473,109 +510,113 @@ const CallBackSuccess = () => <p>Success</p>
473
510
  //}
474
511
 
475
512
  const App = () => (
476
- <OidcProvider configuration={configuration}
477
- loadingComponent={Loading}
478
- authenticatingErrorComponent={AuthenticatingError}
479
- authenticatingComponent={Authenticating}
480
- sessionLostComponent={SessionLost}
481
- //onSessionLost={onSessionLost} // If set "sessionLostComponent" is not displayed and onSessionLost callback is called instead
482
- serviceWorkerNotSupportedComponent={ServiceWorkerNotSupported}
483
- callbackSuccessComponent={CallBackSuccess}
484
- >
485
- {/* isSessionLost && <SessionLost />*/}
486
- <Router>
487
- <Header />
488
- <Routes />
489
- </Router>
490
- </OidcProvider>
513
+ <OidcProvider
514
+ configuration={configuration}
515
+ loadingComponent={Loading}
516
+ authenticatingErrorComponent={AuthenticatingError}
517
+ authenticatingComponent={Authenticating}
518
+ sessionLostComponent={SessionLost}
519
+ //onSessionLost={onSessionLost} // If set "sessionLostComponent" is not displayed and onSessionLost callback is called instead
520
+ serviceWorkerNotSupportedComponent={ServiceWorkerNotSupported}
521
+ callbackSuccessComponent={CallBackSuccess}
522
+ >
523
+ {/* isSessionLost && <SessionLost />*/}
524
+ <Router>
525
+ <Header />
526
+ <Routes />
527
+ </Router>
528
+ </OidcProvider>
491
529
  );
492
530
 
493
531
  render(<App />, document.getElementById('root'));
494
-
495
532
  ```
496
533
 
497
- # How It Works
534
+ ## How It Works
498
535
 
499
- These components encapsulate the use of "AppAuth-JS" in order to hide workfow complexity.
536
+ These components encapsulate the use of [AppAuth-JS](https://github.com/openid/AppAuth-JS) in order to hide workflow complexity.
500
537
  Internally, native History API is used to be router library agnostic.
501
- It use AppAuthJS behind the scene because it very lightweight and created by openid certification team. oidc-client used in V3 is heavy and not longer maintained.
538
+ It use AppAuthJS behind the scene because it very lightweight and created by OpenID certification team. `oidc-client` used in V3 was heavy and no longer maintained.
502
539
 
503
540
  More information about OIDC
504
- - French: https://medium.com/just-tech-it-now/augmentez-la-s%C3%A9curit%C3%A9-et-la-simplicit%C3%A9-de-votre-syst%C3%A8me-dinformation-avec-oauth-2-0-cf0732d71284
505
- - English: https://medium.com/just-tech-it-now/increase-the-security-and-simplicity-of-your-information-system-with-openid-connect-fa8c26b99d6d
506
541
 
542
+ - [French](https://medium.com/just-tech-it-now/augmentez-la-s%C3%A9curit%C3%A9-et-la-simplicit%C3%A9-de-votre-syst%C3%A8me-dinformation-avec-oauth-2-0-cf0732d71284)
543
+ - [English](https://medium.com/just-tech-it-now/increase-the-security-and-simplicity-of-your-information-system-with-openid-connect-fa8c26b99d6d)
507
544
 
508
-
509
- # NextJS
545
+ ## NextJS
510
546
 
511
547
  To work with NextJS you need to inject your own history surcharge like the sample below.
512
548
 
513
- component/layout.js
549
+ **component/layout.js**
550
+
514
551
  ```javascript
515
552
  import { OidcProvider } from '@axa-fr/react-oidc';
516
- import { useRouter } from 'next/router'
553
+ import { useRouter } from 'next/router';
517
554
 
518
555
  const configuration = {
519
556
  client_id: 'interactive.public.short',
520
557
  redirect_uri: 'http://localhost:3001/#authentication/callback',
521
558
  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
522
559
  scope: 'openid profile email api offline_access',
523
- authority: 'https://demo.duendesoftware.com'
560
+ authority: 'https://demo.duendesoftware.com',
524
561
  };
525
562
 
526
- const onEvent=(configurationName, eventName, data )=>{
563
+ const onEvent = (configurationName, eventName, data) => {
527
564
  console.log(`oidc:${configurationName}:${eventName}`, data);
528
- }
565
+ };
529
566
 
530
567
  export default function Layout({ children }) {
531
- const router = useRouter()
532
- const withCustomHistory= () => {
568
+ const router = useRouter();
569
+ const withCustomHistory = () => {
533
570
  return {
534
571
  replaceState: (url) => {
535
- router.replace({
536
- pathname: url,
537
- }).then(() => {
538
- window.dispatchEvent(new Event('popstate'));
539
- });
540
- }
572
+ router
573
+ .replace({
574
+ pathname: url,
575
+ })
576
+ .then(() => {
577
+ window.dispatchEvent(new Event('popstate'));
578
+ });
579
+ },
541
580
  };
542
581
  };
543
-
582
+
544
583
  return (
545
- <>
546
- <OidcProvider configuration={configuration} onEvent={onEvent} withCustomHistory={withCustomHistory} >
547
- <main>{children}</main>
548
- </OidcProvider>
549
- </>
550
- )
584
+ <>
585
+ <OidcProvider
586
+ configuration={configuration}
587
+ onEvent={onEvent}
588
+ withCustomHistory={withCustomHistory}
589
+ >
590
+ <main>{children}</main>
591
+ </OidcProvider>
592
+ </>
593
+ );
551
594
  }
552
-
553
595
  ```
554
596
 
555
- For more information checkout the nextjs react oidc demo: https://github.com/AxaGuilDEv/react-oidc/tree/master/packages/nextjs-demo
597
+ For more information checkout the [NextJS React OIDC demo](https://github.com/AxaGuilDEv/react-oidc/tree/master/packages/nextjs-demo)
556
598
 
557
- # Hash route
599
+ ## Hash route
558
600
 
559
- React oidc work also with hash router.
601
+ `react-oidc` work also with hash router.
560
602
 
561
603
  ```javascript
562
604
  export const configurationIdentityServerWithHash = {
563
- client_id: 'interactive.public.short',
564
- redirect_uri: window.location.origin+'#authentication-callback',
565
- silent_redirect_uri: window.location.origin+'#authentication-silent-callback',
566
- scope: 'openid profile email api offline_access',
567
- authority: 'https://demo.duendesoftware.com',
568
- refresh_time_before_tokens_expiration_in_second: 70,
569
- service_worker_relative_url:'/OidcServiceWorker.js',
570
- service_worker_only: false,
605
+ client_id: 'interactive.public.short',
606
+ redirect_uri: window.location.origin + '#authentication-callback',
607
+ silent_redirect_uri:
608
+ window.location.origin + '#authentication-silent-callback',
609
+ scope: 'openid profile email api offline_access',
610
+ authority: 'https://demo.duendesoftware.com',
611
+ refresh_time_before_tokens_expiration_in_second: 70,
612
+ service_worker_relative_url: '/OidcServiceWorker.js',
613
+ service_worker_only: false,
571
614
  };
572
-
573
-
574
615
  ```
575
616
 
576
- # Service Worker Support
617
+ ## Service Worker Support
577
618
 
578
- - Firefox : tested on firefox 98.0.2
619
+ - Firefox : tested on Firefox 98.0.2
579
620
  - Chrome/Edge : tested on version upper to 90
580
621
  - Opera : tested on version upper to 80
581
622
  - Safari : tested on Safari/605.1.15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axa-fr/react-oidc",
3
- "version": "6.9.4",
3
+ "version": "6.9.6",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "jsnext:main": "dist/index.js",