Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a652ec0

Browse files
added email verification on signup
1 parent d0d3169 commit a652ec0

File tree

4 files changed

+99
-21
lines changed

4 files changed

+99
-21
lines changed

‎client/packages/lowcoder-design/src/components/CustomModal.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ CustomModal.confirm = (props: {
290290
type?: "info" | "warn" | "error" | "success";
291291
width?: number | string;
292292
customStyles?:React.CSSProperties;
293+
showCancelButton?: boolean;
293294
}): any => {
294295

295296
const fixedWidth = typeof props.width === "object" ? undefined : props.width;
@@ -350,6 +351,7 @@ CustomModal.confirm = (props: {
350351
footer={props.footer}
351352
width={props.width}
352353
customStyles={props.customStyles}
354+
showCancelButton={props.showCancelButton !== false}
353355
/>
354356
),
355357
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import axios, { AxiosInstance, AxiosPromise, AxiosRequestConfig } from "axios";
2+
import Api from "./api";
3+
4+
const key = "";
5+
6+
let axiosIns: AxiosInstance | null = null;
7+
8+
const getAxiosInstance = (clientSecret?: string) => {
9+
if (axiosIns && !clientSecret) {
10+
return axiosIns;
11+
}
12+
13+
const apiRequestConfig: AxiosRequestConfig = {
14+
baseURL: "https://emailverifier.reoon.com/api/v1/verify",
15+
};
16+
17+
axiosIns = axios.create(apiRequestConfig);
18+
return axiosIns;
19+
};
20+
21+
export class EmailVerifyApi extends Api {
22+
static quickVerification(email: string): AxiosPromise<any> {
23+
const requestConfig: AxiosRequestConfig = {
24+
method: "GET",
25+
withCredentials: false,
26+
params: {
27+
email,
28+
key,
29+
mode: 'quick',
30+
},
31+
};
32+
33+
return getAxiosInstance().request(requestConfig);
34+
}
35+
}

‎client/packages/lowcoder/src/i18n/locales/en.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3821,7 +3821,10 @@ export const en = {
38213821
"enterPassword": "Enter your password",
38223822
"selectAuthProvider": "Select Authentication Provider",
38233823
"selectWorkspace": "Select your workspace",
3824-
"userNotFound": "User not found. Please make sure you entered the correct email."
3824+
"userNotFound": "User not found. Please make sure you entered the correct email.",
3825+
"emailAlreadyExist": "Email is already registered",
3826+
"emailVerificationFailed": "Email Verification Failed",
3827+
"emailVerificationFailedText": "We couldn't verify your email address. A valid email is required to receive important notifications such as password resets and account updates. Please ensure you're using a valid email and try again."
38253828
},
38263829
"preLoad": {
38273830
"jsLibraryHelpText": "Add JavaScript Libraries to Your Current Application via URL Addresses. lodash, day.js, uuid, numbro are Built into the System for Immediate Use. JavaScript Libraries are Loaded Before the Application is Initialized, Which Can Have an Impact on Application Performance.",

‎client/packages/lowcoder/src/pages/userAuth/register.tsx

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
StyledRouteLinkLogin,
88
TermsAndPrivacyInfo,
99
} from "pages/userAuth/authComponents";
10-
import { FormInput, messageInstance, PasswordInput } from "lowcoder-design";
10+
import { CustomModal, FormInput, messageInstance, PasswordInput } from "lowcoder-design";
1111
import { AUTH_LOGIN_URL, ORG_AUTH_LOGIN_URL } from "constants/routesURL";
1212
import UserApi from "api/userApi";
1313
import { useRedirectUrl } from "util/hooks";
@@ -31,6 +31,8 @@ import { getServerSettings } from "@lowcoder-ee/redux/selectors/applicationSelec
3131
import { useEnterpriseContext } from "@lowcoder-ee/util/context/EnterpriseContext";
3232
import { fetchConfigAction } from "@lowcoder-ee/redux/reduxActions/configActions";
3333
import { fetchOrgPaginationByEmail } from "@lowcoder-ee/util/pagination/axios";
34+
import { EmailVerifyApi } from "@lowcoder-ee/api/emailVerifyApi";
35+
import Typography from "antd/es/typography";
3436

3537
const StyledFormInput = styled(FormInput)`
3638
margin-bottom: 16px;
@@ -57,6 +59,7 @@ function UserRegister() {
5759
const [password, setPassword] = useState("");
5860
const [orgLoading, setOrgLoading] = useState(false);
5961
const [lastEmailChecked, setLastEmailChecked] = useState("");
62+
const [emailVerified, setEmailVerified] = useState(true);
6063
const [signupEnabled, setSignupEnabled] = useState<boolean>(true);
6164
const [signinEnabled, setSigninEnabled] = useState<boolean>(true);
6265
const [defaultOrgId, setDefaultOrgId] = useState<string|undefined>();
@@ -159,27 +162,62 @@ function UserRegister() {
159162
afterLoginSuccess,
160163
);
161164

162-
const checkEmailExist = () => {
165+
const checkEmailExist = async () => {
163166
if (!Boolean(account.length) || lastEmailChecked === account || isEnterpriseMode) return;
164-
165167
setOrgLoading(true);
166-
OrgApi.fetchOrgsByEmail(account)
167-
.then((resp) => {
168-
if (validateResponse(resp)) {
169-
const orgList = resp.data.data;
170-
if (orgList.length) {
171-
messageInstance.error('Email is already registered');
172-
history.push(
173-
AUTH_LOGIN_URL,
174-
{...location.state || {}, email: account},
175-
)
176-
}
168+
try {
169+
const resp = await OrgApi.fetchOrgsByEmail(account);
170+
if (validateResponse(resp)) {
171+
const orgList = resp.data.data;
172+
if (orgList.length) {
173+
messageInstance.error(trans('userAuth.emailAlreadyExist'));
174+
history.push(
175+
AUTH_LOGIN_URL,
176+
{...location.state || {}, email: account},
177+
)
178+
throw new Error(trans('userAuth.emailAlreadyExist'));
177179
}
178-
})
179-
.finally(() => {
180-
setLastEmailChecked(account)
181-
setOrgLoading(false);
180+
}
181+
} finally {
182+
setLastEmailChecked(account)
183+
setOrgLoading(false);
184+
}
185+
}
186+
187+
const verifyEmail = async () => {
188+
if (!Boolean(account.length) || lastEmailChecked === account) return;
189+
try {
190+
const resp = await EmailVerifyApi.quickVerification(account);
191+
if (resp?.data?.status === "valid") return;
192+
193+
setEmailVerified(false);
194+
CustomModal.confirm({
195+
title: trans("userAuth.emailVerificationFailed"),
196+
content: trans("userAuth.emailVerificationFailedText"),
197+
confirmBtnType: "normal",
198+
okText: trans("componentDoc.close"),
199+
showCancelButton: false,
182200
});
201+
throw new Error(trans("userAuth.emailVerificationFailed"));
202+
} catch (error) {
203+
throw error;
204+
}
205+
}
206+
207+
const handleEmailBlur = async () => {
208+
try {
209+
await checkEmailExist();
210+
} catch(error) {
211+
console.error(error);
212+
return;
213+
}
214+
215+
try {
216+
await verifyEmail();
217+
} catch(error) {
218+
console.error(error);
219+
return;
220+
}
183221
}
184222

185223
const registerHeading = trans("userAuth.register")
@@ -201,7 +239,7 @@ function UserRegister() {
201239
label={trans("userAuth.email")}
202240
defaultValue={account}
203241
onChange={(value, valid) => setAccount(valid ? value : "")}
204-
onBlur={checkEmailExist}
242+
onBlur={handleEmailBlur}
205243
placeholder={trans("userAuth.inputEmail")}
206244
checkRule={{
207245
check: checkEmailValid,
@@ -217,7 +255,7 @@ function UserRegister() {
217255
doubleCheck
218256
/>
219257
<ConfirmButton
220-
disabled={!account || !password || submitBtnDisable}
258+
disabled={!account || !password || submitBtnDisable || !emailVerified}
221259
onClick={onSubmit}
222260
loading={loading}
223261
>

0 commit comments

Comments
 (0)