From 0ad2b14dccbc5b058c7bbca4e35759c77f3211b7 Mon Sep 17 00:00:00 2001 From: dvoet Date: Mon, 3 Feb 2025 16:15:15 -0500 Subject: [PATCH 1/2] CORE-299 don't do b2c signout when there is no user (#5242) --- src/auth/oidc-broker.ts | 1 + src/auth/signout/sign-out.test.ts | 21 ++++++++++++++++++++- src/auth/signout/sign-out.ts | 14 ++++++++++---- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/auth/oidc-broker.ts b/src/auth/oidc-broker.ts index 1d72c01235..acf2893757 100644 --- a/src/auth/oidc-broker.ts +++ b/src/auth/oidc-broker.ts @@ -40,6 +40,7 @@ export const getOidcConfig = () => { // Leo's setCookie interval is currently 5 min, set refresh auth then 5 min 30 seconds to guarantee that setCookie's token won't expire between 2 setCookie api calls accessTokenExpiringNotificationTimeInSeconds: 330, includeIdTokenInSilentRenew: true, + includeIdTokenInSilentSignout: true, extraQueryParams: { access_type: 'offline' }, redirect_uri: '', // this field is not being used currently, but is expected from UserManager }; diff --git a/src/auth/signout/sign-out.test.ts b/src/auth/signout/sign-out.test.ts index 465e3d8b4d..99fedd85d7 100644 --- a/src/auth/signout/sign-out.test.ts +++ b/src/auth/signout/sign-out.test.ts @@ -52,6 +52,7 @@ jest.mock('src/libs/state', (): StateExports => { get: jest.fn().mockReturnValue({ userManager: { signoutRedirect: jest.fn(() => 'Default signOutRedirectFn'), + getUser: jest.fn().mockReturnValue('not null'), }, }), }, @@ -91,7 +92,7 @@ describe('sign-out', () => { const link = '/signout'; const expectedState = btoa(JSON.stringify({ signOutRedirect: currentRoute, signOutCause: 'unspecified' })); asMockedFn(oidcStore.get).mockReturnValue({ - userManager: { signoutRedirect: signOutRedirectFn }, + userManager: { signoutRedirect: signOutRedirectFn, getUser: jest.fn().mockReturnValue('not null') }, } as unknown as OidcState); asMockedFn(leoCookieProvider.unsetCookies).mockImplementation(unsetCookiesFn); asMockedFn(Nav.getPath).mockReturnValue(link); @@ -116,6 +117,7 @@ describe('sign-out', () => { asMockedFn(oidcStore.get).mockReturnValue({ userManager: { signoutRedirect: signOutRedirectFn, + getUser: jest.fn().mockReturnValue('not null'), }, } as unknown as OidcState); asMockedFn(removeUserFromLocalState).mockImplementation(removeUserFromLocalStateFn); @@ -131,4 +133,21 @@ describe('sign-out', () => { expect(removeUserFromLocalStateFn).toHaveBeenCalled(); expect(goToRootFn).toHaveBeenCalledWith('root'); }); + it('calls userSignedOut if getUser returns null', async () => { + // Arrange + const removeUserFromLocalStateFn = jest.fn(); + const goToRootFn = jest.fn(); + asMockedFn(oidcStore.get).mockReturnValue({ + userManager: { + getUser: jest.fn().mockReturnValue(null), + }, + } as unknown as OidcState); + asMockedFn(removeUserFromLocalState).mockImplementation(removeUserFromLocalStateFn); + asMockedFn(goToPath).mockImplementation(goToRootFn); + // Act + await doSignOut(); + // Assert + expect(removeUserFromLocalStateFn).toHaveBeenCalled(); + expect(goToRootFn).toHaveBeenCalledWith('root'); + }); }); diff --git a/src/auth/signout/sign-out.ts b/src/auth/signout/sign-out.ts index 3198c89a13..b369ba0a70 100644 --- a/src/auth/signout/sign-out.ts +++ b/src/auth/signout/sign-out.ts @@ -47,10 +47,16 @@ export const doSignOut = async (signOutCause: SignOutCause = 'unspecified'): Pro const { name, query, params }: SignOutRedirect = Nav.getCurrentRoute(); const signOutState: SignOutState = { signOutRedirect: { name, query, params }, signOutCause }; const encodedState = btoa(JSON.stringify(signOutState)); - userManager!.signoutRedirect({ - post_logout_redirect_uri: redirectUrl, - extraQueryParams: { state: encodedState }, - }); + const user = await userManager!.getUser(); + if (user) { + userManager!.signoutRedirect({ + post_logout_redirect_uri: redirectUrl, + extraQueryParams: { state: encodedState }, + }); + } else { + userSignedOut(signOutCause, true); + Nav.goToPath('root'); + } } catch (e: unknown) { console.error('Signing out with B2C failed. Falling back on local signout', e); userSignedOut(signOutCause, true); From 0381840db53455d97183d3b930e980a081c3ea6b Mon Sep 17 00:00:00 2001 From: Kevin Marete <49183352+kevinmarete@users.noreply.github.com> Date: Tue, 4 Feb 2025 10:37:36 -0500 Subject: [PATCH 2/2] [CORE-283] Disable user suggestions in sharing modals (#5245) --- src/groups/Members/EmailSelect.tsx | 1 + src/groups/Members/NewMemberModal.tsx | 4 +++- src/workspaces/ShareWorkspaceModal/ShareWorkspaceModal.tsx | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/groups/Members/EmailSelect.tsx b/src/groups/Members/EmailSelect.tsx index b93e397a7c..0f114d7104 100644 --- a/src/groups/Members/EmailSelect.tsx +++ b/src/groups/Members/EmailSelect.tsx @@ -74,6 +74,7 @@ export const EmailSelect: React.FC = ({ onBlur={handleOnBlur} onChange={handleOnChange} height={200} + noOptionsMessage={() => null} /> ); diff --git a/src/groups/Members/NewMemberModal.tsx b/src/groups/Members/NewMemberModal.tsx index baa0cb648a..1065fd2508 100644 --- a/src/groups/Members/NewMemberModal.tsx +++ b/src/groups/Members/NewMemberModal.tsx @@ -44,6 +44,8 @@ export const NewMemberModal = (props: NewMemberModalProps) => { const signal = useCancellation(); + const enableShareLog = false; // Set "true" to enable suggestions + useOnMount(() => { const loadData = withErrorReporting('Error looking up collaborators')(async () => { const [shareSuggestions, groups] = await Promise.all([Workspaces(signal).getShareLog(), Groups(signal).list()]); @@ -52,7 +54,7 @@ export const NewMemberModal = (props: NewMemberModalProps) => { setSuggestions(suggestions); }); - loadData(); + enableShareLog && loadData(); }); const submit = async () => { diff --git a/src/workspaces/ShareWorkspaceModal/ShareWorkspaceModal.tsx b/src/workspaces/ShareWorkspaceModal/ShareWorkspaceModal.tsx index 25a9c5cd91..84f58296dc 100644 --- a/src/workspaces/ShareWorkspaceModal/ShareWorkspaceModal.tsx +++ b/src/workspaces/ShareWorkspaceModal/ShareWorkspaceModal.tsx @@ -59,6 +59,8 @@ const ShareWorkspaceModal: React.FC = (props: ShareWor const signal = useCancellation(); + const enableShareLog = false; // Set "true" to enable suggestions + // Lifecycle useOnMount(() => { const load = async () => { @@ -100,7 +102,7 @@ const ShareWorkspaceModal: React.FC = (props: ShareWor _.uniq )(groups); - const remainingSuggestions = _.difference(suggestions, _.map('email', acl)); + const remainingSuggestions = enableShareLog ? _.difference(suggestions, _.map('email', acl)) : []; const addUserReminder = 'Did you mean to add collaborators? Add them or clear the "User emails" field to save changes.';