@multiplatform.one/keycloak 0.2.16 → 0.3.1

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 (40) hide show
  1. package/dist/esm/authConfig.mjs +2 -2
  2. package/dist/esm/authConfig.mjs.map +1 -1
  3. package/dist/esm/provider/afterAuth.mjs +1 -1
  4. package/dist/esm/provider/afterAuth.mjs.map +2 -2
  5. package/dist/esm/provider/index.mjs +64 -8
  6. package/dist/esm/provider/index.mjs.map +2 -2
  7. package/dist/esm/provider/keycloakProvider.mjs +32 -10
  8. package/dist/esm/provider/keycloakProvider.mjs.map +2 -2
  9. package/dist/esm/provider/keycloakProvider.native.mjs +1 -1
  10. package/dist/esm/provider/keycloakProvider.native.mjs.map +1 -1
  11. package/dist/jsx/authConfig.mjs +2 -2
  12. package/dist/jsx/authConfig.mjs.map +1 -1
  13. package/dist/jsx/provider/afterAuth.mjs +1 -1
  14. package/dist/jsx/provider/afterAuth.mjs.map +2 -2
  15. package/dist/jsx/provider/index.mjs +45 -7
  16. package/dist/jsx/provider/index.mjs.map +2 -2
  17. package/dist/jsx/provider/keycloakProvider.mjs +30 -10
  18. package/dist/jsx/provider/keycloakProvider.mjs.map +2 -2
  19. package/dist/jsx/provider/keycloakProvider.native.mjs +1 -1
  20. package/dist/jsx/provider/keycloakProvider.native.mjs.map +1 -1
  21. package/dist/lib/authConfig.d.ts +1 -1
  22. package/dist/lib/authConfig.js +2 -2
  23. package/dist/lib/authConfig.js.map +1 -1
  24. package/dist/lib/provider/afterAuth.js +1 -1
  25. package/dist/lib/provider/afterAuth.js.map +2 -2
  26. package/dist/lib/provider/index.d.ts +11 -4
  27. package/dist/lib/provider/index.js +77 -7
  28. package/dist/lib/provider/index.js.map +2 -2
  29. package/dist/lib/provider/keycloakProvider.d.ts +3 -10
  30. package/dist/lib/provider/keycloakProvider.js +33 -11
  31. package/dist/lib/provider/keycloakProvider.js.map +2 -2
  32. package/dist/lib/provider/keycloakProvider.native.js +1 -1
  33. package/dist/lib/provider/keycloakProvider.native.js.map +1 -1
  34. package/dist/lib/tsconfig.build.tsbuildinfo +1 -1
  35. package/package.json +4 -4
  36. package/src/authConfig.ts +3 -3
  37. package/src/provider/afterAuth.tsx +1 -1
  38. package/src/provider/index.tsx +65 -12
  39. package/src/provider/keycloakProvider.native.tsx +1 -1
  40. package/src/provider/keycloakProvider.tsx +28 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/keycloak",
3
- "version": "0.2.16",
3
+ "version": "0.3.1",
4
4
  "description": "keycloak client for multiplatform.one ecosystem",
5
5
  "main": "dist/lib",
6
6
  "module": "dist/esm",
@@ -115,10 +115,10 @@
115
115
  },
116
116
  "dependencies": {
117
117
  "@bitspur/keycloak-js": "^21.1.1",
118
- "@bitspur/react-keycloak-ssr": "^4.0.4",
119
- "@bitspur/react-keycloak-web": "^4.0.4",
118
+ "@bitspur/react-keycloak-ssr": "^4.0.5",
119
+ "@bitspur/react-keycloak-web": "^4.0.5",
120
120
  "core-js-pure": "^3.30.2",
121
- "expo-auth-session": "^4.1.0",
121
+ "expo-auth-session": "^4.0.3",
122
122
  "solito": "^3.2.6"
123
123
  },
