@axa-fr/react-oidc 6.6.1 → 6.6.2-alpha0

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 (54) hide show
  1. package/package.json +2 -1
  2. package/src/App.css +38 -0
  3. package/src/App.specold.tsx +46 -0
  4. package/src/App.tsx +103 -0
  5. package/src/FetchUser.tsx +53 -0
  6. package/src/Home.tsx +24 -0
  7. package/src/MultiAuth.tsx +129 -0
  8. package/src/Profile.tsx +77 -0
  9. package/src/configurations.ts +70 -0
  10. package/src/index.css +13 -0
  11. package/src/index.tsx +9 -0
  12. package/src/logo.svg +7 -0
  13. package/src/oidc/FetchToken.tsx +61 -0
  14. package/src/oidc/OidcProvider.tsx +206 -0
  15. package/src/oidc/OidcSecure.tsx +37 -0
  16. package/src/oidc/ReactOidc.tsx +139 -0
  17. package/src/oidc/User.ts +38 -0
  18. package/src/oidc/core/default-component/AuthenticateError.component.tsx +13 -0
  19. package/src/oidc/core/default-component/Authenticating.component.tsx +13 -0
  20. package/src/oidc/core/default-component/Callback.component.tsx +46 -0
  21. package/src/oidc/core/default-component/Loading.component.tsx +10 -0
  22. package/src/oidc/core/default-component/ServiceWorkerNotSupported.component.tsx +13 -0
  23. package/src/oidc/core/default-component/SessionLost.component.tsx +14 -0
  24. package/src/oidc/core/default-component/SilentCallback.component.tsx +22 -0
  25. package/src/oidc/core/default-component/SilentLogin.component.tsx +35 -0
  26. package/src/oidc/core/default-component/index.ts +6 -0
  27. package/src/oidc/core/routes/OidcRoutes.spec.tsx +15 -0
  28. package/src/oidc/core/routes/OidcRoutes.tsx +69 -0
  29. package/src/oidc/core/routes/__snapshots__/OidcRoutes.spec.tsx.snap +7 -0
  30. package/src/oidc/core/routes/index.ts +2 -0
  31. package/src/oidc/core/routes/withRouter.spec.tsx +48 -0
  32. package/src/oidc/core/routes/withRouter.tsx +64 -0
  33. package/src/oidc/index.ts +5 -0
  34. package/src/oidc/vanilla/OidcServiceWorker.js +442 -0
  35. package/src/oidc/vanilla/OidcTrustedDomains.js +16 -0
  36. package/src/oidc/vanilla/checkSessionIFrame.ts +82 -0
  37. package/src/oidc/vanilla/index.ts +1 -0
  38. package/src/oidc/vanilla/initSession.ts +67 -0
  39. package/src/oidc/vanilla/initWorker.ts +165 -0
  40. package/src/oidc/vanilla/memoryStorageBackend.ts +33 -0
  41. package/src/oidc/vanilla/noHashQueryStringUtils.ts +33 -0
  42. package/src/oidc/vanilla/oidc.ts +1230 -0
  43. package/src/oidc/vanilla/parseTokens.ts +142 -0
  44. package/src/oidc/vanilla/route-utils.spec.ts +15 -0
  45. package/src/oidc/vanilla/route-utils.ts +76 -0
  46. package/src/oidc/vanilla/timer.ts +165 -0
  47. package/src/override/AuthenticateError.component.tsx +14 -0
  48. package/src/override/Authenticating.component.tsx +14 -0
  49. package/src/override/Callback.component.tsx +13 -0
  50. package/src/override/Loading.component.tsx +13 -0
  51. package/src/override/ServiceWorkerNotSupported.component.tsx +15 -0
  52. package/src/override/SessionLost.component.tsx +21 -0
  53. package/src/override/style.ts +10 -0
  54. package/src/setupTests.js +5 -0
