mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
ci: add password complexity options to organization edit page (#1949)
* Support uploading roles and permissions via xlsx file. * Template xlsx file for uploading users and permissions. * reformat according to gofumpt. * fix typo. * add password complexity options to organization edit page. * add password complexity options to organization edit page. * Fixed Typos. * Fixed Typos. * feat:add password complexity options to organization edit page * Auto generate i18n fields. * Refactor code according to instructions * Support autocheck passwd complexity in frontend when setting passwd in user edit page. * feat:Backend Support for password validation in signup and forget page. * feat:Frontend Support for password validation in signup and forget page. * Add default password complex option & Update historical empty filed with default option. * Migrator for field `password_complex_options` in org table. * feat: support frontend password complex option check in user_edit/forget/signup page. * frontend update for user edit page * update i18n file --------- Co-authored-by: hsluoyz <hsluoyz@qq.com>
This commit is contained in:
parent
edc6aa0d50
commit
0f57ac297b
@ -140,6 +140,13 @@ func (c *ApiController) Signup() {
|
||||
username = id
|
||||
}
|
||||
|
||||
password := authForm.Password
|
||||
msg = object.CheckPasswordComplexityByOrg(organization, password)
|
||||
if msg != "" {
|
||||
c.ResponseError(msg)
|
||||
return
|
||||
}
|
||||
|
||||
initScore, err := organization.GetInitScore()
|
||||
if err != nil {
|
||||
c.ResponseError(fmt.Errorf(c.T("account:Get init score failed, error: %w"), err).Error())
|
||||
|
@ -448,6 +448,12 @@ func (c *ApiController) SetPassword() {
|
||||
}
|
||||
}
|
||||
|
||||
msg := object.CheckPasswordComplexity(targetUser, newPassword)
|
||||
if msg != "" {
|
||||
c.ResponseError(msg)
|
||||
return
|
||||
}
|
||||
|
||||
targetUser.Password = newPassword
|
||||
_, err = object.SetUserField(targetUser, "password", targetUser.Password)
|
||||
if err != nil {
|
||||
|
@ -8,6 +8,7 @@
|
||||
"favicon": "",
|
||||
"passwordType": "plain",
|
||||
"passwordSalt": "",
|
||||
"passwordOptions": ["AtLeast6"],
|
||||
"countryCodes": ["US", "ES", "CN", "FR", "DE", "GB", "JP", "KR", "VN", "ID", "SG", "IN"],
|
||||
"defaultAvatar": "",
|
||||
"defaultApplication": "",
|
||||
|
@ -203,6 +203,16 @@ func CheckPassword(user *User, password string, lang string, options ...bool) st
|
||||
}
|
||||
}
|
||||
|
||||
func CheckPasswordComplexityByOrg(organization *Organization, password string) string {
|
||||
errorMsg := checkPasswordComplexity(password, organization.PasswordOptions)
|
||||
return errorMsg
|
||||
}
|
||||
|
||||
func CheckPasswordComplexity(user *User, password string) string {
|
||||
organization, _ := GetOrganizationByUser(user)
|
||||
return CheckPasswordComplexityByOrg(organization, password)
|
||||
}
|
||||
|
||||
func checkLdapUserPassword(user *User, password string, lang string) string {
|
||||
ldaps, err := GetLdaps(user.Owner)
|
||||
if err != nil {
|
||||
|
98
object/check_password_complexity.go
Normal file
98
object/check_password_complexity.go
Normal file
@ -0,0 +1,98 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package object
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type ValidatorFunc func(password string) string
|
||||
|
||||
var (
|
||||
regexLowerCase = regexp.MustCompile(`[a-z]`)
|
||||
regexUpperCase = regexp.MustCompile(`[A-Z]`)
|
||||
regexDigit = regexp.MustCompile(`\d`)
|
||||
regexSpecial = regexp.MustCompile(`[!@#$%^&*]`)
|
||||
)
|
||||
|
||||
func isValidOption_AtLeast6(password string) string {
|
||||
if len(password) < 6 {
|
||||
return "The password must have at least 6 characters"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func isValidOption_AtLeast8(password string) string {
|
||||
if len(password) < 8 {
|
||||
return "The password must have at least 8 characters"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func isValidOption_Aa123(password string) string {
|
||||
hasLowerCase := regexLowerCase.MatchString(password)
|
||||
hasUpperCase := regexUpperCase.MatchString(password)
|
||||
hasDigit := regexDigit.MatchString(password)
|
||||
|
||||
if !hasLowerCase || !hasUpperCase || !hasDigit {
|
||||
return "The password must contain at least one uppercase letter, one lowercase letter and one digit"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func isValidOption_SpecialChar(password string) string {
|
||||
if !regexSpecial.MatchString(password) {
|
||||
return "The password must contain at least one special character"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func isValidOption_NoRepeat(password string) string {
|
||||
for i := 0; i < len(password)-1; i++ {
|
||||
if password[i] == password[i+1] {
|
||||
return "The password must not contain any repeated characters"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func checkPasswordComplexity(password string, options []string) string {
|
||||
if len(password) == 0 {
|
||||
return "Please input your password!"
|
||||
}
|
||||
|
||||
if len(options) == 0 {
|
||||
options = []string{"AtLeast6"}
|
||||
}
|
||||
|
||||
checkers := map[string]ValidatorFunc{
|
||||
"AtLeast6": isValidOption_AtLeast6,
|
||||
"AtLeast8": isValidOption_AtLeast8,
|
||||
"Aa123": isValidOption_Aa123,
|
||||
"SpecialChar": isValidOption_SpecialChar,
|
||||
"NoRepeat": isValidOption_NoRepeat,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
checkerFunc, ok := checkers[option]
|
||||
if ok {
|
||||
errorMsg := checkerFunc(password)
|
||||
if errorMsg != "" {
|
||||
return errorMsg
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
@ -92,6 +92,7 @@ func initBuiltInOrganization() bool {
|
||||
WebsiteUrl: "https://example.com",
|
||||
Favicon: fmt.Sprintf("%s/img/casbin/favicon.ico", conf.GetConfigString("staticBaseUrl")),
|
||||
PasswordType: "plain",
|
||||
PasswordOptions: []string{"AtLeast6"},
|
||||
CountryCodes: []string{"US", "ES", "CN", "FR", "DE", "GB", "JP", "KR", "VN", "ID", "SG", "IN"},
|
||||
DefaultAvatar: fmt.Sprintf("%s/img/casbin.svg", conf.GetConfigString("staticBaseUrl")),
|
||||
Tags: []string{},
|
||||
|
@ -56,6 +56,7 @@ type Organization struct {
|
||||
Favicon string `xorm:"varchar(100)" json:"favicon"`
|
||||
PasswordType string `xorm:"varchar(100)" json:"passwordType"`
|
||||
PasswordSalt string `xorm:"varchar(100)" json:"passwordSalt"`
|
||||
PasswordOptions []string `xorm:"varchar(100)" json:"passwordOptions"`
|
||||
CountryCodes []string `xorm:"varchar(200)" json:"countryCodes"`
|
||||
DefaultAvatar string `xorm:"varchar(200)" json:"defaultAvatar"`
|
||||
DefaultApplication string `xorm:"varchar(100)" json:"defaultApplication"`
|
||||
|
@ -193,6 +193,29 @@ class OrganizationEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}}>
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Password complexity options"), i18next.t("general:Password complexity options - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select
|
||||
virtual={false}
|
||||
style={{width: "100%"}}
|
||||
mode="multiple"
|
||||
value={this.state.organization.passwordOptions}
|
||||
onChange={(value => {
|
||||
this.updateOrganizationField("passwordOptions", value);
|
||||
})}
|
||||
options={[
|
||||
{value: "AtLeast6", name: i18next.t("user:The password must have at least 6 characters")},
|
||||
{value: "AtLeast8", name: i18next.t("user:The password must have at least 8 characters")},
|
||||
{value: "Aa123", name: i18next.t("user:The password must contain at least one uppercase letter, one lowercase letter and one digit")},
|
||||
{value: "SpecialChar", name: i18next.t("user:The password must contain at least one special character")},
|
||||
{value: "NoRepeat", name: i18next.t("user:The password must not contain any repeated characters")},
|
||||
].map((item) => Setting.getOption(item.name, item.value))}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Supported country codes"), i18next.t("general:Supported country codes - Tooltip"))} :
|
||||
|
@ -34,6 +34,7 @@ class OrganizationListPage extends BaseListPage {
|
||||
favicon: `${Setting.StaticBaseUrl}/img/favicon.png`,
|
||||
passwordType: "plain",
|
||||
PasswordSalt: "",
|
||||
passwordOptions: [],
|
||||
countryCodes: ["CN"],
|
||||
defaultAvatar: `${Setting.StaticBaseUrl}/img/casbin.svg`,
|
||||
defaultApplication: "",
|
||||
|
@ -24,6 +24,8 @@ import * as UserBackend from "../backend/UserBackend";
|
||||
import {CheckCircleOutlined, KeyOutlined, LockOutlined, SolutionOutlined, UserOutlined} from "@ant-design/icons";
|
||||
import CustomGithubCorner from "../common/CustomGithubCorner";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import * as PasswordChecker from "../common/PasswordChecker";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
class ForgetPage extends React.Component {
|
||||
@ -45,7 +47,6 @@ class ForgetPage extends React.Component {
|
||||
|
||||
this.form = React.createRef();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.getApplicationObj() === undefined) {
|
||||
if (this.state.applicationName !== undefined) {
|
||||
@ -66,7 +67,6 @@ class ForgetPage extends React.Component {
|
||||
this.onUpdateApplication(application);
|
||||
});
|
||||
}
|
||||
|
||||
getApplicationObj() {
|
||||
return this.props.application;
|
||||
}
|
||||
@ -378,7 +378,15 @@ class ForgetPage extends React.Component {
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t("login:Please input your password!"),
|
||||
validateTrigger: "onChange",
|
||||
validator: (rule, value) => {
|
||||
const errorMsg = PasswordChecker.checkPasswordComplexity(value, application.organizationObj.passwordOptions);
|
||||
if (errorMsg === "") {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(errorMsg);
|
||||
}
|
||||
},
|
||||
},
|
||||
]}
|
||||
hasFeedback
|
||||
|
@ -28,6 +28,7 @@ import CustomGithubCorner from "../common/CustomGithubCorner";
|
||||
import LanguageSelect from "../common/select/LanguageSelect";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import {CountryCodeSelect} from "../common/select/CountryCodeSelect";
|
||||
import * as PasswordChecker from "../common/PasswordChecker";
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
@ -458,8 +459,15 @@ class SignupPage extends React.Component {
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
min: 6,
|
||||
message: i18next.t("login:Please input your password, at least 6 characters!"),
|
||||
validateTrigger: "onChange",
|
||||
validator: (rule, value) => {
|
||||
const errorMsg = PasswordChecker.checkPasswordComplexity(value, application.organizationObj.passwordOptions);
|
||||
if (errorMsg === "") {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject(errorMsg);
|
||||
}
|
||||
},
|
||||
},
|
||||
]}
|
||||
hasFeedback
|
||||
|
82
web/src/common/PasswordChecker.js
Normal file
82
web/src/common/PasswordChecker.js
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import i18next from "i18next";
|
||||
|
||||
function isValidOption_AtLeast6(password) {
|
||||
if (password.length < 6) {
|
||||
return i18next.t("user:The password must have at least 6 characters");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function isValidOption_AtLeast8(password) {
|
||||
if (password.length < 8) {
|
||||
return i18next.t("user:The password must have at least 8 characters");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function isValidOption_Aa123(password) {
|
||||
const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).+$/;
|
||||
if (!regex.test(password)) {
|
||||
return i18next.t("user:The password must contain at least one uppercase letter, one lowercase letter and one digit");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function isValidOption_SpecialChar(password) {
|
||||
const regex = /^(?=.*[!@#$%^&*]).+$/;
|
||||
if (!regex.test(password)) {
|
||||
return i18next.t("user:The password must contain at least one special character");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function isValidOption_NoRepeat(password) {
|
||||
const regex = /(.)\1+/;
|
||||
if (regex.test(password)) {
|
||||
return i18next.t("user:The password must not contain any repeated characters");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
export function checkPasswordComplexity(password, options) {
|
||||
if (password.length === 0) {
|
||||
return i18next.t("login:Please input your password!");
|
||||
}
|
||||
|
||||
if (options.length === 0) {
|
||||
options = ["AtLeast6"];
|
||||
}
|
||||
|
||||
const checkers = {
|
||||
AtLeast6: isValidOption_AtLeast6,
|
||||
AtLeast8: isValidOption_AtLeast8,
|
||||
Aa123: isValidOption_Aa123,
|
||||
SpecialChar: isValidOption_SpecialChar,
|
||||
NoRepeat: isValidOption_NoRepeat,
|
||||
};
|
||||
|
||||
for (const option of options) {
|
||||
const checkerFunc = checkers[option];
|
||||
if (checkerFunc) {
|
||||
const errorMsg = checkerFunc(password);
|
||||
if (errorMsg !== "") {
|
||||
return errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
@ -17,6 +17,8 @@ import i18next from "i18next";
|
||||
import React from "react";
|
||||
import * as UserBackend from "../../backend/UserBackend";
|
||||
import * as Setting from "../../Setting";
|
||||
import * as OrganizationBackend from "../../backend/OrganizationBackend";
|
||||
import * as PasswordChecker from "../PasswordChecker";
|
||||
|
||||
export const PasswordModal = (props) => {
|
||||
const [visible, setVisible] = React.useState(false);
|
||||
@ -27,6 +29,26 @@ export const PasswordModal = (props) => {
|
||||
const {user} = props;
|
||||
const {account} = props;
|
||||
|
||||
const [passwordOptions, setPasswordOptions] = React.useState([]);
|
||||
const [newPasswordValid, setNewPasswordValid] = React.useState(false);
|
||||
const [rePasswordValid, setRePasswordValid] = React.useState(false);
|
||||
const [newPasswordErrorMessage, setNewPasswordErrorMessage] = React.useState("");
|
||||
const [rePasswordErrorMessage, setRePasswordErrorMessage] = React.useState("");
|
||||
|
||||
React.useEffect(() => {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
const organizations = (res.msg === undefined) ? res : [];
|
||||
// Find the user's corresponding organization
|
||||
const organization = organizations.find((org) => org.name === user.owner);
|
||||
if (organization) {
|
||||
setPasswordOptions(organization.passwordOptions);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
});
|
||||
}, [user.owner]);
|
||||
const showModal = () => {
|
||||
setVisible(true);
|
||||
};
|
||||
@ -34,6 +56,24 @@ export const PasswordModal = (props) => {
|
||||
const handleCancel = () => {
|
||||
setVisible(false);
|
||||
};
|
||||
const handleNewPassword = (value) => {
|
||||
setNewPassword(value);
|
||||
|
||||
const errorMessage = PasswordChecker.checkPasswordComplexity(value, passwordOptions);
|
||||
setNewPasswordValid(errorMessage === "");
|
||||
setNewPasswordErrorMessage(errorMessage);
|
||||
};
|
||||
|
||||
const handleRePassword = (value) => {
|
||||
setRePassword(value);
|
||||
|
||||
if (value !== newPassword) {
|
||||
setRePasswordErrorMessage(i18next.t("signup:Your confirmed password is inconsistent with the password!"));
|
||||
setRePasswordValid(false);
|
||||
} else {
|
||||
setRePasswordValid(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handleOk = () => {
|
||||
if (newPassword === "" || rePassword === "") {
|
||||
@ -45,12 +85,44 @@ export const PasswordModal = (props) => {
|
||||
return;
|
||||
}
|
||||
setConfirmLoading(true);
|
||||
UserBackend.setPassword(user.owner, user.name, oldPassword, newPassword).then((res) => {
|
||||
|
||||
OrganizationBackend.getOrganizations("admin").then((res) => {
|
||||
const organizations = (res.msg === undefined) ? res : [];
|
||||
|
||||
// find the users' corresponding organization
|
||||
let organization = null;
|
||||
for (let i = 0; i < organizations.length; i++) {
|
||||
if (organizations[i].name === user.owner) {
|
||||
organization = organizations[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (organization === null) {
|
||||
Setting.showMessage("error", "organization is null");
|
||||
setConfirmLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const errorMsg = PasswordChecker.checkPasswordComplexity(newPassword, organization.passwordOptions);
|
||||
if (errorMsg !== "") {
|
||||
Setting.showMessage("error", errorMsg);
|
||||
setConfirmLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
UserBackend.setPassword(user.owner, user.name, oldPassword, newPassword)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("user:Password set successfully"));
|
||||
setVisible(false);
|
||||
} else {Setting.showMessage("error", i18next.t(`user:${res.msg}`));}
|
||||
} else {
|
||||
Setting.showMessage("error", i18next.t(`user:${res.msg}`));
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
setConfirmLoading(false);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -79,11 +151,23 @@ export const PasswordModal = (props) => {
|
||||
</Row>
|
||||
) : null}
|
||||
<Row style={{width: "100%", marginBottom: "20px"}}>
|
||||
<Input.Password addonBefore={i18next.t("user:New Password")} placeholder={i18next.t("user:input password")} onChange={(e) => setNewPassword(e.target.value)} />
|
||||
<Input.Password
|
||||
addonBefore={i18next.t("user:New Password")}
|
||||
placeholder={i18next.t("user:input password")}
|
||||
onChange={(e) => {handleNewPassword(e.target.value);}}
|
||||
status={(!newPasswordValid && newPasswordErrorMessage) ? "error" : undefined}
|
||||
/>
|
||||
</Row>
|
||||
{!newPasswordValid && newPasswordErrorMessage && <div style={{color: "red", marginTop: "-20px"}}>{newPasswordErrorMessage}</div>}
|
||||
<Row style={{width: "100%", marginBottom: "20px"}}>
|
||||
<Input.Password addonBefore={i18next.t("user:Re-enter New")} placeholder={i18next.t("user:input password")} onChange={(e) => setRePassword(e.target.value)} />
|
||||
<Input.Password
|
||||
addonBefore={i18next.t("user:Re-enter New")}
|
||||
placeholder={i18next.t("user:input password")}
|
||||
onChange={(e) => handleRePassword(e.target.value)}
|
||||
status={(!rePasswordValid && rePasswordErrorMessage) ? "error" : undefined}
|
||||
/>
|
||||
</Row>
|
||||
{!rePasswordValid && rePasswordErrorMessage && <div style={{color: "red", marginTop: "-20px"}}>{rePasswordErrorMessage}</div>}
|
||||
</Col>
|
||||
</Modal>
|
||||
</Row>
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "Organisationen",
|
||||
"Password": "Passwort",
|
||||
"Password - Tooltip": "Stellen Sie sicher, dass das Passwort korrekt ist",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||
"Password salt": "Passwort-Salt",
|
||||
"Password salt - Tooltip": "Zufälliger Parameter, der für die Verschlüsselung von Passwörtern verwendet wird",
|
||||
"Password type": "Passworttyp",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "Bitte geben Sie Ihren Code ein!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"Please input your password!": "Bitte geben Sie Ihr Passwort ein!",
|
||||
"Please input your password, at least 6 characters!": "Bitte geben Sie Ihr Passwort ein, es muss mindestens 6 Zeichen lang sein!",
|
||||
"Please select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "Passwort festlegen...",
|
||||
"Tag": "Tag",
|
||||
"Tag - Tooltip": "Tags des Benutzers",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "Titel",
|
||||
"Title - Tooltip": "Position in der Zugehörigkeit",
|
||||
"Two passwords you typed do not match.": "Zwei von Ihnen eingegebene Passwörter stimmen nicht überein.",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "Organizations",
|
||||
"Password": "Password",
|
||||
"Password - Tooltip": "Make sure the password is correct",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||
"Password salt": "Password salt",
|
||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||
"Password type": "Password type",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"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 select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "Set password...",
|
||||
"Tag": "Tag",
|
||||
"Tag - Tooltip": "Tag of the user",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "Title",
|
||||
"Title - Tooltip": "Position in the affiliation",
|
||||
"Two passwords you typed do not match.": "Two passwords you typed do not match.",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "Organizaciones",
|
||||
"Password": "Contraseña",
|
||||
"Password - Tooltip": "Asegúrate de que la contraseña sea correcta",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||
"Password salt": "Sal de contraseña",
|
||||
"Password salt - Tooltip": "Parámetro aleatorio utilizado para la encriptación de contraseñas",
|
||||
"Password type": "Tipo de contraseña",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "¡Por favor ingrese su código!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"Please input your password!": "¡Ingrese su contraseña, por favor!",
|
||||
"Please input your password, at least 6 characters!": "Por favor ingrese su contraseña, ¡de al menos 6 caracteres!",
|
||||
"Please select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "Establecer contraseña...",
|
||||
"Tag": "Etiqueta",
|
||||
"Tag - Tooltip": "Etiqueta del usuario",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "Título",
|
||||
"Title - Tooltip": "Posición en la afiliación",
|
||||
"Two passwords you typed do not match.": "Dos contraseñas que has escrito no coinciden.",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "Organisations",
|
||||
"Password": "Mot de passe",
|
||||
"Password - Tooltip": "Assurez-vous que le mot de passe est correct",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||
"Password salt": "Sel de mot de passe",
|
||||
"Password salt - Tooltip": "Paramètre aléatoire utilisé pour le cryptage de mot de passe",
|
||||
"Password type": "Type de mot de passe",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "Veuillez entrer votre code !",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"Please input your password!": "Veuillez entrer votre mot de passe !",
|
||||
"Please input your password, at least 6 characters!": "Veuillez entrer votre mot de passe, au moins 6 caractères!",
|
||||
"Please select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "Définir le mot de passe...",
|
||||
"Tag": "Étiquette",
|
||||
"Tag - Tooltip": "Tag de l'utilisateur",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "Titre",
|
||||
"Title - Tooltip": "Position dans l'affiliation",
|
||||
"Two passwords you typed do not match.": "Deux mots de passe que vous avez tapés ne correspondent pas.",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "Organisasi",
|
||||
"Password": "Kata sandi",
|
||||
"Password - Tooltip": "Pastikan kata sandi yang benar",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||
"Password salt": "Garam sandi",
|
||||
"Password salt - Tooltip": "Parameter acak yang digunakan untuk enkripsi kata sandi",
|
||||
"Password type": "Jenis kata sandi",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "Silakan masukkan kode Anda!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"Please input your password!": "Masukkan kata sandi Anda!",
|
||||
"Please input your password, at least 6 characters!": "Silakan masukkan kata sandi Anda, minimal 6 karakter!",
|
||||
"Please select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "Tetapkan kata sandi...",
|
||||
"Tag": "tanda",
|
||||
"Tag - Tooltip": "Tag pengguna",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "Judul",
|
||||
"Title - Tooltip": "Posisi dalam afiliasi",
|
||||
"Two passwords you typed do not match.": "Dua password yang Anda ketikkan tidak cocok.",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "組織",
|
||||
"Password": "パスワード",
|
||||
"Password - Tooltip": "パスワードが正しいことを確認してください",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||
"Password salt": "パスワードのソルト",
|
||||
"Password salt - Tooltip": "ランダムパラメーターは、パスワードの暗号化に使用されます",
|
||||
"Password type": "パスワードタイプ",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "あなたのコードを入力してください!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"Please input your password!": "パスワードを入力してください!",
|
||||
"Please input your password, at least 6 characters!": "パスワードを入力してください。少なくとも6文字です!",
|
||||
"Please select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "パスワードの設定...",
|
||||
"Tag": "タグ",
|
||||
"Tag - Tooltip": "ユーザーのタグ",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "タイトル",
|
||||
"Title - Tooltip": "所属のポジション",
|
||||
"Two passwords you typed do not match.": "2つのパスワードが一致しません。",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "조직들",
|
||||
"Password": "비밀번호",
|
||||
"Password - Tooltip": "비밀번호가 올바른지 확인하세요",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||
"Password salt": "비밀번호 솔트",
|
||||
"Password salt - Tooltip": "암호화에 사용되는 임의 매개변수",
|
||||
"Password type": "암호 유형",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "코드를 입력해주세요!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"Please input your password!": "비밀번호를 입력해주세요!",
|
||||
"Please input your password, at least 6 characters!": "비밀번호를 입력해주세요. 최소 6자 이상 필요합니다!",
|
||||
"Please select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "비밀번호 설정...",
|
||||
"Tag": "태그",
|
||||
"Tag - Tooltip": "사용자의 태그",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "제목",
|
||||
"Title - Tooltip": "소속 내 직위",
|
||||
"Two passwords you typed do not match.": "두 개의 비밀번호가 일치하지 않습니다.",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "Organizações",
|
||||
"Password": "Senha",
|
||||
"Password - Tooltip": "Certifique-se de que a senha está correta",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||
"Password salt": "Salt de senha",
|
||||
"Password salt - Tooltip": "Parâmetro aleatório usado para criptografia de senha",
|
||||
"Password type": "Tipo de senha",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "Por favor, informe o código!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"Please input your password!": "Por favor, informe sua senha!",
|
||||
"Please input your password, at least 6 characters!": "Por favor, informe sua senha, pelo menos 6 caracteres!",
|
||||
"Please select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "Definir senha...",
|
||||
"Tag": "Tag",
|
||||
"Tag - Tooltip": "Tag do usuário",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "Título",
|
||||
"Title - Tooltip": "Cargo na afiliação",
|
||||
"Two passwords you typed do not match.": "As duas senhas digitadas não coincidem.",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "Организации",
|
||||
"Password": "Пароль",
|
||||
"Password - Tooltip": "Убедитесь, что пароль правильный",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||
"Password salt": "Соль пароля",
|
||||
"Password salt - Tooltip": "Случайный параметр, используемый для шифрования пароля",
|
||||
"Password type": "Тип пароля",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "Пожалуйста, введите свой код!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"Please input your password!": "Пожалуйста, введите свой пароль!",
|
||||
"Please input your password, at least 6 characters!": "Пожалуйста, введите свой пароль, длина должна быть не менее 6 символов!",
|
||||
"Please select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "Установить пароль...",
|
||||
"Tag": "Метка",
|
||||
"Tag - Tooltip": "Тег пользователя",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "Заголовок",
|
||||
"Title - Tooltip": "Положение в аффилиации",
|
||||
"Two passwords you typed do not match.": "Два введенных вами пароля не совпадают.",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "Tổ chức",
|
||||
"Password": "Mật khẩu",
|
||||
"Password - Tooltip": "Hãy đảm bảo rằng mật khẩu là chính xác",
|
||||
"Password complexity options": "Password complexity options",
|
||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||
"Password salt": "Muối mật khẩu",
|
||||
"Password salt - Tooltip": "Tham số ngẫu nhiên được sử dụng để mã hóa mật khẩu",
|
||||
"Password type": "Loại mật khẩu",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "Vui lòng nhập mã của bạn!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
"Please input your password!": "Vui lòng nhập mật khẩu của bạn!",
|
||||
"Please input your password, at least 6 characters!": "Vui lòng nhập mật khẩu của bạn, ít nhất 6 ký tự!",
|
||||
"Please select an organization": "Please select an organization",
|
||||
"Please select an organization to sign in": "Please select an organization to sign in",
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "Đặt mật khẩu...",
|
||||
"Tag": "Thẻ",
|
||||
"Tag - Tooltip": "Thẻ của người dùng",
|
||||
"The password must contain at least one special character": "The password must contain at least one special character",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "The password must contain at least one uppercase letter, one lowercase letter and one digit",
|
||||
"The password must have at least 6 characters": "The password must have at least 6 characters",
|
||||
"The password must have at least 8 characters": "The password must have at least 8 characters",
|
||||
"The password must not contain any repeated characters": "The password must not contain any repeated characters",
|
||||
"Title": "Tiêu đề",
|
||||
"Title - Tooltip": "Vị trí trong tổ chức",
|
||||
"Two passwords you typed do not match.": "Hai mật khẩu mà bạn đã nhập không khớp.",
|
||||
|
@ -261,6 +261,8 @@
|
||||
"Organizations": "组织",
|
||||
"Password": "密码",
|
||||
"Password - Tooltip": "请确认密码正确",
|
||||
"Password complexity options": "密码复杂度选项",
|
||||
"Password complexity options - Tooltip": "密码复杂度组合,登录密码复杂度必须符合该规范",
|
||||
"Password salt": "密码Salt值",
|
||||
"Password salt - Tooltip": "用于密码加密的随机参数",
|
||||
"Password type": "密码类型",
|
||||
@ -394,7 +396,6 @@
|
||||
"Please input your code!": "请输入您的验证码!",
|
||||
"Please input your organization name!": "请输入组织的名字!",
|
||||
"Please input your password!": "请输入您的密码!",
|
||||
"Please input your password, at least 6 characters!": "请输入您的密码,不少于6位",
|
||||
"Please select an organization": "请选择一个组织",
|
||||
"Please select an organization to sign in": "请选择要登录的组织",
|
||||
"Please type an organization to sign in": "请输入要登录的组织",
|
||||
@ -938,6 +939,11 @@
|
||||
"Set password...": "设置密码...",
|
||||
"Tag": "标签",
|
||||
"Tag - Tooltip": "用户的标签",
|
||||
"The password must contain at least one special character": "密码必须包含至少一个特殊字符",
|
||||
"The password must contain at least one uppercase letter, one lowercase letter and one digit": "密码必须包含至少一个大写字母、一个小写字母和一个数字",
|
||||
"The password must have at least 6 characters": "密码长度必须至少为6个字符",
|
||||
"The password must have at least 8 characters": "密码长度必须至少为8个字符",
|
||||
"The password must not contain any repeated characters": "密码不得包含任何重复字符",
|
||||
"Title": "职务",
|
||||
"Title - Tooltip": "在工作单位担任的职务",
|
||||
"Two passwords you typed do not match.": "两次输入的密码不匹配。",
|
||||
|
Loading…
x
Reference in New Issue
Block a user