From d8897fac3feb5163d2b68c3284c211b941c25a82 Mon Sep 17 00:00:00 2001 From: kkatusic Date: Mon, 18 Nov 2024 14:59:48 +0100 Subject: [PATCH] added confirmation flow for use inputed code --- src/resolvers/userResolver.ts | 99 ++++++++++++++++++++++++++++++++++- src/utils/errorMessages.ts | 2 + src/utils/locales/en.json | 4 +- src/utils/locales/es.json | 4 +- 4 files changed, 106 insertions(+), 3 deletions(-) diff --git a/src/resolvers/userResolver.ts b/src/resolvers/userResolver.ts index 5eee77bb7..1f931f5f0 100644 --- a/src/resolvers/userResolver.ts +++ b/src/resolvers/userResolver.ts @@ -233,6 +233,33 @@ export class UserResolver { return true; } + /** + * Mutation to handle the process of sending a user email confirmation code. + * + * This function performs the following steps: + * 1. **Retrieve Logged-In User**: Fetches the currently logged-in user using the context (`ctx`). + * 2. **Check Email Verification Status**: + * - If the user's email is already verified, it throws an error with an appropriate message. + * 3. **Check for Email Usage**: + * - Verifies if the provided email is already in use by another user in the database. + * - If the email exists and belongs to a different user, it returns `'EMAIL_EXIST'`. + * 4. **Generate Verification Code**: + * - Creates a random 5-digit numeric code for email verification. + * - Updates the logged-in user's email verification code and email in the database. + * 5. **Send Verification Code**: + * - Uses the notification adapter to send the generated verification code to the provided email. + * 6. **Save User Record**: + * - Saves the updated user information (email and verification code) to the database. + * 7. **Return Status**: + * - If the verification code is successfully sent, it returns `'VERIFICATION_SENT'`. + * + * @param {string} email - The email address to verify. + * @param {ApolloContext} ctx - The GraphQL context containing user and other relevant information. + * @returns {Promise} - A status string indicating the result of the operation: + * - `'EMAIL_EXIST'`: The email is already used by another user. + * - `'VERIFICATION_SENT'`: The verification code has been sent successfully. + * @throws {Error} - If the user's email is already verified. + */ @Mutation(_returns => String) async sendUserEmailConfirmationCodeFlow( @Arg('email') email: string, @@ -240,7 +267,7 @@ export class UserResolver { ): Promise { const user = await getLoggedInUser(ctx); - // Check if email aready veriffied + // Check if email aready verified if (user.isEmailVerified) { throw new Error( i18n.__(translationErrorMessagesKeys.USER_EMAIL_ALREADY_VERIFIED), @@ -260,12 +287,82 @@ export class UserResolver { const code = generateRandomNumericCode(5).toString(); user.emailVerificationCode = code; + user.email = email; await getNotificationAdapter().sendUserEmailConfirmationCodeFlow({ email: email, user: user, }); + await user.save(); + return 'VERIFICATION_SENT'; } + + /** + * Mutation to handle the user confirmation code verification process. + * + * This function performs the following steps: + * 1. **Retrieve Logged-In User**: Fetches the currently logged-in user using the provided context (`ctx`). + * 2. **Check Email Verification Status**: + * - If the user's email is already verified, an error is thrown with an appropriate message. + * 3. **Verify Email Verification Code Presence**: + * - Checks if the user has a stored email verification code in the database. + * - If no code exists, an error is thrown indicating that the code was not found. + * 4. **Validate the Verification Code**: + * - Compares the provided `verifyCode` with the user's stored email verification code. + * - If the codes do not match, an error is thrown indicating the mismatch. + * 5. **Mark Email as Verified**: + * - If the verification code matches, the user's `emailVerificationCode` is cleared (set to `null`), + * and the `isEmailVerified` flag is set to `true`. + * 6. **Save Updated User Data**: + * - The updated user record (email verified status) is saved to the database. + * 7. **Return Status**: + * - Returns `'VERIFICATION_SUCCESS'` to indicate the email verification was completed successfully. + * + * @param {string} verifyCode - The verification code submitted by the user for validation. + * @param {ApolloContext} ctx - The GraphQL context containing the logged-in user's information. + * @returns {Promise} - A status string indicating the result of the verification process: + * - `'VERIFICATION_SUCCESS'`: The email has been successfully verified. + * @throws {Error} - If: + * - The user's email is already verified. + * - No verification code is found in the database for the user. + * - The provided verification code does not match the stored code. + */ + @Mutation(_returns => String) + async sendUserConfirmationCodeFlow( + @Arg('verifyCode') verifyCode: string, + @Ctx() ctx: ApolloContext, + ): Promise { + const user = await getLoggedInUser(ctx); + + // Check if email aready verified + if (user.isEmailVerified) { + throw new Error( + i18n.__(translationErrorMessagesKeys.USER_EMAIL_ALREADY_VERIFIED), + ); + } + + // Check do we have an email verification code inside database + if (!user.emailVerificationCode) { + throw new Error( + i18n.__(translationErrorMessagesKeys.USER_EMAIL_CODE_NOT_FOUND), + ); + } + + // Check if code matches + if (verifyCode !== user.emailVerificationCode) { + throw new Error( + i18n.__(translationErrorMessagesKeys.USER_EMAIL_CODE_NOT_MATCH), + ); + } + + // Save Updated User Data + user.emailVerificationCode = null; + user.isEmailVerified = true; + + await user.save(); + + return 'VERIFICATION_SUCCESS'; + } } diff --git a/src/utils/errorMessages.ts b/src/utils/errorMessages.ts index 0fc4b1ee7..fcc19882a 100644 --- a/src/utils/errorMessages.ts +++ b/src/utils/errorMessages.ts @@ -380,4 +380,6 @@ export const translationErrorMessagesKeys = { 'DRAFT_DONATION_CANNOT_BE_MARKED_AS_FAILED', QR_CODE_DATA_URL_REQUIRED: 'QR_CODE_DATA_URL_REQUIRED', USER_EMAIL_ALREADY_VERIFIED: 'USER_EMAIL_ALREADY_VERIFIED', + USER_EMAIL_CODE_NOT_FOUND: 'USER_EMAIL_CODE_NOT_FOUND', + USER_EMAIL_CODE_NOT_MATCH: 'USER_EMAIL_CODE_NOT_MATCH', }; diff --git a/src/utils/locales/en.json b/src/utils/locales/en.json index 1647cff6a..108888ae4 100644 --- a/src/utils/locales/en.json +++ b/src/utils/locales/en.json @@ -118,5 +118,7 @@ "PROJECT_DOESNT_ACCEPT_RECURRING_DONATION": "PROJECT_DOESNT_ACCEPT_RECURRING_DONATION", "Project does not accept recurring donation": "Project does not accept recurring donation", "QR_CODE_DATA_URL_REQUIRED": "QR_CODE_DATA_URL_REQUIRED", - "USER_EMAIL_ALREADY_VERIFIED": "User email already verified" + "USER_EMAIL_ALREADY_VERIFIED": "User email already verified", + "USER_EMAIL_CODE_NOT_FOUND": "User email verification code not found", + "USER_EMAIL_CODE_NOT_MATCH": "User email verification code not match" } diff --git a/src/utils/locales/es.json b/src/utils/locales/es.json index ca78b3b4e..2ce294b8d 100644 --- a/src/utils/locales/es.json +++ b/src/utils/locales/es.json @@ -107,5 +107,7 @@ "DRAFT_DONATION_DISABLED": "El borrador de donación está deshabilitado", "EVM_SUPPORT_ONLY": "Solo se admite EVM", "EVM_AND_STELLAR_SUPPORT_ONLY": "Solo se admite EVM y Stellar", - "USER_EMAIL_ALREADY_VERIFIED": "El correo electrónico del usuario ya está verificado" + "USER_EMAIL_ALREADY_VERIFIED": "El correo electrónico del usuario ya está verificado", + "USER_EMAIL_CODE_NOT_FOUND": "Código de verificación de correo electrónico de usuario no encontrado", + "USER_EMAIL_CODE_NOT_MATCH": "El código de verificación del correo electrónico del usuario no coincide" }