@axa-fr/react-oidc 6.0.0-alpha7 → 6.0.0-beta0

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.
@@ -125,11 +125,11 @@ const keepAliveAsync = async (event) => {
125
125
  const init = {"status": 200, "statusText": 'oidc-service-worker'};
126
126
  const response = new Response('{}', init);
127
127
  if(!isFromVanilla) {
128
- //for(let i=0; i<10;i++){
129
- await sleep(10000);
130
- // const cache = await caches.open("oidc_dummy_cache");
131
- //await cache.put(event.request, response.clone());
132
- //}
128
+ for(let i=0; i<240;i++){
129
+ await sleep(1000 + Math.floor(Math.random() * 1000));
130
+ const cache = await caches.open("oidc_dummy_cache");
131
+ await cache.put(event.request, response.clone());
132
+ }
133
133
  }
134
134
 
135
135
  return response;
@@ -175,9 +175,7 @@ const handleFetch = async (event) => {
175
175
  break;
176
176
  }
177
177
  }
178
-
179
- console.log("currentDatabase");
180
- console.log(currentDatabase);
178
+
181
179
  return fetch(originalRequest, {
182
180
  body: newBody,
183
181
  method: originalRequest.method,
@@ -191,7 +189,7 @@ const handleFetch = async (event) => {
191
189
  credentials: originalRequest.credentials,
192
190
  integrity: originalRequest.integrity
193
191
  }).then(hideTokens(currentDatabase));
194
- } else if(currentLoginCallbackConfigurationName){
192
+ } else if(actualBody.includes("code_verifier=") && currentLoginCallbackConfigurationName){
195
193
  currentDatabase = database[currentLoginCallbackConfigurationName];
196
194
  currentLoginCallbackConfigurationName=null;
197
195
  return fetch(originalRequest,{
@@ -294,7 +292,7 @@ addEventListener('message', event => {
294
292
  ...currentDatabase.tokens,
295
293
  access_token: ACCESS_TOKEN + "_" + configurationName
296
294
  };
297
- if(currentDatabase.refresh_token){
295
+ if(tokens.refresh_token){
298
296
  tokens.refresh_token = REFRESH_TOKEN + "_" + configurationName;
299
297
  }
300
298
  port.postMessage({
@@ -37,9 +37,8 @@ export const sleepAsync = (milliseconds) => {
37
37
  }
38
38
 
39
39
  const keepAlive = () => {
40
- fetch('/OidcKeepAliveServiceWorker.json').then(() => {
41
- keepAlive();
42
- })
40
+ fetch('/OidcKeepAliveServiceWorker.json');
41
+ sleepAsync(230*1000).then(keepAlive);
43
42
  }
44
43
 
45
44
  const isServiceWorkerProxyActiveAsync = () => {
@@ -20,6 +20,45 @@ import {CheckSessionIFrame} from "./checkSessionIFrame"
20
20
  import {getParseQueryStringFromLocation} from "./route-utils";
21
21
  import {AuthorizationServiceConfigurationJson} from "@openid/appauth/src/authorization_service_configuration";
22
22
 
23
+ const performTokenRequestAsync= async (url, details, extras) => {
24
+
25
+
26
+ for (let [key, value] of Object.entries(extras)) {
27
+ if (details[key] === undefined) {
28
+ details[key] = value;
29
+ }
30
+ }
31
+
32
+ let formBody = [];
33
+ for (const property in details) {
34
+ const encodedKey = encodeURIComponent(property);
35
+ const encodedValue = encodeURIComponent(details[property]);
36
+ formBody.push(`${encodedKey}=${encodedValue}`);
37
+ }
38
+ const formBodyString = formBody.join("&");
39
+
40
+ const response = await internalFetch(url, {
41
+ method: 'POST',
42
+ headers: {
43
+ 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
44
+ },
45
+ body: formBodyString,
46
+ });
47
+ if(response.status !== 200){
48
+ return {success:false, status: response.status}
49
+ }
50
+ const result = await response.json();
51
+ return { success : true,
52
+ data : {
53
+ accessToken: result.access_token,
54
+ expiresIn: result.expires_in,
55
+ idToken: result.id_token,
56
+ refreshToken: result.refresh_token,
57
+ scope: result.scope,
58
+ tokenType: result.token_type,
59
+ }
60
+ };
61
+ }
23
62
 
24
63
  const internalFetch = async (url, headers, numberRetry=0) => {
25
64
  let response;
@@ -30,7 +69,7 @@ const internalFetch = async (url, headers, numberRetry=0) => {
30
69
  () => reject(new Error('Timeout')), 10000))]);
31
70
  } catch (e) {
32
71
  if (e.message === 'Timeout'
33
- || e.message === 'Network request failed' || e.message === "Failed to fetch") {
72
+ || e.message === 'Network request failed') {
34
73
  if(numberRetry <=2) {
35
74
  return await internalFetch(url, headers, numberRetry + 1);
36
75
  }
@@ -205,7 +244,8 @@ const userInfoAsync = async (oidc) => {
205
244
  const fetchUserInfo = async (accessToken) => {
206
245
  const res = await fetch(url, {
207
246
  headers: {
208
- authorization: `Bearer ${accessToken}`
247
+ authorization: `Bearer ${accessToken}`,
248
+ credentials: 'same-origin'
209
249
  }
210
250
  });
211
251
 
@@ -377,13 +417,13 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
377
417
  static eventNames = eventNames;
378
418
 
379
419
  silentSigninCallbackFromIFrame(){
380
- if (this.configuration.silent_redirect_uri) {
420
+ if (this.configuration.silent_redirect_uri && this.configuration.silent_signin_uri) {
381
421
  const queryParams = getParseQueryStringFromLocation(window.location.href);
382
422
  window.top.postMessage(`${this.configurationName}_oidc_tokens:${JSON.stringify({tokens:this.tokens, sessionState:queryParams.session_state})}`, window.location.origin);
383
423
  }
384
424
  }
385
425
  silentSigninErrorCallbackFromIFrame(){
386
- if (this.configuration.silent_redirect_uri) {
426
+ if (this.configuration.silent_redirect_uri && this.configuration.silent_signin_uri) {
387
427
  const queryParams = getParseQueryStringFromLocation(window.location.href);
388
428
  window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error:queryParams.error})}`, window.location.origin);
389
429
  }
@@ -870,13 +910,8 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
870
910
  }
871
911
 
872
912
  async refreshTokensAsync(refreshToken) {
873
-
874
- /*while (document.hidden) {
875
- await sleepAsync(1000);
876
- this.publishEvent(eventNames.refreshTokensAsync, {message:"wait because document is hidden"});
877
- }*/
878
913
 
879
- const localSilentSigninAsync= async (exception=null) => {
914
+ const localSilentSigninAsync= async () => {
880
915
  try {
881
916
  const silent_token_response = await this.silentSigninAsync();
882
917
  if (silent_token_response) {
@@ -889,13 +924,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
889
924
  timer.clearTimeout(this.timeoutId);
890
925
  this.timeoutId=null;
891
926
  }
892
- this.publishEvent(eventNames.refreshTokensAsync_error, exception);
927
+ this.publishEvent(eventNames.refreshTokensAsync_error, {message: "refresh token and silent refresh failed"});
893
928
  return null;
894
929
  }
895
-
896
- try{
897
- this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken:refreshToken});
898
-
930
+
899
931
  const configuration = this.configuration;
900
932
  const clientId = configuration.client_id;
901
933
  const redirectUri = configuration.redirect_uri;
@@ -906,7 +938,6 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
906
938
  return await localSilentSigninAsync();
907
939
  }
908
940
 
909
-
910
941
  let extras = {};
911
942
  if(configuration.token_request_extras) {
912
943
  for (let [key, value] of Object.entries(configuration.token_request_extras)) {
@@ -914,70 +945,39 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
914
945
  }
915
946
  }
916
947
  const oidcServerConfiguration = await this.initAsync(authority, configuration.authority_configuration);
917
-
918
- /*const tokenHandler = new BaseTokenRequestHandler(new FetchRequestor());
919
- // use the token response to make a request for an access token
920
- const request = new TokenRequest({
948
+
949
+ const details = {
921
950
  client_id: clientId,
922
951
  redirect_uri: redirectUri,
923
952
  grant_type: GRANT_TYPE_REFRESH_TOKEN,
924
- code: undefined,
925
953
  refresh_token: refreshToken,
926
- extras
927
- });
954
+ };
928
955
 
929
-
930
- const token_response = await tokenHandler.performTokenRequest(oidcServerConfiguration, request);
931
- */
932
- const performTokenRequestAsync= async (url) => {
933
- const details = {
934
- client_id: clientId,
935
- redirect_uri: redirectUri,
936
- grant_type: GRANT_TYPE_REFRESH_TOKEN,
937
- refresh_token: refreshToken,
938
- };
939
-
940
- for (let [key, value] of Object.entries(extras)) {
941
- if (details[key] === undefined) {
942
- details[key] = value;
956
+ let index = 0;
957
+ while (index <=2) {
958
+ try {
959
+ this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken:refreshToken, tryNumber: index});
960
+ if(index > 1) {
961
+ while (document.hidden) {
962
+ await sleepAsync(1000);
963
+ this.publishEvent(eventNames.refreshTokensAsync, {message: "wait because document is hidden"});
964
+ }
943
965
  }
966
+ const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint, details, extras)
967
+ if (tokenResponse.success) {
968
+ this.publishEvent(eventNames.refreshTokensAsync_end, {success: tokenResponse.success});
969
+ return tokenResponse.data;
970
+ } else {
971
+ this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "bad request" , tokenResponse: tokenResponse});
972
+ return await localSilentSigninAsync();
973
+ }
974
+ } catch (exception) {
975
+ console.error(exception);
976
+ this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message: "exception" ,exception: exception});
944
977
  }
945
-
946
- let formBody = [];
947
- for (const property in details) {
948
- const encodedKey = encodeURIComponent(property);
949
- const encodedValue = encodeURIComponent(details[property]);
950
- formBody.push(`${encodedKey}=${encodedValue}`);
951
- }
952
- const formBodyString = formBody.join("&");
953
-
954
- const response = await internalFetch(url, {
955
- method: 'POST',
956
- headers: {
957
- 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
958
- },
959
- body: formBodyString,
960
- });
961
- const result = await response.json();
962
- return {
963
- accessToken: result.access_token,
964
- expiresIn: result.expires_in,
965
- idToken: result.id_token,
966
- refreshToken: result.refresh_token,
967
- scope: result.scope,
968
- tokenType: result.token_type,
969
- };
978
+ index++;
970
979
  }
971
-
972
- const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint)
973
-
974
- this.publishEvent(eventNames.refreshTokensAsync_end, {message:"success"});
975
- return tokenResponse;
976
- } catch(exception) {
977
- console.error(exception);
978
- this.publishEvent(eventNames.refreshTokensAsync_silent_error, exception);
979
- return await localSilentSigninAsync(exception);
980
- }
980
+
981
981
  }
982
982
 
983
983
  syncTokensAsyncPromise=null;
@@ -1004,7 +1004,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
1004
1004
  if (silent_token_response && silent_token_response.tokens) {
1005
1005
  this.tokens = await setTokensAsync(serviceWorker, silent_token_response.tokens);
1006
1006
  } else{
1007
- this.publishEvent(eventNames.syncTokensAsync_error, null);
1007
+ this.publishEvent(eventNames.syncTokensAsync_error, {message:"no token found in result"});
1008
1008
  if(this.timeoutId){
1009
1009
  timer.clearTimeout(this.timeoutId);
1010
1010
  this.timeoutId=null;
package/src/App.css DELETED
@@ -1,38 +0,0 @@
1
- .App {
2
- text-align: center;
3
- }
4
-
5
- .App-logo {
6
- height: 40vmin;
7
- pointer-events: none;
8
- }
9
-
10
- @media (prefers-reduced-motion: no-preference) {
11
- .App-logo {
12
- animation: App-logo-spin infinite 20s linear;
13
- }
14
- }
15
-
16
- .App-header {
17
- background-color: #282c34;
18
- min-height: 100vh;
19
- display: flex;
20
- flex-direction: column;
21
- align-items: center;
22
- justify-content: center;
23
- font-size: calc(10px + 2vmin);
24
- color: white;
25
- }
26
-
27
- .App-link {
28
- color: #61dafb;
29
- }
30
-
31
- @keyframes App-logo-spin {
32
- from {
33
- transform: rotate(0deg);
34
- }
35
- to {
36
- transform: rotate(360deg);
37
- }
38
- }
@@ -1,46 +0,0 @@
1
- // __tests__/fetch.test.js
2
- /*import React from 'react'
3
- import {rest} from 'msw'
4
- import {setupServer} from 'msw/node'
5
- import {render, fireEvent, waitFor, screen} from '@testing-library/react'
6
- import '@testing-library/jest-dom'
7
- import App from "./App";
8
- import {act} from "react-dom/test-utils";
9
-
10
- const server = setupServer(
11
- rest.get('http://api/.well-known/openid-configuration', (req, res, ctx) => {
12
- return res( ctx.status(200),ctx.json({
13
- "issuer":"https://demo.identityserver.io",
14
- "jwks_uri":"https://demo.identityserver.io/.well-known/openid-configuration/jwks",
15
- "authorization_endpoint":"https://demo.identityserver.io/connect/authorize",
16
- "token_endpoint":"https://demo.identityserver.io/connect/token",
17
- "userinfo_endpoint":"https://demo.identityserver.io/connect/userinfo",
18
- "end_session_endpoint":"https://demo.identityserver.io/connect/endsession",
19
- "check_session_iframe":"https://demo.identityserver.io/connect/checksession",
20
- "revocation_endpoint":"https://demo.identityserver.io/connect/revocation",
21
- "introspection_endpoint":"https://demo.identityserver.io/connect/introspect",
22
- "device_authorization_endpoint":"https://demo.identityserver.io/connect/deviceauthorization","frontchannel_logout_supported":true,"frontchannel_logout_session_supported":true,"backchannel_logout_supported":true,"backchannel_logout_session_supported":true,"scopes_supported":["openid","profile","email","api","api.scope1","api.scope2","scope2","policyserver.runtime","policyserver.management","offline_access"],"claims_supported":["sub","name","family_name","given_name","middle_name","nickname","preferred_username","profile","picture","website","gender","birthdate","zoneinfo","locale","updated_at","email","email_verified"],"grant_types_supported":["authorization_code","client_credentials","refresh_token","implicit","password","urn:ietf:params:oauth:grant-type:device_code"],"response_types_supported":["code","token","id_token","id_token token","code id_token","code token","code id_token token"],"response_modes_supported":["form_post","query","fragment"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"id_token_signing_alg_values_supported":["RS256"],"subject_types_supported":["public"],"code_challenge_methods_supported":["plain","S256"],"request_parameter_supported":true}))
23
- }),
24
- )
25
-
26
- beforeAll(() => server.listen())
27
- afterEach(() => server.resetHandlers())
28
- afterAll(() => server.close())
29
-
30
- test('Load home page then login should log', async () => {
31
-
32
- const configuration = {
33
- client_id: 'interactive.public.short',
34
- redirect_uri: 'http://localhost:4200/authentication/callback',
35
- scope: 'openid profile email api offline_access',
36
- authority: 'http://api',
37
- refresh_time_before_tokens_expiration_in_second: 70,
38
- };
39
- // @ts-ignore
40
- const {debug, getByText, rerender} = render(<App configuration={configuration}/>);
41
- await waitFor(() => getByText('React Demo Application protected by OpenId Connect'));
42
- fireEvent.click(screen.getByText('Login'));
43
- await waitFor(() => getByText('Authentification en cours'));
44
-
45
- })
46
- */
package/src/App.tsx DELETED
@@ -1,96 +0,0 @@
1
- import React, {useReducer} from 'react';
2
- import {BrowserRouter, Route, Link, Routes} from 'react-router-dom';
3
- import { Home } from "./Home";
4
- import { Profile, SecureProfile } from "./Profile";
5
- import { configurationAuth0, configurationIdentityServer, configurationIdentityServerWithoutDiscovery } from './configurations';
6
- import { withOidcSecure, OidcProvider } from "./oidc";
7
- import {FetchUserHoc, FetchUserHook} from "./FetchUser";
8
- import { MultiAuthContainer } from "./MultiAuth";
9
-
10
- const OidcSecureHoc = withOidcSecure(Profile);
11
-
12
- function reducer(state, action) {
13
- switch (action.type) {
14
- case 'event':
15
- return [{...action.data, date:Date.now()}, ...state]
16
- default:
17
- throw new Error();
18
- }
19
- }
20
-
21
- function App() {
22
- const [show, setShow] = React.useState(false);
23
- const [events, dispatch] = useReducer(reducer, []);
24
-
25
- const onEvent=(configurationName, eventName, data )=>{
26
- // console.log(`oidc:${configurationName}:${eventName}`, data);
27
- dispatch({type: 'event', data: {name: `oidc:${configurationName}:${eventName}`, data}})
28
- }
29
- return (<>
30
-
31
- <OidcProvider configuration={configurationIdentityServer} onEvent={onEvent}>
32
- <BrowserRouter>
33
- <nav className="navbar navbar-expand-lg navbar-dark bg-primary">
34
- <a className="navbar-brand" href="/">@axa-fr/react-oidc</a>
35
- <button className="navbar-toggler" type="button" onClick={() => setShow(!show)} data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
36
- <span className="navbar-toggler-icon"/>
37
- </button>
38
- <div style={show ? { display: "block" } : { display: 'none' }} className="collapse navbar-collapse" id="navbarNav">
39
- <ul className="navbar-nav">
40
- <li className="nav-item">
41
- <Link className="nav-link" to="/">Home</Link>
42
- </li>
43
- <li className="nav-item">
44
- <Link className="nav-link" to="/profile">Profile</Link>
45
- </li>
46
- <li className="nav-item">
47
- <Link className="nav-link" to="/profile-secure-component">Secure Profile Component</Link>
48
- </li>
49
- <li className="nav-item">
50
- <Link className="nav-link" to="/profile-secure-hoc">Secure Profile Hoc</Link>
51
- </li>
52
- <li className="nav-item">
53
- <Link className="nav-link" to="/user-fetch-secure-hoc">Secure User Fetch Hoc</Link>
54
- </li>
55
- <li className="nav-item">
56
- <Link className="nav-link" to="/user-fetch-secure-hook">Secure User Fetch Hook</Link>
57
- </li>
58
- <li className="nav-item">
59
- <Link className="nav-link" to="/multi-auth">Multi Auth</Link>
60
- </li>
61
- </ul>
62
- </div>
63
- </nav>
64
-
65
- <div>
66
- <Routes>
67
- <Route path="/" element={<Home></Home>} />
68
- <Route path="/profile" element={<Profile></Profile>} />
69
- <Route path="/profile-secure-component" element={<SecureProfile></SecureProfile>} />
70
- <Route path="/profile-secure-hoc" element={<OidcSecureHoc></OidcSecureHoc>} />
71
- <Route path="/user-fetch-secure-hoc" element={<FetchUserHoc></FetchUserHoc>} />
72
- <Route path="/user-fetch-secure-hook" element={<FetchUserHook></FetchUserHook>} />
73
- <Route path="/multi-auth/*" element={<MultiAuthContainer></MultiAuthContainer>} />
74
- </Routes>
75
- </div>
76
-
77
- </BrowserRouter>
78
- </OidcProvider>
79
- <div className="container-fluid mt-3">
80
- <div className="card">
81
- <div className="card-body" >
82
- <h5 className="card-title">Default configuration Events</h5>
83
- <div style={{"overflowX": "hidden", "overflowY": "scroll", "maxHeight": "400px"}}>
84
- {events.map(e => {
85
- const date = new Date(e.date);
86
- const dateFormated = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
87
- return <p>{dateFormated} {e.name}: { JSON.stringify(e.data)}</p>
88
- })}
89
- </div>
90
- </div>
91
- </div>
92
- </div></>
93
- );
94
- }
95
-
96
- export default App;
package/src/FetchUser.tsx DELETED
@@ -1,53 +0,0 @@
1
- import React, {useEffect, useState} from 'react';
2
-
3
- import {useOidcFetch, withOidcFetch} from "./oidc/FetchToken";
4
- import {OidcSecure} from "./oidc";
5
-
6
- const DisplayUserInfo = ({ fetch }) => {
7
- const [oidcUser, setOidcUser] = useState(null);
8
- const [isLoading, setLoading] = useState(true);
9
-
10
- useEffect(() => {
11
- const fetchUserInfoAsync = async () => {
12
- const res = await fetch("https://demo.duendesoftware.com/connect/userinfo");
13
- if (res.status != 200) {
14
- return null;
15
- }
16
- return res.json();
17
- };
18
- let isMounted = true;
19
- fetchUserInfoAsync().then((userInfo) => {
20
- if(isMounted) {
21
- setLoading(false);
22
- setOidcUser(userInfo)
23
- }
24
- })
25
- return () => {
26
- isMounted = false;
27
- };
28
- },[]);
29
-
30
- if(isLoading){
31
- return <>Loading</>;
32
- }
33
-
34
- return (
35
- <div className="container mt-3">
36
- <div className="card text-white bg-success mb-3">
37
- <div className="card-body">
38
- <h5 className="card-title">User information</h5>
39
- {oidcUser != null && <p className="card-text">{JSON.stringify(oidcUser)}</p>}
40
- </div>
41
- </div>
42
- </div>
43
- )
44
- };
45
-
46
- const UserInfoWithFetchHoc = withOidcFetch(fetch)(DisplayUserInfo);
47
-
48
- export const FetchUserHoc= () => <OidcSecure><UserInfoWithFetchHoc/></OidcSecure>;
49
-
50
- export const FetchUserHook= () => {
51
- const {fetch} = useOidcFetch();
52
- return <OidcSecure><DisplayUserInfo fetch={fetch} /></OidcSecure>
53
- }
package/src/Home.tsx DELETED
@@ -1,22 +0,0 @@
1
- import React from 'react';
2
- import {useOidc} from "./oidc";
3
-
4
- export const Home = () => {
5
-
6
- const { login, logout, isAuthenticated} = useOidc();
7
-
8
- return (
9
- <div className="container-fluid mt-3">
10
- <div className="card">
11
- <div className="card-body">
12
- <h5 className="card-title">Home</h5>
13
- <p className="card-text">React Demo Application protected by OpenId Connect. More info on about oidc on <a href="https://github.com/AxaGuilDEv/react-oidc">GitHub @axa-fr/react-oidc</a></p>
14
- {!isAuthenticated && <p><button type="button" className="btn btn-primary" onClick={() => login('/profile')}>Login</button></p>}
15
- {!isAuthenticated && <p><button type="button" className="btn btn-primary" onClick={() => login('/profile', null, "youhou")}>Login with state</button></p>}
16
- {isAuthenticated && <p><button type="button" className="btn btn-primary" onClick={() => logout('/profile')}>logout /profile</button></p>}
17
- {isAuthenticated && <p><button type="button" className="btn btn-primary" onClick={() => logout('')}>logout</button></p>}
18
- </div>
19
- </div>
20
- </div>
21
- )
22
- };
package/src/MultiAuth.tsx DELETED
@@ -1,116 +0,0 @@
1
- import React, {useState} from 'react';
2
- import {OidcProvider, useOidc, useOidcAccessToken, useOidcIdToken} from "./oidc";
3
- import { configurationIdentityServer, configurationIdentityServerWithHash, configurationGoogle} from "./configurations";
4
- import AuthenticatingError from "./override/AuthenticateError.component"
5
- import Authenticating from "./override/Authenticating.component"
6
- import Loading from "./override/Loading.component"
7
- import {CallBackSuccess} from "./override/Callback.component"
8
- import SessionLost from "./override/SessionLost.component"
9
- import ServiceWorkerNotSupported from "./override/ServiceWorkerNotSupported.component"
10
-
11
- const MultiAuth = ( {configurationName, handleConfigurationChange }) => {
12
- const { login, logout, isAuthenticated} = useOidc(configurationName);
13
- const [fname, setFname] = useState("")
14
-
15
- const handleChange = e => {
16
- setFname(e.target.value)
17
- }
18
- return (
19
- <div className="container-fluid mt-3">
20
- <div className="card">
21
- <div className="card-body">
22
- <h5 className="card-title">Multiple Authentication</h5>
23
- <form>
24
- <label>
25
- First Name:{" "}
26
- <input type="text" value={fname} onChange={handleChange} />
27
- </label>
28
- </form>
29
- <p className="card-text">React Demo Application protected by OpenId Connect with MultipleAuthentication.
30
- <br/>For example, config_1 can have other sensitive scope, config_2 does not ask for the "offline_access" so it does not retrieve the most sensitive token "refresh_token" for very sensitive operation, it retrive only access_token valid for a small amout of time.</p>
31
- <select value={configurationName} onChange={handleConfigurationChange} >
32
- <option value="config_classic">config_classic</option>
33
- <option value="config_without_refresh_token">config_without_refresh_token</option>
34
- <option value="config_google">google</option>
35
- <option value="config_with_hash">config_with_hash</option>
36
- </select>
37
- {!isAuthenticated && <button type="button" className="btn btn-primary" onClick={() => login()}>Login</button>}
38
- {isAuthenticated && <button type="button" className="btn btn-primary" onClick={() => logout()}>logout</button>}
39
- </div>
40
- </div>
41
- </div>
42
- );
43
- };
44
-
45
- if(!sessionStorage.configurationName){
46
- sessionStorage.configurationName = "config_classic";
47
- }
48
-
49
- export const MultiAuthContainer = () => {
50
- const [isSessionLost, setIsSessionLost] = useState(false)
51
- const [configurationName, setConfigurationName] = useState(sessionStorage.configurationName);
52
- const callBack = window.location.origin+"/multi-auth/authentification/callback2";
53
- const silent_redirect_uri = window.location.origin+"/multi-auth/authentification/silent-callback2";
54
- const configurations = {
55
- config_classic: {...configurationIdentityServer,
56
- redirect_uri:callBack,
57
- silent_redirect_uri,
58
- scope: 'openid profile email api offline_access'
59
- },
60
- config_without_refresh_token: {...configurationIdentityServer,
61
- redirect_uri:callBack,
62
- silent_redirect_uri: "",
63
- scope: 'openid profile email api'},
64
- config_google: { ...configurationGoogle },
65
- config_with_hash: { ...configurationIdentityServerWithHash}
66
- }
67
- const handleConfigurationChange = (event) => {
68
- const configurationName = event.target.value;
69
- sessionStorage.configurationName = configurationName;
70
- setConfigurationName(configurationName);
71
-
72
- }
73
-
74
- const onSessionLost = ()=>{
75
- setIsSessionLost(true);
76
- }
77
-
78
- return (
79
- <>
80
- <OidcProvider configuration={configurations[configurationName]}
81
- configurationName={configurationName}
82
- loadingComponent={Loading}
83
- authenticatingErrorComponent={AuthenticatingError}
84
- authenticatingComponent={Authenticating}
85
- serviceWorkerNotSupportedComponent={ServiceWorkerNotSupported}
86
- callbackSuccessComponent={CallBackSuccess}
87
- onSessionLost={onSessionLost}
88
- >
89
- { isSessionLost && <SessionLost configurationName={configurationName}/>}
90
- <MultiAuth configurationName={configurationName} handleConfigurationChange={handleConfigurationChange} />
91
- <DisplayAccessToken configurationName={configurationName} />
92
- </OidcProvider>
93
- </>
94
- );
95
- };
96
-
97
- const DisplayAccessToken = ({configurationName}) => {
98
- const{ accessToken, accessTokenPayload } = useOidcAccessToken(configurationName);
99
- const{ idTokenPayload } = useOidcIdToken(configurationName);
100
-
101
- if(!accessToken){
102
- return <p>you are not authentified</p>
103
- }
104
- return (
105
- <div className="card text-white bg-info mb-3">
106
- <div className="card-body">
107
- <h5 className="card-title">Access Token</h5>
108
- <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>
109
- {<p className="card-text">Access Token: {JSON.stringify(accessToken)}</p>}
110
- {accessTokenPayload != null && <p className="card-text">Access Token Payload: {JSON.stringify(accessTokenPayload)}</p>}
111
- <h5 className="card-title">Id Token</h5>
112
- {idTokenPayload != null && <p className="card-text">Access Token Payload: {JSON.stringify(idTokenPayload)}</p>}
113
- </div>
114
- </div>
115
- )
116
- };