fix: keep the pairing QR on screen while the Security tab checks the server

This commit is contained in:
Linus Rath
2026-09-27 04:18:09 +02:00
parent 1446fd39dc
commit 96e0e6b036
2 changed files with 18 additions and 1 deletions
@@ -453,6 +453,20 @@ describe('AccountSecuritySettings link-device visibility', () => {
expect(screen.queryByText('email_client.title')).toBeNull();
});
it('mounts the linker only once the server probe has a verdict', () => {
// A layout guessed before the verdict remounted the linker afterwards and
// threw away a QR that was already showing.
useAuthStore.setState({ isAuthenticated: true, authMode: 'oauth', client: null });
useAccountSecurityStore.setState({ isStalwart: null, isProbing: false });
const { rerender } = render(<AccountSecuritySettings />);
expect(screen.queryByText('link_device.title')).toBeNull();
expect(screen.getByText('detecting')).toBeInTheDocument();
act(() => useAccountSecurityStore.setState({ isStalwart: false }));
rerender(<AccountSecuritySettings />);
expect(screen.getByText('link_device.title')).toBeInTheDocument();
});
it('hides the linker in Bulwark Lite', () => {
mocks.lite.value = true;
useAccountSecurityStore.setState({ isStalwart: false, isProbing: false });
@@ -1451,7 +1451,10 @@ export function AccountSecuritySettings() {
}
}, [isAuthenticated, client, isStalwart, probe, fetchAll, fetchAuthInfo, isOAuth, fetchPublicKeys, fetchCryptoInfo]);
if (isProbing) {
// Until the probe has a verdict, show the spinner instead of guessing a
// layout: switching layouts remounts every section below, which threw away
// a pairing QR that was already on screen.
if (isProbing || (isStalwart === null && isAuthenticated)) {
return (
<SettingsSection title={t('title')} description={t('description')}>
<div className="flex items-center gap-2 py-4">