diff --git a/src/dashboard/Data/Browser/ImportDialog.react.js b/src/dashboard/Data/Browser/ImportDialog.react.js
index 78e4f2372f..6317dbeee8 100644
--- a/src/dashboard/Data/Browser/ImportDialog.react.js
+++ b/src/dashboard/Data/Browser/ImportDialog.react.js
@@ -34,7 +34,7 @@ export default class ImportDialog extends React.Component {
this.setState({ startedImport: false, file: undefined }));
}}>
diff --git a/src/dashboard/Data/Browser/ImportRelationDialog.react.js b/src/dashboard/Data/Browser/ImportRelationDialog.react.js
index 67604101c5..e77f9800f8 100644
--- a/src/dashboard/Data/Browser/ImportRelationDialog.react.js
+++ b/src/dashboard/Data/Browser/ImportRelationDialog.react.js
@@ -36,7 +36,7 @@ export default class ImportRelationDialog extends React.Component {
{this.state.startedImport ?
- We are importing your data. You will be notified by e-mail once it is completed.
: null }
+ We are importing your data. You will be notified by email once it is completed.
: null }
{this.state.errorMessage ?
Import Request failed with the following error: "{ this.state.errorMessage }".
: null }
diff --git a/src/dashboard/DomainSettings/DomainSettings.react.js b/src/dashboard/DomainSettings/DomainSettings.react.js
index cbb36dc13e..2a199bb810 100644
--- a/src/dashboard/DomainSettings/DomainSettings.react.js
+++ b/src/dashboard/DomainSettings/DomainSettings.react.js
@@ -24,9 +24,7 @@ import Fieldset from 'components/Fieldset/Fieldset.react';
import { amplitudeLogEvent } from 'lib/amplitudeEvents';
import B4aNotification from 'dashboard/Data/Browser/B4aNotification.react';
import browserStyles from 'dashboard/Data/Browser/Browser.scss';
-import StripeValidateCard from 'components/StripeValidateCard/StripeValidateCard.react';
import { Link } from 'react-router-dom';
-import back4app2 from 'lib/back4app2';
@withRouter
class DomainSettings extends DashboardView {
@@ -40,9 +38,12 @@ class DomainSettings extends DashboardView {
domainSettingsError: null,
isUserVerified: false,
+ emailVerified: false,
+ cardValidated: false,
+ isResendingVerificationEmail: false,
+ resendVerificationMessage: null,
canChangeCustomDomain: false,
canChangeSubdomain: false,
- showCardValidation: true,
subdomainName: '',
currentSubdomain: '',
@@ -96,10 +97,8 @@ class DomainSettings extends DashboardView {
}
async loadData() {
- console.log("STATE", this.state);
try {
const response = await this.context.getCustomDomain();
- console.log("RESPONSE", response);
this.setState({ domainSettings: response });
await this.loadHostSettings(response);
} catch (error) {
@@ -119,6 +118,10 @@ class DomainSettings extends DashboardView {
let isActivated = false;
let hasPermission = false;
let isUserVerified = false;
+ const currentUser = AccountManager.currentUser();
+ const verification = (currentUser && currentUser.verification) || {};
+ const emailVerified = !!verification.emailVerified;
+ const cardValidated = !!verification.cardValidation;
if (domains && domains.length > 0) {
customDomainArray = domains;
@@ -141,8 +144,6 @@ class DomainSettings extends DashboardView {
hasPermission = (!response.featuresPermission || response.featuresPermission.webHostLiveQuery === 'Write');
- console.log("response", createdAt);
-
if (response && ((appHostSettings.serverURL && appHostSettings.activated) || (createdAt && ((new Date() - new Date(createdAt)) > (6 * 30 * 24 * 60 * 60 * 1000))))) {
isUserVerified = true;
}
@@ -152,15 +153,11 @@ class DomainSettings extends DashboardView {
const plan = await this.context.getAppPlanData();
if (plan && plan.planName && (plan.planName.indexOf('Free') < 0) && (plan.planName.indexOf('Public') < 0)) {
isUserVerified = true;
- } else {
- const currentUser = AccountManager.currentUser();
- if (currentUser && currentUser.verification.cardValidation) {
- isUserVerified = true;
- }
+ } else if (emailVerified && cardValidated) {
+ isUserVerified = true;
}
} catch (planError) {
- const currentUser = AccountManager.currentUser();
- if (currentUser && currentUser.verification.cardValidation) {
+ if (emailVerified && cardValidated) {
isUserVerified = true;
}
}
@@ -168,6 +165,8 @@ class DomainSettings extends DashboardView {
this.setState({
isUserVerified,
+ emailVerified,
+ cardValidated,
subdomainName,
currentSubdomain,
@@ -296,17 +295,109 @@ class DomainSettings extends DashboardView {
}
}
- async verifyUser() {
+ async handleResendEmailVerification() {
+ if (this.state.isResendingVerificationEmail) {
+ return;
+ }
+
+ this.setState({
+ isResendingVerificationEmail: true,
+ resendVerificationMessage: null,
+ });
+
try {
- const user = await back4app2.me();
- if (user) {
- this.setState({ isUserVerified: true });
- }
- } catch (e) {
- console.log('user validation failed!')
+ 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: typeof err === 'string' && err.trim()
+ ? err
+ : (err && err.message) || 'Failed to resend verification email',
+ },
+ });
}
}
+ renderVerificationRequired() {
+ const { emailVerified, cardValidated, isResendingVerificationEmail, resendVerificationMessage } = this.state;
+
+ return (
+ <>
+ {!emailVerified && (
+
+ Please verify your email to enable this feature.{' '}
+
+ {resendVerificationMessage && (
+
+ {resendVerificationMessage.text}
+
+ )}
+
+ )}
+
+ {!cardValidated && (
+
+ )}
+ >
+ );
+ }
+
getDisplayContent() {
let content = null;
@@ -527,6 +618,8 @@ class DomainSettings extends DashboardView {
{this.state.errorCustomDomain && {this.state.errorCustomDomain}
}
>
+ } else {
+ content = this.renderVerificationRequired();
}
return (
diff --git a/src/dashboard/Notification/EmailVerification.react.js b/src/dashboard/Notification/EmailVerification.react.js
index 0efa655862..a4d6c5f2e8 100644
--- a/src/dashboard/Notification/EmailVerification.react.js
+++ b/src/dashboard/Notification/EmailVerification.react.js
@@ -21,7 +21,7 @@ import { amplitudeLogEvent } from 'lib/amplitudeEvents';
const DEFAULT_VERIFICATION_BODY =
'Hi,\n\n' +
- 'You are being asked to confirm the e-mail address *|email|* with *|appname|*\n\n' +
+ 'You are being asked to confirm the email address *|email|* with *|appname|*\n\n' +
'Click here to confirm it:\n' +
'*|link|*';
@@ -30,7 +30,7 @@ const DEFAULT_FIELDS = {
preventLoginWithUnverifiedEmail: false,
replyTo: 'no-reply@b4a.app',
displayName: '',
- verificationEmailSubject: 'Please verify your e-mail for *|appname|*',
+ verificationEmailSubject: 'Please verify your email for *|appname|*',
verificationEmailBody: DEFAULT_VERIFICATION_BODY,
};
@@ -379,7 +379,7 @@ class EmailVerification extends DashboardView {
input={
@@ -546,7 +546,7 @@ class EmailVerification extends DashboardView {
input={
canEditTemplateFields && trackSetField('verificationEmailSubject', getInputValue(valueOrEvent))
diff --git a/src/dashboard/ServerURLLiveQuery/ServerURLLiveQuery.react.js b/src/dashboard/ServerURLLiveQuery/ServerURLLiveQuery.react.js
index 49eb02c9d8..723425246d 100644
--- a/src/dashboard/ServerURLLiveQuery/ServerURLLiveQuery.react.js
+++ b/src/dashboard/ServerURLLiveQuery/ServerURLLiveQuery.react.js
@@ -45,6 +45,10 @@ class ServerURLLiveQuery extends DashboardView {
loadingError: null,
isUserVerified: false,
+ emailVerified: false,
+ cardValidated: false,
+ isResendingVerificationEmail: false,
+ resendVerificationMessage: null,
hasPermission: true,
isActivated: false,
@@ -182,6 +186,10 @@ class ServerURLLiveQuery extends DashboardView {
let activated = false;
let isActivated = false;
let isUserVerified = false;
+ const currentUser = AccountManager.currentUser();
+ const verification = (currentUser && currentUser.verification) || {};
+ const emailVerified = !!verification.emailVerified;
+ const cardValidated = !!verification.cardValidation;
const schemasChoose = {};
let activatedLiveQuery = {};
let statusLiveQuery = false;
@@ -224,15 +232,11 @@ class ServerURLLiveQuery extends DashboardView {
plan.planName.indexOf('Free') < 0 &&
plan.planName.indexOf('Public') < 0) {
isUserVerified = true;
- } else {
- const currentUser = AccountManager.currentUser();
- if (currentUser && currentUser.verification && currentUser.verification.cardValidation) {
- isUserVerified = true;
- }
+ } else if (emailVerified && cardValidated) {
+ isUserVerified = true;
}
} catch (planError) {
- const currentUser = AccountManager.currentUser();
- if (currentUser && currentUser.verification && currentUser.verification.cardValidation) {
+ if (emailVerified && cardValidated) {
isUserVerified = true;
}
}
@@ -240,6 +244,8 @@ class ServerURLLiveQuery extends DashboardView {
this.setState({
isUserVerified,
+ emailVerified,
+ cardValidated,
hasPermission,
isActivated,
currentSubdomain,
@@ -266,6 +272,116 @@ class ServerURLLiveQuery extends DashboardView {
return domain;
}
+ 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: typeof err === 'string' && err.trim()
+ ? err
+ : (err && err.message) || 'Failed to resend verification email',
+ },
+ });
+ }
+ }
+
+ renderVerificationRequired() {
+ const { emailVerified, cardValidated, isResendingVerificationEmail, resendVerificationMessage } = this.state;
+
+ return (
+
+
+
Server URL and Live Query
+
+ In this section, you can enable a custom Server URL that can be used for real-time database.
+
+
+ {!emailVerified && (
+
+ Please verify your email to enable this feature.{' '}
+
+ {resendVerificationMessage && (
+
+ {resendVerificationMessage.text}
+
+ )}
+
+ )}
+
+ {!cardValidated && (
+
+ )}
+
+
+ );
+ }
+
renderToolbar() {
return (
@@ -462,42 +578,7 @@ class ServerURLLiveQuery extends DashboardView {
);
} else if (!this.state.isUserVerified) {
- content = (
-
-
-
Server URL and Live Query
-
- In this section, you can enable a custom Server URL that can be used for real-time database.
-
-
-
-
- );
+ content = this.renderVerificationRequired();
} else {
const { initialFields, hasPermission } = this.state;