@@ -0,0 +1,82 @@
1
+ const DefaultInterval = 2000;
2
+
3
+ const Log = console;
4
+
5
+ export class CheckSessionIFrame {
6
+ private readonly _client_id: any;
7
+ private readonly _callback: any;
8
+ private _url: any;
9
+ private readonly _interval: number;
10
+ private readonly _stopOnError: boolean;
11
+ private readonly _frame_origin: string;
12
+ private readonly _frame: HTMLIFrameElement;
13
+ private _boundMessageEvent: any;
14
+ private _timer: number;
15
+ constructor(callback, client_id, url, interval=DefaultInterval, stopOnError = true) {
16
+ this._callback = callback;
17
+ this._client_id = client_id;
18
+ this._url = url;
19
+ this._interval = interval || DefaultInterval;
20
+ this._stopOnError = stopOnError;
21
+ const idx = url.indexOf("/", url.indexOf("//") + 2);
22
+ this._frame_origin = url.substr(0, idx);
23
+ this._frame = window.document.createElement("iframe");
24
+ this._frame.style.visibility = "hidden";
25
+ this._frame.style.position = "absolute";
26
+ this._frame.style.display = "none";
27
+ // @ts-ignore
28
+ this._frame.width = 0;
29
+ // @ts-ignore
30
+ this._frame.height = 0;
31
+
32
+ this._frame.src = url;
33
+ }
34
+ load() {
35
+ return new Promise<void>((resolve) => {
36
+ this._frame.onload = () => {
37
+ resolve();
38
+ }
39
+ window.document.body.appendChild(this._frame);
40
+ this._boundMessageEvent = this._message.bind(this);
41
+ window.addEventListener("message", this._boundMessageEvent, false);
42
+ });
43
+ }
44
+ _message(e) {
45
+ if (e.origin === this._frame_origin &&
46
+ e.source === this._frame.contentWindow
47
+ ) {
48
+ if (e.data === "error") {
49
+ Log.error("CheckSessionIFrame: error message from check session op iframe");
50
+ if (this._stopOnError) {
51
+ this.stop();
52
+ }
53
+ }
54
+ else if (e.data === "changed") {
55
+ Log.debug(e)
56
+ Log.debug("CheckSessionIFrame: changed message from check session op iframe");
57
+ this.stop();
58
+ this._callback();
59
+ }
60
+ else {
61
+ Log.debug("CheckSessionIFrame: " + e.data + " message from check session op iframe");
62
+ }
63
+ }
64
+ }
65
+ start(session_state) {
66
+ Log.debug("CheckSessionIFrame.start :" + session_state);
67
+ this.stop();
68
+ let send = () => {
69
+ this._frame.contentWindow.postMessage(this._client_id + " " + session_state, this._frame_origin);
70
+ };
71
+ send();
72
+ this._timer = window.setInterval(send, this._interval);
73
+ }
74
+
75
+ stop() {
76
+ if (this._timer) {
77
+ Log.debug("CheckSessionIFrame.stop");
78
+ window.clearInterval(this._timer);
79
+ this._timer = null;
80
+ }
81
+ }
82
+ }
@@ -0,0 +1 @@
1
+ export { Oidc } from './oidc';
@@ -0,0 +1,67 @@
1
+ export const initSession = (configurationName, redirectUri, storage=sessionStorage) => {
2
+
3
+ const saveItemsAsync =(items) =>{
4
+ storage[`oidc_items.${configurationName}:${redirectUri}`] = JSON.stringify(items);
5
+ return Promise.resolve();
6
+ }
7
+
8
+ const loadItemsAsync=() =>{
9
+ return Promise.resolve(JSON.parse(storage[`oidc_items.${configurationName}:${redirectUri}`]));
10
+ }
11
+
12
+ const clearAsync=(status) =>{
13
+ storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({tokens:null, status});
14
+ return Promise.resolve();
15
+ }
16
+
17
+ const initAsync=async () => {
18
+ if(!storage[`oidc.${configurationName}:${redirectUri}`]){
19
+ storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({tokens:null, status:null});
20
+ return {tokens:null, status:null};
21
+ }
22
+ const data = JSON.parse(storage[`oidc.${configurationName}:${redirectUri}`]);
23
+ return Promise.resolve({ tokens : data.tokens, status: data.status });
24
+ }
25
+
26
+ const setTokens = (tokens) => {
27
+ storage[`oidc.${configurationName}:${redirectUri}`] = JSON.stringify({tokens});
28
+ }
29
+
30
+ const setSessionState = (sessionState) => {
31
+ storage[`oidc.session_state.${configurationName}:${redirectUri}`] = sessionState;
32
+ }
33
+
34
+ const getSessionState= () =>{
35
+ return storage[`oidc.session_state.${configurationName}:${redirectUri}`];
36
+ }
37
+
38
+ const setNonceAsync = (nonce) => {
39
+ localStorage[`oidc.nonce.${configurationName}:${redirectUri}`] = nonce.nonce;
40
+ }
41
+
42
+ const getNonceAsync= async () => {
43
+ // @ts-ignore
44
+ const result = {nonce: localStorage[`oidc.nonce.${configurationName}:${redirectUri}`]};
45
+ return result;
46
+ }
47
+
48
+ const getTokens = () => {
49
+ if(!storage[`oidc.${configurationName}:${redirectUri}`]){
50
+ return null;
51
+ }
52
+ return JSON.stringify({ tokens : JSON.parse(storage[`oidc.${configurationName}:${redirectUri}`]).tokens });
53
+ }
54
+
55
+ return {
56
+ saveItemsAsync,
57
+ loadItemsAsync,
58
+ clearAsync,
59
+ initAsync,
60
+ setTokens,
61
+ getTokens,
62
+ setSessionState,
63
+ getSessionState,
64
+ setNonceAsync,
65
+ getNonceAsync
66
+ };
67
+ }
@@ -0,0 +1,165 @@
1
+ import timer from "./timer"
2
+ import {parseOriginalTokens} from "./parseTokens";
3
+
4
+ function get_browser() {
5
+ let ua = navigator.userAgent, tem,
6
+ M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
7
+ if(/trident/i.test(M[1])){
8
+ tem=/\brv[ :]+(\d+)/g.exec(ua) || [];
9
+ return {name:'ie',version:(tem[1]||'')};
10
+ }
11
+ if(M[1]==='Chrome'){
12
+ tem=ua.match(/\bOPR|Edge\/(\d+)/);
13
+
14
+ if(tem!=null) {
15
+ let version = tem[1];
16
+ if(!version){
17
+ const splits = ua.split(tem[0]+"/");
18
+ if(splits.length>1){
19
+ version = splits[1];
20
+ }
21
+ }
22
+
23
+ return {name:'opera', version};
24
+ }
25
+ }
26
+ M=M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
27
+ if((tem=ua.match(/version\/(\d+)/i))!=null) {M.splice(1,1,tem[1]);}
28
+ return {
29
+ name: M[0].toLowerCase(),
30
+ version: M[1]
31
+ };
32
+ }
33
+
34
+ let keepAliveServiceWorkerTimeoutId = null;
35
+
36
+ export const sleepAsync = (milliseconds) => {
37
+ return new Promise(resolve => timer.setTimeout(resolve, milliseconds))
38
+ }
39
+
40
+ const keepAlive = () => {
41
+ fetch('/OidcKeepAliveServiceWorker.json');
42
+ sleepAsync(230*1000).then(keepAlive);
43
+ }
44
+
45
+ const isServiceWorkerProxyActiveAsync = () => {
46
+ return fetch('/OidcKeepAliveServiceWorker.json', {
47
+ headers: {
48
+ 'oidc-vanilla': "true"
49
+ }})
50
+ .then((response) => {
51
+ return response.statusText === 'oidc-service-worker';
52
+ });
53
+ };
54
+
55
+ const sendMessageAsync = (registration) => (data) =>{
56
+ return new Promise(function(resolve, reject) {
57
+ const messageChannel = new MessageChannel();
58
+ messageChannel.port1.onmessage = function (event) {
59
+ if (event.data && event.data.error) {
60
+ reject(event.data.error);
61
+ } else {
62
+ resolve(event.data);
63
+ }
64
+ };
65
+ registration.active.postMessage(data, [messageChannel.port2]);
66
+ });
67
+ }
68
+
69
+ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName) => {
70
+
71
+ if(typeof window === "undefined" || typeof navigator === "undefined" || !navigator.serviceWorker||!serviceWorkerRelativeUrl){
72
+ return null;
73
+ }
74
+ const {name, version} = get_browser();
75
+ if(name == "chrome" && parseInt(version)<90){
76
+ return null;
77
+ }
78
+ if(name == "opera"){
79
+ if(!version) {
80
+ return null;
81
+ }
82
+ if(parseInt(version.split(".")[0])< 80) {
83
+ return null;
84
+ }
85
+ }
86
+ if(name == "ie"){
87
+ return null;
88
+ }
89
+
90
+ const registration = await navigator.serviceWorker.register(serviceWorkerRelativeUrl);
91
+
92
+ try {
93
+ await navigator.serviceWorker.ready
94
+ }
95
+ catch(err) {
96
+ return null;
97
+ }
98
+
99
+ const saveItemsAsync =(items) =>{
100
+ return sendMessageAsync(registration)({type: "saveItems", data: items, configurationName});
101
+ }
102
+
103
+ const loadItemsAsync=() =>{
104
+ return sendMessageAsync(registration)({type: "loadItems", data: null, configurationName});
105
+ }
106
+
107
+ const unregisterAsync = async () => {
108
+ return await registration.unregister();
109
+ }
110
+
111
+ const clearAsync=(status) =>{
112
+ return sendMessageAsync(registration)({type: "clear", data: {status}, configurationName});
113
+ }
114
+ const initAsync= async (oidcServerConfiguration, where) => {
115
+ const result = await sendMessageAsync(registration)({
116
+ type: "init",
117
+ data: {oidcServerConfiguration, where},
118
+ configurationName
119
+ });
120
+ // @ts-ignore
121
+ return { tokens : parseOriginalTokens(result.tokens, null), status: result.status};
122
+ }
123
+
124
+ const startKeepAliveServiceWorker = () => {
125
+ if (keepAliveServiceWorkerTimeoutId == null) {
126
+ keepAliveServiceWorkerTimeoutId = "not_null";
127
+ keepAlive();
128
+ }
129
+ }
130
+
131
+ const setSessionStateAsync = (sessionState) => {
132
+ return sendMessageAsync(registration)({type: "setSessionState", data: {sessionState}, configurationName});
133
+ }
134
+
135
+ const getSessionStateAsync= async () => {
136
+ const result = await sendMessageAsync(registration)({type: "getSessionState", data: null, configurationName});
137
+ // @ts-ignore
138
+ return result.sessionState;
139
+ }
140
+
141
+ const setNonceAsync = (nonce) => {
142
+ return sendMessageAsync(registration)({type: "setNonce", data: {nonce}, configurationName});
143
+ }
144
+ const NONCE_TOKEN = 'NONCE_SECURED_BY_OIDC_SERVICE_WORKER';
145
+ const getNonceAsync= async () => {
146
+ // @ts-ignore
147
+ const keyNonce = NONCE_TOKEN + '_'+ configurationName;
148
+ return {nonce:keyNonce};
149
+ }
150
+
151
+ return {
152
+ saveItemsAsync,
153
+ loadItemsAsync,
154
+ clearAsync,
155
+ initAsync,
156
+ // getAccessTokenPayloadAsync,
157
+ startKeepAliveServiceWorker,
158
+ isServiceWorkerProxyActiveAsync,
159
+ setSessionStateAsync,
160
+ getSessionStateAsync,
161
+ setNonceAsync,
162
+ getNonceAsync,
163
+ unregisterAsync,
164
+ };
165
+ }
@@ -0,0 +1,33 @@
1
+ export class MemoryStorageBackend {
2
+ public items: any;
3
+ private saveItemsAsync: Function;
4
+
5
+ constructor(saveItemsAsync, items = {}) {
6
+ this.items = items;
7
+ this.saveItemsAsync = saveItemsAsync;
8
+ this.saveItemsAsync.bind(this);
9
+ this.getItem.bind(this);
10
+ this.removeItem.bind(this);
11
+ this.clear.bind(this);
12
+ this.setItem.bind(this);
13
+ }
14
+
15
+ getItem(name) {
16
+ return Promise.resolve(this.items[name]);
17
+ }
18
+
19
+ removeItem(name) {
20
+ delete this.items[name];
21
+ return this.saveItemsAsync(this.items);
22
+ }
23
+
24
+ clear() {
25
+ this.items = {};
26
+ return this.saveItemsAsync(this.items);
27
+ }
28
+
29
+ setItem(name, value) {
30
+ this.items[name] = value;
31
+ return this.saveItemsAsync(this.items);
32
+ }
33
+ }
@@ -0,0 +1,33 @@
1
+ import {BasicQueryStringUtils} from '@openid/appauth';
2
+
3
+ export class NoHashQueryStringUtils extends BasicQueryStringUtils {
4
+ parse(input, useHash) {
5
+ const output = super.parse(input, false /* never use hash */);
6
+ return output;
7
+ }
8
+ }
9
+
10
+ const keys = ["code", "session_state", "state"]
11
+
12
+ export class HashQueryStringUtils extends BasicQueryStringUtils {
13
+ parse(input, useHash) {
14
+ const output = super.parse(input, true /* use hash */);
15
+
16
+ // Fix AppAuthJs behavior
17
+ let propertyToDelelete = null;
18
+ Object.entries(output).map(([key, value]) => {
19
+ keys.forEach(k => {
20
+ if(key.endsWith(`?${k}`)){
21
+ output[k]= value;
22
+ propertyToDelelete = key;
23
+ }
24
+ })
25
+ });
26
+
27
+ if(propertyToDelelete){
28
+ delete output[propertyToDelelete];
29
+ }
30
+
31
+ return output;
32
+ }
33
+ }