Skip to content

Commit

Permalink
Merge pull request #18029 from mozilla/session-expired-fix
Browse files Browse the repository at this point in the history
fix(sync): Always send firefox.fxaLogout on sign out
  • Loading branch information
LZoog authored Nov 16, 2024
2 parents 3ad136a + 2a4e264 commit ea8f8b1
Show file tree
Hide file tree
Showing 23 changed files with 67 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { LocationProvider } from '@reach/router';
import FormPassword from '.';
import { Meta } from '@storybook/react';
import { withLocalization } from 'fxa-react/lib/storybooks';
import { MockSettingsAppLayout } from '../Settings/SettingsLayout/mocks';
import SettingsLayout from '../Settings/SettingsLayout';

export default {
title: 'Components/FormPassword',
Expand All @@ -17,20 +17,20 @@ export default {
} as Meta;
export const WithCurrentPassword = () => (
<LocationProvider>
<MockSettingsAppLayout>
<SettingsLayout>
<div className="max-w-lg mx-auto">
<Subject />
</div>
</MockSettingsAppLayout>
</SettingsLayout>
</LocationProvider>
);

export const WithoutCurrentPassword = () => (
<LocationProvider>
<MockSettingsAppLayout>
<SettingsLayout>
<div className="max-w-lg mx-auto">
<Subject includeCurrentPw={false} />
</div>
</MockSettingsAppLayout>
</SettingsLayout>
</LocationProvider>
);
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { withLocalization } from 'fxa-react/lib/storybooks';
import DropDownAvatarMenu from '.';
import { Account, AppContext } from 'fxa-settings/src/models';
import { mockAppContext, MOCK_ACCOUNT } from 'fxa-settings/src/models/mocks';
import { createMockSettingsIntegration } from '../mocks';

export default {
title: 'Components/Settings/DropDownAvatarMenu',
Expand All @@ -35,14 +34,12 @@ const accountWithoutAvatar = {
},
} as unknown as Account;

const integration = createMockSettingsIntegration();

const storyWithContext = (account: Partial<Account>) => {
const context = { account: account as Account };

const story = () => (
<AppContext.Provider value={mockAppContext(context)}>
<DropDownAvatarMenu {...{ integration }} />
<DropDownAvatarMenu />
</AppContext.Provider>
);
return story;
Expand All @@ -51,6 +48,4 @@ const storyWithContext = (account: Partial<Account>) => {
export const DefaultNoAvatarOrDisplayName =
storyWithContext(accountWithoutAvatar);

export const WithAvatarAndDisplayName = () => (
<DropDownAvatarMenu {...{ integration }} />
);
export const WithAvatarAndDisplayName = () => <DropDownAvatarMenu />;
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import DropDownAvatarMenu from '.';
import { logViewEvent, settingsViewName } from 'fxa-settings/src/lib/metrics';
import { Account, AppContext } from '../../../models';
import { SettingsContext } from '../../../models/contexts/SettingsContext';
import { createMockSettingsIntegration } from '../mocks';
import firefox from '../../../lib/channels/firefox';
import { PLACEHOLDER_IMAGE_URL } from '../../../pages/mocks';

Expand Down Expand Up @@ -49,7 +48,7 @@ describe('DropDownAvatarMenu', () => {
} as unknown as Account;
renderWithLocalizationProvider(
<AppContext.Provider value={mockAppContext({ account })}>
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
<DropDownAvatarMenu />
</AppContext.Provider>
);

Expand All @@ -76,7 +75,7 @@ describe('DropDownAvatarMenu', () => {
it('renders as expected with avatar url and displayName set', () => {
renderWithLocalizationProvider(
<AppContext.Provider value={mockAppContext({ account })}>
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
<DropDownAvatarMenu />
</AppContext.Provider>
);
fireEvent.click(screen.getByTestId('drop-down-avatar-menu-toggle'));
Expand All @@ -88,7 +87,7 @@ describe('DropDownAvatarMenu', () => {
it('closes on esc keypress', () => {
renderWithLocalizationProvider(
<AppContext.Provider value={mockAppContext({ account })}>
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
<DropDownAvatarMenu />
</AppContext.Provider>
);

Expand All @@ -103,7 +102,7 @@ describe('DropDownAvatarMenu', () => {
<AppContext.Provider value={mockAppContext({ account })}>
<div className="w-full flex justify-end">
<div className="flex pr-10 pt-4">
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
<DropDownAvatarMenu />
</div>
</div>
</AppContext.Provider>
Expand All @@ -128,7 +127,7 @@ describe('DropDownAvatarMenu', () => {
<AppContext.Provider
value={mockAppContext({ account, session: mockSession() })}
>
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
<DropDownAvatarMenu />
</AppContext.Provider>
);

Expand All @@ -154,7 +153,7 @@ describe('DropDownAvatarMenu', () => {
renderWithLocalizationProvider(
<AppContext.Provider value={context}>
<SettingsContext.Provider value={settingsContext}>
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
<DropDownAvatarMenu />
</SettingsContext.Provider>
</AppContext.Provider>
);
Expand All @@ -175,14 +174,12 @@ describe('DropDownAvatarMenu', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('is called integration is sync', async () => {
it('is called', async () => {
renderWithLocalizationProvider(
<AppContext.Provider
value={mockAppContext({ account, session: mockSession() })}
>
<DropDownAvatarMenu
integration={createMockSettingsIntegration({ isSync: true })}
/>
<DropDownAvatarMenu />
</AppContext.Provider>
);
fireEvent.click(screen.getByTestId('drop-down-avatar-menu-toggle'));
Expand All @@ -191,20 +188,5 @@ describe('DropDownAvatarMenu', () => {
});
expect(fxaLogoutSpy).toBeCalledWith({ uid: account.uid });
});

it('is not called when integration is not sync', async () => {
renderWithLocalizationProvider(
<AppContext.Provider
value={mockAppContext({ account, session: mockSession() })}
>
<DropDownAvatarMenu integration={createMockSettingsIntegration()} />
</AppContext.Provider>
);
fireEvent.click(screen.getByTestId('drop-down-avatar-menu-toggle'));
await act(async () => {
fireEvent.click(screen.getByTestId('avatar-menu-sign-out'));
});
expect(fxaLogoutSpy).not.toBeCalled();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,8 @@ import { ReactComponent as SignOut } from './sign-out.svg';
import { logViewEvent, settingsViewName } from '../../../lib/metrics';
import { Localized, useLocalization } from '@fluent/react';
import firefox from '../../../lib/channels/firefox';
import { SettingsIntegration } from '../interfaces';

export const DropDownAvatarMenu = ({
integration,
}: {
integration: SettingsIntegration;
}) => {
export const DropDownAvatarMenu = () => {
const { displayName, primaryEmail, avatar, uid } = useAccount();
const session = useSession();
const [isRevealed, setRevealed] = useState(false);
Expand All @@ -39,9 +34,10 @@ export const DropDownAvatarMenu = ({
try {
await session.destroy();

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

logViewEvent(settingsViewName, 'signout.success');
window.location.assign(window.location.origin);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Account, AppContext, useFtlMsgResolver } from '../../../models';
import { MOCK_ACCOUNT, mockAppContext } from '../../../models/mocks';
import { AuthUiErrors } from '../../../lib/auth-errors/auth-errors';
import { withLocalization } from 'fxa-react/lib/storybooks';
import { MockSettingsAppLayout } from '../SettingsLayout/mocks';
import SettingsLayout from '../SettingsLayout';

export default {
title: 'Components/Settings/FlowRecoveryKeyConfirmPwd',
Expand Down Expand Up @@ -76,7 +76,7 @@ const StoryWithContext = (account: Account) => {

return (
<AppContext.Provider value={mockAppContext({ account })}>
<MockSettingsAppLayout>
<SettingsLayout>
<FlowRecoveryKeyConfirmPwd
{...{
localizedBackButtonTitle,
Expand All @@ -87,7 +87,7 @@ const StoryWithContext = (account: Account) => {
viewName,
}}
/>
</MockSettingsAppLayout>
</SettingsLayout>
</AppContext.Provider>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { withLocalization } from 'fxa-react/lib/storybooks';
import { HeaderLockup } from '.';
import { Account, AppContext } from '../../../models';
import { mockAppContext, MOCK_ACCOUNT } from 'fxa-settings/src/models/mocks';
import { createMockSettingsIntegration } from '../mocks';

export default {
title: 'Components/Settings/HeaderLockup',
Expand All @@ -26,19 +25,17 @@ const accountWithoutAvatar = {
},
} as unknown as Account;

const integration = createMockSettingsIntegration();

const storyWithContext = (account: Partial<Account>) => {
const context = { account: account as Account };

const story = () => (
<AppContext.Provider value={mockAppContext(context)}>
<HeaderLockup {...{ integration }} />
<HeaderLockup />
</AppContext.Provider>
);
return story;
};

export const WithDefaultAvatar = storyWithContext(accountWithoutAvatar);

export const WithCustomAvatar = () => <HeaderLockup {...{ integration }} />;
export const WithCustomAvatar = () => <HeaderLockup />;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import React from 'react';
import { screen } from '@testing-library/react';
import { renderWithLocalizationProvider } from 'fxa-react/lib/test-utils/localizationProvider';
import HeaderLockup from '.';
import { createMockSettingsIntegration } from '../mocks';
import { userEvent } from '@testing-library/user-event';
import GleanMetrics from '../../../lib/glean';

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

describe('HeaderLockup', () => {
it('renders as expected', () => {
renderWithLocalizationProvider(
<HeaderLockup integration={createMockSettingsIntegration()} />
);
renderWithLocalizationProvider(<HeaderLockup />);
const headerMenu = screen.getByTestId('header-menu');

expect(
Expand All @@ -45,9 +42,7 @@ describe('HeaderLockup', () => {
});

it('emits Glean event on help link click', async () => {
renderWithLocalizationProvider(
<HeaderLockup integration={createMockSettingsIntegration()} />
);
renderWithLocalizationProvider(<HeaderLockup />);
await userEvent.click(screen.getByRole('link', { name: 'Help' }));
expect(GleanMetrics.accountPref.help).toHaveBeenCalled();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,10 @@ import DropDownAvatarMenu from '../DropDownAvatarMenu';
import { ReactComponent as Help } from './help.svg';
import { ReactComponent as Menu } from './menu.svg';
import { ReactComponent as Close } from './close.svg';
import { SettingsIntegration } from '../interfaces';
import Sidebar from '../Sidebar';
import GleanMetrics from '../../../lib/glean';

export const HeaderLockup = ({
integration,
}: {
integration: SettingsIntegration;
}) => {
export const HeaderLockup = () => {
const [sidebarRevealedState, setNavState] = useState(false);
const { l10n } = useLocalization();
const localizedHelpText = l10n.getString('header-help', null, 'Help');
Expand Down Expand Up @@ -87,7 +82,7 @@ export const HeaderLockup = ({
/>
</LinkExternal>
<BentoMenu />
<DropDownAvatarMenu {...{ integration }} />
<DropDownAvatarMenu />
</>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Page2faReplaceRecoveryCodes } from '.';
import { Meta } from '@storybook/react';
import { LocationProvider } from '@reach/router';
import { withLocalization } from 'fxa-react/lib/storybooks';
import { MockSettingsAppLayout } from '../SettingsLayout/mocks';
import SettingsLayout from '../SettingsLayout';

const session = mockSession(true);
const account = {
Expand Down Expand Up @@ -41,9 +41,9 @@ export default {
export const Default = () => (
<LocationProvider>
<AppContext.Provider value={mockAppContext({ account, session })}>
<MockSettingsAppLayout>
<SettingsLayout>
<Page2faReplaceRecoveryCodes />
</MockSettingsAppLayout>
</SettingsLayout>
</AppContext.Provider>
</LocationProvider>
);
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { LocationProvider } from '@reach/router';
import { Meta } from '@storybook/react';
import PageAvatar from './';
import { withLocalization } from 'fxa-react/lib/storybooks';
import { MockSettingsAppLayout } from '../SettingsLayout/mocks';
import SettingsLayout from '../SettingsLayout';

export default {
title: 'Pages/Settings/Avatar',
Expand All @@ -17,8 +17,8 @@ export default {

export const Default = () => (
<LocationProvider>
<MockSettingsAppLayout>
<SettingsLayout>
<PageAvatar />
</MockSettingsAppLayout>
</SettingsLayout>
</LocationProvider>
);
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { PageChangePassword } from '.';
import { LocationProvider } from '@reach/router';
import { Meta } from '@storybook/react';
import { withLocalization } from 'fxa-react/lib/storybooks';
import { MockSettingsAppLayout } from '../SettingsLayout/mocks';
import SettingsLayout from '../SettingsLayout';

export default {
title: 'Pages/Settings/ChangePassword',
Expand All @@ -17,8 +17,8 @@ export default {

export const Default = () => (
<LocationProvider>
<MockSettingsAppLayout>
<SettingsLayout>
<PageChangePassword />
</MockSettingsAppLayout>
</SettingsLayout>
</LocationProvider>
);
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import React from 'react';
import { LocationProvider } from '@reach/router';
import { Meta } from '@storybook/react';
import { withLocalization } from 'fxa-react/lib/storybooks';
import { MockSettingsAppLayout } from '../SettingsLayout/mocks';
import SettingsLayout from '../SettingsLayout';

export default {
title: 'Pages/Settings/CreatePassword',
Expand All @@ -17,8 +17,8 @@ export default {

export const Default = () => (
<LocationProvider>
<MockSettingsAppLayout>
<SettingsLayout>
<PageCreatePassword />
</MockSettingsAppLayout>
</SettingsLayout>
</LocationProvider>
);
Loading

0 comments on commit ea8f8b1

Please sign in to comment.