Fix: Reset password flow fails when user is signed in (#11811)

### Demo


https://github.com/user-attachments/assets/9589c7cc-f6ba-484a-b002-615c11a92729

Note: For the demo video, I hardcoded the email and manually set the
isTokenValid state to true.

Closes #11689

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: prastoin <paul@twenty.com>
This commit is contained in:
Abdul Rahman
2025-05-02 13:34:44 +05:30
committed by GitHub
parent 8c3a2d8640
commit 9df4778954
2 changed files with 52 additions and 41 deletions

View File

@ -98,7 +98,7 @@ const testCases: {
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' }, { loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' },
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' }, { loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' },
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' }, { loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' },
{ loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: '/objects/companies' }, { loc: AppPath.Invite, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: defaultHomePagePath },
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: '/plan-required' }, { loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: '/plan-required' },
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: '/settings/billing' }, { loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: '/settings/billing' },
@ -107,7 +107,7 @@ const testCases: {
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' }, { loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PROFILE_CREATION, res: '/create/profile' },
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' }, { loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SYNC_EMAIL, res: '/sync/emails' },
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' }, { loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.INVITE_TEAM, res: '/invite-team' },
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: '/objects/companies' }, { loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.COMPLETED, res: undefined },
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired }, { loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PLAN_REQUIRED, res: AppPath.PlanRequired },
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: '/settings/billing' }, { loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.COMPLETED, res: '/settings/billing' },
@ -266,21 +266,27 @@ const testCases: {
]; ];
describe('usePageChangeEffectNavigateLocation', () => { describe('usePageChangeEffectNavigateLocation', () => {
testCases.forEach((testCase) => { it.each(testCases)(
it(`with location ${testCase.loc} and onboardingStatus ${testCase.onboardingStatus} and isWorkspaceSuspended ${testCase.isWorkspaceSuspended} should return ${testCase.res}`, () => { 'with location $loc and onboardingStatus $onboardingStatus and isWorkspaceSuspended $isWorkspaceSuspended should return $res`',
setupMockIsMatchingLocation(testCase.loc); ({
setupMockOnboardingStatus(testCase.onboardingStatus); loc,
setupMockIsWorkspaceActivationStatusEqualsTo( onboardingStatus,
testCase.isWorkspaceSuspended, isWorkspaceSuspended,
); isLoggedIn,
setupMockIsLogged(testCase.isLoggedIn); objectNamePluralFromParams,
setupMockUseParams(testCase.objectNamePluralFromParams); objectNamePluralFromMetadata,
setupMockRecoil(testCase.objectNamePluralFromMetadata); res,
}) => {
expect(usePageChangeEffectNavigateLocation()).toEqual(testCase.res); setupMockIsMatchingLocation(loc);
}); setupMockOnboardingStatus(onboardingStatus);
}); setupMockIsWorkspaceActivationStatusEqualsTo(isWorkspaceSuspended);
setupMockIsLogged(isLoggedIn);
setupMockUseParams(objectNamePluralFromParams);
setupMockRecoil(objectNamePluralFromMetadata);
expect(usePageChangeEffectNavigateLocation()).toEqual(res);
},
);
describe('tests should be exhaustive', () => { describe('tests should be exhaustive', () => {
it('all location, onboarding status and suspended/not suspended workspace activation status should be tested', () => { it('all location, onboarding status and suspended/not suspended workspace activation status should be tested', () => {
expect(testCases.length).toEqual( expect(testCases.length).toEqual(

View File

@ -19,27 +19,24 @@ export const usePageChangeEffectNavigateLocation = () => {
const isWorkspaceSuspended = useIsWorkspaceActivationStatusEqualsTo( const isWorkspaceSuspended = useIsWorkspaceActivationStatusEqualsTo(
WorkspaceActivationStatus.SUSPENDED, WorkspaceActivationStatus.SUSPENDED,
); );
const { defaultHomePagePath } = useDefaultHomePagePath(); const { defaultHomePagePath } = useDefaultHomePagePath();
const isMatchingOpenRoute = const someMatchingLocationOf = (appPaths: AppPath[]): boolean =>
isMatchingLocation(AppPath.Invite) || appPaths.some((appPath) => isMatchingLocation(appPath));
isMatchingLocation(AppPath.ResetPassword); const onGoingUserCreationPaths = [
AppPath.Invite,
const isMatchingOngoingUserCreationRoute = AppPath.SignInUp,
isMatchingOpenRoute || AppPath.VerifyEmail,
isMatchingLocation(AppPath.SignInUp) || AppPath.Verify,
isMatchingLocation(AppPath.VerifyEmail) || ];
isMatchingLocation(AppPath.Verify); const onboardingPaths = [
AppPath.CreateWorkspace,
const isMatchingOnboardingRoute = AppPath.CreateProfile,
isMatchingOngoingUserCreationRoute || AppPath.SyncEmails,
isMatchingLocation(AppPath.CreateWorkspace) || AppPath.InviteTeam,
isMatchingLocation(AppPath.CreateProfile) || AppPath.PlanRequired,
isMatchingLocation(AppPath.SyncEmails) || AppPath.PlanRequiredSuccess,
isMatchingLocation(AppPath.InviteTeam) || ];
isMatchingLocation(AppPath.PlanRequired) ||
isMatchingLocation(AppPath.PlanRequiredSuccess);
const objectNamePlural = useParams().objectNamePlural ?? ''; const objectNamePlural = useParams().objectNamePlural ?? '';
const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
@ -47,14 +44,19 @@ export const usePageChangeEffectNavigateLocation = () => {
(objectMetadataItem) => objectMetadataItem.namePlural === objectNamePlural, (objectMetadataItem) => objectMetadataItem.namePlural === objectNamePlural,
); );
if (!isLoggedIn && !isMatchingOngoingUserCreationRoute) { if (
!isLoggedIn &&
!someMatchingLocationOf([
...onGoingUserCreationPaths,
AppPath.ResetPassword,
])
) {
return AppPath.SignInUp; return AppPath.SignInUp;
} }
if ( if (
onboardingStatus === OnboardingStatus.PLAN_REQUIRED && onboardingStatus === OnboardingStatus.PLAN_REQUIRED &&
!isMatchingLocation(AppPath.PlanRequired) && !someMatchingLocationOf([AppPath.PlanRequired, AppPath.PlanRequiredSuccess])
!isMatchingLocation(AppPath.PlanRequiredSuccess)
) { ) {
return AppPath.PlanRequired; return AppPath.PlanRequired;
} }
@ -67,8 +69,10 @@ export const usePageChangeEffectNavigateLocation = () => {
if ( if (
onboardingStatus === OnboardingStatus.WORKSPACE_ACTIVATION && onboardingStatus === OnboardingStatus.WORKSPACE_ACTIVATION &&
!isMatchingLocation(AppPath.CreateWorkspace) && !someMatchingLocationOf([
!isMatchingLocation(AppPath.PlanRequiredSuccess) AppPath.CreateWorkspace,
AppPath.PlanRequiredSuccess,
])
) { ) {
return AppPath.CreateWorkspace; return AppPath.CreateWorkspace;
} }
@ -96,7 +100,8 @@ export const usePageChangeEffectNavigateLocation = () => {
if ( if (
onboardingStatus === OnboardingStatus.COMPLETED && onboardingStatus === OnboardingStatus.COMPLETED &&
isMatchingOnboardingRoute && someMatchingLocationOf([...onboardingPaths, ...onGoingUserCreationPaths]) &&
!isMatchingLocation(AppPath.ResetPassword) &&
isLoggedIn isLoggedIn
) { ) {
return defaultHomePagePath; return defaultHomePagePath;