From e045f498a8b12501bb90806fc49cac75a9ec6884 Mon Sep 17 00:00:00 2001 From: seavor Date: Mon, 20 Apr 2026 00:03:29 -0500 Subject: [PATCH] fix knownhosts issue --- .../src/components/KnownHosts/KnownHosts.tsx | 2 -- webclient/src/containers/Login/Login.spec.tsx | 22 ++++++++++++++++++- webclient/src/forms/LoginForm/LoginForm.tsx | 22 ++++++++++++++++++- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/webclient/src/components/KnownHosts/KnownHosts.tsx b/webclient/src/components/KnownHosts/KnownHosts.tsx index 416de9875..de2e7b57c 100644 --- a/webclient/src/components/KnownHosts/KnownHosts.tsx +++ b/webclient/src/components/KnownHosts/KnownHosts.tsx @@ -86,8 +86,6 @@ const KnownHosts = (props: any) => { webClient.request.authentication.testConnection({ ...getHostPort(host) }); }; - // Mirror the store's selectedHost into the form field. Also kick off a - // connection test so the user sees the green/red indicator on mount. useEffect(() => { if (!selectedHost) { return; diff --git a/webclient/src/containers/Login/Login.spec.tsx b/webclient/src/containers/Login/Login.spec.tsx index 63c1d475e..3ba49352d 100644 --- a/webclient/src/containers/Login/Login.spec.tsx +++ b/webclient/src/containers/Login/Login.spec.tsx @@ -1,4 +1,4 @@ -import { act, waitFor } from '@testing-library/react'; +import { act, fireEvent, waitFor } from '@testing-library/react'; import { renderWithProviders, createMockWebClient, disconnectedState } from '../../__test-utils__'; @@ -166,6 +166,26 @@ describe('Login — logout cycle (same JS session)', () => { await flushEffects(); expect(hoisted.mockWebClient.request.authentication.login).not.toHaveBeenCalled(); }); + + test('submits with the restored host after a logout→remount without Required error', async () => { + const first = renderWithProviders(, { preloadedState: disconnectedState }); + await flushEffects(); + first.unmount(); + + const { getByRole, queryByText } = renderWithProviders(, { + preloadedState: disconnectedState, + }); + await flushEffects(); + + fireEvent.click(getByRole('button', { name: /LoginForm\.label\.login/ })); + await flushEffects(); + + expect(queryByText(/required/i)).toBeNull(); + expect(hoisted.mockWebClient.request.authentication.login).toHaveBeenCalledTimes(1); + expect(hoisted.mockWebClient.request.authentication.login.mock.calls[0][0]).toMatchObject({ + userName: 'alice', + }); + }); }); describe('Login — refresh cycle', () => { diff --git a/webclient/src/forms/LoginForm/LoginForm.tsx b/webclient/src/forms/LoginForm/LoginForm.tsx index b09470f55..4152d45d3 100644 --- a/webclient/src/forms/LoginForm/LoginForm.tsx +++ b/webclient/src/forms/LoginForm/LoginForm.tsx @@ -174,6 +174,8 @@ const LoginFormBody = ({ const LoginForm = (props: LoginFormProps) => { const { t } = useTranslation(); + const knownHosts = useKnownHosts(); + const settings = useSettings(); const validate = (values: any) => { const errors: any = {}; @@ -193,8 +195,26 @@ const LoginForm = (props: LoginFormProps) => { props.onSubmit({ userName, ...values }); }; + if (knownHosts.status !== LoadingState.READY || settings.status !== LoadingState.READY) { + return null; + } + + const selectedHost = knownHosts.value?.selectedHost; + const initialValues = { + selectedHost, + userName: selectedHost?.userName ?? '', + remember: Boolean(selectedHost?.remember), + autoConnect: Boolean(settings.value?.autoConnect), + password: '', + }; + return ( -
+ {({ handleSubmit, form }) => ( )}