@axa-fr/react-oidc 5.7.0-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 (160) hide show
  1. package/README.md +502 -0
  2. package/dist/FetchToken.d.ts +10 -0
  3. package/dist/FetchToken.d.ts.map +1 -0
  4. package/dist/FetchToken.js +107 -0
  5. package/dist/FetchToken.js.map +1 -0
  6. package/dist/OidcProvider.d.ts +25 -0
  7. package/dist/OidcProvider.d.ts.map +1 -0
  8. package/dist/OidcProvider.js +133 -0
  9. package/dist/OidcProvider.js.map +1 -0
  10. package/dist/OidcSecure.d.ts +10 -0
  11. package/dist/OidcSecure.d.ts.map +1 -0
  12. package/dist/OidcSecure.js +68 -0
  13. package/dist/OidcSecure.js.map +1 -0
  14. package/dist/OidcServiceWorker.js +272 -0
  15. package/dist/OidcTrustedDomains.js +6 -0
  16. package/dist/ReactOidc.d.ts +17 -0
  17. package/dist/ReactOidc.d.ts.map +1 -0
  18. package/dist/ReactOidc.js +106 -0
  19. package/dist/ReactOidc.js.map +1 -0
  20. package/dist/User.d.ts +15 -0
  21. package/dist/User.d.ts.map +1 -0
  22. package/dist/User.js +48 -0
  23. package/dist/User.js.map +1 -0
  24. package/dist/core/default-component/AuthenticateError.component.d.ts +4 -0
  25. package/dist/core/default-component/AuthenticateError.component.d.ts.map +1 -0
  26. package/dist/core/default-component/AuthenticateError.component.js +32 -0
  27. package/dist/core/default-component/AuthenticateError.component.js.map +1 -0
  28. package/dist/core/default-component/Authenticating.component.d.ts +4 -0
  29. package/dist/core/default-component/Authenticating.component.d.ts.map +1 -0
  30. package/dist/core/default-component/Authenticating.component.js +32 -0
  31. package/dist/core/default-component/Authenticating.component.js.map +1 -0
  32. package/dist/core/default-component/Callback.component.d.ts +5 -0
  33. package/dist/core/default-component/Callback.component.d.ts.map +1 -0
  34. package/dist/core/default-component/Callback.component.js +118 -0
  35. package/dist/core/default-component/Callback.component.js.map +1 -0
  36. package/dist/core/default-component/Loading.component.d.ts +4 -0
  37. package/dist/core/default-component/Loading.component.d.ts.map +1 -0
  38. package/dist/core/default-component/Loading.component.js +29 -0
  39. package/dist/core/default-component/Loading.component.js.map +1 -0
  40. package/dist/core/default-component/ServiceWorkerInstall.component.d.ts +4 -0
  41. package/dist/core/default-component/ServiceWorkerInstall.component.d.ts.map +1 -0
  42. package/dist/core/default-component/ServiceWorkerInstall.component.js +122 -0
  43. package/dist/core/default-component/ServiceWorkerInstall.component.js.map +1 -0
  44. package/dist/core/default-component/ServiceWorkerNotSupported.component.d.ts +4 -0
  45. package/dist/core/default-component/ServiceWorkerNotSupported.component.d.ts.map +1 -0
  46. package/dist/core/default-component/ServiceWorkerNotSupported.component.js +32 -0
  47. package/dist/core/default-component/ServiceWorkerNotSupported.component.js.map +1 -0
  48. package/dist/core/default-component/SessionLost.component.d.ts +4 -0
  49. package/dist/core/default-component/SessionLost.component.d.ts.map +1 -0
  50. package/dist/core/default-component/SessionLost.component.js +14 -0
  51. package/dist/core/default-component/SessionLost.component.js.map +1 -0
  52. package/dist/core/default-component/SilentCallback.component.d.ts +4 -0
  53. package/dist/core/default-component/SilentCallback.component.d.ts.map +1 -0
  54. package/dist/core/default-component/SilentCallback.component.js +96 -0
  55. package/dist/core/default-component/SilentCallback.component.js.map +1 -0
  56. package/dist/core/default-component/index.d.ts +7 -0
  57. package/dist/core/default-component/index.d.ts.map +1 -0
  58. package/dist/core/default-component/index.js +20 -0
  59. package/dist/core/default-component/index.js.map +1 -0
  60. package/dist/core/routes/OidcRoutes.d.ts +12 -0
  61. package/dist/core/routes/OidcRoutes.d.ts.map +1 -0
  62. package/dist/core/routes/OidcRoutes.js +71 -0
  63. package/dist/core/routes/OidcRoutes.js.map +1 -0
  64. package/dist/core/routes/index.d.ts +3 -0
  65. package/dist/core/routes/index.d.ts.map +1 -0
  66. package/dist/core/routes/index.js +9 -0
  67. package/dist/core/routes/index.js.map +1 -0
  68. package/dist/core/routes/route-utils.d.ts +2 -0
  69. package/dist/core/routes/route-utils.d.ts.map +1 -0
  70. package/dist/core/routes/route-utils.js +32 -0
  71. package/dist/core/routes/route-utils.js.map +1 -0
  72. package/dist/core/routes/withRouter.d.ts +19 -0
  73. package/dist/core/routes/withRouter.d.ts.map +1 -0
  74. package/dist/core/routes/withRouter.js +33 -0
  75. package/dist/core/routes/withRouter.js.map +1 -0
  76. package/dist/index.d.ts +6 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +19 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/vanilla/index.d.ts +2 -0
  81. package/dist/vanilla/index.d.ts.map +1 -0
  82. package/dist/vanilla/index.js +6 -0
  83. package/dist/vanilla/index.js.map +1 -0
  84. package/dist/vanilla/initSession.d.ts +11 -0
  85. package/dist/vanilla/initSession.d.ts.map +1 -0
  86. package/dist/vanilla/initSession.js +72 -0
  87. package/dist/vanilla/initSession.js.map +1 -0
  88. package/dist/vanilla/initWorker.d.ts +13 -0
  89. package/dist/vanilla/initWorker.d.ts.map +1 -0
  90. package/dist/vanilla/initWorker.js +211 -0
  91. package/dist/vanilla/initWorker.js.map +1 -0
  92. package/dist/vanilla/memoryStorageBackend.d.ts +10 -0
  93. package/dist/vanilla/memoryStorageBackend.d.ts.map +1 -0
  94. package/dist/vanilla/memoryStorageBackend.js +33 -0
  95. package/dist/vanilla/memoryStorageBackend.js.map +1 -0
  96. package/dist/vanilla/noHashQueryStringUtils.d.ts +5 -0
  97. package/dist/vanilla/noHashQueryStringUtils.d.ts.map +1 -0
  98. package/dist/vanilla/noHashQueryStringUtils.js +31 -0
  99. package/dist/vanilla/noHashQueryStringUtils.js.map +1 -0
  100. package/dist/vanilla/oidc.d.ts +77 -0
  101. package/dist/vanilla/oidc.d.ts.map +1 -0
  102. package/dist/vanilla/oidc.js +814 -0
  103. package/dist/vanilla/oidc.js.map +1 -0
  104. package/dist/vanilla/timer.d.ts +8 -0
  105. package/dist/vanilla/timer.d.ts.map +1 -0
  106. package/dist/vanilla/timer.js +135 -0
  107. package/dist/vanilla/timer.js.map +1 -0
  108. package/package.json +73 -0
  109. package/src/App.css +38 -0
  110. package/src/App.specold.tsx +46 -0
  111. package/src/App.tsx +61 -0
  112. package/src/FetchUser.tsx +53 -0
  113. package/src/Home.tsx +20 -0
  114. package/src/MultiAuth.tsx +114 -0
  115. package/src/Profile.tsx +77 -0
  116. package/src/configurations.ts +53 -0
  117. package/src/index.css +13 -0
  118. package/src/index.tsx +9 -0
  119. package/src/logo.svg +7 -0
  120. package/src/oidc/FetchToken.tsx +51 -0
  121. package/src/oidc/OidcProvider.tsx +165 -0
  122. package/src/oidc/OidcSecure.tsx +32 -0
  123. package/src/oidc/ReactOidc.tsx +112 -0
  124. package/src/oidc/User.ts +38 -0
  125. package/src/oidc/core/default-component/AuthenticateError.component.tsx +13 -0
  126. package/src/oidc/core/default-component/Authenticating.component.tsx +13 -0
  127. package/src/oidc/core/default-component/Callback.component.tsx +49 -0
  128. package/src/oidc/core/default-component/Loading.component.tsx +10 -0
  129. package/src/oidc/core/default-component/ServiceWorkerInstall.component.tsx +51 -0
  130. package/src/oidc/core/default-component/ServiceWorkerNotSupported.component.tsx +13 -0
  131. package/src/oidc/core/default-component/SessionLost.component.tsx +14 -0
  132. package/src/oidc/core/default-component/SilentCallback.component.tsx +31 -0
  133. package/src/oidc/core/default-component/index.ts +6 -0
  134. package/src/oidc/core/routes/OidcRoutes.spec.tsx +16 -0
  135. package/src/oidc/core/routes/OidcRoutes.tsx +69 -0
  136. package/src/oidc/core/routes/__snapshots__/OidcRoutes.spec.tsx.snap +7 -0
  137. package/src/oidc/core/routes/index.ts +2 -0
  138. package/src/oidc/core/routes/route-utils.spec.ts +9 -0
  139. package/src/oidc/core/routes/route-utils.ts +34 -0
  140. package/src/oidc/core/routes/withRouter.spec.tsx +48 -0
  141. package/src/oidc/core/routes/withRouter.tsx +60 -0
  142. package/src/oidc/index.ts +5 -0
  143. package/src/oidc/vanilla/OidcServiceWorker.js +272 -0
  144. package/src/oidc/vanilla/OidcTrustedDomains.js +6 -0
  145. package/src/oidc/vanilla/index.ts +1 -0
  146. package/src/oidc/vanilla/initSession.ts +36 -0
  147. package/src/oidc/vanilla/initWorker.ts +153 -0
  148. package/src/oidc/vanilla/memoryStorageBackend.ts +33 -0
  149. package/src/oidc/vanilla/noHashQueryStringUtils.ts +7 -0
  150. package/src/oidc/vanilla/oidc.ts +600 -0
  151. package/src/oidc/vanilla/timer.ts +157 -0
  152. package/src/override/AuthenticateError.component.tsx +14 -0
  153. package/src/override/Authenticating.component.tsx +14 -0
  154. package/src/override/Callback.component.tsx +13 -0
  155. package/src/override/Loading.component.tsx +13 -0
  156. package/src/override/ServiceWorkerNotSupported.component.tsx +15 -0
  157. package/src/override/SessionLost.component.tsx +21 -0
  158. package/src/override/style.ts +10 -0
  159. package/src/setupTests.js +5 -0
  160. package/tsconfig.json +38 -0
