@particle-network/authkit
Version:
Auth Core provides MPC (Multi-Party Computation)-based threshold signatures.
414 lines (408 loc) • 23.2 kB
JavaScript
"use client";
import {
defaultCountriesData,
getCurrentCountry
} from "./chunk-RV3XNWPJ.mjs";
import {
react_auth_code_input_default
} from "./chunk-XQHFQR5F.mjs";
import {
svg_icon_default
} from "./chunk-E62IDKOD.mjs";
import {
power_footer_default
} from "./chunk-P6ZCFYHW.mjs";
import {
EmailRegExp,
isPhoneValid,
useAuthCoreModal,
useCustomNavigate,
useCustomize,
useMessage_default,
useTranslation
} from "./chunk-INJ3VAC7.mjs";
import "./chunk-55PCA22M.mjs";
// src/pages/account/accountBind/index.tsx
import { DownOutlined } from "@ant-design/icons";
import { getBindSecurityAccounCaptcha as getBindSecurityAccounCaptcha2, getCloudflareTurnstileResponse as getCloudflareTurnstileResponse2 } from "@particle-network/auth-core";
import { useRequest as useRequest2 } from "ahooks";
import { Button as Button2 } from "antd";
import getUnicodeFlagIcon from "country-flag-icons/unicode";
import React2, { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
// src/pages/account/accountBind/captcha-input.tsx
import {
ApiError,
bindSecurityAccount,
getBindSecurityAccounCaptcha,
getCloudflareTurnstileResponse,
syncUserInfo
} from "@particle-network/auth-core";
import { useInterval, useRequest } from "ahooks";
import { Button } from "antd";
import throttle from "lodash/throttle.js";
import qs from "qs";
import React, { useCallback, useEffect, useRef, useState } from "react";
// src/pages/account/accountBind/index.less
var accountBind_default = ".set-email-container {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n height: 100%;\n overflow: auto;\n color: var(--text-color);\n}\n.set-email-container .footer-box {\n position: absolute;\n bottom: 10px;\n margin: 0;\n}\n@media (max-height: 500px) {\n .set-email-container .footer-box {\n display: none;\n }\n}\n.set-email-container .display-none {\n display: none;\n}\n.set-email-container .error-tip {\n width: 90%;\n height: 0;\n padding-left: 10px;\n margin-top: 6px;\n margin-bottom: 0;\n text-align: left;\n color: red;\n opacity: 0;\n transition: all 0.3s;\n}\n.set-email-container .error-tip.show {\n height: 30px;\n opacity: 1;\n}\n.set-email-container .set-email-title {\n margin-top: 60px;\n font-size: 22px;\n color: var(--text-color);\n}\n.set-email-container .patment-tips1 {\n width: 80vw;\n margin-top: 30px;\n font-size: 14px;\n text-align: center;\n color: var(--text-color);\n}\n@media (min-width: 600px) {\n .set-email-container .patment-tips1 {\n width: calc(80 * var(--vw));\n }\n}\n.set-email-container .set-email-buttons {\n position: absolute;\n bottom: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: auto;\n padding-bottom: 20px;\n}\n.set-email-container .success-icon {\n width: 50px;\n height: 50px;\n margin-top: 60px;\n}\n.set-email-container .set-email-desc-1 {\n box-sizing: border-box;\n padding: 0 18px;\n margin: 15px 0 25px;\n font-weight: 400;\n font-size: 14px;\n line-height: 16px;\n text-align: center;\n color: var(--text-color);\n}\n.set-email-container .account-input-box {\n position: relative;\n z-index: 3;\n width: 90%;\n height: 47px;\n margin-top: 28px;\n border-radius: var(--primary-btn-border-radius);\n line-height: 47px;\n color: var(--text-color);\n background-color: var(--input-background-color);\n opacity: 1;\n}\n.set-email-container .account-input-box .account-select-country {\n position: absolute;\n z-index: 2;\n top: 54px;\n left: 2%;\n width: 96%;\n height: 210px;\n border-radius: var(--card-border-radius) !important;\n overflow-y: auto;\n background-color: var(--input-background-color);\n}\n.set-email-container .account-input-box .account-select-country::-webkit-scrollbar {\n display: none;\n width: 0;\n}\n.set-email-container .account-input-box .account-select-country .account-select-country-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n height: 47px;\n padding: 5px 0 5px 13px;\n margin: 0;\n border-bottom: 1px solid var(--card-unclickable-background-color);\n font-size: 14px;\n color: var(--text-color);\n cursor: pointer;\n}\n.set-email-container .account-input-box .account-select-country .account-select-country-item:hover {\n background-color: var(--card-unclickable-background-color);\n}\n.set-email-container .account-input-box .account-select-country .account-select-country-item div {\n display: flex;\n margin-right: 13px;\n}\n.set-email-container .account-input-box .account-select-country .account-select-country-item div .country-name {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.set-email-container .account-input-box input[type='number']::-webkit-inner-spin-button,\n.set-email-container .account-input-box input[type='number']::-webkit-outer-spin-button {\n appearance: none;\n margin: 0;\n}\n.set-email-container .account-input-box.phone {\n display: flex;\n align-items: center;\n border: 1px solid var(--input-background-color);\n border-radius: var(--primary-btn-border-radius);\n}\n.set-email-container .account-input-box.phone[data-focus='true'] {\n border: 1px solid var(--accent-color) !important;\n}\n.set-email-container .account-input-box.phone input {\n border: none !important;\n}\n.set-email-container .account-input-box.phone input:focus {\n border: none !important;\n}\n.set-email-container .account-input-box .account-select-opt {\n display: flex;\n flex-shrink: 0;\n justify-content: center;\n align-items: center;\n width: 60px;\n height: 100%;\n padding-left: 8px;\n cursor: pointer;\n}\n.set-email-container .account-input-box .account-select-opt .account-select-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: hidden;\n font-size: 15px;\n}\n.set-email-container .account-input-box .account-select-opt .down-more {\n margin-left: 8px;\n font-size: 10px;\n}\n.set-email-container .account-input-box span {\n flex-shrink: 0;\n margin: 0;\n font-size: 15px;\n}\n.set-email-container .account-input-box input {\n flex-shrink: 1;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n padding: 0 15px;\n outline: none;\n font-weight: 400;\n font-size: 15px;\n color: var(--text-color);\n background-color: transparent;\n}\n.set-email-container .send-code-btn {\n margin-bottom: 0 !important;\n}\n.set-email-container .account-submit-btn {\n width: 90%;\n height: 47px;\n padding: 0;\n margin-top: 38px;\n border: none;\n border-radius: var(--primary-btn-border-radius);\n font-weight: 500;\n font-size: var(--primary-btn-font-size);\n line-height: 47px;\n text-align: center;\n color: var(--primary-btn-color);\n background: var(--primary-btn-background-color);\n opacity: 1;\n}\n.set-email-container .account-submit-btn.bottom-margin {\n margin-bottom: 100px;\n}\n.set-email-container .account-submit-btn:hover {\n border: none;\n color: var(--primary-btn-color) !important;\n background: var(--primary-btn-background-color) !important;\n opacity: var(--hover-opacity);\n}\n.set-email-container .account-switch-item {\n margin-top: 40px;\n font-weight: 500;\n font-size: 13px;\n line-height: 19px;\n color: var(--accent-color);\n cursor: pointer;\n}\n.set-email-container .set-email-desc-2 {\n min-width: 116px;\n height: 23px;\n padding: 0 15px;\n border-radius: var(--primary-btn-border-radius);\n font-weight: 400;\n font-size: 12px;\n line-height: 23px;\n text-align: center;\n color: var(--secondary-text-color);\n background: var(--tag-background-color);\n opacity: 1;\n}\n.set-email-container .code-error {\n position: absolute;\n left: calc((100vw - 316px) / 2);\n margin-top: 220px;\n font-weight: 400;\n font-size: 12px;\n color: var(--error-color);\n}\n@media (min-width: 600px) {\n .set-email-container .code-error {\n left: calc((var(--vw) * 100 - 316px) / 2);\n }\n}\n.set-email-container .back {\n display: flex;\n align-items: center;\n height: 19px;\n margin-top: 90px;\n margin-bottom: 20px;\n font-weight: 400;\n font-size: 16px;\n line-height: 19px;\n color: var(--accent-color);\n opacity: 1;\n cursor: pointer;\n gap: 8px;\n}\n.set-email-container .back svg {\n position: relative;\n top: 0;\n color: var(--accent-color);\n}\n.set-email-container .send-again {\n margin-top: 20px;\n border: none !important;\n outline: none !important;\n font-weight: 400;\n font-size: 16px;\n line-height: 19px;\n color: var(--text-color);\n background-color: transparent;\n box-shadow: none;\n}\n.set-email-container .send-again:hover {\n color: var(--text-color);\n background-color: transparent !important;\n}\n.set-email-container .send-again:disabled {\n opacity: 0.5;\n}\n";
// src/pages/account/accountBind/captcha-input.tsx
var CaptchaInput = (props) => {
const { bindAccount, backToInputAccount, redirectUrl = "", verifyToken = "" } = props;
const message = useMessage_default();
const { t } = useTranslation();
const { themeType, language } = useCustomize();
const navigate = useCustomNavigate();
const [captchaCode, setCaptchaCode] = useState("");
const [interval, setInterval] = useState(1e3);
const [countdown, setCountdown] = useState(60);
const [errorTip, setErrorTip] = useState();
const inputRef = useRef(null);
const { authCoreModal } = useAuthCoreModal();
const [bindLoading, setBindLoading] = useState(false);
useInterval(() => {
if (countdown > 0) {
const result = countdown - 1;
setCountdown(result);
if (result === 0) {
setInterval(void 0);
}
}
}, interval);
const { run: runBinding } = useRequest(bindSecurityAccount, {
manual: true,
onBefore: () => {
setBindLoading(true);
},
onSuccess: (result) => {
syncUserInfo();
if (redirectUrl) {
navigate(redirectUrl.split("?")[0], {
replace: true,
back: true,
state: {
...qs.parse(redirectUrl.split("?")[1]),
verifyToken: result == null ? void 0 : result.token,
account: bindAccount
}
});
} else if (!result.has_set_payment_password) {
navigate("/account/set-password");
} else {
navigate("/account/security", { replace: true });
}
},
onError: (error) => {
console.log("bind accounts error", error);
if ((error == null ? void 0 : error.error_code) === ApiError.InvalidCode) {
setErrorTip(t("login.invalid_code"));
} else if ((error == null ? void 0 : error.error_code) === ApiError.ResendCode) {
setErrorTip(t("login.please_send_again"));
}
},
onFinally: () => {
setTimeout(() => {
setBindLoading(false);
}, 2e3);
}
});
const { loading: codeLoading, run: runGetCode } = useRequest(getBindSecurityAccounCaptcha, {
manual: true,
onSuccess: (result, params) => {
if (!interval) {
setCountdown(60);
setInterval(1e3);
}
},
onError: (error) => {
setCountdown(0);
setInterval(void 0);
}
});
const submitBind = (code) => {
let param;
if (bindAccount.includes("@")) {
param = { email: bindAccount, code: code || captchaCode };
} else {
param = { phone: bindAccount, code: code || captchaCode };
}
if (verifyToken) {
param.token = verifyToken;
}
runBinding(param);
};
const requestCaptchaCode = () => {
setErrorTip("");
if (bindAccount.includes("@")) {
runGetCode({
email: bindAccount
});
} else {
getCloudflareTurnstileResponse({
theme: themeType,
language,
getContainer: () => {
return authCoreModal.rootBody;
}
}).then((token) => {
runGetCode({
phone: bindAccount,
cf_turnstile_response: token
});
}).catch((error) => {
message.error(t("error.server_20112"));
});
}
};
const onCodeInputChange = (code) => {
setCaptchaCode(code);
setErrorTip("");
if (code.length === 6) {
throttleSubmitBind(code);
}
};
const throttleSubmitBind = useCallback(
throttle(
(code) => {
submitBind(code);
},
1e3,
{
leading: true,
trailing: false
}
),
[]
);
useEffect(() => {
var _a;
const elements = document.getElementsByClassName("react-input-code");
const contextmenuEvent = (e) => e.preventDefault();
(_a = elements[0]) == null ? void 0 : _a.addEventListener("contextmenu", contextmenuEvent);
return () => {
var _a2;
(_a2 = elements[0]) == null ? void 0 : _a2.removeEventListener("contextmenu", contextmenuEvent);
};
}, []);
const handleCodeInputFocus = () => {
var _a;
const elements = document.getElementsByClassName("input-code-item");
(_a = elements[Math.min(captchaCode.length, 5)]) == null ? void 0 : _a.focus();
};
return /* @__PURE__ */ React.createElement("div", { className: "set-email-container" }, /* @__PURE__ */ React.createElement("style", null, accountBind_default), /* @__PURE__ */ React.createElement(svg_icon_default, { className: "icon-navigation-back", name: "circle_back", onClick: backToInputAccount }), /* @__PURE__ */ React.createElement("h2", { className: "set-email-title" }, t("account.enter_code")), /* @__PURE__ */ React.createElement("p", { className: "set-email-desc-2", style: { margin: 20 } }, bindAccount), /* @__PURE__ */ React.createElement("div", { onClick: handleCodeInputFocus }, /* @__PURE__ */ React.createElement(
react_auth_code_input_default,
{
containerClassName: "react-input-code",
inputClassName: "input-code-item",
allowedCharacters: "numeric",
length: 6,
ref: inputRef,
placeholder: " ",
onChange: onCodeInputChange
}
)), errorTip && /* @__PURE__ */ React.createElement("div", { className: "code-error" }, errorTip), /* @__PURE__ */ React.createElement(
Button,
{
disabled: captchaCode.length !== 6,
className: "account-submit-btn",
loading: bindLoading,
onClick: () => submitBind()
},
t("common.confirm")
), /* @__PURE__ */ React.createElement(Button, { className: "send-again", onClick: requestCaptchaCode, disabled: countdown > 0 || codeLoading }, countdown > 0 ? `${t("login.send_again")} (${countdown}s)` : t("login.send_again")), /* @__PURE__ */ React.createElement("div", { className: "back", onClick: backToInputAccount }, /* @__PURE__ */ React.createElement(svg_icon_default, { className: "arrow1-icon", name: "arrow1_icon" }), /* @__PURE__ */ React.createElement("span", null, t("login.back"))), /* @__PURE__ */ React.createElement(power_footer_default, null));
};
var captcha_input_default = CaptchaInput;
// src/pages/account/accountBind/index.tsx
var AccountBind = (props) => {
const navigate = useCustomNavigate();
const { t } = useTranslation();
const state = props;
const redirectUrl = state == null ? void 0 : state.redirectUrl;
const verifyToken = state == null ? void 0 : state.verifyToken;
const message = useMessage_default();
const clickRef = useRef2();
const [bindAccount, setBindAccount] = useState2("");
const [countryData, setCountryData] = useState2(["United States", "us", "1"]);
const [isSendCode, setIsSendCode] = useState2(false);
const accountInputRef = useRef2(null);
const [errorMsg, setError] = useState2("");
const { themeType, language } = useCustomize();
const { authCoreModal } = useAuthCoreModal();
const [accountType, setAccountType] = useState2("email");
useEffect2(() => {
if (accountType === "phone" || (state == null ? void 0 : state.showSwitch)) {
const currentCountry = getCurrentCountry();
if (currentCountry) {
setCountryData(currentCountry);
}
}
}, [accountType, state == null ? void 0 : state.showSwitch]);
const [visbSelectCountry, setVisbSelectCountry] = useState2(false);
useEffect2(() => {
if (visbSelectCountry) {
document.addEventListener("click", clickCallback, true);
return () => {
document.removeEventListener("click", clickCallback, true);
};
}
}, [visbSelectCountry]);
const clickCallback = (event) => {
setTimeout(() => {
var _a;
if ((_a = clickRef.current) == null ? void 0 : _a.contains(event.target)) {
return;
}
setVisbSelectCountry(false);
});
};
useEffect2(() => {
const type = state == null ? void 0 : state.accountType;
if (type) {
setAccountType(type);
}
}, [state]);
const { loading: codeLoading, run: runGetCode } = useRequest2(getBindSecurityAccounCaptcha2, {
manual: true,
onSuccess: (result, params) => {
setIsSendCode(result);
},
onError: (error) => {
const code = (error == null ? void 0 : error.error_code) || 0;
if (code === 50003 || code === 50004) {
setBindAccount("");
accountInputRef.current.value = "";
}
}
});
const checkAndRequestCode = () => {
let account = accountInputRef.current.value;
if (accountType === "email") {
if (!account) {
return setError(t("account.input_vaild_email"));
} else if (!EmailRegExp.test(account)) {
return setError(t("login.email_format_error"));
}
} else {
const regionCode = countryData[1].toUpperCase();
if (!account && account !== "0") {
return setError(t("account.input_vaild_mobile"));
} else if (!isPhoneValid(account, regionCode)) {
return setError(t("login.phone_format_error"));
} else {
account = `+${countryData[2]}${account}`;
}
}
setBindAccount(account);
if (!account.includes("@")) {
getCloudflareTurnstileResponse2({
theme: themeType,
language,
getContainer: () => {
return authCoreModal.rootBody;
}
}).then((token) => {
runGetCode({
phone: account,
cf_turnstile_response: token
});
}).catch((error) => {
message.error(t("error.server_20112"));
});
} else {
runGetCode({
email: account
});
}
};
const changeAccountType = () => {
setError("");
setAccountType(accountType === "email" ? "phone" : "email");
setBindAccount("");
};
useEffect2(() => {
setTimeout(() => {
var _a;
(_a = accountInputRef.current) == null ? void 0 : _a.focus();
});
}, []);
if (isSendCode) {
return /* @__PURE__ */ React2.createElement(
captcha_input_default,
{
bindAccount,
redirectUrl: redirectUrl || "",
verifyToken,
backToInputAccount: () => {
setIsSendCode(false);
}
}
);
}
return /* @__PURE__ */ React2.createElement("div", { className: "set-email-container" }, /* @__PURE__ */ React2.createElement("style", null, accountBind_default), /* @__PURE__ */ React2.createElement(svg_icon_default, { className: "icon-navigation-back", name: "circle_back", onClick: () => navigate(-1) }), /* @__PURE__ */ React2.createElement("h2", { className: "set-email-title" }, accountType === "email" ? t("account.set_your_email") : t("account.set_your_mobile")), /* @__PURE__ */ React2.createElement("p", { className: "set-email-desc-1" }, accountType === "email" ? t("account.set_your_email_tip") : t("account.set_your_mobile_tip")), accountType === "email" ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { className: "account-input-box" }, /* @__PURE__ */ React2.createElement(
"input",
{
onInput: () => setError(""),
className: "input_email",
type: "email",
placeholder: t("account.place_email_address"),
ref: accountInputRef,
defaultValue: bindAccount,
onKeyDown: (e) => {
if (e.key === "Enter") {
checkAndRequestCode();
}
}
}
))) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { className: "account-input-box phone", ref: clickRef }, visbSelectCountry && /* @__PURE__ */ React2.createElement("div", { className: "account-select-country" }, defaultCountriesData.map((item, index) => /* @__PURE__ */ React2.createElement(
"p",
{
key: index,
className: "account-select-country-item",
onClick: () => {
setCountryData(item);
setVisbSelectCountry(false);
}
},
/* @__PURE__ */ React2.createElement("div", { className: "country-box" }, /* @__PURE__ */ React2.createElement("div", { className: "country-flag" }, getUnicodeFlagIcon(`${item[1]}`)), /* @__PURE__ */ React2.createElement("span", { className: "country-name" }, item[0])),
/* @__PURE__ */ React2.createElement("div", { className: "country-code" }, "+" + item[2])
))), /* @__PURE__ */ React2.createElement("div", { className: "account-select-opt", onClick: () => setVisbSelectCountry(!visbSelectCountry) }, /* @__PURE__ */ React2.createElement("div", { className: "account-select-icon" }, getUnicodeFlagIcon(`${countryData[1]}`)), /* @__PURE__ */ React2.createElement(DownOutlined, { className: "down-more" })), /* @__PURE__ */ React2.createElement("span", null, "+", countryData[2]), /* @__PURE__ */ React2.createElement(
"input",
{
onInput: () => {
var _a;
setError("");
accountInputRef.current.value = ((_a = accountInputRef.current.value.match(/^\d+/)) == null ? void 0 : _a[0]) || "";
},
type: "text",
className: "no-number dd",
placeholder: t("account.mobile"),
ref: accountInputRef,
onWheel: (e) => e.target.blur(),
defaultValue: bindAccount.replace(`+${countryData[2]}`, ""),
onKeyDown: (e) => {
if (e.key === "Enter") {
checkAndRequestCode();
}
},
onFocus: () => {
var _a;
(_a = document.querySelector(".account-input-box.phone")) == null ? void 0 : _a.setAttribute("data-focus", "true");
},
onBlur: () => {
var _a;
(_a = document.querySelector(".account-input-box.phone")) == null ? void 0 : _a.setAttribute("data-focus", "false");
}
}
))), /* @__PURE__ */ React2.createElement("p", { className: `error-tip ${errorMsg ? "show" : ""}` }, errorMsg), /* @__PURE__ */ React2.createElement(
Button2,
{
className: "send-code-btn account-submit-btn bottom-margin",
loading: codeLoading,
onClick: checkAndRequestCode
},
t("login.get_captcha")
), (state == null ? void 0 : state.showSwitch) && /* @__PURE__ */ React2.createElement("div", { className: "account-switch-item", onClick: changeAccountType }, accountType === "email" ? t("account.switch_text_mobile") : t("account.switch_text_email")), /* @__PURE__ */ React2.createElement(power_footer_default, null));
};
var accountBind_default2 = AccountBind;
export {
accountBind_default2 as default
};
//# sourceMappingURL=accountBind-IPYIFN5F.mjs.map