diff --git a/src/dashboard/Notification/EmailVerification.react.js b/src/dashboard/Notification/EmailVerification.react.js index c3a06cc6c..0efa65586 100644 --- a/src/dashboard/Notification/EmailVerification.react.js +++ b/src/dashboard/Notification/EmailVerification.react.js @@ -108,7 +108,10 @@ class EmailVerification extends DashboardView { canEditAllProperties: false, canChangeEmailTemplate: false, hasPermission: true, + emailVerified: false, isUserVerified: false, + isResendingVerificationEmail: false, + resendVerificationMessage: null, alertValidationCreditCard: false, errorMessage: null, allEmailSettings: null, @@ -210,14 +213,21 @@ class EmailVerification extends DashboardView { async loadEmailSettings() { try { const data = await this.context.getEmailSettings(); - const { emailSettings, preventLoginWithUnverifiedEmail, canChangeEmailTemplate, featuresPermission, isPaidPlan, userVerification } = data; - + const { + emailSettings, + preventLoginWithUnverifiedEmail, + canChangeEmailTemplate, + featuresPermission, + isPaidPlan, + userVerification = {}, + } = data; + + const emailVerified = !!userVerification.emailVerified; const isUserVerified = isPaidPlan || ( - userVerification.emailVerified && - userVerification.phoneNumberVerified && - userVerification.cardValidation + emailVerified && + !!userVerification.cardValidation ); - const alertValidationCreditCard = !isPaidPlan && (!userVerification || !userVerification.cardValidation); + const alertValidationCreditCard = !userVerification.cardValidation; const hasPermission = !featuresPermission || featuresPermission.verificationEmails === 'Write'; const canEditAllProperties = !!(emailSettings && emailSettings.canEditAllProperties); @@ -236,6 +246,7 @@ class EmailVerification extends DashboardView { canEditAllProperties, canChangeEmailTemplate: !!canChangeEmailTemplate, hasPermission, + emailVerified, isUserVerified, alertValidationCreditCard, errorMessage: null, @@ -249,15 +260,57 @@ class EmailVerification extends DashboardView { } } + async handleResendEmailVerification() { + if (this.state.isResendingVerificationEmail) { + return; + } + + this.setState({ + isResendingVerificationEmail: true, + resendVerificationMessage: null, + }); + + try { + const result = await this.context.resendEmailVerification(); + this.setState({ + isResendingVerificationEmail: false, + resendVerificationMessage: { + type: 'success', + text: typeof result === 'string' && result.trim() + ? result + : 'Verification email sent.', + }, + }); + } catch (err) { + this.setState({ + isResendingVerificationEmail: false, + resendVerificationMessage: { + type: 'error', + text: getLoadErrorMessage(err, 'Failed to resend verification email'), + }, + }); + } + } + renderForm({ fields, setField }) { - const { canChangeEmailTemplate, isUserVerified, hasPermission } = this.state; - const canEditBasicFields = isUserVerified && hasPermission; - const canEditTemplateFields = canEditBasicFields && canChangeEmailTemplate; + const { + canChangeEmailTemplate, + emailVerified, + isUserVerified, + hasPermission, + alertValidationCreditCard, + isResendingVerificationEmail, + resendVerificationMessage, + } = this.state; + const canEditVerificationSettings = emailVerified && !alertValidationCreditCard && hasPermission; + const canAccessTemplateSection = isUserVerified && hasPermission; + const canEditTemplateFields = canAccessTemplateSection && canChangeEmailTemplate; const replyToTrimmed = (fields.replyTo || '').trim(); const replyToInvalid = canEditTemplateFields && (!replyToTrimmed || !validateEmailFormat(replyToTrimmed)); - const showTemplateUpgradeCta = isUserVerified && hasPermission && !canEditTemplateFields; + const showTemplateUpgradeCta = canAccessTemplateSection && !canEditTemplateFields; + const showVerificationAlert = !emailVerified; const trackSetField = (key, value) => { setField(key, value); @@ -271,15 +324,9 @@ class EmailVerification extends DashboardView { return (
- {!isUserVerified && ( -
- Please verify your account to manage email settings. -
- )} - {!hasPermission && (
You do not have permission to edit email verification settings.
@@ -287,9 +334,70 @@ class EmailVerification extends DashboardView {
-
+ {showVerificationAlert && ( +
+ Please verify your account to manage email settings.{' '} + + {resendVerificationMessage && ( +
+ {resendVerificationMessage.text} +
+ )} +
+ )} + + {alertValidationCreditCard && ( +
+ + } + input={ + + } + theme={Field.Theme.BLUE} + /> +
+ )} + +
- canEditBasicFields && trackSetField('verificationEmailEnaled', value) + canEditVerificationSettings && trackSetField('verificationEmailEnaled', value) } - disabled={!canEditBasicFields} + disabled={!canEditVerificationSettings} />
} @@ -329,9 +437,9 @@ class EmailVerification extends DashboardView { additionalStyles={{ margin: '6px 0px' }} value={fields.verificationEmailEnaled ? fields.preventLoginWithUnverifiedEmail : false} onChange={value => - canEditBasicFields && trackSetField('preventLoginWithUnverifiedEmail', value) + canEditVerificationSettings && trackSetField('preventLoginWithUnverifiedEmail', value) } - disabled={!canEditBasicFields || !fields.verificationEmailEnaled} + disabled={!canEditVerificationSettings || !fields.verificationEmailEnaled} />
} @@ -343,138 +451,140 @@ class EmailVerification extends DashboardView {
-
Email templates and sender
-
- Customize reply-to, display name, and verification email content. Requires a plan that includes - customizable email templates. -
- - {showTemplateUpgradeCta && ( -
- - } - input={ -
- -
- } - theme={Field.Theme.BLUE} - /> -
- )} - -
-
- - } - input={ -
- - canEditTemplateFields && trackSetField('replyTo', getInputValue(valueOrEvent)) - } - disabled={!canEditTemplateFields} - error={replyToInvalid} +
+
Email templates and sender
+
+ Customize reply-to, display name, and verification email content. Requires a plan that includes + customizable email templates. +
+ + {showTemplateUpgradeCta && ( +
+ -
- } - textAlign="right" - theme={Field.Theme.BLUE} - /> - - } - input={ -
- - canEditTemplateFields && trackSetField('displayName', getInputValue(valueOrEvent)) - } - disabled={!canEditTemplateFields} + } + input={ +
+ +
+ } + theme={Field.Theme.BLUE} + /> +
+ )} + +
+
+ -
- } - textAlign="right" - theme={Field.Theme.BLUE} - /> - - } - input={ -
- - canEditTemplateFields && trackSetField('verificationEmailSubject', getInputValue(valueOrEvent)) - } - disabled={!canEditTemplateFields} + } + input={ +
+ + canEditTemplateFields && trackSetField('replyTo', getInputValue(valueOrEvent)) + } + disabled={!canEditTemplateFields} + error={replyToInvalid} + /> +
+ } + textAlign="right" + theme={Field.Theme.BLUE} + /> + -
- } - textAlign="right" - theme={Field.Theme.BLUE} - /> - - } - input={ -
- - canEditTemplateFields && trackSetField('verificationEmailBody', getInputValue(valueOrEvent)) - } - disabled={!canEditTemplateFields} + } + input={ +
+ + canEditTemplateFields && trackSetField('displayName', getInputValue(valueOrEvent)) + } + disabled={!canEditTemplateFields} + /> +
+ } + textAlign="right" + theme={Field.Theme.BLUE} + /> + -
- } - textAlign="right" - theme={Field.Theme.BLUE} - /> - + } + input={ +
+ + canEditTemplateFields && trackSetField('verificationEmailSubject', getInputValue(valueOrEvent)) + } + disabled={!canEditTemplateFields} + /> +
+ } + textAlign="right" + theme={Field.Theme.BLUE} + /> + + } + input={ +
+ + canEditTemplateFields && trackSetField('verificationEmailBody', getInputValue(valueOrEvent)) + } + disabled={!canEditTemplateFields} + /> +
+ } + textAlign="right" + theme={Field.Theme.BLUE} + /> + +
@@ -486,7 +596,7 @@ class EmailVerification extends DashboardView { const toolbar = ( ); - const { isLoading, initialFields, errorMessage, hasPermission, isUserVerified, canChangeEmailTemplate } = this.state; + const { isLoading, initialFields, errorMessage, hasPermission, emailVerified, isUserVerified, canChangeEmailTemplate } = this.state; const fieldsOptions = { verificationEmailEnaled: { friendlyName: 'enable verification emails', showTo: true }, @@ -583,7 +693,7 @@ class EmailVerification extends DashboardView { /> )} footerContents={({ changes }) => { - if (!hasPermission || !isUserVerified) { + if (!hasPermission || !emailVerified) { return null; } return renderChangedValuesFooter(changes, fieldsOptions); diff --git a/src/lib/ParseApp.js b/src/lib/ParseApp.js index 9443288c8..bb3ca2ee3 100644 --- a/src/lib/ParseApp.js +++ b/src/lib/ParseApp.js @@ -2023,7 +2023,7 @@ export default class ParseApp { async resendEmailVerification() { try { return ( - await axios.post( + await axios.get( // eslint-disable-next-line no-undef `${b4aSettings.BACK4APP_API_PATH}/email-verification/resend`, { withCredentials: true }