feat: login by code (#344)

Signed-off-by: abingcbc <abingcbc626@gmail.com>
This commit is contained in:
Bingchang Chen
2021-12-07 00:05:53 +08:00
committed by GitHub
parent 113398c36b
commit 70a550d8bc
13 changed files with 95 additions and 49 deletions

View File

@ -139,53 +139,35 @@ func (c *ApiController) Login() {
if form.Password == "" {
var verificationCodeType string
var checkResult string
// check result through Email or Phone
if strings.Contains(form.Email, "@") {
if strings.Contains(form.Username, "@") {
verificationCodeType = "email"
checkResult := object.CheckVerificationCode(form.Email, form.EmailCode)
if len(checkResult) != 0 {
responseText := fmt.Sprintf("Email%s", checkResult)
c.ResponseError(responseText)
return
}
checkResult = object.CheckVerificationCode(form.Username, form.Code)
} else {
verificationCodeType = "phone"
checkPhone := fmt.Sprintf("+%s%s", form.PhonePrefix, form.Email)
checkResult := object.CheckVerificationCode(checkPhone, form.EmailCode)
if len(checkResult) != 0 {
responseText := fmt.Sprintf("Phone%s", checkResult)
if len(form.PhonePrefix) == 0 {
responseText := fmt.Sprintf("%s%s", verificationCodeType, "No phone prefix")
c.ResponseError(responseText)
return
}
checkPhone := fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username)
checkResult = object.CheckVerificationCode(checkPhone, form.Code)
}
// get user
var userId string
if form.Username == "" {
userId, _ = c.RequireSignedIn()
} else {
userId = fmt.Sprintf("%s/%s", form.Organization, form.Username)
}
user = object.GetUser(userId)
if user == nil {
c.ResponseError("No such user.")
if len(checkResult) != 0 {
responseText := fmt.Sprintf("%s%s", verificationCodeType, checkResult)
c.ResponseError(responseText)
return
}
// disable the verification code
switch verificationCodeType {
case "email":
if user.Email != form.Email {
c.ResponseError("wrong email!")
}
object.DisableVerificationCode(form.Email)
case "phone":
if user.Phone != form.Email {
c.ResponseError("wrong phone!")
}
object.DisableVerificationCode(form.Email)
object.DisableVerificationCode(form.Username)
user = object.GetUserByFields(form.Organization, form.Username)
if user == nil {
c.ResponseError("No such user.")
return
}
} else {
password := form.Password

View File

@ -45,6 +45,7 @@ func (c *ApiController) SendVerificationCode() {
checkType := c.Ctx.Request.Form.Get("checkType")
checkId := c.Ctx.Request.Form.Get("checkId")
checkKey := c.Ctx.Request.Form.Get("checkKey")
checkUser := c.Ctx.Request.Form.Get("checkUser")
remoteAddr := util.GetIPFromRequest(c.Ctx.Request)
if len(destType) == 0 || len(dest) == 0 || len(orgId) == 0 || !strings.Contains(orgId, "/") || len(checkType) == 0 || len(checkId) == 0 || len(checkKey) == 0 {
@ -67,6 +68,12 @@ func (c *ApiController) SendVerificationCode() {
organization := object.GetOrganization(orgId)
application := object.GetApplicationByOrganizationName(organization.Name)
if checkUser == "true" && user == nil &&
object.GetUserByFields(organization.Name, dest) == nil {
c.ResponseError("No such user.")
return
}
sendResp := errors.New("Invalid dest type.")
switch destType {
case "email":

View File

@ -136,10 +136,9 @@ class ForgetPage extends React.Component {
AuthBackend.login({
application: forms.step2.getFieldValue("application"),
organization: forms.step2.getFieldValue("organization"),
email: forms.step2.getFieldValue("email"),
emailCode: forms.step2.getFieldValue("emailCode"),
username: forms.step2.getFieldValue("email"),
code: forms.step2.getFieldValue("emailCode"),
phonePrefix: this.state.application?.organizationObj.phonePrefix,
username: this.state.username,
type: "login"
}, oAuthParams).then(res => {
if (res.status === "ok") {

View File

@ -49,6 +49,7 @@ class LoginPage extends React.Component {
isCodeSignin: false,
msg: null,
username: null,
validEmailOrPhone: false
};
}
@ -109,6 +110,7 @@ class LoginPage extends React.Component {
const application = this.getApplicationObj();
const ths = this;
values["type"] = this.state.type;
values["phonePrefix"] = this.getApplicationObj()?.organizationObj.phonePrefix;
const oAuthParams = Util.getOAuthGetParameters();
AuthBackend.login(values, oAuthParams)
@ -288,11 +290,28 @@ class LoginPage extends React.Component {
</Form.Item>
<Form.Item
name="username"
rules={[{ required: true, message: i18next.t("login:Please input your username, Email or phone!") }]}
rules={[
{
required: true,
message: i18next.t("login:Please input your username, Email or phone!")
},
{
validator: (_, value) => {
if (this.state.isCodeSignin) {
if (this.state.email !== "" && !Setting.isValidEmail(this.state.username) && !Setting.isValidPhone(this.state.username)) {
this.setState({validEmailOrPhone: false});
return Promise.reject(i18next.t("login:The input is not valid Email or Phone!"));
}
}
this.setState({validEmailOrPhone: true});
return Promise.resolve();
}
}
]}
>
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder={i18next.t("login:username, Email or phone")}
placeholder={ this.state.isCodeSignin ? i18next.t("login:Email or phone") : i18next.t("login:username, Email or phone") }
disabled={!application.enablePassword}
onChange={e => {
this.setState({
@ -308,8 +327,8 @@ class LoginPage extends React.Component {
rules={[{ required: true, message: i18next.t("login:Please input your code!") }]}
>
<CountDownInput
disabled={this.state.username?.length === 0}
onButtonClickArgs={[this.state.email, "email", Setting.getApplicationOrgName(application)]}
disabled={this.state.username?.length === 0 || !this.state.validEmailOrPhone}
onButtonClickArgs={[this.state.username, "", Setting.getApplicationOrgName(application), true]}
/>
</Form.Item>
) : (

View File

@ -88,7 +88,7 @@ export function setPassword(userOwner, userName, oldPassword, newPassword) {
}).then(res => res.json());
}
export function sendCode(checkType, checkId, checkKey, dest, type, orgId) {
export function sendCode(checkType, checkId, checkKey, dest, type, orgId, checkUser) {
let formData = new FormData();
formData.append("checkType", checkType);
formData.append("checkId", checkId);
@ -96,6 +96,7 @@ export function sendCode(checkType, checkId, checkKey, dest, type, orgId) {
formData.append("dest", dest);
formData.append("type", type);
formData.append("organizationId", orgId);
formData.append("checkUser", checkUser);
return fetch(`${Setting.ServerUrl}/api/send-verification-code`, {
method: "POST",
credentials: "include",

View File

@ -18,6 +18,8 @@ import * as Setting from "../Setting";
import i18next from "i18next";
import * as UserBackend from "../backend/UserBackend";
import {SafetyOutlined} from "@ant-design/icons";
import * as Util from "../auth/Util";
import {isValidEmail, isValidPhone} from "../Setting";
const { Search } = Input;
@ -40,6 +42,14 @@ export const CountDownInput = (props) => {
const handleOk = () => {
setVisible(false);
if (isValidEmail(onButtonClickArgs[0])) {
onButtonClickArgs[1] = "email";
} else if (isValidPhone(onButtonClickArgs[0])) {
onButtonClickArgs[1] = "phone";
} else {
Util.showMessage("error", i18next.t("login:Invalid Email or phone"))
return;
}
UserBackend.sendCode(checkType, checkId, key, ...onButtonClickArgs).then(res => {
setKey("");
if (res) {

View File

@ -177,6 +177,7 @@
"Please input your code!": "Please input your code!",
"Please input your password!": "Please input your password!",
"Please input your password, at least 6 characters!": "Please input your password, at least 6 characters!",
"Please input your Email or phone!": "Please input your Email or phone!",
"Please input your username, Email or phone!": "Please input your username, Email or phone!",
"Sign In": "Sign In",
"Sign in with code": "Sign in with code",
@ -185,7 +186,10 @@
"Signing in...": "Signing in...",
"To access": "To access",
"sign up now": "sign up now",
"username, Email or phone": "username, Email or phone"
"Email or phone": "Email or phone",
"username, Email or phone": "username, Email or phone",
"Invalid Email or phone": "Invalid Email or phone",
"The input is not valid Email or Phone!": "The input is not valid Email or Phone!"
},
"organization": {
"Default avatar": "Default avatar",

View File

@ -177,6 +177,7 @@
"Please input your code!": "Please input your code!",
"Please input your password!": "Please input your password!",
"Please input your password, at least 6 characters!": "Please input your password, at least 6 characters!",
"Please input your Email or phone!": "Please input your Email or phone!",
"Please input your username, Email or phone!": "Please input your username, Email or phone!",
"Sign In": "Sign In",
"Sign in with code": "Sign in with code",
@ -185,7 +186,10 @@
"Signing in...": "Signing in...",
"To access": "To access",
"sign up now": "sign up now",
"username, Email or phone": "username, Email or phone"
"Email or phone": "Email or phone",
"username, Email or phone": "username, Email or phone",
"Invalid Email or phone": "Invalid Email or phone",
"The input is not valid Email or Phone!": "The input is not valid Email or Phone!"
},
"organization": {
"Default avatar": "Default avatar",

View File

@ -177,6 +177,7 @@
"Please input your code!": "Please input your code!",
"Please input your password!": "Please input your password!",
"Please input your password, at least 6 characters!": "Please input your password, at least 6 characters!",
"Please input your Email or phone!": "Please input your Email or phone!",
"Please input your username, Email or phone!": "Please input your username, Email or phone!",
"Sign In": "Sign In",
"Sign in with code": "Sign in with code",
@ -185,7 +186,10 @@
"Signing in...": "Signing in...",
"To access": "To access",
"sign up now": "sign up now",
"username, Email or phone": "username, Email or phone"
"Email or phone": "Email or phone",
"username, Email or phone": "username, Email or phone",
"Invalid Email or phone": "Invalid Email or phone",
"The input is not valid Email or Phone!": "The input is not valid Email or Phone!"
},
"organization": {
"Default avatar": "Default avatar",

View File

@ -177,6 +177,7 @@
"Please input your code!": "Please input your code!",
"Please input your password!": "Please input your password!",
"Please input your password, at least 6 characters!": "Please input your password, at least 6 characters!",
"Please input your Email or phone!": "Please input your Email or phone!",
"Please input your username, Email or phone!": "Please input your username, Email or phone!",
"Sign In": "Sign In",
"Sign in with code": "Sign in with code",
@ -185,7 +186,10 @@
"Signing in...": "Signing in...",
"To access": "To access",
"sign up now": "sign up now",
"username, Email or phone": "username, Email or phone"
"Email or phone": "Email or phone",
"username, Email or phone": "username, Email or phone",
"Invalid Email or phone": "Invalid Email or phone",
"The input is not valid Email or Phone!": "The input is not valid Email or Phone!"
},
"organization": {
"Default avatar": "Default avatar",

View File

@ -177,6 +177,7 @@
"Please input your code!": "Please input your code!",
"Please input your password!": "Please input your password!",
"Please input your password, at least 6 characters!": "Please input your password, at least 6 characters!",
"Please input your Email or phone!": "Please input your Email or phone!",
"Please input your username, Email or phone!": "Please input your username, Email or phone!",
"Sign In": "Sign In",
"Sign in with code": "Sign in with code",
@ -185,7 +186,10 @@
"Signing in...": "Signing in...",
"To access": "To access",
"sign up now": "sign up now",
"username, Email or phone": "username, Email or phone"
"Email or phone": "Email or phone",
"username, Email or phone": "username, Email or phone",
"Invalid Email or phone": "Invalid Email or phone",
"The input is not valid Email or Phone!": "The input is not valid Email or Phone!"
},
"organization": {
"Default avatar": "Default avatar",

View File

@ -177,6 +177,7 @@
"Please input your code!": "Please input your code!",
"Please input your password!": "Please input your password!",
"Please input your password, at least 6 characters!": "Please input your password, at least 6 characters!",
"Please input your Email or phone!": "Please input your Email or phone!",
"Please input your username, Email or phone!": "Please input your username, Email or phone!",
"Sign In": "Sign In",
"Sign in with code": "Sign in with code",
@ -185,7 +186,10 @@
"Signing in...": "Signing in...",
"To access": "To access",
"sign up now": "sign up now",
"username, Email or phone": "username, Email or phone"
"Email or phone": "Email or phone",
"username, Email or phone": "username, Email or phone",
"Invalid Email or phone": "Invalid Email or phone",
"The input is not valid Email or Phone!": "The input is not valid Email or Phone!"
},
"organization": {
"Default avatar": "Default avatar",

View File

@ -177,6 +177,7 @@
"Please input your code!": "请输入您的验证码!",
"Please input your password!": "请输入您的密码!",
"Please input your password, at least 6 characters!": "请输入您的密码不少于6位",
"Please input your Email or phone!": "请输入您的Email或手机号",
"Please input your username, Email or phone!": "请输入您的用户名、Email或手机号",
"Sign In": "登录",
"Sign in with code": "验证码登录",
@ -185,7 +186,10 @@
"Signing in...": "正在登录...",
"To access": "访问",
"sign up now": "立即注册",
"username, Email or phone": "用户名、Email或手机号"
"Email or phone": "Email或手机号",
"username, Email or phone": "用户名、Email或手机号",
"Invalid Email or phone": "无效的Email或手机号",
"The input is not valid Email or Phone!": "您输入的电子邮箱格式或手机号有误!"
},
"organization": {
"Default avatar": "默认头像",