Skip to content

Commit

Permalink
Merge branch '10553-bug' into 10553-bug-test
Browse files Browse the repository at this point in the history
  • Loading branch information
nechama-krigsman committed Dec 4, 2024
2 parents 27d3d50 + 0f7d774 commit 4625fa0
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 134 deletions.
5 changes: 2 additions & 3 deletions shared/src/proxies/users/verifyUserPendingEmailProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ import { put } from '../requests';
*/
export const verifyUserPendingEmailInteractor = (
applicationContext,
{ clientConnectionId, token }: { clientConnectionId: string; token: string },
{ token }: { token: string },
): Promise<void> => {
return put({
applicationContext,
body: {
clientConnectionId,
token,
},
endpoint: '/async/users/verify-email',
endpoint: '/users/verify-email',
});
};
5 changes: 1 addition & 4 deletions web-api/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1034,10 +1034,7 @@ app.delete(
lambdaWrapper(getUserPendingEmailStatusLambda),
);
app.put('/users/pending-email', lambdaWrapper(updateUserPendingEmailLambda));
app.put(
'/async/users/verify-email',
lambdaWrapper(verifyUserPendingEmailLambda, { isAsync: true }),
);
app.put('/users/verify-email', lambdaWrapper(verifyUserPendingEmailLambda));
app.get(
'/users/email-availability',
lambdaWrapper(checkEmailAvailabilityLambda),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
isAuthorized,
} from '../../../../../shared/src/authorization/authorizationClientService';
import { ServerApplicationContext } from '@web-api/applicationContext';
import { UnauthorizedError } from '@web-api/errors/errors';
import { UnknownAuthUser } from '@shared/business/entities/authUser/AuthUser';
import {
calculateDifferenceInHours,
Expand All @@ -29,21 +30,11 @@ export const userTokenHasExpired = (

export const verifyUserPendingEmailInteractor = async (
applicationContext: ServerApplicationContext,
{ clientConnectionId, token }: { token: string; clientConnectionId: string },
{ token }: { token: string },
authorizedUser: UnknownAuthUser,
): Promise<void> => {
if (!isAuthorized(authorizedUser, ROLE_PERMISSIONS.EMAIL_MANAGEMENT)) {
return await applicationContext
.getNotificationGateway()
.sendNotificationToUser({
applicationContext,
clientConnectionId,
message: {
action: 'set_verify_email_notification',
message: 'Unauthorized to manage emails',
},
userId: (authorizedUser as UnknownAuthUser)?.userId!,
});
throw new UnauthorizedError('Unauthorized to manage emails.');
}

const user = await applicationContext
Expand All @@ -61,35 +52,14 @@ export const verifyUserPendingEmailInteractor = async (
'Unable to verify pending email, either the user clicked the verify link twice or their verification token did not match',
{ email: authorizedUser.email },
);
return await applicationContext
.getNotificationGateway()
.sendNotificationToUser({
applicationContext,
clientConnectionId,
message: {
action: 'set_verify_email_notification',
message: 'Tokens do not match',
},
userId: user.userId,
});
throw new UnauthorizedError('Tokens do not match');
}

if (userTokenHasExpired(user.pendingEmailVerificationTokenTimestamp)) {
applicationContext.logger.info('Pending email verification link expired', {
email: authorizedUser.email,
});
return await applicationContext
.getNotificationGateway()
.sendNotificationToUser({
applicationContext,
clientConnectionId,
message: {
action: 'set_verify_email_notification',
message: 'Link has expired',
messageType: 'expiredToken',
},
userId: user.userId,
});
throw new UnauthorizedError('Link has expired');
}

const isEmailAvailable = await applicationContext
Expand All @@ -100,17 +70,7 @@ export const verifyUserPendingEmailInteractor = async (
});

if (!isEmailAvailable) {
return await applicationContext
.getNotificationGateway()
.sendNotificationToUser({
applicationContext,
clientConnectionId,
message: {
action: 'set_verify_email_notification',
message: 'Email is not available',
},
userId: user.userId,
});
throw new Error('Email is not available');
}

const { updatedUser } = await updateUserPendingEmailRecord(
Expand Down Expand Up @@ -170,17 +130,4 @@ export const verifyUserPendingEmailInteractor = async (
user: updatedUser,
});
}

