Compare commits

...

3 Commits

9 changed files with 79 additions and 38 deletions

View File

@ -986,6 +986,18 @@ func (c *ApiController) Login() {
}
}
if authForm.Language != "" {
user := c.getCurrentUser()
if user != nil {
user.Language = authForm.Language
_, err = object.UpdateUser(user.GetId(), user, []string{"language"}, user.IsAdmin)
if err != nil {
c.ResponseError(err.Error())
return
}
}
}
c.Data["json"] = resp
c.ServeJSON()
}

View File

@ -258,7 +258,7 @@ func (c *ApiController) SendVerificationCode() {
return
}
sendResp = object.SendVerificationCodeToEmail(organization, user, provider, clientIp, vform.Dest, c.GetAcceptLanguage())
sendResp = object.SendVerificationCodeToEmail(organization, user, provider, clientIp, vform.Dest)
case object.VerifyTypePhone:
if vform.Method == LoginVerification || vform.Method == ForgetVerification {
if user != nil && util.GetMaskedPhone(user.Phone) == vform.Dest {
@ -304,7 +304,7 @@ func (c *ApiController) SendVerificationCode() {
c.ResponseError(fmt.Sprintf(c.T("verification:Phone number is invalid in your region %s"), vform.CountryCode))
return
} else {
sendResp = object.SendVerificationCodeToPhone(organization, user, provider, clientIp, phone, c.GetAcceptLanguage())
sendResp = object.SendVerificationCodeToPhone(organization, user, provider, clientIp, phone)
}
}

View File

@ -34,6 +34,7 @@ type AuthForm struct {
Phone string `json:"phone"`
Affiliation string `json:"affiliation"`
IdCard string `json:"idCard"`
Language string `json:"language"`
Region string `json:"region"`
InvitationCode string `json:"invitationCode"`

View File

@ -97,29 +97,30 @@ type Application struct {
IsShared bool `json:"isShared"`
IpRestriction string `json:"ipRestriction"`
ClientId string `xorm:"varchar(100)" json:"clientId"`
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
RedirectUris []string `xorm:"varchar(1000)" json:"redirectUris"`
TokenFormat string `xorm:"varchar(100)" json:"tokenFormat"`
TokenSigningMethod string `xorm:"varchar(100)" json:"tokenSigningMethod"`
TokenFields []string `xorm:"varchar(1000)" json:"tokenFields"`
ExpireInHours int `json:"expireInHours"`
RefreshExpireInHours int `json:"refreshExpireInHours"`
SignupUrl string `xorm:"varchar(200)" json:"signupUrl"`
SigninUrl string `xorm:"varchar(200)" json:"signinUrl"`
ForgetUrl string `xorm:"varchar(200)" json:"forgetUrl"`
AffiliationUrl string `xorm:"varchar(100)" json:"affiliationUrl"`
IpWhitelist string `xorm:"varchar(200)" json:"ipWhitelist"`
TermsOfUse string `xorm:"varchar(100)" json:"termsOfUse"`
SignupHtml string `xorm:"mediumtext" json:"signupHtml"`
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
ThemeData *ThemeData `xorm:"json" json:"themeData"`
FooterHtml string `xorm:"mediumtext" json:"footerHtml"`
FormCss string `xorm:"text" json:"formCss"`
FormCssMobile string `xorm:"text" json:"formCssMobile"`
FormOffset int `json:"formOffset"`
FormSideHtml string `xorm:"mediumtext" json:"formSideHtml"`
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
ClientId string `xorm:"varchar(100)" json:"clientId"`
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
RedirectUris []string `xorm:"varchar(1000)" json:"redirectUris"`
TokenFormat string `xorm:"varchar(100)" json:"tokenFormat"`
TokenSigningMethod string `xorm:"varchar(100)" json:"tokenSigningMethod"`
TokenFields []string `xorm:"varchar(1000)" json:"tokenFields"`
ExpireInHours int `json:"expireInHours"`
RefreshExpireInHours int `json:"refreshExpireInHours"`
SignupUrl string `xorm:"varchar(200)" json:"signupUrl"`
SigninUrl string `xorm:"varchar(200)" json:"signinUrl"`
ForgetUrl string `xorm:"varchar(200)" json:"forgetUrl"`
AffiliationUrl string `xorm:"varchar(100)" json:"affiliationUrl"`
IpWhitelist string `xorm:"varchar(200)" json:"ipWhitelist"`
TermsOfUse string `xorm:"varchar(100)" json:"termsOfUse"`
SignupHtml string `xorm:"mediumtext" json:"signupHtml"`
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
ThemeData *ThemeData `xorm:"json" json:"themeData"`
FooterHtml string `xorm:"mediumtext" json:"footerHtml"`
FormCss string `xorm:"text" json:"formCss"`
FormCssMobile string `xorm:"text" json:"formCssMobile"`
FormOffset int `json:"formOffset"`
FormSideHtml string `xorm:"mediumtext" json:"formSideHtml"`
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
FormBackgroundUrlMobile string `xorm:"varchar(200)" json:"formBackgroundUrlMobile"`
FailedSigninLimit int `json:"failedSigninLimit"`
FailedSigninFrozenTime int `json:"failedSigninFrozenTime"`

View File

@ -60,7 +60,7 @@ type VerificationRecord struct {
IsUsed bool `xorm:"notnull" json:"isUsed"`
}
func IsAllowSend(user *User, remoteAddr, recordType, lang string) error {
func IsAllowSend(user *User, remoteAddr, recordType string) error {
var record VerificationRecord
record.RemoteAddr = remoteAddr
record.Type = recordType
@ -78,15 +78,10 @@ func IsAllowSend(user *User, remoteAddr, recordType, lang string) error {
return errors.New("you can only send one code in 60s")
}
err = checkSigninErrorTimes(user, lang)
if err != nil {
return err
}
return nil
}
func SendVerificationCodeToEmail(organization *Organization, user *User, provider *Provider, remoteAddr string, dest string, lang string) error {
func SendVerificationCodeToEmail(organization *Organization, user *User, provider *Provider, remoteAddr string, dest string) error {
sender := organization.DisplayName
title := provider.Title
@ -104,7 +99,7 @@ func SendVerificationCodeToEmail(organization *Organization, user *User, provide
}
content = strings.Replace(content, "%{user.friendlyName}", userString, 1)
err := IsAllowSend(user, remoteAddr, provider.Category, lang)
err := IsAllowSend(user, remoteAddr, provider.Category)
if err != nil {
return err
}
@ -122,8 +117,8 @@ func SendVerificationCodeToEmail(organization *Organization, user *User, provide
return nil
}
func SendVerificationCodeToPhone(organization *Organization, user *User, provider *Provider, remoteAddr string, dest string, lang string) error {
err := IsAllowSend(user, remoteAddr, provider.Category, lang)
func SendVerificationCodeToPhone(organization *Organization, user *User, provider *Provider, remoteAddr string, dest string) error {
err := IsAllowSend(user, remoteAddr, provider.Category)
if err != nil {
return err
}

View File

@ -804,6 +804,33 @@ class ApplicationEditPage extends React.Component {
</Row>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("application:Background URL Mobile"), i18next.t("application:Background URL Mobile - Tooltip"))} :
</Col>
<Col span={22} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:URL"), i18next.t("general:URL - Tooltip"))} :
</Col>
<Col span={22} >
<Input prefix={<LinkOutlined />} value={this.state.application.formBackgroundUrlMobile} onChange={e => {
this.updateApplicationField("formBackgroundUrlMobile", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{i18next.t("general:Preview")}:
</Col>
<Col span={22} >
<a target="_blank" rel="noreferrer" href={this.state.application.formBackgroundUrlMobile}>
<img src={this.state.application.formBackgroundUrlMobile} alt={this.state.application.formBackgroundUrlMobile} height={90} style={{marginBottom: "20px"}} />
</a>
</Col>
</Row>
</Col>
</Row>
<Row>
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("application:Custom CSS"), i18next.t("application:Custom CSS - Tooltip"))} :

View File

@ -109,7 +109,7 @@ class EntryPage extends React.Component {
<React.Fragment>
<CustomHead headerHtml={this.state.application?.headerHtml} />
<div className={`${isDarkMode ? "loginBackgroundDark" : "loginBackground"}`}
style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${this.state.application?.formBackgroundUrl})`}}>
style={{backgroundImage: Setting.inIframe() ? null : (Setting.isMobile() ? `url(${this.state.application?.formBackgroundUrlMobile})` : `url(${this.state.application?.formBackgroundUrl})`)}}>
<Spin size="large" spinning={this.state.application === undefined && this.state.pricing === undefined} tip={i18next.t("login:Loading")}
style={{width: "100%", margin: "0 auto", position: "absolute"}} />
<Switch>

View File

@ -61,6 +61,7 @@ class LoginPage extends React.Component {
isTermsOfUseVisible: false,
termsOfUseContent: "",
orgChoiceMode: new URLSearchParams(props.location?.search).get("orgChoiceMode") ?? null,
userLang: null,
};
if (this.state.type === "cas" && props.match?.params.casApplicationName !== undefined) {
@ -415,6 +416,7 @@ class LoginPage extends React.Component {
login(values) {
// here we are supposed to determine whether Casdoor is working as an OAuth server or CAS server
values["language"] = this.state.userLang ?? "";
if (this.state.type === "cas") {
// CAS
const casParams = Util.getCasParameters();
@ -566,7 +568,7 @@ class LoginPage extends React.Component {
return (
<div key={resultItemKey} className="login-languages">
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<LanguageSelect languages={application.organizationObj.languages} />
<LanguageSelect languages={application.organizationObj.languages} onClick={key => {this.setState({userLang: key});}} />
</div>
);
} else if (signinItem.name === "Signin methods") {
@ -805,7 +807,6 @@ class LoginPage extends React.Component {
<Form
name="normal_login"
initialValues={{
organization: application.organization,
application: application.name,
autoSignin: true,

View File

@ -30,6 +30,7 @@ class LanguageSelect extends React.Component {
this.state = {
classes: props,
languages: props.languages ?? Setting.Countries.map(item => item.key),
onClick: props.onClick,
};
Setting.Countries.forEach((country) => {
@ -50,6 +51,9 @@ class LanguageSelect extends React.Component {
render() {
const languageItems = this.getOrganizationLanguages(this.state.languages);
const onClick = (e) => {
if (typeof this.state.onClick === "function") {
this.state.onClick(e.key);
}
Setting.setLanguage(e.key);
};