mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-16 03:20:42 +08:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0818de85d1 | ||
![]() |
457c6098a4 | ||
![]() |
60f979fbb5 | ||
![]() |
ff53e44fa6 | ||
![]() |
1832de47db | ||
![]() |
535eb0c465 | ||
![]() |
c190634cf3 |
@@ -854,6 +854,7 @@ func (c *ApiController) Login() {
|
||||
}
|
||||
|
||||
if authForm.Passcode != "" {
|
||||
user.CountryCode = user.GetCountryCode(user.CountryCode)
|
||||
mfaUtil := object.GetMfaUtil(authForm.MfaType, user.GetPreferredMfaProps(false))
|
||||
if mfaUtil == nil {
|
||||
c.ResponseError("Invalid multi-factor authentication type")
|
||||
|
@@ -294,6 +294,7 @@ func (c *ApiController) SendVerificationCode() {
|
||||
}
|
||||
|
||||
vform.CountryCode = mfaProps.CountryCode
|
||||
vform.CountryCode = user.GetCountryCode(vform.CountryCode)
|
||||
}
|
||||
|
||||
provider, err = application.GetSmsProvider(vform.Method, vform.CountryCode)
|
||||
|
@@ -520,11 +520,41 @@ func CheckUsername(username string, lang string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func CheckUsernameWithEmail(username string, lang string) string {
|
||||
if username == "" {
|
||||
return i18n.Translate(lang, "check:Empty username.")
|
||||
} else if len(username) > 39 {
|
||||
return i18n.Translate(lang, "check:Username is too long (maximum is 39 characters).")
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/58726546/github-username-convention-using-regex
|
||||
|
||||
if !util.ReUserNameWithEmail.MatchString(username) {
|
||||
return i18n.Translate(lang, "check:Username supports email format. Also The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline. Also pay attention to the email format.")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func CheckUpdateUser(oldUser, user *User, lang string) string {
|
||||
if oldUser.Name != user.Name {
|
||||
if msg := CheckUsername(user.Name, lang); msg != "" {
|
||||
return msg
|
||||
// Check if the organization uses email as the username
|
||||
organization, err := GetOrganizationByUser(oldUser)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
if organization == nil {
|
||||
return fmt.Sprintf(i18n.Translate(lang, "The organization: %s does not exist"), oldUser.Owner)
|
||||
}
|
||||
if organization.UseEmailAsUsername {
|
||||
if msg := CheckUsernameWithEmail(user.Name, lang); msg != "" {
|
||||
return msg
|
||||
}
|
||||
} else {
|
||||
if msg := CheckUsername(user.Name, lang); msg != "" {
|
||||
return msg
|
||||
}
|
||||
}
|
||||
|
||||
if HasUserByField(user.Owner, "name", user.Name) {
|
||||
return i18n.Translate(lang, "check:Username already exists")
|
||||
}
|
||||
|
@@ -43,6 +43,8 @@ func CheckEntryIp(clientIp string, user *User, application *Application, organiz
|
||||
if err != nil {
|
||||
application.IpRestriction = err.Error() + application.Name
|
||||
return fmt.Errorf(err.Error() + application.Name)
|
||||
} else {
|
||||
application.IpRestriction = ""
|
||||
}
|
||||
|
||||
if organization == nil && application.OrganizationObj != nil {
|
||||
@@ -55,6 +57,8 @@ func CheckEntryIp(clientIp string, user *User, application *Application, organiz
|
||||
if err != nil {
|
||||
organization.IpRestriction = err.Error() + organization.Name
|
||||
return fmt.Errorf(err.Error() + organization.Name)
|
||||
} else {
|
||||
organization.IpRestriction = ""
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -25,10 +25,11 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
rePhone *regexp.Regexp
|
||||
ReWhiteSpace *regexp.Regexp
|
||||
ReFieldWhiteList *regexp.Regexp
|
||||
ReUserName *regexp.Regexp
|
||||
rePhone *regexp.Regexp
|
||||
ReWhiteSpace *regexp.Regexp
|
||||
ReFieldWhiteList *regexp.Regexp
|
||||
ReUserName *regexp.Regexp
|
||||
ReUserNameWithEmail *regexp.Regexp
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -36,6 +37,7 @@ func init() {
|
||||
ReWhiteSpace, _ = regexp.Compile(`\s`)
|
||||
ReFieldWhiteList, _ = regexp.Compile(`^[A-Za-z0-9]+$`)
|
||||
ReUserName, _ = regexp.Compile("^[a-zA-Z0-9]+([-._][a-zA-Z0-9]+)*$")
|
||||
ReUserNameWithEmail, _ = regexp.Compile(`^([a-zA-Z0-9]+([-._][a-zA-Z0-9]+)*)|([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$`) // Add support for email formats
|
||||
}
|
||||
|
||||
func IsEmailValid(email string) bool {
|
||||
|
@@ -603,7 +603,7 @@ class ApplicationEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("general:IP whitelist"), i18next.t("general:IP whitelist - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input placeholder = {this.state.application.organizationObj?.ipWhitelist} value={this.state.application.ipWhiteList} onChange={e => {
|
||||
<Input placeholder = {this.state.application.organizationObj?.ipWhitelist} value={this.state.application.ipWhitelist} onChange={e => {
|
||||
this.updateApplicationField("ipWhitelist", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
|
@@ -908,7 +908,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Custom HTTP SMS", "Qiniu Cloud Kodo", "Synology", "Casdoor"].includes(this.state.provider.type) ? null : (
|
||||
{["Custom HTTP SMS", "Synology", "Casdoor"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||
|
@@ -187,7 +187,7 @@ class RoleEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("role:Sub users"), i18next.t("role:Sub users - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} mode="multiple" style={{width: "100%"}} value={this.state.role.users}
|
||||
<Select virtual={true} mode="multiple" style={{width: "100%"}} value={this.state.role.users}
|
||||
onChange={(value => {this.updateRoleField("users", value);})}
|
||||
options={this.state.users.map((user) => Setting.getOption(`${user.owner}/${user.name}`, `${user.owner}/${user.name}`))}
|
||||
/>
|
||||
|
@@ -444,8 +444,8 @@ class LoginPage extends React.Component {
|
||||
formValues={values}
|
||||
authParams={casParams}
|
||||
application={this.getApplicationObj()}
|
||||
onFail={() => {
|
||||
Setting.showMessage("error", i18next.t("mfa:Verification failed"));
|
||||
onFail={(errorMessage) => {
|
||||
Setting.showMessage("error", errorMessage);
|
||||
}}
|
||||
onSuccess={(res) => loginHandler(res)}
|
||||
/>);
|
||||
@@ -513,8 +513,8 @@ class LoginPage extends React.Component {
|
||||
formValues={values}
|
||||
authParams={oAuthParams}
|
||||
application={this.getApplicationObj()}
|
||||
onFail={() => {
|
||||
Setting.showMessage("error", i18next.t("mfa:Verification failed"));
|
||||
onFail={(errorMessage) => {
|
||||
Setting.showMessage("error", errorMessage);
|
||||
}}
|
||||
onSuccess={(res) => loginHandler(res)}
|
||||
/>);
|
||||
|
@@ -37,7 +37,7 @@ class MfaSetupPage extends React.Component {
|
||||
this.state = {
|
||||
account: props.account,
|
||||
application: null,
|
||||
applicationName: props.account.signupApplication ?? "",
|
||||
applicationName: props.account.signupApplication ?? localStorage.getItem("applicationName") ?? "",
|
||||
current: location.state?.from !== undefined ? 1 : 0,
|
||||
mfaProps: null,
|
||||
mfaType: params.get("mfaType") ?? SmsMfaType,
|
||||
|
Reference in New Issue
Block a user