return await applicationContext
.getNotificationGateway()
.sendNotificationToUser({
applicationContext,
clientConnectionId,
message: {
action: 'set_verify_email_notification',
message: 'Email has been updated',
messageType: 'success',
},
userId: user.userId,
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const setInitialVerifyAlertMessageAction = () => {
return {
alertInfo: {
message: 'DAWSON is updating your email. Please wait.',
title: 'Updating email address',
},
};
};
89 changes: 44 additions & 45 deletions web-client/src/presenter/actions/verifyUserPendingEmailAction.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { TROUBLESHOOTING_INFO } from '@shared/business/entities/EntityConstants';
import { state } from '@web-client/presenter/app.cerebral';
import React from 'react';

const successAlertMessage = {
message: 'Your email address is verified. You can now log in to DAWSON.',
title: 'Email address verified',
};

const expiredTokenAlertError = {
message: (
<>
Expand All @@ -17,6 +11,21 @@ const expiredTokenAlertError = {
title: 'Verification email link expired',
};

const requestTimedOutAlertError = {
message: (
<>
Request timed out. This potentially means another process is currently
updating this user. Your request cannot be completed. Please try to log
in. If you’re still having trouble, contact{' '}
<a href={`mailto:${TROUBLESHOOTING_INFO.APP_SUPPORT_EMAIL}`}>
{TROUBLESHOOTING_INFO.APP_SUPPORT_EMAIL}
</a>
.
</>
),
title: 'Request Timed Out',
};

export const genericAlertError = {
message: (
<>
Expand All @@ -31,51 +40,41 @@ export const genericAlertError = {
title: 'Unable to complete your request',
};

type VerifyEmailNotificationType = 'success' | 'expiredToken';

const alertDictionary: { [key in VerifyEmailNotificationType]: any } = {
expiredToken: expiredTokenAlertError,
success: successAlertMessage,
};

const alertKeyDictionary: { [key in VerifyEmailNotificationType]: any } = {
expiredToken: 'alertWarning',
success: 'alertSuccess',
};

export const verifyUserPendingEmailAction = async ({
applicationContext,
get,
path,
props,
}: ActionProps<{ token: string }>) => {
const clientConnectionId = get(state.clientConnectionId);
const { token } = props;

await applicationContext
.getUseCases()
.verifyUserPendingEmailInteractor(applicationContext, {
clientConnectionId,
token,
});
try {
await applicationContext
.getUseCases()
.verifyUserPendingEmailInteractor(applicationContext, {
token,
});

return {
alertInfo: {
message: 'DAWSON is updating your email. Please wait.',
title: 'Updating email address',
},
};
};

export const setVerifyUserPendingEmailNotificationAction = ({
props,
store,
}: ActionProps<{ messageType: VerifyEmailNotificationType }>) => {
const { messageType } = props;
store.unset(state.alertWarning);
store.unset(state.alertSuccess);
store.unset(state.alertInfo);
return path.success({
alertSuccess: {
message:
'Your email address is verified. You can now log in to DAWSON.',
title: 'Email address verified',
},
});
} catch (e: any) {
if (e.message === 'Link has expired') {
return path.error({
alertError: expiredTokenAlertError,
});
}
if (e.message === 'Endpoint request timed out') {
return path.error({
alertError: requestTimedOutAlertError,
});
}

const KEY = alertKeyDictionary[messageType] || 'alertWarning';
const MESSAGE = alertDictionary[messageType] || genericAlertError;
store.set(state[KEY], MESSAGE);
return path.error({
alertError: genericAlertError,
});
}
};
2 changes: 0 additions & 2 deletions web-client/src/presenter/presenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,6 @@ import { setSelectedMessagesSequence } from './sequences/setSelectedMessagesSequ
import { setTrialSessionCalendarErrorSequence } from '@web-client/presenter/sequences/setTrialSessionCalendarErrorSequence';
import { setTrialSessionCalendarSequence } from './sequences/setTrialSessionCalendarSequence';
import { setTrialSessionsFiltersSequence } from '@web-client/presenter/sequences/setTrialSessionsFiltersSequence';
import { setVerifyEmailNotificationSequence } from '@web-client/presenter/sequences/setVerifyEmailNotificationSequence';
import { setViewerCorrespondenceToDisplaySequence } from './sequences/setViewerCorrespondenceToDisplaySequence';
import { setViewerDocumentToDisplaySequence } from './sequences/setViewerDocumentToDisplaySequence';
import { setViewerDraftDocumentToDisplaySequence } from './sequences/setViewerDraftDocumentToDisplaySequence';
Expand Down Expand Up @@ -1272,7 +1271,6 @@ export const presenterSequences = {
setTrialSessionCalendarErrorSequence,
setTrialSessionCalendarSequence,
setTrialSessionsFiltersSequence,
setVerifyEmailNotificationSequence,
setViewerCorrespondenceToDisplaySequence:
setViewerCorrespondenceToDisplaySequence as unknown as Function,
setViewerDocumentToDisplaySequence:
Expand Down
27 changes: 14 additions & 13 deletions web-client/src/presenter/sequences/gotoVerifyEmailSequence.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { clearUserAction } from '../actions/clearUserAction';
import { navigateToLoginAction } from '@web-client/presenter/actions/Login/navigateToLoginAction';
import { refreshTokenAction } from '@web-client/presenter/actions/Login/refreshTokenAction';
import { setAlertErrorAction } from '@web-client/presenter/actions/setAlertErrorAction';
import { setAlertInfoAction } from '@web-client/presenter/actions/setAlertInfoAction';
import { setNotLoggedInVerificationAction } from '@web-client/presenter/actions/setNotLoggedInVerificationAction';
import { startWebSocketConnectionSequenceDecorator } from '@web-client/presenter/utilities/startWebSocketConnectionSequenceDecorator';
import { setAlertSuccessAction } from '@web-client/presenter/actions/setAlertSuccessAction';
import { setInitialVerifyAlertMessageAction } from '@web-client/presenter/actions/setInitialVerifyAlertMessageAction';
import { verifyUserPendingEmailAction } from '../actions/verifyUserPendingEmailAction';

export const gotoVerifyEmailSequence =
startWebSocketConnectionSequenceDecorator([
refreshTokenAction,
{
userIsLoggedIn: [verifyUserPendingEmailAction, setAlertInfoAction],
userIsNotLoggedIn: [setNotLoggedInVerificationAction],
},
clearUserAction,
navigateToLoginAction,
]) as unknown as (props: { token: string }) => void;
export const gotoVerifyEmailSequence = [
setInitialVerifyAlertMessageAction,
setAlertInfoAction,
navigateToLoginAction,
verifyUserPendingEmailAction,
{
error: [setAlertErrorAction],
success: [setAlertSuccessAction],
},
clearUserAction,
] as unknown as (props: { token: string }) => void;

This file was deleted.

3 changes: 0 additions & 3 deletions web-client/src/providers/socketRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,6 @@ export const socketRouter = (app, onMessageCallbackFn?) => {
case 'download_csv_file':
await app.getSequence('downloadCsvFileSequence')(message);
break;
case 'set_verify_email_notification':
await app.getSequence('setVerifyEmailNotificationSequence')(message);
break;
}

(onMessageCallbackFn || noop)(message);
Expand Down

0 comments on commit 4625fa0

Please sign in to comment.