124
124
  "resolutions": {
package/src/authConfig.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * File Created: 08-11-2022 09:21:15
5
5
  * Author: Clay Risser
6
6
  * -----
7
- * Last Modified: 25-04-2023 23:08:17
7
+ * Last Modified: 14-05-2023 01:22:15
8
8
  * Modified By: Clay Risser
9
9
  * -----
10
10
  * Risser Labs LLC (c) Copyright 2021 - 2022
@@ -26,8 +26,8 @@ import { createContext } from 'react';
26
26
 
27
27
  export const defaultAuthConfig: AuthConfig = {
28
28
  ensureFreshness: true,
29
- persist: true,
30
- ssr: true,
29
+ persist: false,
30
+ ssr: false,
31
31
  };
32
32
 
33
33
  export const AuthConfigContext = createContext<AuthConfig>(defaultAuthConfig);
@@ -57,7 +57,7 @@ export const AfterAuth: FC<AfterAuthProps> = ({ children }: AfterAuthProps) => {
57
57
  }, [authState.idToken]);
58
58
 
59
59
  useEffect(() => {
60
- if (authConfig.debug && authState.refreshToken) logger.debug(authState.refreshToken);
60
+ if (authConfig.debug && authState.refreshToken) logger.debug('refreshToken', authState.refreshToken);
61
61
  }, [authState.refreshToken]);
62
62
 
