From 43e35b5bee00a647b30c25ae027b0c4e8616c75d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Matias=CC=8Cko?= Date: Sun, 3 Sep 2023 00:15:46 +0200 Subject: [PATCH] un-expected logout fix --- http-gateway/web/packages/shared-ui | 2 +- .../src/containers/App/AppInner/AppInner.tsx | 10 +++--- .../AddRemoteClientModal.tsx | 8 +++-- .../RemoteClients/RemoteClients.i18n.ts | 8 ++++- .../RemoteClientsAuthProvider.tsx | 28 ++++------------- .../RemoteClientsAuthProvider.types.ts | 5 --- .../RemoteClientsPage/RemoteClientsPage.tsx | 31 ++++++++++--------- 7 files changed, 41 insertions(+), 51 deletions(-) diff --git a/http-gateway/web/packages/shared-ui b/http-gateway/web/packages/shared-ui index 800b3d071..a06f43c37 160000 --- a/http-gateway/web/packages/shared-ui +++ b/http-gateway/web/packages/shared-ui @@ -1 +1 @@ -Subproject commit 800b3d071b7c810ce67b7096e276248a2dbbc7fb +Subproject commit a06f43c376da171d93af3cc3775ec7ee788584d5 diff --git a/http-gateway/web/src/containers/App/AppInner/AppInner.tsx b/http-gateway/web/src/containers/App/AppInner/AppInner.tsx index f629d70fa..43f114853 100644 --- a/http-gateway/web/src/containers/App/AppInner/AppInner.tsx +++ b/http-gateway/web/src/containers/App/AppInner/AppInner.tsx @@ -22,7 +22,7 @@ import AppLayout from '@/containers/App/AppLayout/AppLayout' const AppInner = (props: Props) => { const { wellKnownConfig, openTelemetry, collapsed, setCollapsed } = props - const { userData, userManager, signOutRedirect } = useAuth() + const { userData, userManager, signOutRedirect, isLoading } = useAuth() const [footerExpanded, setFooterExpanded] = useLocalStorage('footerPanelExpanded', false) @@ -42,18 +42,18 @@ const AppInner = (props: Props) => { [footerExpanded, collapsed, setCollapsed, setFooterExpanded, wellKnownConfig, openTelemetry] ) - if (userData) { + if (!userData || isLoading) { + return + } else { security.setAccessToken(userData.access_token) + // security.setUserData(userData) // for remote clients - clientAppSettings.setUserData(userData) clientAppSettings.setSignOutRedirect(signOutRedirect) if (userManager) { security.setUserManager(userManager) } - } else { - return } return ( diff --git a/http-gateway/web/src/containers/RemoteClients/List/AddRemoteClientModal/AddRemoteClientModal.tsx b/http-gateway/web/src/containers/RemoteClients/List/AddRemoteClientModal/AddRemoteClientModal.tsx index 53f21b2b8..25ae2873e 100644 --- a/http-gateway/web/src/containers/RemoteClients/List/AddRemoteClientModal/AddRemoteClientModal.tsx +++ b/http-gateway/web/src/containers/RemoteClients/List/AddRemoteClientModal/AddRemoteClientModal.tsx @@ -158,7 +158,10 @@ const AddRemoteClientModal: FC = (props) => { }) .catch((e) => { setVersionLoading(false) - Notification.error({ title: _(t.error), message: _(t.clientError) }, { notificationId: notificationId.HUB_ADD_REMOTE_CLIENT_MODAL_ON_SUBMIT }) + Notification.error( + { title: _(t.error), message: _(t.clientError, { remoteClientUrl: url }) }, + { notificationId: notificationId.HUB_ADD_REMOTE_CLIENT_MODAL_ON_SUBMIT, onClick: () => window.open(url, '_blank') } + ) }) } @@ -235,7 +238,7 @@ const AddRemoteClientModal: FC = (props) => {
{!isEditMode && (
- Nutnost akceptovat certifikat + {_(t.certificateAcceptDescription)}
)} @@ -323,6 +326,7 @@ const AddRemoteClientModal: FC = (props) => { ] : undefined } + maxWidth={600} onClose={handleClose} portalTarget={document.getElementById('modal-root')} renderBody={renderBody} diff --git a/http-gateway/web/src/containers/RemoteClients/RemoteClients.i18n.ts b/http-gateway/web/src/containers/RemoteClients/RemoteClients.i18n.ts index b4f48b304..3f7564ba4 100644 --- a/http-gateway/web/src/containers/RemoteClients/RemoteClients.i18n.ts +++ b/http-gateway/web/src/containers/RemoteClients/RemoteClients.i18n.ts @@ -103,7 +103,8 @@ export const messages = defineMessages({ }, clientError: { id: 'remoteClients.clientError', - defaultMessage: 'No client is reachable on the IP address', + defaultMessage: + 'Failed to add the remote client. The certificate for the provided URL may not have been accepted by browser. Please ensure you open the {remoteClientUrl} in your browser, verify and accept the certificate before attempting to add the client.', }, version: { id: 'remoteClients.version', @@ -158,4 +159,9 @@ export const messages = defineMessages({ defaultMessage: 'Application Initialization Restricted. Please ensure the remote client user logs out before proceeding. Only after the different user has logged out, will you be able to utilize the application.', }, + certificateAcceptDescription: { + id: 'remoteClients.certificateAcceptDescription', + defaultMessage: + 'Before adding a remote client, verify their TLS certificate for security. To proceed, open the URL in your browser, verify and accept the certificate. Adding a client involves sharing credentials, so ensure you trust them.', + }, }) diff --git a/http-gateway/web/src/containers/RemoteClients/RemoteClientsAuthProvider/RemoteClientsAuthProvider.tsx b/http-gateway/web/src/containers/RemoteClients/RemoteClientsAuthProvider/RemoteClientsAuthProvider.tsx index c2510e331..358978742 100644 --- a/http-gateway/web/src/containers/RemoteClients/RemoteClientsAuthProvider/RemoteClientsAuthProvider.tsx +++ b/http-gateway/web/src/containers/RemoteClients/RemoteClientsAuthProvider/RemoteClientsAuthProvider.tsx @@ -1,7 +1,6 @@ -import { forwardRef, useEffect, useImperativeHandle, useState } from 'react' +import { FC, useEffect, useState } from 'react' import { useIntl } from 'react-intl' -import { clientAppSettings } from '@shared-ui/common/services' import { getJwksData, getOpenIdConfiguration, @@ -16,40 +15,27 @@ import AppLoader from '@shared-ui/app/clientApp/App/AppLoader' import Notification from '@shared-ui/components/Atomic/Notification/Toast' import { messages as t } from '../RemoteClients.i18n' -import { AppAuthProviderRefType, Props } from './RemoteClientsAuthProvider.types' +import { Props } from './RemoteClientsAuthProvider.types' import notificationId from '@/notificationId' -const RemoteClientsAuthProvider = forwardRef((props, ref) => { +const RemoteClientsAuthProvider: FC = (props) => { const { wellKnownConfig, reInitialization, clientData, children, setAuthError, setInitialize, unauthorizedCallback } = props - const { id, clientUrl, authenticationMode, preSharedSubjectId, preSharedKey } = clientData + const { clientUrl, authenticationMode, preSharedSubjectId, preSharedKey } = clientData const { formatMessage: _ } = useIntl() - const [userData] = useState(clientAppSettings.getUserData()) - const [signOutRedirect] = useState(clientAppSettings.getSignOutRedirect()) const [reInitializationLoading, setReInitializationLoading] = useState(false) const [initializationLoading, setInitializationLoading] = useState(false) - useImperativeHandle(ref, () => ({ - getSignOutMethod: () => - signOutRedirect({ - post_logout_redirect_uri: window.location.origin, - }), - getUserData: () => userData, - })) - useEffect(() => { if (reInitialization && !reInitializationLoading) { setReInitializationLoading(true) - console.log('%c reInitializationProp start! ', 'background: #f0000; color: #bada55') reset(clientUrl, unauthorizedCallback) .then(() => { - console.log('%c reset done! ', 'background: #222; color: #bada55') setInitialize(false) setReInitializationLoading(false) }) .catch(() => {}) } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [reInitialization, clientUrl, id, setInitialize, wellKnownConfig?.isInitialized, reInitializationLoading, unauthorizedCallback]) + }, [reInitialization, clientUrl, setInitialize, reInitializationLoading, unauthorizedCallback]) useEffect(() => { if (wellKnownConfig && !wellKnownConfig.isInitialized && !initializationLoading) { @@ -66,7 +52,6 @@ const RemoteClientsAuthProvider = forwardRef((pro identityCertificateChallenge.certificateSigningRequest ).then((result) => { initializeFinal(identityCertificateChallenge.state, result.data.certificate).then(() => { - console.log('%c init done x509! ', 'background: #bada55; color: #1a1a1a') setInitialize(true) setInitializationLoading(false) }) @@ -85,7 +70,6 @@ const RemoteClientsAuthProvider = forwardRef((pro initializedByPreShared(preSharedSubjectId, preSharedKey) .then((r) => { if (r.status === 200) { - console.log('%c init done PSK! ', 'background: #bada55; color: #1a1a1a') setInitialize(true) setInitializationLoading(false) } @@ -123,7 +107,7 @@ const RemoteClientsAuthProvider = forwardRef((pro } return children -}) +} RemoteClientsAuthProvider.displayName = 'RemoteClientsAuthProvider' diff --git a/http-gateway/web/src/containers/RemoteClients/RemoteClientsAuthProvider/RemoteClientsAuthProvider.types.ts b/http-gateway/web/src/containers/RemoteClients/RemoteClientsAuthProvider/RemoteClientsAuthProvider.types.ts index 86f20fc96..e6529e9ef 100644 --- a/http-gateway/web/src/containers/RemoteClients/RemoteClientsAuthProvider/RemoteClientsAuthProvider.types.ts +++ b/http-gateway/web/src/containers/RemoteClients/RemoteClientsAuthProvider/RemoteClientsAuthProvider.types.ts @@ -3,11 +3,6 @@ import { ReactElement } from 'react' import { WellKnownConfigType } from '@shared-ui/common/hooks' import { RemoteClientType } from '@shared-ui/app/clientApp/RemoteClients/RemoteClients.types' -export type AppAuthProviderRefType = { - getSignOutMethod(): any - getUserData(): any -} - export type Props = { children: ReactElement clientData: RemoteClientType diff --git a/http-gateway/web/src/containers/RemoteClients/RemoteClientsPage/RemoteClientsPage.tsx b/http-gateway/web/src/containers/RemoteClients/RemoteClientsPage/RemoteClientsPage.tsx index d4d605132..230822f4f 100644 --- a/http-gateway/web/src/containers/RemoteClients/RemoteClientsPage/RemoteClientsPage.tsx +++ b/http-gateway/web/src/containers/RemoteClients/RemoteClientsPage/RemoteClientsPage.tsx @@ -1,4 +1,4 @@ -import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { FC, useCallback, useEffect, useMemo, useState } from 'react' import { useIntl } from 'react-intl' import { Helmet } from 'react-helmet' import jwtDecode from 'jwt-decode' @@ -18,7 +18,6 @@ import * as styles from './RemoteClientsPage.styles' import { messages as g } from '@/containers/Global.i18n' import { messages as t } from '../RemoteClients.i18n' import RemoteClientsAuthProvider from '@/containers/RemoteClients/RemoteClientsAuthProvider' -import { AppAuthProviderRefType } from '../RemoteClientsAuthProvider/RemoteClientsAuthProvider.types' const RemoteClientsPage: FC = (props) => { const { children } = props @@ -43,7 +42,6 @@ const RemoteClientsPage: FC = (props) => { const [authError, setAuthError] = useState(undefined) const [initializedByAnother, setInitializedByAnother] = useState(false) const [suspectedUnauthorized, setSuspectedUnauthorized] = useState(false) - const authProviderRef = useRef(null) const setInitialize = useCallback( (value = true) => { @@ -72,14 +70,15 @@ const RemoteClientsPage: FC = (props) => { [wellKnownConfig, clientData] ) - const unCompareOwners = useCallback((wellKnownConfig?: WellKnownConfigType) => { - const userData = clientAppSettings.getUserData() + const differentOwner = useCallback((wellKnownConfig?: WellKnownConfigType) => { if (!wellKnownConfig?.isInitialized) { return false } - if (userData && wellKnownConfig) { - const parsedData = jwtDecode(userData.access_token) + const accessToken = security.getAccessToken() + + if (accessToken && wellKnownConfig) { + const parsedData = jwtDecode(accessToken) const ownerId = get(parsedData, wellKnownConfig?.remoteProvisioning?.jwtOwnerClaim as string, '') if (ownerId !== wellKnownConfig?.owner) { @@ -91,22 +90,26 @@ const RemoteClientsPage: FC = (props) => { }, []) useEffect(() => { - if (wellKnownConfig && unCompareOwners(wellKnownConfig) && !initializedByAnother) { + clientAppSettings.setUseToken(!differentOwner(wellKnownConfig) && clientData.authenticationMode === DEVICE_AUTH_MODE.X509) + }, [wellKnownConfig, clientData.authenticationMode, differentOwner]) + + useEffect(() => { + if (wellKnownConfig && differentOwner(wellKnownConfig) && !initializedByAnother) { setInitializedByAnother(true) } - }, [unCompareOwners, initializedByAnother, wellKnownConfig]) + }, [differentOwner, initializedByAnother, wellKnownConfig]) const unauthorizedCallback = useCallback(() => { setSuspectedUnauthorized(true) reFetchConfig().then((newWellKnownConfig: WellKnownConfigType) => { - if (!unCompareOwners(newWellKnownConfig)) { - setSuspectedUnauthorized(false) - } else { + if (differentOwner(newWellKnownConfig)) { setInitializedByAnother(true) + } else { + setSuspectedUnauthorized(false) } }) - }, [unCompareOwners, reFetchConfig]) + }, [differentOwner, reFetchConfig]) const contextValue = useMemo( () => ({ @@ -127,7 +130,6 @@ const RemoteClientsPage: FC = (props) => { return } else { clientAppSettings.setWellKnowConfig(wellKnownConfig) - clientAppSettings.setUseToken(!unCompareOwners(wellKnownConfig) && clientData.authenticationMode === DEVICE_AUTH_MODE.X509) if (wellKnownConfig.remoteProvisioning) { clientAppSettings.setWebOAuthConfig({ @@ -153,7 +155,6 @@ const RemoteClientsPage: FC = (props) => {