Skip to content

Commit 834e88c

Browse files
committed
fix(sync): Always send firefox.fxaLogout on sign out
Because: * If users are signed into the browser but they've accessed account settings in a non-Sync context, the browser holds onto the old session token, leading to a 'Session Expired' page when they try to access CAD or account settings from the browser This commit: * Removes the isSync() check around the firefox.fxaLogout call
1 parent 6a04b30 commit 834e88c

File tree

7 files changed

+23
-65
lines changed

7 files changed

+23
-65
lines changed

packages/fxa-settings/src/components/Settings/AppLayout/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,20 @@ import HeaderLockup from '../HeaderLockup';
77
import ContentSkip from '../ContentSkip';
88
import Footer from 'fxa-react/components/Footer';
99
import { AlertBar } from '../AlertBar';
10-
import { SettingsIntegration } from '../interfaces';
1110

1211
type AppLayoutProps = {
1312
children: React.ReactNode;
14-
integration: SettingsIntegration;
1513
};
1614

17-
export const AppLayout = ({ children, integration }: AppLayoutProps) => {
15+
export const AppLayout = ({ children }: AppLayoutProps) => {
1816
return (
1917
<div
2018
className="flex flex-col justify-between min-h-screen"
2119
data-testid="app"
2220
>
2321
<ContentSkip />
2422
<div id="body-top" className="hidden mobileLandscape:block" />
25-
<HeaderLockup {...{ integration }} />
23+
<HeaderLockup />
2624
<div className="max-w-screen-desktopXl flex-1 w-full mx-auto tablet:px-20 desktop:px-12">
2725
<main id="main" data-testid="main" className="w-full">
2826
<AlertBar />

packages/fxa-settings/src/components/Settings/DropDownAvatarMenu/index.stories.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { withLocalization } from 'fxa-react/lib/storybooks';
88
import DropDownAvatarMenu from '.';
99
import { Account, AppContext } from 'fxa-settings/src/models';
1010
import { mockAppContext, MOCK_ACCOUNT } from 'fxa-settings/src/models/mocks';
11-
import { createMockSettingsIntegration } from '../mocks';
1211

1312
export default {
1413
title: 'Components/Settings/DropDownAvatarMenu',
@@ -35,14 +34,12 @@ const accountWithoutAvatar = {
3534
},
3635
} as unknown as Account;
3736

38-
const integration = createMockSettingsIntegration();
39-
4037
const storyWithContext = (account: Partial<Account>) => {
4138
const context = { account: account as Account };
4239

4340
const story = () => (
4441
<AppContext.Provider value={mockAppContext(context)}>
45-
<DropDownAvatarMenu {...{ integration }} />
42+
<DropDownAvatarMenu />
4643
</AppContext.Provider>
4744
);
4845
return story;
@@ -51,6 +48,4 @@ const storyWithContext = (account: Partial<Account>) => {
5148
export const DefaultNoAvatarOrDisplayName =
5249
storyWithContext(accountWithoutAvatar);
5350

54-
export const WithAvatarAndDisplayName = () => (
55-
<DropDownAvatarMenu {...{ integration }} />
56-
);
51+
export const WithAvatarAndDisplayName = () => <DropDownAvatarMenu />;

packages/fxa-settings/src/components/Settings/DropDownAvatarMenu/index.test.tsx

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import DropDownAvatarMenu from '.';
1414
import { logViewEvent, settingsViewName } from 'fxa-settings/src/lib/metrics';
1515
import { Account, AppContext } from '../../../models';
1616
import { SettingsContext } from '../../../models/contexts/SettingsContext';
17-
import { createMockSettingsIntegration } from '../mocks';
1817
import firefox from '../../../lib/channels/firefox';
1918

2019
jest.mock('../../../models/AlertBarInfo');
@@ -48,7 +47,7 @@ describe('DropDownAvatarMenu', () => {
4847
} as unknown as Account;
4948
renderWithLocalizationProvider(
5049
<AppContext.Provider value={mockAppContext({ account })}>
51-
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
50+
<DropDownAvatarMenu />
5251
</AppContext.Provider>
5352
);
5453

@@ -75,7 +74,7 @@ describe('DropDownAvatarMenu', () => {
7574
it('renders as expected with avatar url and displayName set', () => {
7675
renderWithLocalizationProvider(
7776
<AppContext.Provider value={mockAppContext({ account })}>
78-
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
77+
<DropDownAvatarMenu />
7978
</AppContext.Provider>
8079
);
8180
fireEvent.click(screen.getByTestId('drop-down-avatar-menu-toggle'));
@@ -87,7 +86,7 @@ describe('DropDownAvatarMenu', () => {
8786
it('closes on esc keypress', () => {
8887
renderWithLocalizationProvider(
8988
<AppContext.Provider value={mockAppContext({ account })}>
90-
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
89+
<DropDownAvatarMenu />
9190
</AppContext.Provider>
9291
);
9392

@@ -102,7 +101,7 @@ describe('DropDownAvatarMenu', () => {
102101
<AppContext.Provider value={mockAppContext({ account })}>
103102
<div className="w-full flex justify-end">
104103
<div className="flex pr-10 pt-4">
105-
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
104+
<DropDownAvatarMenu />
106105
</div>
107106
</div>
108107
</AppContext.Provider>
@@ -127,7 +126,7 @@ describe('DropDownAvatarMenu', () => {
127126
<AppContext.Provider
128127
value={mockAppContext({ account, session: mockSession() })}
129128
>
130-
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
129+
<DropDownAvatarMenu />
131130
</AppContext.Provider>
132131
);
133132

@@ -153,7 +152,7 @@ describe('DropDownAvatarMenu', () => {
153152
renderWithLocalizationProvider(
154153
<AppContext.Provider value={context}>
155154
<SettingsContext.Provider value={settingsContext}>
156-
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
155+
<DropDownAvatarMenu />
157156
</SettingsContext.Provider>
158157
</AppContext.Provider>
159158
);
@@ -174,14 +173,12 @@ describe('DropDownAvatarMenu', () => {
174173
afterEach(() => {
175174
jest.restoreAllMocks();
176175
});
177-
it('is called integration is sync', async () => {
176+
it('is called', async () => {
178177
renderWithLocalizationProvider(
179178
<AppContext.Provider
180179
value={mockAppContext({ account, session: mockSession() })}
181180
>
182-
<DropDownAvatarMenu
183-
integration={createMockSettingsIntegration({ isSync: true })}
184-
/>
181+
<DropDownAvatarMenu />
185182
</AppContext.Provider>
186183
);
187184
fireEvent.click(screen.getByTestId('drop-down-avatar-menu-toggle'));
@@ -190,20 +187,5 @@ describe('DropDownAvatarMenu', () => {
190187
});
191188
expect(fxaLogoutSpy).toBeCalledWith({ uid: account.uid });
192189
});
193-
194-
it('is not called when integration is not sync', async () => {
195-
renderWithLocalizationProvider(
196-
<AppContext.Provider
197-
value={mockAppContext({ account, session: mockSession() })}
198-
>
199-
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
200-
</AppContext.Provider>
201-
);
202-
fireEvent.click(screen.getByTestId('drop-down-avatar-menu-toggle'));
203-
await act(async () => {
204-
fireEvent.click(screen.getByTestId('avatar-menu-sign-out'));
205-
});
206-
expect(fxaLogoutSpy).not.toBeCalled();
207-
});
208190
});
209191
});

packages/fxa-settings/src/components/Settings/DropDownAvatarMenu/index.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,8 @@ import { ReactComponent as SignOut } from './sign-out.svg';
1111
import { logViewEvent, settingsViewName } from '../../../lib/metrics';
1212
import { Localized, useLocalization } from '@fluent/react';
1313
import firefox from '../../../lib/channels/firefox';
14-
import { SettingsIntegration } from '../interfaces';
1514

16-
export const DropDownAvatarMenu = ({
17-
integration,
18-
}: {
19-
integration: SettingsIntegration;
20-
}) => {
15+
export const DropDownAvatarMenu = () => {
2116
const { displayName, primaryEmail, avatar, uid } = useAccount();
2217
const session = useSession();
2318
const [isRevealed, setRevealed] = useState(false);
@@ -39,9 +34,10 @@ export const DropDownAvatarMenu = ({
3934
try {
4035
await session.destroy();
4136

42-
if (integration.isSync()) {
43-
firefox.fxaLogout({ uid });
44-
}
37+
// Send a logout event to Firefox even if the user is in a non-Sync flow.
38+
// If the user is signed into the browser, they need to drop the now
39+
// destroyed session token.
40+
firefox.fxaLogout({ uid });
4541

4642
logViewEvent(settingsViewName, 'signout.success');
4743
window.location.assign(window.location.origin);

packages/fxa-settings/src/components/Settings/HeaderLockup/index.stories.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { withLocalization } from 'fxa-react/lib/storybooks';
88
import { HeaderLockup } from '.';
99
import { Account, AppContext } from '../../../models';
1010
import { mockAppContext, MOCK_ACCOUNT } from 'fxa-settings/src/models/mocks';
11-
import { createMockSettingsIntegration } from '../mocks';
1211

1312
export default {
1413
title: 'Components/Settings/HeaderLockup',
@@ -26,19 +25,17 @@ const accountWithoutAvatar = {
2625
},
2726
} as unknown as Account;
2827

29-
const integration = createMockSettingsIntegration();
30-
3128
const storyWithContext = (account: Partial<Account>) => {
3229
const context = { account: account as Account };
3330

3431
const story = () => (
3532
<AppContext.Provider value={mockAppContext(context)}>
36-
<HeaderLockup {...{ integration }} />
33+
<HeaderLockup />
3734
</AppContext.Provider>
3835
);
3936
return story;
4037
};
4138

4239
export const WithDefaultAvatar = storyWithContext(accountWithoutAvatar);
4340

44-
export const WithCustomAvatar = () => <HeaderLockup {...{ integration }} />;
41+
export const WithCustomAvatar = () => <HeaderLockup />;

packages/fxa-settings/src/components/Settings/HeaderLockup/index.test.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import React from 'react';
66
import { screen } from '@testing-library/react';
77
import { renderWithLocalizationProvider } from 'fxa-react/lib/test-utils/localizationProvider';
88
import HeaderLockup from '.';
9-
import { createMockSettingsIntegration } from '../mocks';
109
import { userEvent } from '@testing-library/user-event';
1110
import GleanMetrics from '../../../lib/glean';
1211

@@ -21,9 +20,7 @@ jest.mock('../../../lib/glean', () => ({
2120

2221
describe('HeaderLockup', () => {
2322
it('renders as expected', () => {
24-
renderWithLocalizationProvider(
25-
<HeaderLockup integration={createMockSettingsIntegration()} />
26-
);
23+
renderWithLocalizationProvider(<HeaderLockup />);
2724
const headerMenu = screen.getByTestId('header-menu');
2825

2926
expect(
@@ -45,9 +42,7 @@ describe('HeaderLockup', () => {
4542
});
4643

4744
it('emits Glean event on help link click', async () => {
48-
renderWithLocalizationProvider(
49-
<HeaderLockup integration={createMockSettingsIntegration()} />
50-
);
45+
renderWithLocalizationProvider(<HeaderLockup />);
5146
await userEvent.click(screen.getByRole('link', { name: 'Help' }));
5247
expect(GleanMetrics.accountPref.help).toHaveBeenCalled();
5348
});

packages/fxa-settings/src/components/Settings/HeaderLockup/index.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,10 @@ import DropDownAvatarMenu from '../DropDownAvatarMenu';
1212
import { ReactComponent as Help } from './help.svg';
1313
import { ReactComponent as Menu } from './menu.svg';
1414
import { ReactComponent as Close } from './close.svg';
15-
import { SettingsIntegration } from '../interfaces';
1615
import Sidebar from '../Sidebar';
1716
import GleanMetrics from '../../../lib/glean';
1817

19-
export const HeaderLockup = ({
20-
integration,
21-
}: {
22-
integration: SettingsIntegration;
23-
}) => {
18+
export const HeaderLockup = () => {
2419
const [sidebarRevealedState, setNavState] = useState(false);
2520
const { l10n } = useLocalization();
2621
const localizedHelpText = l10n.getString('header-help', null, 'Help');
@@ -87,7 +82,7 @@ export const HeaderLockup = ({
8782
/>
8883
</LinkExternal>
8984
<BentoMenu />
90-
<DropDownAvatarMenu {...{ integration }} />
85+
<DropDownAvatarMenu />
9186
</>
9287
);
9388

0 commit comments

Comments
 (0)