Skip to content

Commit

Permalink
Add conditional Keycloak provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Derstilon committed Oct 19, 2023
1 parent d01e688 commit c775239
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ function App() {
<ThemeProvider theme={theme} />,
<SnackbarProvider maxSnack={3} />,
<KeycloakAuth />,
<Store />,
<DialogProvider />,
<Auth />,
<ShSimulation />,
<PythonConverterService />,
<Store />,
<Loader />
]}>
<WrapperApp />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Button } from '@mui/material';
import { useKeycloak } from 'keycloak-react-web';

import { useKeycloakAuth } from '../../../services/KeycloakAuthService';
import { ConcreteDialogProps, CustomDialog } from './CustomDialog';

export function RejectKeycloakUserDialog({
onClose,
reason
}: ConcreteDialogProps & { reason: string }) {
const { keycloak, initialized } = useKeycloak();
const { keycloak, initialized } = useKeycloakAuth();

return (
<CustomDialog
Expand Down
53 changes: 39 additions & 14 deletions src/ThreeEditor/js/Storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,52 @@ function Storage() {

request.onerror = function (event) {
console.error('IndexedDB', event);
// delete database
const req = indexedDB.deleteDatabase(name);
req.onsuccess = function () {
console.log('Deleted database successfully');
};

req.onerror = function () {
console.log('Could not delete database');
};

req.onblocked = function () {
console.log('Could not delete database due to the operation being blocked');
};
};
},

get: function (callback) {
const transaction = database.transaction(['states'], 'readwrite');
const objectStore = transaction.objectStore('states');
const request = objectStore.get(0);
request.onsuccess = function (event) {
callback(event.target.result);
};
try {
const transaction = database.transaction(['states'], 'readwrite');
const objectStore = transaction.objectStore('states');
const request = objectStore.get(0);
request.onsuccess = function (event) {
callback(event.target.result);
};
} catch (error) {
console.error(error);
callback();
}
},

set: function (data) {
const start = performance.now();

const transaction = database.transaction(['states'], 'readwrite');
const objectStore = transaction.objectStore('states');
const request = objectStore.put(data, 0);
request.onsuccess = function () {
devLog('Saved state to IndexedDB.', `${(performance.now() - start).toFixed(2)}ms`);
};
try {
const start = performance.now();

const transaction = database.transaction(['states'], 'readwrite');
const objectStore = transaction.objectStore('states');
const request = objectStore.put(data, 0);
request.onsuccess = function () {
devLog(
'Saved state to IndexedDB.',
`${(performance.now() - start).toFixed(2)}ms`
);
};
} catch (error) {
console.error(error);
}
},

clear: function () {
Expand Down
4 changes: 2 additions & 2 deletions src/WrapperApp/components/Panels/LoginPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Box, Button, Card, CardContent, TextField, Typography, useTheme } from '@mui/material';
import { useKeycloak } from 'keycloak-react-web';
import { ChangeEvent, useCallback, useEffect, useState } from 'react';

import { useConfig } from '../../../config/ConfigService';
import { useAuth } from '../../../services/AuthService';
import { useKeycloakAuth } from '../../../services/KeycloakAuthService';

export default function LoginPanel() {
const { altAuth } = useConfig();
const { login } = useAuth();
const { keycloak, initialized } = useKeycloak();
const { keycloak, initialized } = useKeycloakAuth();
const theme = useTheme();

const [username, setUsername] = useState('');
Expand Down
13 changes: 3 additions & 10 deletions src/services/AuthService.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Backdrop, CircularProgress, Theme, Typography } from '@mui/material';
import { useKeycloak } from 'keycloak-react-web';
import ky, { HTTPError } from 'ky';
import { KyInstance } from 'ky/distribution/types/ky';
import { useSnackbar } from 'notistack';
Expand All @@ -18,6 +17,7 @@ import useIntervalAsync from '../util/hooks/useIntervalAsync';
import { snakeToCamelCase } from '../util/Notation/Notation';
import { useDialog } from './DialogService';
import { createGenericContext, GenericContextProviderProps } from './GenericContext';
import { useKeycloakAuth } from './KeycloakAuthService';

type AuthUser = Pick<ResponseAuthStatus, 'username' | 'source'>;

Expand Down Expand Up @@ -80,7 +80,7 @@ const Auth = ({ children }: GenericContextProviderProps) => {
const [user, setUser] = useState<AuthUser | null>(load(StorageKey.USER, isAuthUser));
const [reachInterval, setReachInterval] = useState<number>();
const [refreshInterval, setRefreshInterval] = useState<number | undefined>(180000); // 3 minutes in ms default interval for refresh token
const { keycloak, initialized } = useKeycloak();
const { keycloak, initialized } = useKeycloakAuth();
const [keyCloakInterval, setKeyCloakInterval] = useState<number>();
const [isServerReachable, setIsServerReachable] = useState<boolean | null>(null);
const { enqueueSnackbar } = useSnackbar();
Expand Down Expand Up @@ -215,14 +215,7 @@ const Auth = ({ children }: GenericContextProviderProps) => {
: err.message
});
});
}, [
initialized,
keycloak.authenticated,
keycloak.token,
keycloak.tokenParsed?.preferred_username,
kyRef,
open
]);
}, [initialized, keycloak, kyRef, open]);

useEffect(() => {
if (initialized && keycloak.authenticated)
Expand Down
22 changes: 22 additions & 0 deletions src/services/GenericContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,25 @@ export const createGenericContext = <T extends unknown>() => {

return [useGenericContext, genericContext.Provider] as const;
};

export const createSubstituteContext = <T extends unknown>(useSubstituted: () => T) => {
// Create a context with a generic parameter or undefined
const genericContext = createContext<T | undefined>(undefined);

// Check if the value provided to the context is defined or call the substitute
const useSubstituteOrGenericContext = () => {
const contextIsDefined = useContext(genericContext);

try {
return useSubstituted();
} catch (e) {
if (!contextIsDefined) {
throw new Error('useSubstituteOrGenericContext must be used within a Provider');
}

return contextIsDefined;
}
};

return [useSubstituteOrGenericContext, genericContext.Provider] as const;
};
33 changes: 29 additions & 4 deletions src/services/KeycloakAuthService.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import Keycloak, { KeycloakInitOptions } from 'keycloak-js';
import { KeycloakProvider } from 'keycloak-react-web';
import { KeycloakProvider, useKeycloak } from 'keycloak-react-web';

import { GenericContextProviderProps } from './GenericContext';
import { useConfig } from '../config/ConfigService';
import { createSubstituteContext, GenericContextProviderProps } from './GenericContext';

const authInstance = new Keycloak({
url: `${
Expand All @@ -20,12 +21,36 @@ const initOptions = {
enableLogging: false
} as const satisfies KeycloakInitOptions;

export const KeycloakAuth = ({ children }: GenericContextProviderProps) => {
return (
export type KeycloakAuthContext =
| {
initialized: false;
keycloak?: Keycloak;
}
| {
initialized: true;
keycloak: Keycloak;
};

const [useKeycloakAuth, KeycloakAuthContextProvider] =
createSubstituteContext<KeycloakAuthContext>(useKeycloak);

const KeycloakAuth = ({ children }: GenericContextProviderProps) => {
const { altAuth } = useConfig();

return altAuth ? (
<KeycloakProvider
client={authInstance}
initOptions={initOptions}>
{children}
</KeycloakProvider>
) : (
<KeycloakAuthContextProvider
value={{
initialized: false
}}>
{children}
</KeycloakAuthContextProvider>
);
};

export { KeycloakAuth, useKeycloakAuth };

0 comments on commit c775239

Please sign in to comment.