@@ -0,0 +1,51 @@
1
+ import React, {useEffect, useState, ComponentType} from 'react';
2
+ import AuthenticatingError from "./AuthenticateError.component";
3
+ import Oidc from "../../vanilla/oidc";
4
+ import Authenticating from "./Authenticating.component";
5
+
6
+ const ServiceWorkerInstall: ComponentType<any> = ({callBackError, authenticating, configurationName }) => {
7
+ const getOidc = Oidc.get;
8
+ const [error, setError] = useState(false);
9
+ const [isLoading, setLoading] = useState(true);
10
+
11
+ const CallbackErrorComponent = callBackError || AuthenticatingError;
12
+ const CallbackSuccessComponent = authenticating || Authenticating;
13
+
14
+ useEffect(() => {
15
+ let isMounted = true;
16
+ const playCallbackAsync = async () => {
17
+ try {
18
+ const params = new Proxy(new URLSearchParams(window.location.search), {
19
+ // @ts-ignore
20
+ get: (searchParams, prop) => searchParams.get(prop),
21
+ });
22
+ // @ts-ignore
23
+ await getOidc(configurationName).loginAsync(decodeURIComponent(params.callbackPath), false);
24
+ if(isMounted) {
25
+ setLoading(false);
26
+ }
27
+ } catch (error) {
28
+ if(isMounted) {
29
+ setError(true);
30
+ setLoading(false);
31
+ }
32
+ }
33
+ };
34
+ playCallbackAsync();
35
+ return () => {
36
+ isMounted = false;
37
+ };
38
+ },[]);
39
+
40
+ if(isLoading){
41
+ return null;
42
+ }
43
+
44
+ if(error){
45
+ return <CallbackErrorComponent configurationName={configurationName} />
46
+ }
47
+
48
+ return <CallbackSuccessComponent configurationName={configurationName} />;
49
+ };
50
+
51
+ export default ServiceWorkerInstall;
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import {ComponentType} from "react";
3
+
4
+ const ServiceWorkerNotSupported : ComponentType<any> = () => (
5
+ <div className="oidc-serviceworker">
6
+ <div className="oidc-serviceworker__container">
7
+ <h1 className="oidc-serviceworker__title">Unable to authenticate on this browser</h1>
8
+ <p className="oidc-serviceworker__content">Your browser is not secure enough to make authentication work. Try updating your browser or use a newer browser.</p>
9
+ </div>
10
+ </div>
11
+ );
12
+
13
+ export default ServiceWorkerNotSupported;
@@ -0,0 +1,14 @@
1
+ import React, {ComponentType} from 'react';
2
+
3
+ export const SessionLost: ComponentType<any> = () => (
4
+ <div className="oidc-session-lost">
5
+ <div className="oidc-session-lost__container">
6
+ <h1 className="oidc-session-lost__title">Session timed out</h1>
7
+ <p className="oidc-session-lost__content">
8
+ Your session has expired. Please re-authenticate.
9
+ </p>
10
+ </div>
11
+ </div>
12
+ );
13
+
14
+ export default SessionLost;
@@ -0,0 +1,31 @@
1
+ import React, {useEffect, ComponentType} from 'react';
2
+ import Oidc from "../../vanilla/oidc";
3
+ import {OidcSecure} from "../../OidcSecure";
4
+
5
+ const CallBack = ({configurationName}) =>{
6
+ const getOidc = Oidc.get;
7
+ useEffect(() => {
8
+ let isMounted = true;
9
+ const playCallbackAsync = async () => {
10
+ if(isMounted) {
11
+ const oidc = getOidc(configurationName);
12
+ oidc.silentSigninCallbackFromIFrame();
13
+ }
14
+ };
15
+ playCallbackAsync();
16
+
17
+ return () => {
18
+ isMounted = false;
19
+ };
20
+ },[]);
21
+
22
+ return <></>;
23
+ }
24
+
25
+ const CallbackManager: ComponentType<any> = ({configurationName }) => {
26
+ return <OidcSecure configurationName={configurationName}>
27
+ <CallBack configurationName={configurationName}/>
28
+ </OidcSecure>;
29
+ };
30
+
31
+ export default CallbackManager;
@@ -0,0 +1,6 @@
1
+ export { default as Authenticating } from './Authenticating.component';
2
+ export { default as Callback, CallBackSuccess } from './Callback.component';
3
+ export { default as SessionLost } from './SessionLost.component';
4
+ export { default as Loading } from './Loading.component';
5
+ export { default as AuthenticateError } from './AuthenticateError.component';
6
+ export { default as ServiceWorkerNotSupported } from './ServiceWorkerNotSupported.component';
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import OidcRoutes from './OidcRoutes';
3
+ import { FC } from 'react';
4
+ import {render} from "@testing-library/react";
5
+
6
+ describe('Authenticating test suite', () => {
7
+ it('renders correctly', () => {
8
+ const props = {
9
+ children: 'http://url.com',
10
+ callbackComponent: () => <div>tcallback component</div>,
11
+ redirect_uri: 'http://example.com:3000/authentication/callback',
12
+ };
13
+ const { asFragment } = render(<OidcRoutes {...props} />);
14
+ expect(asFragment()).toMatchSnapshot();
15
+ });
16
+ });
@@ -0,0 +1,69 @@
1
+ import React, { ComponentType, FC, PropsWithChildren, useEffect, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { getPath } from './route-utils';
4
+ import CallbackComponent from '../default-component/Callback.component';
5
+ import SilentCallbackComponent from "../default-component/SilentCallback.component";
6
+ import ServiceWorkerInstall from "../default-component/ServiceWorkerInstall.component";
7
+
8
+ const propTypes = {
9
+ callbackComponent: PropTypes.elementType,
10
+ redirect_uri: PropTypes.string.isRequired,
11
+ children: PropTypes.node,
12
+ };
13
+
14
+ const defaultProps: Partial<OidcRoutesProps> = {
15
+
16
+ };
17
+
18
+ type OidcRoutesProps = {
19
+ callbackSuccessComponent?: ComponentType;
20
+ callbackErrorComponent?: ComponentType;
21
+ authenticatingComponent?: ComponentType;
22
+ configurationName:string;
23
+ redirect_uri: string;
24
+ silent_redirect_uri?: string;
25
+ };
26
+
27
+ const OidcRoutes: FC<PropsWithChildren<OidcRoutesProps>> = ({
28
+ callbackErrorComponent,
29
+ callbackSuccessComponent,
30
+ authenticatingComponent,
31
+ redirect_uri,
32
+ silent_redirect_uri,
33
+ children, configurationName
34
+ }) => {
35
+ // This exist because in next.js window outside useEffect is null
36
+ const pathname = window ? window.location.pathname : '';
37
+
38
+ const [path, setPath] = useState(pathname);
39
+
40
+ useEffect(() => {
41
+ const setNewPath = () => setPath(window.location.pathname);
42
+ setNewPath();
43
+ window.addEventListener('popstate', setNewPath, false);
44
+ return () => window.removeEventListener('popstate', setNewPath, false);
45
+ });
46
+
47
+ const callbackPath = getPath(redirect_uri);
48
+
49
+ if(silent_redirect_uri){
50
+ if(path === getPath(silent_redirect_uri)){
51
+ return <SilentCallbackComponent configurationName={configurationName} />
52
+ }
53
+ }
54
+
55
+ switch (path) {
56
+ case callbackPath:
57
+ return <CallbackComponent callBackError={callbackErrorComponent} callBackSuccess={callbackSuccessComponent} configurationName={configurationName} />;
58
+ case callbackPath +"/service-worker-install" :
59
+ return <ServiceWorkerInstall callBackError={callbackErrorComponent} authenticating={authenticatingComponent} configurationName={configurationName} />;
60
+ default:
61
+ return <>{children}</>;
62
+ }
63
+ };
64
+
65
+ // @ts-ignore
66
+ OidcRoutes.propTypes = propTypes;
67
+ OidcRoutes.defaultProps = defaultProps;
68
+
69
+ export default React.memo(OidcRoutes);
@@ -0,0 +1,7 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Authenticating test suite renders correctly 1`] = `
4
+ <DocumentFragment>
5
+ http://url.com
6
+ </DocumentFragment>
7
+ `;
@@ -0,0 +1,2 @@
1
+ export { default as OidcRoutes } from './OidcRoutes';
2
+ export { ReactOidcHistory } from './withRouter';
@@ -0,0 +1,9 @@
1
+ import { getPath } from './route-utils';
2
+
3
+ it('getPath should return the full path of an url', () => {
4
+ const path1 = getPath('http://example.com/pathname');
5
+ const path2 = getPath('http://example.com:3000/pathname/?search=test#hash');
6
+
7
+ expect(path1).toEqual('/pathname');
8
+ expect(path2).toEqual('/pathname/?search=test#hash');
9
+ });
@@ -0,0 +1,34 @@
1
+ const getLocation = (href: string) => {
2
+ const match = href.match(
3
+ // eslint-disable-next-line no-useless-escape
4
+ /^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/
5
+ );
6
+ return (
7
+ match && {
8
+ href,
9
+ protocol: match[1],
10
+ host: match[2],
11
+ hostname: match[3],
12
+ port: match[4],
13
+ path: match[5],
14
+ search: match[6],
15
+ hash: match[7],
16
+ }
17
+ );
18
+ };
19
+
20
+ export const getPath = (href: string) => {
21
+ const location = getLocation(href);
22
+ let { path } = location;
23
+ const { search, hash } = location;
24
+
25
+ if (search) {
26
+ path += search;
27
+ }
28
+
29
+ if (hash) {
30
+ path += hash;
31
+ }
32
+
33
+ return path;
34
+ };
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import '@testing-library/jest-dom/extend-expect';
3
+ import { CreateEvent, WindowInternal } from './withRouter';
4
+
5
+ describe('WithRouter test Suite', () => {
6
+ const generateKeyMock = () => '123ABC';
7
+ const paramsMock = { bubbles: false, cancelable: false, detail: 'detail' };
8
+ beforeEach(() => {});
9
+ it('should CreateEvent return correct Event if not on IE', () => {
10
+ const windowMock = {
11
+ CustomEvent: jest.fn().mockImplementation((event, params) => {
12
+ return { event, params };
13
+ }),
14
+ };
15
+ const documentMock = {} as Document;
16
+ const res = CreateEvent((windowMock as unknown) as WindowInternal, documentMock)(
17
+ 'event test',
18
+ paramsMock
19
+ );
20
+ expect(res).toEqual({
21
+ event: 'event test',
22
+ params: { bubbles: false, cancelable: false, detail: 'detail' },
23
+ });
24
+ });
25
+
26
+ it('should createEvent create a polyfill when the default func is undefined', () => {
27
+ const windowMock = {
28
+ Event: {
29
+ prototype: 'protoMock',
30
+ },
31
+ };
32
+ const evtMock = {
33
+ initCustomEvent: jest.fn(),
34
+ };
35
+ const documentMock = {
36
+ createEvent: jest.fn(() => evtMock),
37
+ };
38
+ const typedDocumentMock = (documentMock as unknown) as Document;
39
+ const res = CreateEvent((windowMock as unknown) as WindowInternal, typedDocumentMock)(
40
+ 'event test',
41
+ paramsMock
42
+ );
43
+ expect(res).toEqual({ ...evtMock });
44
+ expect(documentMock.createEvent).toHaveBeenCalledWith('CustomEvent');
45
+ expect(evtMock.initCustomEvent).toHaveBeenCalledWith('event test', false, false, 'detail');
46
+ });
47
+
48
+ });
@@ -0,0 +1,60 @@
1
+ import React from 'react';
2
+
3
+ const generateKey = () =>
4
+ Math.random()
5
+ .toString(36)
6
+ .substr(2, 6);
7
+
8
+ // Exported only for test
9
+ export type WindowInternal = Window & {
10
+ CustomEvent?: new <T>(typeArg: string, eventInitDict?: CustomEventInit<T>) => CustomEvent<T>;
11
+ Event: typeof Event;
12
+ };
13
+
14
+ type IPrototype = {
15
+ prototype: any;
16
+ };
17
+
18
+ type InitCustomEventParams<T = any> = {
19
+ bubbles: boolean;
20
+ cancelable: boolean;
21
+ detail: T;
22
+ };
23
+
24
+ // IE Polyfill for CustomEvent
25
+ export const CreateEvent = (windowInternal: WindowInternal, documentInternal: Document) => (
26
+ event: string,
27
+ params: InitCustomEventParams
28
+ ): CustomEvent => {
29
+ if (typeof windowInternal.CustomEvent === 'function') {
30
+ return new windowInternal.CustomEvent(event, params);
31
+ }
32
+ const paramsToFunction = params || { bubbles: false, cancelable: false, detail: undefined };
33
+ const evt: CustomEvent = documentInternal.createEvent('CustomEvent');
34
+ evt.initCustomEvent(event, paramsToFunction.bubbles, paramsToFunction.cancelable, paramsToFunction.detail);
35
+ (evt as CustomEvent & IPrototype).prototype = windowInternal.Event.prototype;
36
+ return evt;
37
+ };
38
+
39
+ type WindowHistoryState = typeof window.history.state;
40
+
41
+ export interface ReactOidcHistory {
42
+ replaceState: (url?: string | null, stateHistory?: WindowHistoryState) => void;
43
+ }
44
+
45
+ const getHistory = (
46
+ windowInternal: WindowInternal,
47
+ CreateEventInternal: (event: string, params?: InitCustomEventParams) => CustomEvent,
48
+ generateKeyInternal: typeof generateKey
49
+ ) => {
50
+ return {
51
+ replaceState: (url?: string | null, stateHistory?: WindowHistoryState): void => {
52
+ const key = generateKeyInternal();
53
+ const state = stateHistory || windowInternal.history.state;
54
+ windowInternal.history.replaceState({ key, state }, null, url);
55
+ windowInternal.dispatchEvent(CreateEventInternal('popstate'));
56
+ },
57
+ };
58
+ };
59
+
60
+ export const getCustomHistory = () => getHistory(window, CreateEvent(window, document), generateKey);
@@ -0,0 +1,5 @@
1
+ export { withOidcSecure, OidcSecure } from "./OidcSecure";
2
+ export { useOidcUser, OidcUserStatus} from "./User";
3
+ export { useOidc, useOidcAccessToken, useOidcIdToken } from "./ReactOidc";
4
+ export { withOidcFetch, useOidcFetch } from "./FetchToken";
5
+ export { OidcProvider } from "./OidcProvider";
@@ -0,0 +1,272 @@
1
+ this.importScripts('OidcTrustedDomains.js');
2
+
3
+ const id = Math.round(new Date().getTime() / 1000).toString();
4
+
5
+ const keepAliveJsonFilename = "OidcKeepAliveServiceWorker.json";
6
+ const handleInstall = (event) => {
7
+ console.log('[OidcServiceWorker] service worker installed ' + id);
8
+ self.skipWaiting();
9
+ };
10
+
11
+ const handleActivate = () => {
12
+ console.log('[OidcServiceWorker] service worker activated ' + id);
13
+ self.clients.claim();
14
+ };
15
+
16
+ let currentLoginCallbackConfigurationName = null;
17
+ let database = {
18
+ default: {
19
+ configurationName: "default",
20
+ tokens: null,
21
+ items:[],
22
+ oidcServerConfiguration: null
23
+ }
24
+ };
25
+
26
+ const countLetter = (str, find)=> {
27
+ return (str.split(find)).length - 1;
28
+ }
29
+
30
+ function extractAccessTokenPayload(accessToken) {
31
+ try{
32
+ if (!accessToken) {
33
+ return null;
34
+ }
35
+ if(countLetter(accessToken,'.') === 2) {
36
+ return JSON.parse(atob(accessToken.split('.')[1]));
37
+ } else {
38
+ return null;
39
+ }
40
+ } catch (e) {
41
+ console.warn(e);
42
+ }
43
+ return null;
44
+ }
45
+
46
+ function hideTokens(currentDatabaseElement) {
47
+ const configurationName = currentDatabaseElement.configurationName;
48
+ return (response) => {
49
+ return response.json().then(tokens => {
50
+ currentDatabaseElement.tokens = tokens;
51
+ const secureTokens = {
52
+ ...tokens,
53
+ access_token: ACCESS_TOKEN +"_" + configurationName,
54
+ refresh_token: REFRESH_TOKEN + "_" + configurationName,
55
+ };
56
+ const body = JSON.stringify(secureTokens)
57
+ return new Response(body, response);
58
+ });
59
+ };
60
+ }
61
+
62
+ const getCurrentDatabasesTokenEndpoint = (database, url) => {
63
+ const databases = [];
64
+ for (const [key, value] of Object.entries(database)) {
65
+ if(value && value.oidcServerConfiguration !=null && url.startsWith(value.oidcServerConfiguration.tokenEndpoint)){
66
+ databases.push(value);
67
+ }
68
+ }
69
+ return databases;
70
+ }
71
+
72
+ const getCurrentDatabaseDomain = (database, url) => {
73
+ for (const [key, currentDatabase] of Object.entries(database)) {
74
+
75
+ const oidcServerConfiguration = currentDatabase.oidcServerConfiguration;
76
+ const domainsToSendTokens = oidcServerConfiguration != null ? [
77
+ oidcServerConfiguration.userInfoEndpoint, ...trustedDomains[key]
78
+ ] : [...trustedDomains[key]];
79
+
80
+ let hasToSendToken = false;
81
+ for(let i=0;i<domainsToSendTokens.length;i++) {
82
+ const domain = domainsToSendTokens[i];
83
+ if (url.startsWith(domain)) {
84
+ hasToSendToken = true;
85
+ break;
86
+ }
87
+ }
88
+
89
+ if(hasToSendToken){
90
+ if(!currentDatabase.tokens) {
91
+ return null;
92
+ }
93
+ return currentDatabase;
94
+ }
95
+ }
96
+
97
+ return null;
98
+ }
99
+
100
+ const serializeHeaders = (headers) => {
101
+ let headersObj = {};
102
+ for (let key of headers.keys()) {
103
+ headersObj[key] = headers.get(key);
104
+ }
105
+ return headersObj;
106
+ };
107
+
108
+ const REFRESH_TOKEN = 'REFRESH_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER';
109
+ const ACCESS_TOKEN = 'ACCESS_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER';
110
+
111
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
112
+
113
+ const keepAliveAsync = async (event) => {
114
+ const originalRequest = event.request;
115
+ const isFromVanilla = originalRequest.headers.has('oidc-vanilla');
116
+ if(!isFromVanilla) {
117
+ await sleep(15000);
118
+ }
119
+ const init = {"status": 200, "statusText": 'oidc-service-worker'};
120
+ return new Response('{}', init);
121
+ }
122
+
123
+ const handleFetch = async (event) => {
124
+ const originalRequest = event.request;
125
+
126
+ if(originalRequest.url.includes(keepAliveJsonFilename) ){
127
+ event.respondWith(keepAliveAsync(event));
128
+ return;
129
+ }
130
+
131
+ const currentDatabaseForRequestAccessToken = getCurrentDatabaseDomain(database, originalRequest.url);
132
+ if(currentDatabaseForRequestAccessToken && currentDatabaseForRequestAccessToken.tokens) {
133
+ const newRequest = new Request(originalRequest, {
134
+ headers: {
135
+ ...serializeHeaders(originalRequest.headers),
136
+ authorization: "Bearer " + currentDatabaseForRequestAccessToken.tokens.access_token
137
+ }
138
+ });
139
+ event.waitUntil(event.respondWith(fetch(newRequest)));
140
+ }
141
+
142
+ if(event.request.method !== "POST"){
143
+ return;
144
+ }
145
+ let currentDatabase = null;
146
+ const currentDatabases = getCurrentDatabasesTokenEndpoint(database, originalRequest.url);
147
+ const numberDatabase = currentDatabases.length;
148
+ if(numberDatabase > 0) {
149
+ const maPromesse = new Promise((resolve, reject) => {
150
+ const response = originalRequest.clone().text().then(actualBody => {
151
+ if(actualBody.includes(REFRESH_TOKEN)) {
152
+ let newBody = actualBody;
153
+ for(let i= 0;i<numberDatabase;i++){
154
+ const currentDb = currentDatabases[i];
155
+ const key = REFRESH_TOKEN + '_'+ currentDb.configurationName;
156
+ if(currentDb && currentDb.tokens != null && actualBody.includes(key)) {
157
+ newBody = newBody.replace(key, encodeURIComponent(currentDb.tokens.refresh_token));
158
+ currentDatabase = currentDb;
159
+ break;
160
+ }
161
+ }
162
+ return fetch(originalRequest, {
163
+ body: newBody,
164
+ method: originalRequest.method,
165
+ headers: {
166
+ ...serializeHeaders(originalRequest.headers),
167
+ },
168
+ mode: originalRequest.mode,
169
+ cache: originalRequest.cache,
170
+ redirect: originalRequest.redirect,
171
+ referrer: originalRequest.referrer,
172
+ credentials: originalRequest.credentials,
173
+ integrity: originalRequest.integrity
174
+ }).then(hideTokens(currentDatabase));
175
+ } else if(currentLoginCallbackConfigurationName){
176
+ currentDatabase = database[currentLoginCallbackConfigurationName];
177
+ currentLoginCallbackConfigurationName=null;
178
+ return fetch(originalRequest,{
179
+ body: actualBody,
180
+ method: originalRequest.method,
181
+ headers: {
182
+ ...serializeHeaders(originalRequest.headers),
183
+ },
184
+ mode: originalRequest.mode,
185
+ cache: originalRequest.cache,
186
+ redirect: originalRequest.redirect,
187
+ referrer: originalRequest.referrer,
188
+ credentials: originalRequest.credentials,
189
+ integrity: originalRequest.integrity
190
+ }).then(hideTokens(currentDatabase));
191
+ }
192
+ });
193
+ response.then(r => {
194
+ if(r !== undefined){
195
+ resolve(r);
196
+ }
197
+ }).catch(err => {
198
+ if(err !== undefined) {
199
+ reject(err);
200
+ }
201
+ });
202
+ });
203
+ event.waitUntil(event.respondWith(maPromesse));
204
+ }
205
+ };
206
+
207
+ self.addEventListener('install', handleInstall);
208
+ self.addEventListener('activate', handleActivate);
209
+ self.addEventListener('fetch', handleFetch);
210
+
211
+ addEventListener('message', event => {
212
+ const port = event.ports[0];
213
+ const data = event.data;
214
+ const configurationName = data.configurationName;
215
+ let currentDatabase = database[configurationName];
216
+
217
+ if(!currentDatabase){
218
+ database[configurationName] = {
219
+ tokens: null,
220
+ items:[],
221
+ oidcServerConfiguration: null,
222
+ configurationName: configurationName,
223
+ };
224
+ currentDatabase = database[configurationName];
225
+ if(!trustedDomains[configurationName]) {
226
+ trustedDomains[configurationName] = [];
227
+ }
228
+ }
229
+ switch (data.type){
230
+ case "loadItems":
231
+ port.postMessage(database[configurationName].items);
232
+ return;
233
+ case "clear":
234
+ currentDatabase.tokens = null;
235
+ currentDatabase.items = null;
236
+ port.postMessage({configurationName});
237
+ return;
238
+ case "init":
239
+ currentDatabase.oidcServerConfiguration = data.data.oidcServerConfiguration;
240
+ const where = data.data.where;
241
+ if(where === "loginCallbackAsync" || where === "tryKeepExistingSessionAsync") {
242
+ currentLoginCallbackConfigurationName = configurationName;
243
+ } else{
244
+ currentLoginCallbackConfigurationName = null;
245
+ }
246
+ if(!currentDatabase.tokens){
247
+ port.postMessage({
248
+ tokens:null,
249
+ configurationName});
250
+ } else {
251
+ port.postMessage({
252
+ tokens: {
253
+ ...currentDatabase.tokens,
254
+ refresh_token: REFRESH_TOKEN + "_" + configurationName,
255
+ access_token: ACCESS_TOKEN + "_" + configurationName
256
+ },
257
+ configurationName
258
+ });
259
+ }
260
+ return;
261
+
262
+ case "getAccessTokenPayload":
263
+ const accessTokenPayload = extractAccessTokenPayload(currentDatabase.tokens.access_token);
264
+ port.postMessage({configurationName, accessTokenPayload});
265
+ return;
266
+ default:
267
+ currentDatabase.items = data.data;
268
+ port.postMessage({configurationName});
269
+ return;
270
+ }
271
+ });
272
+
@@ -0,0 +1,6 @@
1
+ 
2
+ // Add here trusted domains, access tokens will be send to
3
+ const trustedDomains = {
4
+ default:["http://localhost:4200"],
5
+ auth0:[]
6
+ };
@@ -0,0 +1 @@
1
+ export { Oidc } from './oidc';