Compare commits

..

5 Commits

12 changed files with 1611 additions and 5 deletions

View File

@@ -435,9 +435,15 @@ func (c *ApiController) ResetEmailOrPhone() {
switch destType {
case object.VerifyTypeEmail:
id := user.GetId()
user.Email = dest
user.EmailVerified = true
_, err = object.UpdateUser(user.GetId(), user, []string{"email", "email_verified"}, false)
columns := []string{"email", "email_verified"}
if organization.UseEmailAsUsername {
user.Name = user.Email
columns = append(columns, "name")
}
_, err = object.UpdateUser(id, user, columns, false)
case object.VerifyTypePhone:
user.Phone = dest
_, err = object.SetUserField(user, "phone", user.Phone)
@@ -449,6 +455,9 @@ func (c *ApiController) ResetEmailOrPhone() {
c.ResponseError(err.Error())
return
}
if organization.UseEmailAsUsername {
c.SetSessionUsername(user.GetId())
}
err = object.DisableVerificationCode(checkDest)
if err != nil {

View File

@@ -47,6 +47,7 @@ func TestGenerateI18nFrontend(t *testing.T) {
applyToOtherLanguage("frontend", "fa", data)
applyToOtherLanguage("frontend", "cs", data)
applyToOtherLanguage("frontend", "sk", data)
applyToOtherLanguage("frontend", "az", data)
}
func TestGenerateI18nBackend(t *testing.T) {
@@ -77,4 +78,5 @@ func TestGenerateI18nBackend(t *testing.T) {
applyToOtherLanguage("backend", "fa", data)
applyToOtherLanguage("backend", "cs", data)
applyToOtherLanguage("backend", "sk", data)
applyToOtherLanguage("backend", "az", data)
}

193
i18n/locales/az/data.json Normal file
View File

@@ -0,0 +1,193 @@
{
"account": {
"Failed to add user": "İstifadəçi əlavə etmə uğursuz oldu",
"Get init score failed, error: %w": "Başlanğıc xal alınması uğursuz oldu, xəta: %w",
"Please sign out first": "Xahiş edirik əvvəlcə çıxış edin",
"The application does not allow to sign up new account": "Tətbiq yeni hesab qeydiyyatına icazə vermir"
},
"auth": {
"Challenge method should be S256": "Çağırış metodu S256 olmalıdır",
"DeviceCode Invalid": "Cihaz Kodu Etibarsızdır",
"Failed to create user, user information is invalid: %s": "İstifadəçi yaratma uğursuz oldu, istifadəçi məlumatları etibarsızdır: %s",
"Failed to login in: %s": "Giriş uğursuz oldu: %s",
"Invalid token": "Etibarsız token",
"State expected: %s, but got: %s": "Gözlənilən vəziyyət: %s, lakin alınan: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "Provayder üçün hesab: %s və istifadəçi adı: %s (%s) mövcud deyil və %%s vasitəsilə yeni hesab olaraq qeydiyyatdan keçməyə icazə verilmir, xahiş edirik qeydiyyat üçün başqa üsul istifadə edin",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "Provayder üçün hesab: %s və istifadəçi adı: %s (%s) mövcud deyil və yeni hesab olaraq qeydiyyatdan keçməyə icazə verilmir, xahiş edirik IT dəstəyinizlə əlaqə saxlayın",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "Provayder üçün hesab: %s və istifadəçi adı: %s (%s) artıq başqa hesabla əlaqələndirilmişdir: %s (%s)",
"The application: %s does not exist": "Tətbiq: %s mövcud deyil",
"The application: %s has disabled users to signin": "Tətbiq: %s istifadəçilərin girişini söndürmüşdür",
"The login method: login with LDAP is not enabled for the application": "Giriş metodu: LDAP ilə giriş bu tətbiq üçün aktiv deyil",
"The login method: login with SMS is not enabled for the application": "Giriş metodu: SMS ilə giriş bu tətbiq üçün aktiv deyil",
"The login method: login with email is not enabled for the application": "Giriş metodu: email ilə giriş bu tətbiq üçün aktiv deyil",
"The login method: login with face is not enabled for the application": "Giriş metodu: üz ilə giriş bu tətbiq üçün aktiv deyil",
"The login method: login with password is not enabled for the application": "Giriş metodu: şifrə ilə giriş bu tətbiq üçün aktiv deyil",
"The organization: %s does not exist": "Təşkilat: %s mövcud deyil",
"The organization: %s has disabled users to signin": "Təşkilat: %s istifadəçilərin girişini söndürmüşdür",
"The provider: %s does not exist": "Provayder: %s mövcud deyil",
"The provider: %s is not enabled for the application": "Provayder: %s bu tətbiq üçün aktiv deyil",
"Unauthorized operation": "İcazəsiz əməliyyat",
"Unknown authentication type (not password or provider), form = %s": "Naməlum təsdiq növü (şifrə və ya provayder deyil), forma = %s",
"User's tag: %s is not listed in the application's tags": "İstifadəçinin teqi: %s tətbiqin teqləri siyahısında yoxdur",
"UserCode Expired": "İstifadəçi Kodunun Vaxtı Keçib",
"UserCode Invalid": "İstifadəçi Kodu Etibarsızdır",
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "ödənişli istifadəçi %s aktiv və ya gözləyən abunəyə malik deyil və tətbiq: %s defolt qiymətləndirməyə malik deyil",
"the application for user %s is not found": "istifadəçi %s üçün tətbiq tapılmadı",
"the organization: %s is not found": "təşkilat: %s tapılmadı"
},
"cas": {
"Service %s and %s do not match": "Xidmət %s və %s uyğun gəlmir"
},
"check": {
"%s does not meet the CIDR format requirements: %s": "%s CIDR format tələblərinə cavab vermir: %s",
"Affiliation cannot be blank": "Mənsub sahəsi boş ola bilməz",
"CIDR for IP: %s should not be empty": "IP üçün CIDR: %s boş olmamalıdır",
"Default code does not match the code's matching rules": "Defolt kod kodun uyğunluq qaydalara uyğun gəlmir",
"DisplayName cannot be blank": "Göstərilən Ad boş ola bilməz",
"DisplayName is not valid real name": "Göstərilən Ad etibarlı həqiqi ad deyil",
"Email already exists": "Email artıq mövcuddur",
"Email cannot be empty": "Email boş ola bilməz",
"Email is invalid": "Email etibarsızdır",
"Empty username.": "Boş istifadəçi adı.",
"Face data does not exist, cannot log in": "Üz məlumatları mövcud deyil, giriş edilə bilməz",
"Face data mismatch": "Üz məlumatları uyğun gəlmir",
"Failed to parse client IP: %s": "Müştəri IP-ni təhlil etmək uğursuz oldu: %s",
"FirstName cannot be blank": "Ad boş ola bilməz",
"Invitation code cannot be blank": "Dəvət kodu boş ola bilməz",
"Invitation code exhausted": "Dəvət kodu tükənib",
"Invitation code is invalid": "Dəvət kodu etibarsızdır",
"Invitation code suspended": "Dəvət kodu dayandırılıb",
"LDAP user name or password incorrect": "LDAP istifadəçi adı və ya şifrə yanlışdır",
"LastName cannot be blank": "Soyad boş ola bilməz",
"Multiple accounts with same uid, please check your ldap server": "Eyni uid ilə çoxlu hesablar, xahiş edirik ldap serverinizi yoxlayın",
"Organization does not exist": "Təşkilat mövcud deyil",
"Password cannot be empty": "Şifrə boş ola bilməz",
"Phone already exists": "Telefon artıq mövcuddur",
"Phone cannot be empty": "Telefon boş ola bilməz",
"Phone number is invalid": "Telefon nömrəsi etibarsızdır",
"Please register using the email corresponding to the invitation code": "Xahiş edirik dəvət koduna uyğun email istifadə edərək qeydiyyatdan keçin",
"Please register using the phone corresponding to the invitation code": "Xahiş edirik dəvət koduna uyğun telefon istifadə edərək qeydiyyatdan keçin",
"Please register using the username corresponding to the invitation code": "Xahiş edirik dəvət koduna uyğun istifadəçi adı istifadə edərək qeydiyyatdan keçin",
"Session outdated, please login again": "Sessiyanın vaxtı keçib, xahiş edirik yenidən daxil olun",
"The invitation code has already been used": "Dəvət kodu artıq istifadə edilib",
"The user is forbidden to sign in, please contact the administrator": "İstifadəçinin girişi qadağandır, xahiş edirik administratorla əlaqə saxlayın",
"The user: %s doesn't exist in LDAP server": "İstifadəçi: %s LDAP serverində mövcud deyil",
"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.": "İstifadəçi adı yalnız hərf-rəqəm simvolları, alt xətt və ya defis ehtiva edə bilər, ardıcıl defis və ya alt xətt ola bilməz və defis və ya alt xəttlə başlaya və ya bitə bilməz.",
"The value \\\"%s\\\" for account field \\\"%s\\\" doesn't match the account item regex": "Hesab sahəsi \\\"%s\\\" üçün dəyər \\\"%s\\\" hesab elementi regex-inə uyğun gəlmir",
"The value \\\"%s\\\" for signup field \\\"%s\\\" doesn't match the signup item regex of the application \\\"%s\\\"": "Qeydiyyat sahəsi \\\"%s\\\" üçün dəyər \\\"%s\\\" tətbiq \\\"%s\\\"in qeydiyyat elementi regex-inə uyğun gəlmir",
"Username already exists": "İstifadəçi adı artıq mövcuddur",
"Username cannot be an email address": "İstifadəçi adı email ünvanı ola bilməz",
"Username cannot contain white spaces": "İstifadəçi adı boşluqlar ehtiva edə bilməz",
"Username cannot start with a digit": "İstifadəçi adı rəqəmlə başlaya bilməz",
"Username is too long (maximum is 255 characters).": "İstifadəçi adı çox uzundur (maksimum 255 simvoldur).",
"Username must have at least 2 characters": "İstifadəçi adı ən azı 2 simvola malik olmalıdır",
"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.": "İstifadəçi adı email formatını dəstəkləyir. Həmçinin istifadəçi adı yalnız hərf-rəqəm simvolları, alt xətt və ya defis ehtiva edə bilər, ardıcıl defis və ya alt xətt ola bilməz və defis və ya alt xəttlə başlaya və ya bitə bilməz. Həmçinin email formatına diqqət edin.",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Yanlış şifrə və ya kod dəfələrlə daxil etmisiniz, xahiş edirik %d dəqiqə gözləyin və yenidən cəhd edin",
"Your IP address: %s has been banned according to the configuration of: ": "IP ünvanınız: %s konfiqurasiyaya görə qadağan edilib: ",
"Your password has expired. Please reset your password by clicking \\\"Forgot password\\\"": "Şifrənizin vaxtı keçib. Xahiş edirik \\\"Şifrəni unutdum\\\" düyməsinə basaraq şifrənizi sıfırlayın",
"Your region is not allow to signup by phone": "Regionunuzda telefonla qeydiyyata icazə verilmir",
"password or code is incorrect": "şifrə və ya kod yanlışdır",
"password or code is incorrect, you have %s remaining chances": "şifrə və ya kod yanlışdır, %s şansınız qalıb",
"unsupported password type: %s": "dəstəklənməyən şifrə növü: %s"
},
"enforcer": {
"the adapter: %s is not found": "adapter: %s tapılmadı"
},
"general": {
"Failed to import groups": "Qrupları idxal etmək uğursuz oldu",
"Failed to import users": "İstifadəçiləri idxal etmək uğursuz oldu",
"Missing parameter": "Parametr çatışmır",
"Only admin user can specify user": "Yalnız admin istifadəçi başqa istifadəçini təyin edə bilər",
"Please login first": "Xahiş edirik əvvəlcə daxil olun",
"The organization: %s should have one application at least": "Təşkilat: %s ən azı bir tətbiqə malik olmalıdır",
"The user: %s doesn't exist": "İstifadəçi: %s mövcud deyil",
"Wrong userId": "Yanlış istifadəçi ID-si",
"don't support captchaProvider: ": "captcha provayderini dəstəkləmir: ",
"this operation is not allowed in demo mode": "bu əməliyyat demo rejimində icazə verilmir",
"this operation requires administrator to perform": "bu əməliyyat administrator tərəfindən yerinə yetirilməsini tələb edir"
},
"ldap": {
"Ldap server exist": "LDAP serveri mövcuddur"
},
"link": {
"Please link first": "Xahiş edirik əvvəlcə əlaqələndirin",
"This application has no providers": "Bu tətbiqin provayderləri yoxdur",
"This application has no providers of type": "Bu tətbiqin bu növdə provayderi yoxdur",
"This provider can't be unlinked": "Bu provayderin əlaqəsi kəsilə bilməz",
"You are not the global admin, you can't unlink other users": "Siz qlobal admin deyilsiniz, digər istifadəçilərin əlaqəsini kəsə bilməzsiniz",
"You can't unlink yourself, you are not a member of any application": "Öz əlaqənizi kəsə bilməzsiniz, heç bir tətbiqin üzvü deyilsiniz"
},
"organization": {
"Only admin can modify the %s.": "Yalnız admin %s-ni dəyişdirə bilər.",
"The %s is immutable.": "%s dəyişilməzdir.",
"Unknown modify rule %s.": "Naməlum dəyişdirmə qaydası %s.",
"adding a new user to the 'built-in' organization is currently disabled. Please note: all users in the 'built-in' organization are global administrators in Casdoor. Refer to the docs: https://casdoor.org/docs/basic/core-concepts#how-does-casdoor-manage-itself. If you still wish to create a user for the 'built-in' organization, go to the organization's settings page and enable the 'Has privilege consent' option.": "'built-in' təşkilatına yeni istifadəçi əlavə etmək hazırda söndürülüb. Qeyd edin: 'built-in' təşkilatındakı bütün istifadəçilər Casdoor-da qlobal administratorlardır. Sənədlərə baxın: https://casdoor.org/docs/basic/core-concepts#how-does-casdoor-manage-itself. Əgər hələ də 'built-in' təşkilat üçün istifadəçi yaratmaq istəyirsinizsə, təşkilatın tənzimləmələr səhifəsinə gedib 'İmtiyaz razılığına malikdir' seçimini aktiv edin."
},
"permission": {
"The permission: \\\"%s\\\" doesn't exist": "İcazə: \\\"%s\\\" mövcud deyil"
},
"provider": {
"Invalid application id": "Etibarsız tətbiq id-si",
"the provider: %s does not exist": "provayder: %s mövcud deyil"
},
"resource": {
"User is nil for tag: avatar": "Avatar teqi üçün istifadəçi nil-dir",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "İstifadəçi adı və ya tam fayl yolu boşdur: istifadəçi adı = %s, tam fayl yolu = %s"
},
"saml": {
"Application %s not found": "Tətbiq %s tapılmadı"
},
"saml_sp": {
"provider %s's category is not SAML": "provayder %s-in kateqoriyası SAML deyil"
},
"service": {
"Empty parameters for emailForm: %v": "emailForm üçün boş parametrlər: %v",
"Invalid Email receivers: %s": "Etibarsız Email qəbuledicilər: %s",
"Invalid phone receivers: %s": "Etibarsız telefon qəbuledicilər: %s"
},
"storage": {
"The objectKey: %s is not allowed": "obyekt açarı: %s icazə verilmir",
"The provider type: %s is not supported": "provayder növü: %s dəstəklənmir"
},
"subscription": {
"Error": "Xəta"
},
"token": {
"Grant_type: %s is not supported in this application": "Grant_type: %s bu tətbiqdə dəstəklənmir",
"Invalid application or wrong clientSecret": "Etibarsız tətbiq və ya yanlış müştəri sirri",
"Invalid client_id": "Etibarsız client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Yönləndirmə URI: %s icazə verilən Yönləndirmə URI siyahısında mövcud deyil",
"Token not found, invalid accessToken": "Token tapılmadı, etibarsız accessToken"
},
"user": {
"Display name cannot be empty": "Göstərilən ad boş ola bilməz",
"MFA email is enabled but email is empty": "MFA email aktiv edilib, lakin email boşdur",
"MFA phone is enabled but phone number is empty": "MFA telefon aktiv edilib, lakin telefon nömrəsi boşdur",
"New password cannot contain blank space.": "Yeni şifrə boş yer ehtiva edə bilməz.",
"the user's owner and name should not be empty": "istifadəçinin sahibi və adı boş olmamalıdır"
},
"util": {
"No application is found for userId: %s": "İstifadəçi ID-si üçün heç bir tətbiq tapılmadı: %s",
"No provider for category: %s is found for application: %s": "Tətbiq üçün kateqoriya üçün heç bir provayder tapılmadı: %s: %s",
"The provider: %s is not found": "Provayder: %s tapılmadı"
},
"verification": {
"Invalid captcha provider.": "Etibarsız captcha provaydeři.",
"Phone number is invalid in your region %s": "Telefon nömrəsi sizin regionunuzda etibarsızdır %s",
"The verification code has already been used!": "Doğrulama kodu artıq istifadə edilib!",
"The verification code has not been sent yet!": "Doğrulama kodu hələ göndərilməyib!",
"Turing test failed.": "Türinq testi uğursuz oldu.",
"Unable to get the email modify rule.": "Email dəyişdirmə qaydasını əldə etmək mümkün olmadı.",
"Unable to get the phone modify rule.": "Telefon dəyişdirmə qaydasını əldə etmək mümkün olmadı.",
"Unknown type": "Naməlum növ",
"Wrong verification code!": "Yanlış doğrulama kodu!",
"You should verify your code in %d min!": "Kodunuzu %d dəqiqə içində doğrulamalısınız!",
"please add a SMS provider to the \\\"Providers\\\" list for the application: %s": "xahiş edirik tətbiq üçün \\\"Provaydeerlər\\\" siyahısına SMS provaydeři əlavə edin: %s",
"please add an Email provider to the \\\"Providers\\\" list for the application: %s": "xahiş edirik tətbiq üçün \\\"Provaydeerlər\\\" siyahısına Email provaydeři əlavə edin: %s",
"the user does not exist, please sign up first": "istifadəçi mövcud deyil, xahiş edirik əvvəlcə qeydiyyatdan keçin"
},
"webauthn": {
"Found no credentials for this user": "Bu istifadəçi üçün heç bir etimadnamə tapılmadı",
"Please call WebAuthnSigninBegin first": "Xahiş edirik əvvəlcə WebAuthnSigninBegin çağırın"
}
}

View File

@@ -37,7 +37,8 @@
"UA",
"KZ",
"CZ",
"SK"
"SK",
"AZ"
],
"defaultAvatar": "",
"defaultApplication": "",
@@ -66,7 +67,8 @@
"kk",
"fa",
"cs",
"sk"
"sk",
"az"
],
"masterPassword": "",
"defaultPassword": "",

View File

@@ -60,6 +60,7 @@ export const Countries = [
{label: "فارسی", key: "fa", country: "IR", alt: "فارسی"},
{label: "Čeština", key: "cs", country: "CZ", alt: "Čeština"},
{label: "Slovenčina", key: "sk", country: "SK", alt: "Slovenčina"},
{label: "Azərbaycan dili", key: "az", country: "AZ", alt: "Azərbaycan dili"},
];
export function getThemeData(organization, application) {
@@ -156,7 +157,7 @@ export const OtherProviderInfo = {
url: "https://control.msg91.com/app/",
},
"OSON SMS": {
logo: "https://osonsms.com/images/osonsms-logo.svg",
logo: `${StaticBaseUrl}/img/social_osonsms.svg`,
url: "https://osonsms.com/",
},
"Custom HTTP SMS": {

View File

@@ -1117,6 +1117,32 @@ class UserEditPage extends React.Component {
</Col>
</Row>
);
} else if (accountItem.name === "First name") {
return (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:First name"), i18next.t("general:First name - Tooltip"))} :
</Col>
<Col span={22}>
<Input value={this.state.user.firstName} onChange={e => {
this.updateUserField("firstName", e.target.value);
}} />
</Col>
</Row>
);
} else if (accountItem.name === "Last name") {
return (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Last name"), i18next.t("general:Last name - Tooltip"))} :
</Col>
<Col span={22}>
<Input value={this.state.user.lastName} onChange={e => {
this.updateUserField("lastName", e.target.value);
}} />
</Col>
</Row>
);
}
}

View File

@@ -364,6 +364,40 @@ class SignupPage extends React.Component {
<Input className="signup-name-input" placeholder={signupItem.placeholder} />
</Form.Item>
);
} else if (signupItem.name === "First name" && this.state?.displayNameRule !== "First, last") {
return (
<Form.Item
name="firstName"
className="signup-first-name"
label={signupItem.label ? signupItem.label : i18next.t("general:First name")}
rules={[
{
required: required,
message: i18next.t("signup:Please input your first name!"),
whitespace: true,
},
]}
>
<Input className="signup-first-name-input" placeholder={signupItem.placeholder} />
</Form.Item>
);
} else if (signupItem.name === "Last name" && this.state?.displayNameRule !== "First, last") {
return (
<Form.Item
name="lastName"
className="signup-last-name"
label={signupItem.label ? signupItem.label : i18next.t("general:Last name")}
rules={[
{
required: required,
message: i18next.t("signup:Please input your last name!"),
whitespace: true,
},
]}
>
<Input className="signup-last-name-input" placeholder={signupItem.placeholder} />
</Form.Item>
);
} else if (signupItem.name === "Affiliation") {
return (
<Form.Item
@@ -776,6 +810,12 @@ class SignupPage extends React.Component {
this.form.current?.setFieldValue("invitationCode", this.state.invitationCode);
}
}
const displayNameItem = application.signupItems?.find(item => item.name === "Display name");
if (displayNameItem && !this.state.displayNameRule) {
this.setState({displayNameRule: displayNameItem.rule});
}
return (
<Form
{...formItemLayout}

View File

@@ -83,7 +83,7 @@ export const CaptchaModal = (props) => {
const renderDefaultCaptcha = () => {
if (noModal) {
return (
<Row style={{textAlign: "center"}}>
<Row style={{textAlign: "center"}} gutter={10}>
<Col
style={{flex: noModal ? "70%" : "100%"}}>
<Input

View File

@@ -133,6 +133,9 @@ function initLanguage() {
case "sk-SK":
language = "sk";
break;
case "az":
language = "az";
break;
default:
language = Conf.DefaultLanguage;
}

1326
web/src/locales/az/data.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -67,6 +67,8 @@ class AccountTable extends React.Component {
{name: "ID", label: i18next.t("general:ID")},
{name: "Name", label: i18next.t("general:Name")},
{name: "Display name", label: i18next.t("general:Display name")},
{name: "First name", label: i18next.t("general:First name")},
{name: "Last name", label: i18next.t("general:Last name")},
{name: "Avatar", label: i18next.t("general:Avatar")},
{name: "User type", label: i18next.t("general:User type")},
{name: "Password", label: i18next.t("general:Password")},

View File

@@ -94,6 +94,8 @@ class SignupTable extends React.Component {
{name: "Username", displayName: i18next.t("signup:Username")},
{name: "ID", displayName: i18next.t("general:ID")},
{name: "Display name", displayName: i18next.t("general:Display name")},
{name: "First name", displayName: i18next.t("general:First name")},
{name: "Last name", displayName: i18next.t("general:Last name")},
{name: "Affiliation", displayName: i18next.t("user:Affiliation")},
{name: "Gender", displayName: i18next.t("user:Gender")},
{name: "Bio", displayName: i18next.t("user:Bio")},