diff --git a/JeMPI_Apps/JeMPI_UI/src/hooks/useAuth.tsx b/JeMPI_Apps/JeMPI_UI/src/hooks/useAuth.tsx index 1f45450b8..bda054cb4 100644 --- a/JeMPI_Apps/JeMPI_UI/src/hooks/useAuth.tsx +++ b/JeMPI_Apps/JeMPI_UI/src/hooks/useAuth.tsx @@ -47,12 +47,12 @@ export const AuthChecker = ({ children }: AuthProviderProps): JSX.Element => { const oauthRef = useRef(null) const { mutate: validateOAuth } = useMutation({ - mutationFn: apiClient.validateOAuth, + mutationFn: apiClient.validateOAuth.bind(apiClient), onSuccess(response) { enqueueSnackbar(`Successfully logged in using KeyCloak`, { variant: 'success' }) - authContext.setUser(response) + authContext.setUser(response as User) navigate({ pathname: '/' }) }, onError() { @@ -117,6 +117,7 @@ const currentUserOueryClientKey = 'auth-user' export const AuthProvider = ({ children }: AuthProviderProps): JSX.Element => { const { apiClient, config } = useConfig() + const keycloack = getKeycloak(config) const queryClient = useQueryClient() const { enqueueSnackbar } = useSnackbar() @@ -136,7 +137,7 @@ export const AuthProvider = ({ children }: AuthProviderProps): JSX.Element => { }) const { mutate: logout } = useMutation({ - mutationFn: apiClient.logout, + mutationFn: apiClient.logout.bind(apiClient), onSuccess(data: any, navigate: NavigateFunction) { queryClient.clear() navigate({ pathname: '/login' }) @@ -153,7 +154,7 @@ export const AuthProvider = ({ children }: AuthProviderProps): JSX.Element => { } const signInWithKeyCloak = () => { - getKeycloak(config).init({ + keycloack.init({ onLoad: 'login-required', redirectUri: window.location.href, checkLoginIframe: false diff --git a/JeMPI_Apps/JeMPI_UI/src/services/ApiClient.ts b/JeMPI_Apps/JeMPI_UI/src/services/ApiClient.ts index 65e1d113c..342f0d1ca 100644 --- a/JeMPI_Apps/JeMPI_UI/src/services/ApiClient.ts +++ b/JeMPI_Apps/JeMPI_UI/src/services/ApiClient.ts @@ -53,10 +53,7 @@ export class ApiClient { if (['post', 'patch', 'put', 'delete'].indexOf(method || '') !== -1) { const csrfToken = getCookie('XSRF-TOKEN') if (csrfToken) { - request.headers = { - ...request.headers, - 'X-XSRF-TOKEN': csrfToken - } + request.headers['X-XSRF-TOKEN'] = csrfToken } } return request diff --git a/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/DockerBase.ts b/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/DockerBase.ts index 9cde6ae9e..a19c7b7cd 100644 --- a/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/DockerBase.ts +++ b/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/DockerBase.ts @@ -1,4 +1,5 @@ import Docker from 'dockerode' +import { getTestEnvConfig } from './Utils' export abstract class DockerBase{ @@ -15,22 +16,9 @@ export abstract class DockerBase{ abstract HasLoadedFunc(): () => Promise; GetEnvConfig(){ - return { - isDev: process.env.NODE_ENV !== 'production', - apiUrl: process.env.REACT_APP_JEMPI_BASE_API_HOST - ? `${process.env.REACT_APP_JEMPI_BASE_API_HOST}:${process.env.REACT_APP_JEMPI_BASE_API_PORT}` - : `${window.location.protocol}//${window.location.hostname}:${process.env.REACT_APP_JEMPI_BASE_API_PORT}`, - shouldMockBackend: process.env.REACT_APP_MOCK_BACKEND === 'true', - KeyCloakUrl: process.env.KC_FRONTEND_URL || 'http://localhost:9088', - KeyCloakRealm: process.env.KC_REALM_NAME || 'platform-realm', - KeyCloakClientId: process.env.KC_JEMPI_CLIENT_ID || 'jempi-oauth', - useSso: process.env.REACT_APP_ENABLE_SSO === 'true', - maxUploadCsvSize: +( - process.env.REACT_APP_MAX_UPLOAD_CSV_SIZE_IN_MEGABYTES || 128 - ), - showBrandLogo: process.env.REACT_APP_SHOW_BRAND_LOGO === 'true' - } + return getTestEnvConfig() } + async Start(){ await this.CreateService() } diff --git a/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockJeMPI_API/MockJeMPI_API.ts b/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockJeMPI_API/MockJeMPI_API.ts index e59dca44e..7e936e849 100644 --- a/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockJeMPI_API/MockJeMPI_API.ts +++ b/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockJeMPI_API/MockJeMPI_API.ts @@ -4,7 +4,7 @@ import { constants as httpsStatusCodes } from 'http2'; import path from 'path'; import fs from 'fs'; import moxios from '../../../../../src/services/mockBackend' -import { config } from '../../../../../src/config' +import { getTestEnvConfig } from '../Utils' type methods = 'POST' | 'GET' | 'PUT' | string export type IMockEndpointConfig = { [urlPath:string] : { @@ -23,6 +23,7 @@ class MockJeMPIAPIServer { appUrl:string constructor(extendingConfig:IMockEndpointConfig, appPort:number){ + const config = getTestEnvConfig(); this.server =this.CreateMockServer(extendingConfig) const parsedUrl = new URL(config.apiUrl); this.serverPort = parseInt(parsedUrl.port) diff --git a/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockKafka/MockKafka.ts b/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockKafka/MockKafka.ts deleted file mode 100644 index b64a622d1..000000000 --- a/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockKafka/MockKafka.ts +++ /dev/null @@ -1,155 +0,0 @@ - -import axios from 'axios' -import path from 'path'; -import fs from 'fs'; -import { DockerBase } from '../DockerBase'; -import { useConfig } from 'hooks/useConfig'; -import getConfig from 'config'; - -class MockKeyCloack extends DockerBase{ - - keyClockUrl:string - keyClockUrlPort:string - keyClockRealm:string - keyClockClient:string - addtionalUser:any[] - - constructor(userConfig:any[]=[]){ - super() - const config = this.GetEnvConfig(); - const parsedUrl = new URL(config.KeyCloakUrl); - - this.keyClockUrl = config.KeyCloakUrl - this.keyClockUrlPort = parsedUrl.port - this.keyClockRealm = config.KeyCloakRealm - this.keyClockClient = config.KeyCloakClientId - - this.addtionalUser = userConfig - } - - GetServiceName(){ - return "JeMPIMockKafka" - } - - GetConfig(){ - return { - name: this.serviceName, - Image: 'bitnami/kafka:latest', - ExposedPorts: { - '9092/tcp': {} - }, - HostConfig: { - PortBindings: { - '9092/tcp': [{ HostPort: '9092' }], - }, - Env: [ - 'KAFKA_CFG_NODE_ID=0', - 'KAFKA_CFG_PROCESS_ROLES=controller,broker', - 'KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093', - 'KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT', - 'KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093', - 'KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER' - ], - }, - } - } - - GetUsers(){ - return [{username: "admin", password: "admin"}, ...this.addtionalUser].map(v => { - return { - username: v.username, - enabled: true, - credentials: [ - { - type: "password", - value: v.password, - temporary: false - } - ] - } - }) - } - - async Start(){ - await super.Start() - //await this.AddRealms() - console.log(`\n\nKeyClock Ready! Running on port ${this.keyClockUrlPort}\n\n`) - } - - async AddRealms(){ - console.log("\nAdding Realms:\n\n") - try { - const accessTokenData:any = await axios.post( - `${this.keyClockUrl}/realms/master/protocol/openid-connect/token`, - { - grant_type: "password", - client_id: "admin-cli", - username: "user", - password: "bitnami", - }, - { - headers: { - "Content-Type": "application/x-www-form-urlencoded" - }, - } - ); - - const response = await axios.post( - `${this.keyClockUrl}/admin/realms`, - { - realm: this.keyClockRealm, - enabled: true, - clients: [ - { - clientId: this.keyClockClient, - enabled: true, - publicClient: false, - directAccessGrantsEnabled: true, - redirectUris: ["*"], - webOrigins: ["*"], - defaultRoles: [ - "user" - ] - } - ], - users: this.GetUsers() - }, - { - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${accessTokenData?.data?.access_token}` - }, - } - ); - - console.log(`Realm '${this.keyClockRealm}' created successfully.`); - console.log(response.data); - } catch (error:any) { - console.error('Error creating realm:', error.response ? error.response.data : error.message); - } - } - - HasLoadedFunc(): () => Promise { - return () => axios.get(this.keyClockUrl) - } - - -} - -// let fullPath:string = "" -// if(process.argv.length > 2 ){ -// const potentialPath:string = process.argv[2] -// let potentialFullPath:string = path.isAbsolute(potentialPath) ? potentialPath : path.resolve(__dirname, potentialPath ) - -// if (!fs.existsSync(potentialFullPath)){ -// console.error(`The file path ${potentialFullPath} does not exist`) -// } -// else{ -// fullPath = potentialFullPath -// } -// } -// else{ -// fullPath = path.resolve(__dirname, "./keycloakUsers.json") -// } - -new MockKeyCloack().Start() \ No newline at end of file diff --git a/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockKeyCloak/MockKeyCloak.ts b/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockKeyCloak/MockKeyCloak.ts index 790330ff6..35c218c9d 100644 --- a/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockKeyCloak/MockKeyCloak.ts +++ b/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/MockKeyCloak/MockKeyCloak.ts @@ -3,11 +3,10 @@ import axios from 'axios' import Docker from 'dockerode' import path from 'path'; import fs from 'fs'; -import { config } from '../../../../../src/config' +import { DockerBase } from '../DockerBase'; + +class MockKeyCloack extends DockerBase{ -class MockKeyCloack { - docker:Docker - serviceName:string keyClockUrl:string keyClockUrlPort:string keyClockRealm:string @@ -15,6 +14,8 @@ class MockKeyCloack { addtionalUser:any[] constructor(userConfig:any[]=[]){ + super() + const config = this.GetEnvConfig(); const parsedUrl = new URL(config.KeyCloakUrl); this.keyClockUrl = config.KeyCloakUrl @@ -23,7 +24,6 @@ class MockKeyCloack { this.keyClockClient = config.KeyCloakClientId this.docker = new Docker() - this.serviceName = "JeMPIMockKeyCloak" this.addtionalUser = userConfig } @@ -121,56 +121,14 @@ class MockKeyCloack { } } - async CreateService(){ - const waitToLoad = (checkPromise:() => Promise, waitFor: 'resolve' | 'reject') => { - return new Promise( (resolve:any, reject:any) => { - let time= 0 - const addTime = () =>{ - if (time > 60000){ - reject("Timeout starting keycloak") - } - time += 1000 - } - - const interval = setInterval(() => checkPromise().then(() => { - if (waitFor === 'resolve'){ - clearInterval(interval) - resolve() - }else{ - addTime() - } - - }).catch(() => { - if (waitFor === 'reject'){ - clearInterval(interval) - resolve() - }else{ - addTime() - } - }), 1000) - }) - } - - const containers = await this.docker.listContainers() - const targetContainerInfo = containers.find(container => container.Names.includes("/"+this.serviceName)); - if (targetContainerInfo){ - const targetContainer = await this.docker.getContainer(targetContainerInfo.Id) - await targetContainer.stop() - const stream = await targetContainer.attach({ stream: true, stdout: true, stderr: true }) - stream.pipe(process.stdout) - await waitToLoad(() => this.docker.getContainer(targetContainerInfo.Id).inspect(), 'reject') - - - } - - const container = await this.docker.createContainer(this.GetConfig()) - await container.start() - const stream = await container.attach({ stream: true, stdout: true, stderr: true }) - stream.pipe(process.stdout) - await waitToLoad(() => axios.get(this.keyClockUrl), 'resolve') - + GetServiceName(): string { + return "JeMPIMockKeyCloak" + } + HasLoadedFunc(): () => Promise { + return () => axios.get(this.keyClockUrl) } + } let fullPath:string = "" diff --git a/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/Utils.ts b/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/Utils.ts new file mode 100644 index 000000000..c893da7e3 --- /dev/null +++ b/JeMPI_Apps/JeMPI_UI/tests/test.utils/mocks/enviroments/Utils.ts @@ -0,0 +1,17 @@ +export const getTestEnvConfig = () => { + return { + isDev: process.env.NODE_ENV !== 'production', + apiUrl: process.env.REACT_APP_JEMPI_BASE_API_HOST + ? `${process.env.REACT_APP_JEMPI_BASE_API_HOST}:${process.env.REACT_APP_JEMPI_BASE_API_PORT}` + : `http://localhost:50000/JeMPI`, + shouldMockBackend: process.env.REACT_APP_MOCK_BACKEND === 'true', + KeyCloakUrl: process.env.KC_FRONTEND_URL || 'http://localhost:9088', + KeyCloakRealm: process.env.KC_REALM_NAME || 'platform-realm', + KeyCloakClientId: process.env.KC_JEMPI_CLIENT_ID || 'jempi-oauth', + useSso: process.env.REACT_APP_ENABLE_SSO === 'true', + maxUploadCsvSize: +( + process.env.REACT_APP_MAX_UPLOAD_CSV_SIZE_IN_MEGABYTES || 128 + ), + showBrandLogo: process.env.REACT_APP_SHOW_BRAND_LOGO === 'true' + } +} \ No newline at end of file