63
63
  useEffect(() => {
@@ -23,30 +23,83 @@
23
23
  */
24
24
 
25
25
  import React, { useMemo } from 'react';
26
+ import type { AuthClientEvent, AuthClientError, AuthClientTokens } from '@bitspur/react-keycloak-core';
26
27
  import type { AuthConfig } from '../authConfig';
27
- import type { FC } from 'react';
28
- import type { KeycloakProviderProps } from './keycloakProvider';
28
+ import type { FC, ComponentType, ReactNode } from 'react';
29
+ import type { KeycloakConfig, KeycloakInitOptions } from '@bitspur/keycloak-js';
29
30
  import { AuthConfigContext, defaultAuthConfig } from '../authConfig';
30
31
  import { KeycloakProvider } from './keycloakProvider';
32
+ // @ts-ignore
33
+ import { config } from 'app/config';
31
34
 
32
- export interface AuthProviderProps extends KeycloakProviderProps {
33
- authConfig?: Partial<AuthConfig>;
35
+ export interface AuthProviderProps
36
+ extends Partial<Omit<AuthConfig, 'persist'>>,
37
+ Omit<KeycloakConfig, 'url'>,
38
+ KeycloakInitOptions {
39
+ children: ReactNode;
40
+ cookies?: unknown;
41
+ disabled?: boolean;
42
+ baseUrl?: string;
43
+ loadingComponent?: ComponentType;
44
+ onEvent?: (eventType: AuthClientEvent, error?: AuthClientError) => void;
45
+ onTokens?: (tokens: AuthClientTokens) => void;
34
46
  }
35
47
 
36
- export const AuthProvider: FC<AuthProviderProps> = (props: AuthProviderProps) => {
37
- const { authConfig, debug } = props;
38
- const authConfigValue = useMemo(
48
+ const persist = config.get('KEYCLOAK_PERSIST') === '1';
49
+
50
+ export const AuthProvider: FC<AuthProviderProps> = ({
51
+ // keycloak config
52
+ realm,
53
+ clientId,
54
+ baseUrl,
55
+ // auth config
56
+ debug,
57
+ ensureFreshness,
58
+ loginRoute,
59
+ messageHandlerKeys,
60
+ ssr,
61
+ // props
62
+ children,
63
+ cookies,
64
+ disabled,
65
+ loadingComponent,
66
+ onEvent,
67
+ onTokens,
68
+ ...keycloakInitOptions
69
+ }: AuthProviderProps) => {
70
+ const authConfig = useMemo(
39
71
  () => ({
40
72
  ...defaultAuthConfig,
41
- ...authConfig,
42
- debug: !!debug,
73
+ debug,
74
+ ensureFreshness,
75
+ loginRoute,
76
+ messageHandlerKeys,
77
+ persist,
78
+ ssr,
43
79
  }),
44
- [],
80
+ [debug, ensureFreshness, loginRoute, messageHandlerKeys, persist, ssr],
45
81
  );
46
82
 
83
+ if (disabled) {
84
+ return <AuthConfigContext.Provider value={authConfig}>{children}</AuthConfigContext.Provider>;
85
+ }
86
+
47
87
  return (
48
- <AuthConfigContext.Provider value={authConfigValue}>
49
- <KeycloakProvider {...props} />
88
+ <AuthConfigContext.Provider value={authConfig}>
89
+ <KeycloakProvider
90
+ cookies={cookies}
91
+ keycloakConfig={{
92
+ realm,
93
+ clientId,
94
+ url: baseUrl,
95
+ }}
96
+ keycloakInitOptions={keycloakInitOptions}
97
+ loadingComponent={loadingComponent}
98
+ onEvent={onEvent}
99
+ onTokens={onTokens}
100
+ >
101
+ {children}
102
+ </KeycloakProvider>
50
103
  </AuthConfigContext.Provider>
51
104
  );
52
105
  };
@@ -32,7 +32,7 @@ import { KeycloakProvider as ExpoKeycloakProvider } from 'expo-keycloak-auth';
32
32
  export const KeycloakProvider: FC<KeycloakProviderProps> = ({ children, keycloakConfig }: KeycloakProviderProps) => {
33
33
  const clonedKeycloakConfig = {
34
34
  ...(keycloakConfig as Omit<KeycloakConfig, 'baseUrl'>),
35
- url: keycloakConfig.baseUrl,
35
+ url: keycloakConfig.url,
36
36
  };
37
37
  // @ts-ignore
38
38
  delete keycloakConfig.baseUrl;
@@ -25,7 +25,7 @@
25
25
  import Keycloak from '@bitspur/keycloak-js';
26
26
  import React, { useMemo, useEffect, useState, useCallback } from 'react';
27
27
  import type { AuthClientEvent, AuthClientError, AuthClientTokens } from '@bitspur/react-keycloak-core';
28
- import type { KeycloakInitOptions } from '@bitspur/keycloak-js';
28
+ import type { KeycloakInitOptions, KeycloakConfig } from '@bitspur/keycloak-js';
29
29
  import type { ReactNode, ComponentType } from 'react';
30
30
  import { AfterAuth } from './afterAuth';
31
31
  import { MultiPlatform } from 'multiplatform.one';
@@ -38,8 +38,6 @@ import { useRouter } from 'next/router';
38
38
  export interface KeycloakProviderProps {
39
39
  children: ReactNode;
40
40
  cookies?: unknown;
41
- debug?: boolean;
42
- disabled?: boolean;
43
41
  keycloakConfig: KeycloakConfig;
44
42
  keycloakInitOptions?: KeycloakInitOptions;
45
43
  loadingComponent?: ComponentType;
@@ -52,27 +50,25 @@ const logger = console;
52
50
  export function KeycloakProvider({
53
51
  children,
54
52
  cookies,
55
- debug,
56
53
  keycloakConfig,
57
54
  keycloakInitOptions,
58
55
  loadingComponent,
59
56
  onEvent,
60
57
  onTokens,
61
58
  }: KeycloakProviderProps) {
59
+ const { debug, ensureFreshness, persist, messageHandlerKeys, ssr } = useAuthConfig();
62
60
  const authState = useAuthState();
63
61
  const LoadingComponent = loadingComponent || (() => <>{debug ? 'authenticating' : null}</>);
64
62
  const { query } = MultiPlatform.isNext ? useRouter() : { query: {} };
65
- const authConfig = useAuthConfig();
66
63
  const [idToken, setIdToken] = useState<string | boolean>(
67
- ('idToken' in query && (query.idToken?.toString() || true)) || (authConfig.persist && authState.idToken) || false,
64
+ ('idToken' in query && (query.idToken?.toString() || true)) || (persist && authState.idToken) || false,
68
65
  );
69
66
  const [token, setToken] = useState<string | boolean>(
70
- ('token' in query && (query.token?.toString() || true)) || (authConfig.persist && authState.token) || false,
67
+ ('token' in query && (query.token?.toString() || true)) || (persist && authState.token) || false,
71
68
  );
72
69
  const [refreshToken, setRefreshToken] = useState<string | boolean>(
73
- (authConfig.ensureFreshness &&
74
- (('refreshToken' in query && (query.refreshToken?.toString() || true)) ||
75
- (authConfig.persist && authState.refreshToken))) ||
70
+ (ensureFreshness &&
71
+ (('refreshToken' in query && (query.refreshToken?.toString() || true)) || (persist && authState.refreshToken))) ||
76
72
  false,
77
73
  );
78
74
  const explicitToken = 'idToken' in query || 'token' in query || 'refreshToken' in query;
@@ -80,13 +76,19 @@ export function KeycloakProvider({
80
76
  useEffect(() => {
81
77
  if (token !== true && refreshToken !== true && idToken !== true) return;
82
78
  if (debug) logger.debug('post message', { type: 'LOADED' });
83
- (authConfig.messageHandlerKeys || []).forEach((key: string) => {
79
+ (messageHandlerKeys || []).forEach((key: string) => {
84
80
  window?.webkit?.messageHandlers?.[key]?.postMessage(JSON.stringify({ type: 'LOADED' }));
85
81
  });
86
82
  window?.ReactNativeWebView?.postMessage(JSON.stringify({ type: 'LOADED' }));
87
83
  window?.parent?.postMessage(JSON.stringify({ type: 'LOADED' }));
88
84
  }, []);
89
85
 
86
+ useEffect(() => {
87
+ if (typeof idToken === 'string' && !isTokenValid(idToken)) setIdToken(false);
88
+ if (typeof refreshToken === 'string' && !isTokenValid(refreshToken)) setRefreshToken(false);
89
+ if (typeof token === 'string' && !isTokenValid(token)) setToken(false);
90
+ }, [idToken, token, refreshToken]);
91
+
90
92
  useEffect(() => {
91
93
  if (token !== true) return;
92
94
  const messageCallback = (e: MessageEvent<any>) => {
@@ -188,7 +190,7 @@ export function KeycloakProvider({
188
190
  () =>
189
191
  typeof window !== 'undefined' &&
190
192
  new Keycloak({
191
- url: keycloakConfig.baseUrl,
193
+ url: keycloakConfig.url,
192
194
  realm: keycloakConfig.realm,
193
195
  clientId: keycloakConfig.clientId,
194
196
  }),
@@ -214,11 +216,13 @@ export function KeycloakProvider({
214
216
  }, [keycloakInitOptions, token, refreshToken, idToken]);
215
217
 
216
218
  if (token === true || idToken === true || refreshToken === true) return <LoadingComponent />;
217
- if (cookies && authConfig.ssr) {
219
+ if (cookies && ssr) {
218
220
  return (
219
221
  // @ts-ignore
220
222
  <SSRKeycloakProvider
221
223
  LoadingComponent={<LoadingComponent />}
224
+ // keycloak-js already handles refreshing tokens
225
+ autoRefreshToken={false}
222
226
  initOptions={initOptions}
223
227
  onEvent={handleEvent}
224
228
  onTokens={onTokens}
@@ -226,7 +230,7 @@ export function KeycloakProvider({
226
230
  keycloakConfig={{
227
231
  clientId: keycloakConfig.clientId,
228
232
  realm: keycloakConfig.realm,
229
- url: keycloakConfig.baseUrl,
233
+ url: keycloakConfig.url,
230
234
  }}
231
235
  >
232
236
  <AfterAuth>{children}</AfterAuth>
@@ -238,6 +242,8 @@ export function KeycloakProvider({
238
242
  <ReactKeycloakProvider
239
243
  LoadingComponent={<LoadingComponent />}
240
244
  authClient={keycloak}
245
+ // keycloak-js already handles refreshing tokens
246
+ autoRefreshToken={false}
241
247
  initOptions={initOptions}
242
248
  onEvent={handleEvent}
243
249
  onTokens={onTokens}
@@ -247,11 +253,14 @@ export function KeycloakProvider({
247
253
  );
248
254
  }
249
255
 
250
- export interface KeycloakConfig {
251
- clientId: string;
252
- realm: string;
253
- scheme?: string;
254
- baseUrl: string;
256
+ export function isTokenValid(token: string) {
257
+ try {
258
+ const { exp } = JSON.parse(Buffer.from(token.split('.')?.[1] || '', 'base64').toString() || '{}');
259
+ return Math.floor(Date.now() / 1000) <= exp;
260
+ } catch (err) {
261
+ if (err instanceof SyntaxError) return false;
262
+ throw err;
263
+ }
255
264
  }
256
265
 
257
266
  export const defaultKeycloakInitOptions: KeycloakInitOptions = {