Compare commits

...

29 Commits

Author SHA1 Message Date
d1c55d5aa7 fix: improve error message in token_cas.go 2024-03-17 22:01:49 +08:00
c8aa35c9c6 feat: add token to the page for Chrome extension (#2804)
* feat: add token to the page for Chrome extension

* Update token_oauth.go

---------

Co-authored-by: Eric Luo <hsluoyz@qq.com>
2024-03-17 22:01:28 +08:00
6037f37b87 feat: add default token format for built-in app 2024-03-17 20:46:01 +08:00
1b478903d8 feat: fix login page error cannot show bug 2024-03-17 11:39:12 +08:00
4f5ac7a10b Fix Face IDs label 2024-03-17 09:56:24 +08:00
e81ba62234 Improve Face ID signin method UI 2024-03-17 09:56:23 +08:00
Ron
a19060c7cb fix: missing parameter type_token_hint in IntrospectToken() (#2812)
* fix: missing parameter type_token_hint in IntrospectToken(); fix key token type
2024-03-17 01:39:04 +08:00
96812f676b fix: "fs" module not found issue in face-api.js for browser usage (#2810) 2024-03-17 01:35:43 +08:00
04f0458b5c feat: improve handleCameraError() and camera call logic (#2809)
add i18n for face recognition
2024-03-16 22:52:57 +08:00
fd0bcd9a17 Improve getObject() for "/api/get-policies" 2024-03-16 21:42:00 +08:00
01a5958307 Improve error text in RequireAdmin() 2024-03-16 21:14:19 +08:00
be88b00278 feat: improve RequireAdmin() logic 2024-03-16 20:49:17 +08:00
1bd0245e7a Improve CheckVerificationCode() error message, add receiver to index 2024-03-16 18:16:29 +08:00
cc84bd37cf Add object field in RecordListPage 2024-03-16 16:57:04 +08:00
8302fcf805 Improve handleCameraError() 2024-03-16 09:55:55 +08:00
391a533ce1 feat: add "Face ID" login method (#2782)
Face Login via face-api.js
2024-03-16 09:04:00 +08:00
57431a59ad fix: Ensure /api/get-app-login Returns Captcha Provider for Applications Configured with Captcha (#2800)
In LoginPage.js, the line 92:const captchaProviderItems = this.getCaptchaProviderItems(this.props.application); 

captchaProviderItems have no Captcha Provider.
2024-03-15 19:56:12 +08:00
88a4736520 feat: fix GetDashboard() page 2024-03-15 19:52:19 +08:00
2cb6ff69ae fix: show selected organizations' statistics in dashboard page (#2805)
* fix: show selected organizations' statistics in dashboard page

* Update get-dashboard.go

* Update saml_idp.go

---------

Co-authored-by: Eric Luo <hsluoyz@qq.com>
2024-03-15 19:36:39 +08:00
e1e5943a3e fix: fix the issue of adding xmlns="" when generating XML (#2799)
* fix:solve the problem of adding xmlns="" when generating XML

* fix:remove fmt.Println

* Update saml_idp.go

---------

Co-authored-by: zhaoxianfei <zhaoxianfei@meiqia.cn>
Co-authored-by: Eric Luo <hsluoyz@qq.com>
2024-03-13 23:59:05 +08:00
3875896c1e feat: support custom header logo (#2801)
* feat: support custom header logo

* feat: add i18n

* feat: preview default logo when field is empty

* feat: improve logo setting and display logic

* feat: change logoLight to logo
2024-03-13 23:33:43 +08:00
7e2f265420 feat: improve organization select UI (#2798) 2024-03-12 19:39:53 +08:00
53ef179e9b Set Webhook.Url length to 200 2024-03-11 18:18:01 +08:00
376ef0ed14 feat: support custom Email content in /send-email API 2024-03-11 11:48:00 +08:00
ca183be336 Improve ManagedAccountTable UI 2024-03-11 00:13:34 +08:00
e5da57a005 feat: fix cert's ES options 2024-03-10 19:30:05 +08:00
e4e225db32 Use "ES512" value 2024-03-10 19:25:41 +08:00
a1add992ee Support legacy "RSA" value 2024-03-10 19:23:54 +08:00
2aac265ed4 Improve populateContent() 2024-03-10 18:58:53 +08:00
95 changed files with 1408 additions and 167 deletions

View File

@ -307,6 +307,7 @@ func (c *ApiController) Logout() {
}
c.ClearUserSession()
c.ClearTokenSession()
owner, username := util.GetOwnerAndNameFromId(user)
_, err := object.DeleteSessionId(util.GetSessionId(owner, username, object.CasdoorApplication), c.Ctx.Input.CruSession.SessionID())
if err != nil {
@ -353,6 +354,7 @@ func (c *ApiController) Logout() {
}
c.ClearUserSession()
c.ClearTokenSession()
// TODO https://github.com/casdoor/casdoor/pull/1494#discussion_r1095675265
owner, username := util.GetOwnerAndNameFromId(user)
@ -433,6 +435,17 @@ func (c *ApiController) GetAccount() {
return
}
token := c.GetSessionToken()
if token == nil {
token, err = object.GetTokenForExtension(user, c.Ctx.Request.Host)
if err != nil {
c.ResponseError(err.Error())
return
}
c.SetSessionToken(token)
}
u.AccessToken = token.AccessToken
resp := Response{
Status: "ok",
Sub: user.Id,

View File

@ -327,7 +327,38 @@ func (c *ApiController) Login() {
}
var user *object.User
if authForm.Password == "" {
if authForm.SigninMethod == "Face ID" {
if user, err = object.GetUserByFields(authForm.Organization, authForm.Username); err != nil {
c.ResponseError(err.Error(), nil)
return
} else if user == nil {
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(authForm.Organization, authForm.Username)))
return
}
var application *object.Application
application, err = object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
if err != nil {
c.ResponseError(err.Error(), nil)
return
}
if application == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
return
}
if !application.IsFaceIdEnabled() {
c.ResponseError(c.T("auth:The login method: login with face is not enabled for the application"))
return
}
if err := object.CheckFaceId(user, authForm.FaceId, c.GetAcceptLanguage()); err != nil {
c.ResponseError(err.Error(), nil)
return
}
} else if authForm.Password == "" {
if user, err = object.GetUserByFields(authForm.Organization, authForm.Username); err != nil {
c.ResponseError(err.Error(), nil)
return

View File

@ -122,6 +122,17 @@ func (c *ApiController) GetSessionUsername() string {
return user.(string)
}
func (c *ApiController) GetSessionToken() *object.Token {
tokenValue := c.GetSession("token")
var token *object.Token
var ok bool
if token, ok = tokenValue.(*object.Token); !ok {
token = nil
}
return token
}
func (c *ApiController) GetSessionApplication() *object.Application {
clientId := c.GetSession("aud")
if clientId == nil {
@ -141,6 +152,10 @@ func (c *ApiController) ClearUserSession() {
c.SetSessionData(nil)
}
func (c *ApiController) ClearTokenSession() {
c.SetSessionToken(nil)
}
func (c *ApiController) GetSessionOidc() (string, string) {
sessionData := c.GetSessionData()
if sessionData != nil &&
@ -167,6 +182,10 @@ func (c *ApiController) SetSessionUsername(user string) {
c.SetSession("username", user)
}
func (c *ApiController) SetSessionToken(token *object.Token) {
c.SetSession("token", token)
}
// GetSessionData ...
func (c *ApiController) GetSessionData() *SessionData {
session := c.GetSession("SessionData")

View File

@ -85,6 +85,11 @@ func (c *ApiController) GetRecords() {
// @Success 200 {object} object.Record The Response object
// @router /get-records-filter [post]
func (c *ApiController) GetRecordsByFilter() {
_, ok := c.RequireAdmin()
if !ok {
return
}
body := string(c.Ctx.Input.RequestBody)
record := &casvisorsdk.Record{}

View File

@ -60,7 +60,6 @@ func (c *ApiController) SendEmail() {
}
var emailForm EmailForm
err := json.Unmarshal(c.Ctx.Input.RequestBody, &emailForm)
if err != nil {
c.ResponseError(err.Error())
@ -87,7 +86,7 @@ func (c *ApiController) SendEmail() {
// when receiver is the reserved keyword: "TestSmtpServer", it means to test the SMTP server instead of sending a real Email
if len(emailForm.Receivers) == 1 && emailForm.Receivers[0] == "TestSmtpServer" {
err := object.DailSmtpServer(provider)
err = object.DailSmtpServer(provider)
if err != nil {
c.ResponseError(err.Error())
return
@ -112,20 +111,23 @@ func (c *ApiController) SendEmail() {
return
}
code := "123456"
content := emailForm.Content
if content == "" {
code := "123456"
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
content := strings.Replace(provider.Content, "%s", code, 1)
if !strings.HasPrefix(userId, "app/") {
var user *object.User
user, err = object.GetUser(userId)
if err != nil {
c.ResponseError(err.Error())
return
}
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
content = strings.Replace(provider.Content, "%s", code, 1)
if !strings.HasPrefix(userId, "app/") {
var user *object.User
user, err = object.GetUser(userId)
if err != nil {
c.ResponseError(err.Error())
return
}
if user != nil {
content = strings.Replace(content, "%{user.friendlyName}", user.GetFriendlyName(), 1)
if user != nil {
content = strings.Replace(content, "%{user.friendlyName}", user.GetFriendlyName(), 1)
}
}
}

View File

@ -317,7 +317,8 @@ func (c *ApiController) IntrospectToken() {
return
}
token, err := object.GetTokenByTokenValue(tokenValue)
tokenTypeHint := c.Input().Get("token_type_hint")
token, err := object.GetTokenByTokenValue(tokenValue, tokenTypeHint)
if err != nil {
c.ResponseTokenError(err.Error())
return

View File

@ -127,6 +127,12 @@ func (c *ApiController) RequireAdmin() (string, bool) {
if user.Owner == "built-in" {
return "", true
}
if !user.IsAdmin {
c.ResponseError(c.T("general:this operation requires administrator to perform"))
return "", false
}
return user.Owner, true
}

View File

@ -61,6 +61,8 @@ type AuthForm struct {
Plan string `json:"plan"`
Pricing string `json:"pricing"`
FaceId []float64 `json:"faceId"`
}
func GetAuthFormFieldValue(form *AuthForm, fieldName string) (bool, string) {

2
go.mod
View File

@ -14,7 +14,7 @@ require (
github.com/casdoor/notify v0.45.0
github.com/casdoor/oss v1.6.0
github.com/casdoor/xorm-adapter/v3 v3.1.0
github.com/casvisor/casvisor-go-sdk v1.1.0
github.com/casvisor/casvisor-go-sdk v1.3.0
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
github.com/denisenkom/go-mssqldb v0.9.0
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect

4
go.sum
View File

@ -1093,8 +1093,8 @@ github.com/casdoor/oss v1.6.0 h1:IOWrGLJ+VO82qS796eaRnzFPPA1Sn3cotYTi7O/VIlQ=
github.com/casdoor/oss v1.6.0/go.mod h1:rJAWA0hLhtu94t6IRpotLUkXO1NWMASirywQYaGizJE=
github.com/casdoor/xorm-adapter/v3 v3.1.0 h1:NodWayRtSLVSeCvL9H3Hc61k0G17KhV9IymTCNfh3kk=
github.com/casdoor/xorm-adapter/v3 v3.1.0/go.mod h1:4WTcUw+bTgBylGHeGHzTtBvuTXRS23dtwzFLl9tsgFM=
github.com/casvisor/casvisor-go-sdk v1.1.0 h1:XRDrlDuMjXfPsNa1INLHASPHdV/vgwh1gPZ7+v9fNHk=
github.com/casvisor/casvisor-go-sdk v1.1.0/go.mod h1:frnNtH5GA0wxzAQLyZxxfL0RSsSub9GQPi2Ybe86ocE=
github.com/casvisor/casvisor-go-sdk v1.3.0 h1:HVgm2g3lWpNX2wBNidzR743QY4O5kAjLUJ9tS2juO8g=
github.com/casvisor/casvisor-go-sdk v1.3.0/go.mod h1:frnNtH5GA0wxzAQLyZxxfL0RSsSub9GQPi2Ybe86ocE=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "Die Anmeldeart \"Anmeldung mit Passwort\" ist für die Anwendung nicht aktiviert",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "Der Anbieter: %s ist nicht für die Anwendung aktiviert",
@ -38,6 +39,8 @@
"Email cannot be empty": "E-Mail darf nicht leer sein",
"Email is invalid": "E-Mail ist ungültig",
"Empty username.": "Leerer Benutzername.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "Vorname darf nicht leer sein",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "El método de inicio de sesión: inicio de sesión con contraseña no está habilitado para la aplicación",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "El proveedor: %s no está habilitado para la aplicación",
@ -38,6 +39,8 @@
"Email cannot be empty": "El correo electrónico no puede estar vacío",
"Email is invalid": "El correo electrónico no es válido",
"Empty username.": "Nombre de usuario vacío.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "El nombre no puede estar en blanco",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "La méthode de connexion : connexion avec mot de passe n'est pas activée pour l'application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "Le fournisseur :%s n'est pas activé pour l'application",
@ -38,6 +39,8 @@
"Email cannot be empty": "L'e-mail ne peut pas être vide",
"Email is invalid": "L'adresse e-mail est invalide",
"Empty username.": "Nom d'utilisateur vide.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "Le prénom ne peut pas être laissé vide",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "Metode login: login dengan kata sandi tidak diaktifkan untuk aplikasi tersebut",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "Penyedia: %s tidak diaktifkan untuk aplikasi ini",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email tidak boleh kosong",
"Email is invalid": "Email tidak valid",
"Empty username.": "Nama pengguna kosong.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "Nama depan tidak boleh kosong",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "ログイン方法:パスワードでのログインはアプリケーションで有効になっていません",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "プロバイダー:%sはアプリケーションでは有効化されていません",
@ -38,6 +39,8 @@
"Email cannot be empty": "メールが空白にできません",
"Email is invalid": "電子メールは無効です",
"Empty username.": "空のユーザー名。",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "ファーストネームは空白にできません",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "어플리케이션에서는 암호를 사용한 로그인 방법이 활성화되어 있지 않습니다",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "제공자 %s은(는) 응용 프로그램에서 활성화되어 있지 않습니다",
@ -38,6 +39,8 @@
"Email cannot be empty": "이메일은 비어 있을 수 없습니다",
"Email is invalid": "이메일이 유효하지 않습니다",
"Empty username.": "빈 사용자 이름.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "이름은 공백일 수 없습니다",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "Метод входа: вход с паролем не включен для приложения",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "Провайдер: %s не включен для приложения",
@ -38,6 +39,8 @@
"Email cannot be empty": "Электронная почта не может быть пустой",
"Email is invalid": "Адрес электронной почты недействительный",
"Empty username.": "Пустое имя пользователя.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "Имя не может быть пустым",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "FirstName cannot be blank",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
"The login method: login with face is not enabled for the application": "The login method: login with face is not enabled for the application",
"The login method: login with password is not enabled for the application": "Phương thức đăng nhập: đăng nhập bằng mật khẩu không được kích hoạt cho ứng dụng",
"The organization: %s does not exist": "The organization: %s does not exist",
"The provider: %s is not enabled for the application": "Nhà cung cấp: %s không được kích hoạt cho ứng dụng",
@ -38,6 +39,8 @@
"Email cannot be empty": "Email không thể để trống",
"Email is invalid": "Địa chỉ email không hợp lệ",
"Empty username.": "Tên đăng nhập trống.",
"Face data does not exist, cannot log in": "Face data does not exist, cannot log in",
"Face data mismatch": "Face data mismatch",
"FirstName cannot be blank": "Tên không được để trống",
"Invitation code cannot be blank": "Invitation code cannot be blank",
"Invitation code exhausted": "Invitation code exhausted",

View File

@ -18,6 +18,7 @@
"The login method: login with LDAP is not enabled for the application": "该应用禁止采用LDAP登录方式",
"The login method: login with SMS is not enabled for the application": "该应用禁止采用短信登录方式",
"The login method: login with email is not enabled for the application": "该应用禁止采用邮箱登录方式",
"The login method: login with face is not enabled for the application": "该应用禁止采用人脸登录",
"The login method: login with password is not enabled for the application": "该应用禁止采用密码登录方式",
"The organization: %s does not exist": "组织: %s 不存在",
"The provider: %s is not enabled for the application": "该应用的提供商: %s未被启用",
@ -38,6 +39,8 @@
"Email cannot be empty": "邮箱不可为空",
"Email is invalid": "无效邮箱",
"Empty username.": "用户名不可为空",
"Face data does not exist, cannot log in": "未录入人脸数据,无法登录",
"Face data mismatch": "人脸不匹配",
"FirstName cannot be blank": "名不可以为空",
"Invitation code cannot be blank": "邀请码不能为空",
"Invitation code exhausted": "邀请码使用次数已耗尽",

View File

@ -110,6 +110,11 @@
"name": "WebAuthn",
"displayName": "WebAuthn",
"rule": "None"
},
{
"name": "Face ID",
"displayName": "Face ID",
"rule": "None"
}
],
"signupItems": [
@ -179,8 +184,10 @@
"refresh_token"
],
"redirectUris": [
""
"http://localhost:9000/callback"
],
"tokenFormat": "JWT",
"tokenFields": [],
"expireInHours": 168,
"failedSigninLimit": 5,
"failedSigninFrozenTime": 15

View File

@ -311,6 +311,9 @@ func extendApplicationWithSigninMethods(application *Application) (err error) {
signinMethod := &SigninMethod{Name: "WebAuthn", DisplayName: "WebAuthn", Rule: "None"}
application.SigninMethods = append(application.SigninMethods, signinMethod)
}
signinMethod := &SigninMethod{Name: "Face ID", DisplayName: "Face ID", Rule: "None"}
application.SigninMethods = append(application.SigninMethods, signinMethod)
}
if len(application.SigninMethods) == 0 {
@ -505,7 +508,7 @@ func GetMaskedApplication(application *Application, userId string) *Application
providerItems := []*ProviderItem{}
for _, providerItem := range application.Providers {
if providerItem.Provider != nil && (providerItem.Provider.Category == "OAuth" || providerItem.Provider.Category == "Web3") {
if providerItem.Provider != nil && (providerItem.Provider.Category == "OAuth" || providerItem.Provider.Category == "Web3" || providerItem.Provider.Category == "Captcha") {
providerItems = append(providerItems, providerItem)
}
}
@ -757,6 +760,17 @@ func (application *Application) IsLdapEnabled() bool {
return false
}
func (application *Application) IsFaceIdEnabled() bool {
if len(application.SigninMethods) > 0 {
for _, signinMethod := range application.SigninMethods {
if signinMethod.Name == "Face ID" {
return true
}
}
}
return false
}
func IsOriginAllowed(origin string) (bool, error) {
applications, err := GetApplications("")
if err != nil {

View File

@ -16,7 +16,6 @@ package object
import (
"fmt"
"strings"
"github.com/casdoor/casdoor/util"
"github.com/xorm-io/core"
@ -206,26 +205,41 @@ func (p *Cert) GetId() string {
}
func (p *Cert) populateContent() error {
if p.Certificate == "" || p.PrivateKey == "" {
var err error
var certificate, privateKey string
if strings.HasPrefix(p.CryptoAlgorithm, "RS") {
certificate, privateKey, err = generateRsaKeys(p.BitSize, util.ParseInt(p.CryptoAlgorithm[2:]), p.ExpireInYears, p.Name, p.Owner)
} else if strings.HasPrefix(p.CryptoAlgorithm, "ES") {
certificate, privateKey, err = generateEsKeys(p.BitSize, util.ParseInt(p.CryptoAlgorithm[2:]), p.ExpireInYears, p.Name, p.Owner)
} else if strings.HasPrefix(p.CryptoAlgorithm, "PS") {
certificate, privateKey, err = generateRsaPssKeys(p.BitSize, util.ParseInt(p.CryptoAlgorithm[2:]), p.ExpireInYears, p.Name, p.Owner)
} else {
err = fmt.Errorf("Crypto algorithm %s is not found", p.CryptoAlgorithm)
}
if err != nil {
return err
}
p.Certificate = certificate
p.PrivateKey = privateKey
if p.Certificate != "" && p.PrivateKey != "" {
return nil
}
if len(p.CryptoAlgorithm) < 3 {
err := fmt.Errorf("populateContent() error, unsupported crypto algorithm: %s", p.CryptoAlgorithm)
return err
}
if p.CryptoAlgorithm == "RSA" {
p.CryptoAlgorithm = "RS256"
}
sigAlgorithm := p.CryptoAlgorithm[:2]
shaSize, err := util.ParseIntWithError(p.CryptoAlgorithm[2:])
if err != nil {
return err
}
var certificate, privateKey string
if sigAlgorithm == "RS" {
certificate, privateKey, err = generateRsaKeys(p.BitSize, shaSize, p.ExpireInYears, p.Name, p.Owner)
} else if sigAlgorithm == "ES" {
certificate, privateKey, err = generateEsKeys(shaSize, p.ExpireInYears, p.Name, p.Owner)
} else if sigAlgorithm == "PS" {
certificate, privateKey, err = generateRsaPssKeys(p.BitSize, shaSize, p.ExpireInYears, p.Name, p.Owner)
} else {
err = fmt.Errorf("populateContent() error, unsupported signature algorithm: %s", sigAlgorithm)
}
if err != nil {
return err
}
p.Certificate = certificate
p.PrivateKey = privateKey
return nil
}

View File

@ -28,6 +28,10 @@ type Dashboard struct {
}
func GetDashboard(owner string) (*Dashboard, error) {
if owner == "All" {
owner = ""
}
dashboard := &Dashboard{
OrganizationCounts: make([]int, 31),
UserCounts: make([]int, 31),
@ -36,14 +40,13 @@ func GetDashboard(owner string) (*Dashboard, error) {
SubscriptionCounts: make([]int, 31),
}
var wg sync.WaitGroup
organizations := []Organization{}
users := []User{}
providers := []Provider{}
applications := []Application{}
subscriptions := []Subscription{}
var wg sync.WaitGroup
wg.Add(5)
go func() {
defer wg.Done()

View File

@ -45,6 +45,7 @@ func InitDb() {
}
initWebAuthn()
initToken()
}
func getBuiltInAccountItems() []*AccountItem {
@ -184,6 +185,7 @@ func initBuiltInApplication() {
{Name: "Password", DisplayName: "Password", Rule: "All"},
{Name: "Verification code", DisplayName: "Verification code", Rule: "All"},
{Name: "WebAuthn", DisplayName: "WebAuthn", Rule: "None"},
{Name: "Face ID", DisplayName: "Face ID", Rule: "None"},
},
SignupItems: []*SignupItem{
{Name: "ID", Visible: false, Required: true, Prompted: false, Rule: "Random"},
@ -197,6 +199,7 @@ func initBuiltInApplication() {
},
Tags: []string{},
RedirectUris: []string{},
TokenFormat: "JWT",
TokenFields: []string{},
ExpireInHours: 168,
FormOffset: 2,
@ -307,6 +310,10 @@ func initWebAuthn() {
gob.Register(webauthn.SessionData{})
}
func initToken() {
gob.Register(&Token{})
}
func initBuiltInUserModel() {
model, err := GetModel("built-in/user-model-built-in")
if err != nil {

View File

@ -54,6 +54,8 @@ type Organization struct {
DisplayName string `xorm:"varchar(100)" json:"displayName"`
WebsiteUrl string `xorm:"varchar(100)" json:"websiteUrl"`
Logo string `xorm:"varchar(200)" json:"logo"`
LogoDark string `xorm:"varchar(200)" json:"logoDark"`
Favicon string `xorm:"varchar(100)" json:"favicon"`
PasswordType string `xorm:"varchar(100)" json:"passwordType"`
PasswordSalt string `xorm:"varchar(100)" json:"passwordSalt"`

View File

@ -63,6 +63,7 @@ func NewRecord(ctx *context.Context) *casvisorsdk.Record {
Action: action,
Language: languageCode,
Object: object,
Response: "",
IsTriggered: false,
}
return &record

View File

@ -179,8 +179,8 @@ type IdpSSODescriptor struct {
}
type NameIDFormat struct {
XMLName xml.Name
Value string `xml:",innerxml"`
// XMLName xml.Name
Value string `xml:",innerxml"`
}
type SingleSignOnService struct {
@ -190,7 +190,7 @@ type SingleSignOnService struct {
}
type Attribute struct {
XMLName xml.Name
// XMLName xml.Name
Name string `xml:"Name,attr"`
NameFormat string `xml:"NameFormat,attr"`
FriendlyName string `xml:"FriendlyName,attr"`

View File

@ -137,21 +137,24 @@ func GetTokenByRefreshToken(refreshToken string) (*Token, error) {
return &token, nil
}
func GetTokenByTokenValue(tokenValue string) (*Token, error) {
token, err := GetTokenByAccessToken(tokenValue)
if err != nil {
return nil, err
}
if token != nil {
return token, nil
}
token, err = GetTokenByRefreshToken(tokenValue)
if err != nil {
return nil, err
}
if token != nil {
return token, nil
func GetTokenByTokenValue(tokenValue, tokenTypeHint string) (*Token, error) {
switch tokenTypeHint {
case "access_token":
token, err := GetTokenByAccessToken(tokenValue)
if err != nil {
return nil, err
}
if token != nil {
return token, nil
}
case "refresh_token":
token, err := GetTokenByRefreshToken(tokenValue)
if err != nil {
return nil, err
}
if token != nil {
return token, nil
}
}
return nil, nil

View File

@ -261,7 +261,7 @@ func GetValidationBySaml(samlRequest string, host string) (string, string, error
ok, _, service, userId := GetCasTokenByTicket(ticket)
if !ok {
return "", "", fmt.Errorf("ticket %s found", ticket)
return "", "", fmt.Errorf("the CAS token for ticket %s is not found", ticket)
}
user, err := GetUser(userId)
@ -270,7 +270,7 @@ func GetValidationBySaml(samlRequest string, host string) (string, string, error
}
if user == nil {
return "", "", fmt.Errorf("user %s found", userId)
return "", "", fmt.Errorf("the user %s is not found", userId)
}
application, err := GetApplicationByUser(user)
@ -279,7 +279,7 @@ func GetValidationBySaml(samlRequest string, host string) (string, string, error
}
if application == nil {
return "", "", fmt.Errorf("application for user %s found", userId)
return "", "", fmt.Errorf("the application for user %s is not found", userId)
}
samlResponse, err := NewSamlResponse11(user, request.RequestID, host)

View File

@ -27,7 +27,7 @@ import (
"time"
)
func generateRsaKeys(bitSize int, algorithmType int, expireInYears int, commonName string, organization string) (string, string, error) {
func generateRsaKeys(bitSize int, shaSize int, expireInYears int, commonName string, organization string) (string, string, error) {
// https://stackoverflow.com/questions/64104586/use-golang-to-get-rsa-key-the-same-way-openssl-genrsa
// https://stackoverflow.com/questions/43822945/golang-can-i-create-x509keypair-using-rsa-key
@ -58,7 +58,7 @@ func generateRsaKeys(bitSize int, algorithmType int, expireInYears int, commonNa
BasicConstraintsValid: true,
}
switch algorithmType {
switch shaSize {
case 256:
tml.SignatureAlgorithm = x509.SHA256WithRSA
case 384:
@ -66,7 +66,7 @@ func generateRsaKeys(bitSize int, algorithmType int, expireInYears int, commonNa
case 512:
tml.SignatureAlgorithm = x509.SHA512WithRSA
default:
return "", "", fmt.Errorf("unsupported algorithm type")
return "", "", fmt.Errorf("generateRsaKeys() error, unsupported SHA size: %d", shaSize)
}
cert, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &key.PublicKey, key)
@ -83,9 +83,9 @@ func generateRsaKeys(bitSize int, algorithmType int, expireInYears int, commonNa
return string(certPem), string(privateKeyPem), nil
}
func generateEsKeys(bitSize int, algorithmType int, expireInYears int, commonName string, organization string) (string, string, error) {
func generateEsKeys(shaSize int, expireInYears int, commonName string, organization string) (string, string, error) {
var curve elliptic.Curve
switch algorithmType {
switch shaSize {
case 256:
curve = elliptic.P256()
case 384:
@ -93,7 +93,7 @@ func generateEsKeys(bitSize int, algorithmType int, expireInYears int, commonNam
case 512:
curve = elliptic.P521() // ES512(P521,SHA512)
default:
return "", "", fmt.Errorf("unsupported algorithm type")
return "", "", fmt.Errorf("generateEsKeys() error, unsupported SHA size: %d", shaSize)
}
// Generate ECDSA key pair.
@ -139,7 +139,7 @@ func generateEsKeys(bitSize int, algorithmType int, expireInYears int, commonNam
return string(certPem), string(privateKeyPem), nil
}
func generateRsaPssKeys(bitSize int, algorithmType int, expireInYears int, commonName string, organization string) (string, string, error) {
func generateRsaPssKeys(bitSize int, shaSize int, expireInYears int, commonName string, organization string) (string, string, error) {
// Generate RSA key.
key, err := rsa.GenerateKey(rand.Reader, bitSize)
if err != nil {
@ -173,7 +173,7 @@ func generateRsaPssKeys(bitSize int, algorithmType int, expireInYears int, commo
}
// Set the signature algorithm based on the hash function
switch algorithmType {
switch shaSize {
case 256:
tml.SignatureAlgorithm = x509.SHA256WithRSAPSS
case 384:
@ -181,7 +181,7 @@ func generateRsaPssKeys(bitSize int, algorithmType int, expireInYears int, commo
case 512:
tml.SignatureAlgorithm = x509.SHA512WithRSAPSS
default:
return "", "", fmt.Errorf("unsupported algorithm type")
return "", "", fmt.Errorf("generateRsaPssKeys() error, unsupported SHA size: %d", shaSize)
}
cert, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &key.PublicKey, key)

View File

@ -37,7 +37,7 @@ func TestGenerateRsaKeys(t *testing.T) {
func TestGenerateEsKeys(t *testing.T) {
fileId := "token_jwt_key"
certificate, privateKey, err := generateEsKeys(4096, 256, 20, "Casdoor Cert", "Casdoor Organization")
certificate, privateKey, err := generateEsKeys(256, 20, "Casdoor Cert", "Casdoor Organization")
if err != nil {
panic(err)
}

View File

@ -726,3 +726,19 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
}
return token, nil, nil
}
func GetTokenForExtension(user *User, host string) (*Token, error) {
application, err := GetApplicationByUser(user)
if err != nil {
return nil, err
}
if application == nil {
return nil, fmt.Errorf("the application for user %s is not found", user.Id)
}
token, err := GetTokenByUser(application, user, "profile", "", host)
if err != nil {
return nil, err
}
return token, nil
}

View File

@ -98,6 +98,7 @@ type User struct {
PreHash string `xorm:"varchar(100)" json:"preHash"`
AccessKey string `xorm:"varchar(100)" json:"accessKey"`
AccessSecret string `xorm:"varchar(100)" json:"accessSecret"`
AccessToken string `xorm:"mediumtext" json:"accessToken"`
CreatedIp string `xorm:"varchar(100)" json:"createdIp"`
LastSigninTime string `xorm:"varchar(100)" json:"lastSigninTime"`
@ -190,6 +191,7 @@ type User struct {
MultiFactorAuths []*MfaProps `xorm:"-" json:"multiFactorAuths,omitempty"`
Invitation string `xorm:"varchar(100) index" json:"invitation"`
InvitationCode string `xorm:"varchar(100) index" json:"invitationCode"`
FaceIds []*FaceId `json:"faceIds"`
Ldap string `xorm:"ldap varchar(100)" json:"ldap"`
Properties map[string]string `json:"properties"`
@ -227,6 +229,11 @@ type ManagedAccount struct {
SigninUrl string `xorm:"varchar(200)" json:"signinUrl"`
}
type FaceId struct {
Name string `xorm:"varchar(100) notnull pk" json:"name"`
FaceIdData []float64 `json:"faceIdData"`
}
func GetUserFieldStringValue(user *User, fieldName string) (bool, string, error) {
val := reflect.ValueOf(*user)
fieldValue := val.FieldByName(fieldName)
@ -667,7 +674,7 @@ func UpdateUser(id string, user *User, columns []string, isAdmin bool) (bool, er
columns = []string{
"owner", "display_name", "avatar", "first_name", "last_name",
"location", "address", "country_code", "region", "language", "affiliation", "title", "id_card_type", "id_card", "homepage", "bio", "tag", "language", "gender", "birthday", "education", "score", "karma", "ranking", "signup_application",
"is_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties", "webauthnCredentials", "managedAccounts",
"is_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties", "webauthnCredentials", "managedAccounts", "face_ids",
"signin_wrong_times", "last_signin_wrong_time", "groups", "access_key", "access_secret",
"github", "google", "qq", "wechat", "facebook", "dingtalk", "weibo", "gitee", "linkedin", "wecom", "lark", "gitlab", "adfs",
"baidu", "alipay", "casdoor", "infoflow", "apple", "azuread", "azureadb2c", "slack", "steam", "bilibili", "okta", "douyin", "line", "amazon",

View File

@ -387,6 +387,11 @@ func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, lang str
itemsChanged = append(itemsChanged, item)
}
if newUser.FaceIds != nil {
item := GetAccountItemByName("Face ID", organization)
itemsChanged = append(itemsChanged, item)
}
if oldUser.IsAdmin != newUser.IsAdmin {
item := GetAccountItemByName("Is admin", organization)
itemsChanged = append(itemsChanged, item)

View File

@ -17,6 +17,7 @@ package object
import (
"errors"
"fmt"
"math"
"math/rand"
"strings"
"time"
@ -53,7 +54,7 @@ type VerificationRecord struct {
Type string `xorm:"varchar(10)"`
User string `xorm:"varchar(100) notnull"`
Provider string `xorm:"varchar(100) notnull"`
Receiver string `xorm:"varchar(100) notnull"`
Receiver string `xorm:"varchar(100) index notnull"`
Code string `xorm:"varchar(10) notnull"`
Time int64 `xorm:"notnull"`
IsUsed bool
@ -183,7 +184,7 @@ func CheckVerificationCode(dest string, code string, lang string) (*VerifyResult
return nil, err
}
if record == nil {
return &VerifyResult{noRecordError, i18n.Translate(lang, "verification:Code has not been sent yet!")}, nil
return &VerifyResult{noRecordError, i18n.Translate(lang, "verification:The verification code has not been sent yet, or has already been used!")}, nil
}
timeout, err := conf.GetConfigInt64("verificationCodeTimeout")
@ -236,6 +237,28 @@ func CheckSigninCode(user *User, dest, code, lang string) error {
}
}
func CheckFaceId(user *User, faceId []float64, lang string) error {
if len(user.FaceIds) == 0 {
return fmt.Errorf(i18n.Translate(lang, "check:Face data does not exist, cannot log in"))
}
for _, userFaceId := range user.FaceIds {
if faceId == nil || len(userFaceId.FaceIdData) != len(faceId) {
continue
}
var sumOfSquares float64
for i := 0; i < len(userFaceId.FaceIdData); i++ {
diff := userFaceId.FaceIdData[i] - faceId[i]
sumOfSquares += diff * diff
}
if math.Sqrt(sumOfSquares) < 0.25 {
return nil
}
}
return fmt.Errorf(i18n.Translate(lang, "check:Face data mismatch"))
}
func GetVerifyType(username string) (verificationCodeType string) {
if strings.Contains(username, "@") {
return VerifyTypeEmail

View File

@ -33,7 +33,7 @@ type Webhook struct {
Organization string `xorm:"varchar(100) index" json:"organization"`
Url string `xorm:"varchar(100)" json:"url"`
Url string `xorm:"varchar(200)" json:"url"`
Method string `xorm:"varchar(100)" json:"method"`
ContentType string `xorm:"varchar(100)" json:"contentType"`
Headers []*Header `xorm:"mediumtext" json:"headers"`

View File

@ -66,10 +66,18 @@ func getObject(ctx *context.Context) (string, string) {
path := ctx.Request.URL.Path
if method == http.MethodGet {
if ctx.Request.URL.Path == "/api/get-policies" && ctx.Input.Query("id") == "/" {
adapterId := ctx.Input.Query("adapterId")
if adapterId != "" {
return util.GetOwnerAndNameFromIdNoCheck(adapterId)
if ctx.Request.URL.Path == "/api/get-policies" {
if ctx.Input.Query("id") == "/" {
adapterId := ctx.Input.Query("adapterId")
if adapterId != "" {
return util.GetOwnerAndNameFromIdNoCheck(adapterId)
}
} else {
// query == "?id=built-in/admin"
id := ctx.Input.Query("id")
if id != "" {
return util.GetOwnerAndNameFromIdNoCheck(id)
}
}
}

View File

@ -93,6 +93,7 @@ module.exports = {
"buffer": false,
"crypto": false,
"os": false,
"fs": false,
},
}
},

View File

@ -29,6 +29,7 @@
"craco-less": "^2.0.0",
"echarts": "^5.4.3",
"ethers": "5.6.9",
"face-api.js": "^0.22.2",
"file-saver": "^2.0.5",
"i18n-iso-countries": "^7.0.0",
"i18next": "^19.8.9",

View File

@ -51,6 +51,7 @@ class App extends Component {
classes: props,
selectedMenuKey: 0,
account: undefined,
accessToken: undefined,
uri: null,
themeAlgorithm: storageThemeAlgorithm,
themeData: Conf.ThemeDefault,
@ -153,11 +154,7 @@ class App extends Component {
}
getLogo(themes) {
if (themes.includes("dark")) {
return `${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256_dark.png`;
} else {
return `${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256.png`;
}
return Setting.getLogo(themes);
}
setLanguage(account) {
@ -232,9 +229,11 @@ class App extends Component {
AuthBackend.getAccount(query)
.then((res) => {
let account = null;
let accessToken = null;
if (res.status === "ok") {
account = res.data;
account.organization = res.data2;
accessToken = res.data.accessToken;
this.setLanguage(account);
this.setTheme(Setting.getThemeData(account.organization), Conf.InitThemeAlgorithm);
@ -246,6 +245,7 @@ class App extends Component {
this.setState({
account: account,
accessToken: accessToken,
});
});
}
@ -260,6 +260,7 @@ class App extends Component {
return (
<React.Fragment>
{!this.state.account ? null : <div style={{display: "none"}} id="CasdoorApplicationName" value={this.state.account.signupApplication} />}
{!this.state.account ? null : <div style={{display: "none"}} id="CasdoorAccessToken" value={this.state.accessToken} />}
<Footer id="footer" style={
{
textAlign: "center",

View File

@ -1081,7 +1081,7 @@ class ApplicationEditPage extends React.Component {
submitApplicationEdit(exitAfterSave) {
const application = Setting.deepCopy(this.state.application);
application.providers = application.providers?.filter(provider => this.state.providers.map(provider => provider.name).includes(provider.name));
application.signinMethods = application.signinMethods?.filter(signinMethod => ["Password", "Verification code", "WebAuthn", "LDAP"].includes(signinMethod.name));
application.signinMethods = application.signinMethods?.filter(signinMethod => ["Password", "Verification code", "WebAuthn", "LDAP", "Face ID"].includes(signinMethod.name));
ApplicationBackend.updateApplication("admin", this.state.applicationName, application)
.then((res) => {

View File

@ -50,6 +50,7 @@ class ApplicationListPage extends BaseListPage {
{name: "Password", displayName: "Password", rule: "All"},
{name: "Verification code", displayName: "Verification code", rule: "All"},
{name: "WebAuthn", displayName: "WebAuthn", rule: "None"},
{name: "Face ID", displayName: "Face ID", rule: "None"},
],
signupItems: [
{name: "ID", visible: false, required: true, rule: "Random"},

View File

@ -171,21 +171,15 @@ class CertEditPage extends React.Component {
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.cert.cryptoAlgorithm} onChange={(value => {
this.updateCertField("cryptoAlgorithm", value);
if (value === "RS256" || value === "PS256") {
this.updateCertField("bitSize", 2048);
} else if (value === "RS384" || value === "PS384") {
this.updateCertField("bitSize", 2048);
} else if (value === "RS512" || value === "PS512") {
this.updateCertField("bitSize", 2048);
} else if (value === "ES256") {
this.updateCertField("bitSize", 256);
} else if (value === "ES384") {
this.updateCertField("bitSize", 384);
} else if (value === "ES521") {
this.updateCertField("bitSize", 521);
} else {
if (value.startsWith("ES")) {
this.updateCertField("bitSize", 0);
} else {
if (this.state.cert.bitSize !== 1024 && this.state.cert.bitSize !== 2048 && this.state.cert.bitSize !== 4096) {
this.updateCertField("bitSize", 2048);
}
}
this.updateCertField("certificate", "");
this.updateCertField("privateKey", "");
})}>
@ -205,22 +199,26 @@ class CertEditPage extends React.Component {
</Select>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("cert:Bit size"), i18next.t("cert:Bit size - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.cert.bitSize} onChange={(value => {
this.updateCertField("bitSize", value);
this.updateCertField("certificate", "");
this.updateCertField("privateKey", "");
})}>
{
Setting.getCryptoAlgorithmOptions(this.state.cert.cryptoAlgorithm).map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
</Col>
</Row>
{
this.state.cert.cryptoAlgorithm.startsWith("ES") ? null : (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("cert:Bit size"), i18next.t("cert:Bit size - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.cert.bitSize} onChange={(value => {
this.updateCertField("bitSize", value);
this.updateCertField("certificate", "");
this.updateCertField("privateKey", "");
})}>
{
Setting.getCryptoAlgorithmOptions(this.state.cert.cryptoAlgorithm).map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
</Col>
</Row>
)
}
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("cert:Expire in years"), i18next.t("cert:Expire in years - Tooltip"))} :

View File

@ -71,7 +71,9 @@ class EntryPage extends React.Component {
this.props.updataThemeData(themeData);
this.props.updateApplication(application);
localStorage.setItem("applicationName", application.name);
if (application) {
localStorage.setItem("applicationName", application.name);
}
};
const onUpdatePricing = (pricing) => {

View File

@ -220,9 +220,29 @@ function ManagementPage(props) {
return [];
}
const textColor = props.themeAlgorithm.includes("dark") ? "white" : "black";
let textColor = "black";
const twoToneColor = props.themeData.colorPrimary;
let logo = props.account.organization.logo ? props.account.organization.logo : Setting.getLogo(props.themeAlgorithm);
if (props.themeAlgorithm.includes("dark")) {
if (props.account.organization.logoDark) {
logo = props.account.organization.logoDark;
}
textColor = "white";
}
!Setting.isMobile() ? res.push({
label:
<Link to="/">
<img className="logo" src={logo ?? props.logo} alt="logo" />
</Link>,
disabled: true,
style: {
padding: 0,
height: "auto",
},
}) : null;
res.push(Setting.getItem(<Link style={{color: textColor}} to="/">{i18next.t("general:Home")}</Link>, "/home", <HomeTwoTone twoToneColor={twoToneColor} />, [
Setting.getItem(<Link to="/">{i18next.t("general:Dashboard")}</Link>, "/"),
Setting.getItem(<Link to="/shortcuts">{i18next.t("general:Shortcuts")}</Link>, "/shortcuts"),
@ -400,11 +420,6 @@ function ManagementPage(props) {
<React.Fragment>
<EnableMfaNotification account={props.account} />
<Header style={{padding: "0", marginBottom: "3px", backgroundColor: props.themeAlgorithm.includes("dark") ? "black" : "white"}} >
{Setting.isMobile() ? null : (
<Link to={"/"}>
<div className="logo" style={{background: `url(${props.logo})`}} />
</Link>
)}
{props.requiredEnableMfa || (Setting.isMobile() ?
<React.Fragment>
<Drawer title={i18next.t("general:Close")} placement="left" visible={menuVisible} onClose={onClose}>
@ -426,7 +441,7 @@ function ManagementPage(props) {
items={getMenuItems()}
mode={"horizontal"}
selectedKeys={[props.selectedMenuKey]}
style={{position: "absolute", left: "145px", right: menuStyleRight, backgroundColor: props.themeAlgorithm.includes("dark") ? "black" : "white"}}
style={{position: "absolute", left: 0, right: menuStyleRight, backgroundColor: props.themeAlgorithm.includes("dark") ? "black" : "white"}}
/>
)}
{

View File

@ -56,6 +56,7 @@ class OrganizationEditPage extends React.Component {
this.props.history.push("/404");
return;
}
organization["enableDarkLogo"] = !!organization["logoDark"];
this.setState({
organization: organization,
@ -141,6 +142,78 @@ 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:Enable dark logo"), i18next.t("general:Enable dark logo - Tooltip"))} :
</Col>
<Col span={22} >
<Switch checked={this.state.organization.enableDarkLogo} onChange={e => {
this.updateOrganizationField("enableDarkLogo", e);
if (!e) {
this.updateOrganizationField("logoDark", "");
}
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Logo"), i18next.t("general:Logo - Tooltip"))} :
</Col>
<Col span={22} >
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 1}>
{Setting.getLabel(i18next.t("general:URL"), i18next.t("general:URL - Tooltip"))} :
</Col>
<Col span={23} >
<Input prefix={<LinkOutlined />} value={this.state.organization.logo} onChange={e => {
this.updateOrganizationField("logo", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 1}>
{i18next.t("general:Preview")}:
</Col>
<Col span={23}>
<a target="_blank" rel="noreferrer" href={this.state.organization.logo}>
<img src={this.state.organization.logo ? this.state.organization.logo : Setting.getLogo([""])} alt={this.state.organization.logo} height={90} style={{background: "white", marginBottom: "20px"}} />
</a>
</Col>
</Row>
</Col>
</Row>
{
!this.state.organization.enableDarkLogo ? null : (<Row style={{marginTop: "20px"}}>
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Logo dark"), i18next.t("general:Logo dark - Tooltip"))} :
</Col>
<Col span={22}>
<Row style={{marginTop: "20px"}}>
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 1}>
{Setting.getLabel(i18next.t("general:URL"), i18next.t("general:URL - Tooltip"))} :
</Col>
<Col span={23}>
<Input prefix={<LinkOutlined />} value={this.state.organization.logoDark} onChange={e => {
this.updateOrganizationField("logoDark", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}}>
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 1}>
{i18next.t("general:Preview")}:
</Col>
<Col span={23}>
<a target="_blank" rel="noreferrer" href={this.state.organization.logoDark}>
<img
src={this.state.organization.logoDark ? this.state.organization.logoDark : Setting.getLogo(["dark"])}
alt={this.state.organization.logoDark} height={90}
style={{background: "#141414", marginBottom: "20px"}} />
</a>
</Col>
</Row>
</Col>
</Row>)
}
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Favicon"), i18next.t("general:Favicon - Tooltip"))} :

View File

@ -65,7 +65,7 @@ class RecordListPage extends BaseListPage {
title: i18next.t("general:Client IP"),
dataIndex: "clientIp",
key: "clientIp",
width: "150px",
width: "100px",
sorter: true,
...this.getColumnSearchProps("clientIp"),
render: (text, record, index) => {
@ -80,7 +80,7 @@ class RecordListPage extends BaseListPage {
title: i18next.t("general:Timestamp"),
dataIndex: "createdTime",
key: "createdTime",
width: "180px",
width: "150px",
sorter: true,
render: (text, record, index) => {
return Setting.getFormattedDate(text);
@ -105,7 +105,7 @@ class RecordListPage extends BaseListPage {
title: i18next.t("general:User"),
dataIndex: "user",
key: "user",
width: "120px",
width: "100px",
sorter: true,
...this.getColumnSearchProps("user"),
render: (text, record, index) => {
@ -151,6 +151,14 @@ class RecordListPage extends BaseListPage {
sorter: true,
...this.getColumnSearchProps("language"),
},
{
title: i18next.t("record:Object"),
dataIndex: "object",
key: "object",
width: "90px",
sorter: true,
...this.getColumnSearchProps("object"),
},
{
title: i18next.t("general:Action"),
dataIndex: "action",

View File

@ -89,6 +89,14 @@ export function getAlgorithmNames(themeData) {
return algorithms;
}
export function getLogo(themes) {
if (themes.includes("dark")) {
return `${StaticBaseUrl}/img/casdoor-logo_1185x256_dark.png`;
} else {
return `${StaticBaseUrl}/img/casdoor-logo_1185x256.png`;
}
}
export const OtherProviderInfo = {
SMS: {
"Aliyun SMS": {
@ -1101,7 +1109,9 @@ export function getProviderTypeOptions(category) {
}
export function getCryptoAlgorithmOptions(cryptoAlgorithm) {
if (cryptoAlgorithm === "RS256") {
if (cryptoAlgorithm.startsWith("ES")) {
return [];
} else {
return (
[
{id: 1024, name: "1024"},
@ -1109,26 +1119,6 @@ export function getCryptoAlgorithmOptions(cryptoAlgorithm) {
{id: 4096, name: "4096"},
]
);
} else if (cryptoAlgorithm === "HS256" || cryptoAlgorithm === "ES256") {
return (
[
{id: 256, name: "256"},
]
);
} else if (cryptoAlgorithm === "ES384") {
return (
[
{id: 384, name: "384"},
]
);
} else if (cryptoAlgorithm === "ES521") {
return (
[
{id: 521, name: "521"},
]
);
} else {
return [];
}
}
@ -1174,6 +1164,10 @@ export function isLdapEnabled(application) {
return isSigninMethodEnabled(application, "LDAP");
}
export function isFaceIdEnabled(application) {
return isSigninMethodEnabled(application, "Face ID");
}
export function getLoginLink(application) {
let url;
if (application === null) {

View File

@ -40,6 +40,7 @@ import {DeleteMfa} from "./backend/MfaBackend";
import {CheckCircleOutlined, HolderOutlined, UsergroupAddOutlined} from "@ant-design/icons";
import * as MfaBackend from "./backend/MfaBackend";
import AccountAvatar from "./account/AccountAvatar";
import FaceIdTable from "./table/FaceIdTable";
const {Option} = Select;
@ -59,6 +60,7 @@ class UserEditPage extends React.Component {
loading: true,
returnUrl: null,
idCardInfo: ["ID card front", "ID card back", "ID card with person"],
openFaceRecognitionModal: false,
};
}
@ -974,6 +976,21 @@ class UserEditPage extends React.Component {
</Col>
</Row>
);
} else if (accountItem.name === "Face ID") {
return (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("user:Face IDs"), i18next.t("user:Face IDs"))} :
</Col>
<Col span={22} >
<FaceIdTable
title={i18next.t("user:Face IDs")}
table={this.state.user.faceIds}
onUpdateTable={(table) => {this.updateUserField("faceIds", table);}}
/>
</Col>
</Row>
);
}
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import React, {Suspense, lazy} from "react";
import {Button, Checkbox, Col, Form, Input, Result, Spin, Tabs} from "antd";
import {ArrowLeftOutlined, LockOutlined, UserOutlined} from "@ant-design/icons";
import {withRouter} from "react-router-dom";
@ -36,6 +36,7 @@ import {CaptchaModal, CaptchaRule} from "../common/modal/CaptchaModal";
import RedirectForm from "../common/RedirectForm";
import {MfaAuthVerifyForm, NextMfa, RequiredMfa} from "./mfa/MfaAuthVerifyForm";
import {GoogleOneTapLoginVirtualButton} from "./GoogleLoginButton";
const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionModal"));
class LoginPage extends React.Component {
constructor(props) {
@ -52,6 +53,7 @@ class LoginPage extends React.Component {
validEmail: false,
enableCaptchaModal: CaptchaRule.Never,
openCaptchaModal: false,
openFaceRecognitionModal: false,
verifyCaptcha: undefined,
samlResponse: "",
relayState: "",
@ -214,6 +216,7 @@ class LoginPage extends React.Component {
}
case "WebAuthn": return "webAuthn";
case "LDAP": return "ldap";
case "Face ID": return "faceId";
}
}
@ -263,6 +266,8 @@ class LoginPage extends React.Component {
values["signinMethod"] = "WebAuthn";
} else if (this.state.loginMethod === "ldap") {
values["signinMethod"] = "LDAP";
} else if (this.state.loginMethod === "faceId") {
values["signinMethod"] = "Face ID";
}
const oAuthParams = Util.getOAuthGetParameters();
@ -340,6 +345,13 @@ class LoginPage extends React.Component {
this.signInWithWebAuthn(username, values);
return;
}
if (this.state.loginMethod === "faceId") {
this.setState({
openFaceRecognitionModal: true,
values: values,
});
return;
}
if (this.state.loginMethod === "password" || this.state.loginMethod === "ldap") {
if (this.state.enableCaptchaModal === CaptchaRule.Always) {
this.setState({
@ -657,6 +669,25 @@ class LoginPage extends React.Component {
i18next.t("login:Sign In")
}
</Button>
{
this.state.loginMethod === "faceId" ?
<Suspense fallback={null}>
<FaceRecognitionModal
visible={this.state.openFaceRecognitionModal}
onOk={(faceId) => {
const values = this.state.values;
values["faceId"] = faceId;
this.login(values);
this.setState({openFaceRecognitionModal: false});
}}
onCancel={() => this.setState({openFaceRecognitionModal: false})}
/>
</Suspense>
:
<>
</>
}
{
this.renderCaptchaModal(application)
}
@ -721,7 +752,7 @@ class LoginPage extends React.Component {
);
}
const showForm = Setting.isPasswordEnabled(application) || Setting.isCodeSigninEnabled(application) || Setting.isWebAuthnEnabled(application) || Setting.isLdapEnabled(application);
const showForm = Setting.isPasswordEnabled(application) || Setting.isCodeSigninEnabled(application) || Setting.isWebAuthnEnabled(application) || Setting.isLdapEnabled(application) || Setting.isFaceIdEnabled(application);
if (showForm) {
let loginWidth = 320;
if (Setting.getLanguage() === "fr") {
@ -1029,12 +1060,18 @@ class LoginPage extends React.Component {
[generateItemKey("Verification code", "Phone only"), {label: i18next.t("login:Verification code"), key: "verificationCodePhone"}],
[generateItemKey("WebAuthn", "None"), {label: i18next.t("login:WebAuthn"), key: "webAuthn"}],
[generateItemKey("LDAP", "None"), {label: i18next.t("login:LDAP"), key: "ldap"}],
[generateItemKey("Face ID", "None"), {label: i18next.t("login:Face ID"), key: "faceId"}],
]);
application?.signinMethods?.forEach((signinMethod) => {
const item = itemsMap.get(generateItemKey(signinMethod.name, signinMethod.rule));
if (item) {
const label = signinMethod.name === signinMethod.displayName ? item.label : signinMethod.displayName;
let label = signinMethod.name === signinMethod.displayName ? item.label : signinMethod.displayName;
if (application?.signinMethods?.length >= 4 && label === "Verification code") {
label = "Code";
}
items.push({label: label, key: item.key});
}
});
@ -1117,7 +1154,7 @@ class LoginPage extends React.Component {
};
return (
<div style={{height: 300, width: 300}}>
<div style={{height: 300}}>
{renderChoiceBox()}
</div>
);
@ -1188,11 +1225,9 @@ class LoginPage extends React.Component {
</div>
<div className="login-form">
<div>
<div>
{
this.renderLoginPanel(application)
}
</div>
{
this.renderLoginPanel(application)
}
</div>
</div>
</div>

View File

@ -31,17 +31,32 @@ const Dashboard = (props) => {
return () => window.removeEventListener("storageTourChanged", handleTourChange);
}, []);
React.useEffect(() => {
window.addEventListener("storageOrganizationChanged", handleOrganizationChange);
return () => window.removeEventListener("storageOrganizationChanged", handleOrganizationChange);
}, [props.owner]);
React.useEffect(() => {
if (!Setting.isLocalAdminUser(props.account)) {
props.history.push("/apps");
}
}, [props.account]);
const getOrganizationName = () => {
let organization = localStorage.getItem("organization") === "All" ? "" : localStorage.getItem("organization");
if (!Setting.isAdminUser(props.account) && Setting.isLocalAdminUser(props.account)) {
organization = props.account.owner;
}
return organization;
};
React.useEffect(() => {
if (!Setting.isLocalAdminUser(props.account)) {
return;
}
DashboardBackend.getDashboard(props.account.owner).then((res) => {
const organization = getOrganizationName();
DashboardBackend.getDashboard(organization).then((res) => {
if (res.status === "ok") {
setDashboardData(res.data);
} else {
@ -54,6 +69,21 @@ const Dashboard = (props) => {
setIsTourVisible(TourConfig.getTourVisible());
};
const handleOrganizationChange = () => {
if (!Setting.isLocalAdminUser(props.account)) {
return;
}
const organization = getOrganizationName();
DashboardBackend.getDashboard(organization).then((res) => {
if (res.status === "ok") {
setDashboardData(res.data);
} else {
Setting.showMessage("error", res.msg);
}
});
};
const setIsTourToLocal = () => {
TourConfig.setIsTourVisible(false);
setIsTourVisible(false);

View File

@ -0,0 +1,220 @@
// Copyright 2024 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 * as faceapi from "face-api.js";
import React, {useState} from "react";
import {Button, Modal, Progress, Spin, message} from "antd";
import i18next from "i18next";
const FaceRecognitionModal = (props) => {
const {visible, onOk, onCancel} = props;
const [modelsLoaded, setModelsLoaded] = React.useState(false);
const [isCameraCaptured, setIsCameraCaptured] = useState(false);
const videoRef = React.useRef();
const canvasRef = React.useRef();
const detection = React.useRef(null);
const mediaStreamRef = React.useRef(null);
const [percent, setPercent] = useState(0);
React.useEffect(() => {
const loadModels = async() => {
// const MODEL_URL = process.env.PUBLIC_URL + "/models";
// const MODEL_URL = "https://justadudewhohacks.github.io/face-api.js/models";
// const MODEL_URL = "https://cdn.casbin.org/site/casdoor/models";
const MODEL_URL = "https://cdn.casdoor.com/casdoor/models";
Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri(MODEL_URL),
faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),
faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),
]).then((val) => {
setModelsLoaded(true);
}).catch((err) => {
message.error(i18next.t("login:Model loading failure"));
onCancel();
});
};
loadModels();
}, []);
React.useEffect(() => {
if (visible) {
setPercent(0);
if (modelsLoaded) {
navigator.mediaDevices
.getUserMedia({video: {facingMode: "user"}})
.then((stream) => {
mediaStreamRef.current = stream;
setIsCameraCaptured(true);
}).catch((error) => {
handleCameraError(error);
});
}
} else {
clearInterval(detection.current);
detection.current = null;
setIsCameraCaptured(false);
}
return () => {
clearInterval(detection.current);
detection.current = null;
setIsCameraCaptured(false);
};
}, [visible, modelsLoaded]);
React.useEffect(() => {
if (isCameraCaptured) {
let count = 0;
const interval = setInterval(() => {
count++;
if (videoRef.current) {
videoRef.current.srcObject = mediaStreamRef.current;
videoRef.current.play();
clearInterval(interval);
}
if (count >= 30) {
clearInterval(interval);
onCancel();
}
}, 100);
} else {
mediaStreamRef.current?.getTracks().forEach(track => track.stop());
if (videoRef.current) {
videoRef.current.srcObject = null;
}
}
}, [isCameraCaptured]);
const handleStreamVideo = () => {
let count = 0;
let goodCount = 0;
if (!detection.current) {
detection.current = setInterval(async() => {
if (modelsLoaded && videoRef.current && visible) {
const faces = await faceapi.detectAllFaces(videoRef.current, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceDescriptors();
count++;
if (count % 50 === 0) {
message.warning(i18next.t("login:Please ensure sufficient lighting and align your face in the center of the recognition box"));
} else if (count > 300) {
message.error(i18next.t("login:Face recognition failed"));
onCancel();
}
if (faces.length === 1) {
const face = faces[0];
setPercent(Math.round(face.detection.score * 100));
const array = Array.from(face.descriptor);
if (face.detection.score > 0.9) {
goodCount++;
if (face.detection.score > 0.99 || goodCount > 10) {
clearInterval(detection.current);
onOk(array);
}
}
} else {
setPercent(Math.round(percent / 2));
}
}
}, 100);
}
};
const handleCameraError = (error) => {
onCancel();
if (error instanceof DOMException) {
if (error.name === "NotFoundError" || error.name === "DevicesNotFoundError") {
message.error(i18next.t("login:Please ensure that you have a camera device for facial recognition"));
} else if (error.name === "NotAllowedError" || error.name === "PermissionDeniedError") {
message.error(i18next.t("login:Please provide permission to access the camera"));
} else if (error.name === "NotReadableError" || error.name === "TrackStartError") {
message.error(i18next.t("login:The camera is currently in use by another webpage"));
} else if (error.name === "TypeError") {
message.error(i18next.t("login:Please load the webpage using HTTPS, otherwise the camera cannot be accessed"));
} else {
message.error(error.message);
}
}
};
return (
<div>
<Modal
closable={false}
maskClosable={false}
destroyOnClose={true}
open={visible && isCameraCaptured}
title={i18next.t("login:Face Recognition")}
width={350}
footer={[
<Button key="back" onClick={onCancel}>
Cancel
</Button>,
]}
>
<Progress percent={percent} />
<div style={{marginTop: "20px", marginBottom: "50px", justifyContent: "center", alignContent: "center", position: "relative", flexDirection: "column"}}>
{
modelsLoaded ?
<div style={{display: "flex", justifyContent: "center", alignContent: "center"}}>
<video
ref={videoRef}
onPlay={handleStreamVideo}
style={{
borderRadius: "50%",
height: "220px",
verticalAlign: "middle",
width: "220px",
objectFit: "cover",
}}
></video>
<div style={{
position: "absolute",
width: "240px",
height: "240px",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
}}>
<svg width="240" height="240" fill="none">
<circle
strokeDasharray="700"
strokeDashoffset={700 - 6.9115 * percent}
strokeWidth="4"
cx="120"
cy="120"
r="110"
stroke="#5734d3"
transform="rotate(-90, 120, 120)"
strokeLinecap="round"
style={{transition: "all .2s linear"}}
></circle>
</svg>
</div>
<canvas ref={canvasRef} style={{position: "absolute"}} />
</div>
:
<div>
<Spin tip={i18next.t("login:Loading")} size="large" style={{display: "flex", justifyContent: "center", alignContent: "center"}}>
<div className="content" />
</Spin>
</div>
}
</div>
</Modal>
</div>
);
};
export default FaceRecognitionModal;

View File

@ -27,9 +27,6 @@ code {
}
.logo {
background: url("https://cdn.casbin.org/img/casdoor-logo_1185x256.png");
background-size: 130px, 27px !important;
width: 130px;
height: 27px;
margin: 17px 0 16px 15px;
float: left;

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Tabellenname des Policy Stores",
"Adapters": "Adapter",
"Add": "Hinzufügen",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Zugehörigkeits-URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Gültige E-Mail-Adresse",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Fehler beim hinzufügen",
"Failed to connect to server": "Die Verbindung zum Server konnte nicht hergestellt werden",
"Failed to delete": "Konnte nicht gelöscht werden",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Symbole, die die Anwendung der Außenwelt präsentiert",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Hauptpasswort",
@ -456,6 +462,9 @@
"Continue with": "Weitermachen mit",
"Email": "Email",
"Email or phone": "E-Mail oder Telefon",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Passwort vergessen?",
@ -465,9 +474,12 @@
"Logging out...": "Ausloggen...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "Kein Konto?",
"Or sign in with another account": "Oder mit einem anderen Konto anmelden",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Bitte geben Sie Ihre E-Mail oder Telefonnummer ein!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Melden Sie sich mit {type} an",
"Signing in...": "Anmelden...",
"Successfully logged in with WebAuthn credentials": "Erfolgreich mit WebAuthn-Anmeldeinformationen angemeldet",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "Die Eingabe ist keine gültige E-Mail-Adresse oder Telefonnummer!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "E-Mail darf nicht leer sein",
"Email/phone reset successfully": "E-Mail-/Telefon-Zurücksetzung erfolgreich durchgeführt",
"Empty input!": "Leere Eingabe!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Startseite des Benutzers",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Nombre de la tabla de la tienda de políticas",
"Adapters": "Adaptadores",
"Add": "Añadir",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "URL de afiliación",
@ -229,9 +230,12 @@
"Email - Tooltip": "Dirección de correo electrónico válida",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "No se pudo agregar",
"Failed to connect to server": "No se pudo conectar al servidor",
"Failed to delete": "No se pudo eliminar",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logotipo",
"Logo - Tooltip": "Iconos que la aplicación presenta al mundo exterior",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Contraseña maestra",
@ -456,6 +462,9 @@
"Continue with": "Continúe con",
"Email": "Email",
"Email or phone": "Correo electrónico o teléfono",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "¿Olvidaste tu contraseña?",
@ -465,9 +474,12 @@
"Logging out...": "Cerrando sesión...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "¿No tienes cuenta?",
"Or sign in with another account": "O inicia sesión con otra cuenta",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "¡Por favor introduzca su correo electrónico o teléfono!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Inicia sesión con {tipo}",
"Signing in...": "Iniciando sesión...",
"Successfully logged in with WebAuthn credentials": "Inició sesión correctamente con las credenciales de WebAuthn",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "¡La entrada no es un correo electrónico o número de teléfono válido!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "El correo electrónico no puede estar vacío",
"Email/phone reset successfully": "Restablecimiento de correo electrónico/teléfono exitoso",
"Empty input!": "¡Entrada vacía!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Página de inicio del usuario",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Nom de la table du magasin de règle",
"Adapters": "Adaptateurs",
"Add": "Ajouter",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Administration",
"Affiliation URL": "URL d'affiliation",
@ -229,9 +230,12 @@
"Email - Tooltip": "Adresse e-mail valide",
"Email only": "Email only",
"Enable": "Activer",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Activé",
"Enabled successfully": "Activé avec succès",
"Enforcers": "Exécuteurs",
"FaceIdData": "FaceIdData",
"Failed to add": "Échec d'ajout",
"Failed to connect to server": "Échec de la connexion au serveur",
"Failed to delete": "Échec de la suppression",
@ -268,6 +272,8 @@
"Logging & Auditing": "Journalisation et Audit",
"Logo": "Logo",
"Logo - Tooltip": "Icônes que l'application présente au monde extérieur",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "Type d'authentification multifacteur",
"MFA items - Tooltip": "Types d'authentification multifacteur - Infobulle",
"Master password": "Mot de passe passe-partout",
@ -456,6 +462,9 @@
"Continue with": "Continuer avec",
"Email": "Email",
"Email or phone": "Email ou téléphone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Échec de l'obtention de l'autorisation MetaMask",
"Failed to obtain Web3-Onboard authorization": "Échec de l'obtention de l'autorisation MetaMask",
"Forgot password?": "Mot de passe oublié ?",
@ -465,9 +474,12 @@
"Logging out...": "Déconnexion...",
"Login button": "Login button",
"MetaMask plugin not detected": "Le plugin MetaMask n'a pas été détecté",
"Model loading failure": "Model loading failure",
"No account?": "Pas de compte ?",
"Or sign in with another account": "Ou connectez-vous avec un autre compte",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Veuillez saisir votre adresse e-mail ou votre numéro de téléphone !",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"Please input your code!": "Veuillez saisir votre code !",
"Please input your organization name!": "Veuillez saisir le nom de votre organisation !",
"Please input your password!": "Veuillez saisir votre mot de passe !",
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"Please select an organization": "Veuillez sélectionner une organisation",
"Please select an organization to sign in": "Veuillez choisir une organisation pour vous connecter",
"Please type an organization to sign in": "Veuillez entrer une organisation pour vous connecter",
@ -484,6 +498,7 @@
"Sign in with {type}": "Connectez-vous avec {type}",
"Signing in...": "Connexion en cours...",
"Successfully logged in with WebAuthn credentials": "Connexion avec les identifiants WebAuthn réussie",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "L'entrée n'est pas une adresse e-mail ou un numéro de téléphone valide !",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Le champ e-mail doit être rempli",
"Email/phone reset successfully": "E-mail ou téléphone réinitialisé avec succès",
"Empty input!": "Champ vide !",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Genre",
"Gender - Tooltip": "Genre - Infobulle",
"Homepage": "Site web",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Nama tabel dari penyimpanan kebijakan",
"Adapters": "Adaptor",
"Add": "Tambahkan",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "URL Afiliasi",
@ -229,9 +230,12 @@
"Email - Tooltip": "Alamat email yang valid",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Gagal menambahkan",
"Failed to connect to server": "Gagal terhubung ke server",
"Failed to delete": "Gagal menghapus",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Ikon-ikon yang disajikan aplikasi ke dunia luar",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Kata sandi utama",
@ -456,6 +462,9 @@
"Continue with": "Lanjutkan dengan",
"Email": "Email",
"Email or phone": "Email atau telepon",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Lupa kata sandi?",
@ -465,9 +474,12 @@
"Logging out...": "Keluar...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "Tidak memiliki akun?",
"Or sign in with another account": "Atau masuk dengan akun lain",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Silahkan masukkan email atau nomor telepon Anda!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Masuk dengan {type}",
"Signing in...": "Masuk...",
"Successfully logged in with WebAuthn credentials": "Berhasil masuk dengan kredensial WebAuthn",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "Input yang Anda masukkan tidak valid, tidak sesuai dengan Email atau nomor telepon!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email tidak boleh kosong",
"Email/phone reset successfully": "Email/telepon berhasil diatur ulang",
"Empty input!": "Masukan kosong!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "ポリシー・ストアのテーブル名",
"Adapters": "アダプター",
"Add": "追加",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "所属するURL",
@ -229,9 +230,12 @@
"Email - Tooltip": "有効な電子メールアドレス",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "追加できませんでした",
"Failed to connect to server": "サーバーに接続できませんでした",
"Failed to delete": "削除に失敗しました",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "ロゴ",
"Logo - Tooltip": "アプリケーションが外部世界に示すアイコン",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "マスターパスワード",
@ -456,6 +462,9 @@
"Continue with": "続ける",
"Email": "Email",
"Email or phone": "メールまたは電話",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "パスワードを忘れましたか?",
@ -465,9 +474,12 @@
"Logging out...": "ログアウト中...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "アカウントがありませんか?",
"Or sign in with another account": "別のアカウントでサインインする",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "あなたのメールアドレスまたは電話番号を入力してください!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"Please input your code!": "あなたのコードを入力してください!",
"Please input your organization name!": "Please input your organization name!",
"Please input your password!": "パスワードを入力してください!",
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "{type}でサインインしてください",
"Signing in...": "サインイン中...",
"Successfully logged in with WebAuthn credentials": "WebAuthnの認証情報で正常にログインしました",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "入力されたのは有効なメールアドレスまたは電話番号ではありません",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "電子メールは空にできません",
"Email/phone reset successfully": "メール/電話のリセットが成功しました",
"Empty input!": "空の入力!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "ユーザーのホームページ",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "정책 저장소의 테이블 이름",
"Adapters": "어댑터",
"Add": "추가하다",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "소속 URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "유효한 이메일 주소",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "추가하지 못했습니다",
"Failed to connect to server": "서버에 연결하지 못했습니다",
"Failed to delete": "삭제에 실패했습니다",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "로고",
"Logo - Tooltip": "애플리케이션이 외부 세계에 제시하는 아이콘들",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "마스터 비밀번호",
@ -456,6 +462,9 @@
"Continue with": "계속하다",
"Email": "Email",
"Email or phone": "이메일 또는 전화",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "비밀번호를 잊으셨나요?",
@ -465,9 +474,12 @@
"Logging out...": "로그아웃 중...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "계정이 없나요?",
"Or sign in with another account": "다른 계정으로 로그인하세요",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "이메일 또는 전화번호를 입력해주세요!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"Please input your code!": "코드를 입력해주세요!",
"Please input your organization name!": "Please input your organization name!",
"Please input your password!": "비밀번호를 입력해주세요!",
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "{type}로 로그인하세요",
"Signing in...": "로그인 중...",
"Successfully logged in with WebAuthn credentials": "WebAuthn 자격 증명으로 로그인 성공적으로 수행했습니다",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "입력한 값은 유효한 이메일 또는 전화번호가 아닙니다!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "이메일은 비어 있을 수 없습니다",
"Email/phone reset successfully": "이메일/전화 초기화가 성공적으로 완료되었습니다",
"Empty input!": "빈 입력!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "사용자의 홈페이지",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Nome da tabela do armazenamento de políticas",
"Adapters": "Adaptadores",
"Add": "Adicionar",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "URL da Afiliação",
@ -229,9 +230,12 @@
"Email - Tooltip": "Endereço de e-mail válido",
"Email only": "Email only",
"Enable": "Habilitar",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Habilitado",
"Enabled successfully": "Habilitado com sucesso",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Falha ao adicionar",
"Failed to connect to server": "Falha ao conectar ao servidor",
"Failed to delete": "Falha ao excluir",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Ícones que o aplicativo apresenta para o mundo externo",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Senha mestra",
@ -456,6 +462,9 @@
"Continue with": "Continuar com",
"Email": "Email",
"Email or phone": "Email ou telefone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Esqueceu a senha?",
@ -465,9 +474,12 @@
"Logging out...": "Saindo...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "Não possui uma conta?",
"Or sign in with another account": "Ou entre com outra conta",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Por favor, informe seu email ou telefone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Entrar com {type}",
"Signing in...": "Entrando...",
"Successfully logged in with WebAuthn credentials": "Logado com sucesso usando credenciais WebAuthn",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "O valor inserido não é um email ou número de telefone válido!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "O e-mail não pode ficar em branco",
"Email/phone reset successfully": "Redefinição de e-mail/telefone com sucesso",
"Empty input!": "Entrada vazia!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gênero",
"Gender - Tooltip": "Gênero - Tooltip",
"Homepage": "Página inicial",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Имя таблицы хранилища политик",
"Adapters": "Адаптеры",
"Add": "Добавить",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "URL принадлежности",
@ -229,9 +230,12 @@
"Email - Tooltip": "Действительный адрес электронной почты",
"Email only": "Email only",
"Enable": "Включить",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Включено",
"Enabled successfully": "Успешно включено",
"Enforcers": "Контролёры доступа",
"FaceIdData": "FaceIdData",
"Failed to add": "Не удалось добавить",
"Failed to connect to server": "Не удалось подключиться к серверу",
"Failed to delete": "Не удалось удалить",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Логотип",
"Logo - Tooltip": "Иконки, которые приложение представляет во внешний мир",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Главный пароль",
@ -456,6 +462,9 @@
"Continue with": "Продолжайте с",
"Email": "Email",
"Email or phone": "Электронная почта или телефон",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Не удалось получить авторизацию MetaMask",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Забыли пароль?",
@ -465,9 +474,12 @@
"Logging out...": "Выход...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "Нет аккаунта?",
"Or sign in with another account": "Или войти с другой учетной записью",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Пожалуйста, введите свой адрес электронной почты или номер телефона!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"Please input your code!": "Пожалуйста, введите свой код!",
"Please input your organization name!": "Please input your organization name!",
"Please input your password!": "Пожалуйста, введите свой пароль!",
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Войти с помощью {type}",
"Signing in...": "Вход в систему...",
"Successfully logged in with WebAuthn credentials": "Успешный вход с учетными данными WebAuthn",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "Ввод не является действительным адресом электронной почты или телефонным номером!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email не может быть пустым",
"Email/phone reset successfully": "Электронная почта / номер телефона успешно сброшены",
"Empty input!": "Пустой ввод!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Главная страница пользователя",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Ekle",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Geçerli e-posta adresi",
"Email only": "Sadece eposta",
"Enable": "Etkinleştir",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Etkin",
"Enabled successfully": "Başarıyla etkinleştirildi",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Ekleme başarısız oldu.",
"Failed to connect to server": "Sunucuya bağlanılamıyor",
"Failed to delete": "Silme başarısız oldu",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "İle devam et",
"Email": "E-Posta",
"Email or phone": "E-posta veya telefon",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Metamask yetkilendirmesi başarısız",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Şifrenizi mi unuttunuz?",
@ -465,9 +474,12 @@
"Logging out...": ıkış yapılıyor...",
"Login button": "Login button",
"MetaMask plugin not detected": "Metamask plugin-in bulunamadı",
"Model loading failure": "Model loading failure",
"No account?": "Hesabınız yok mu?",
"Or sign in with another account": "Veya başka bir hesapla giriş yapın",
"Phone": "Telefon",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Lütfen Telefon numaranızı ya da E-Posta adresinizi giriniz!",
"Please input your Email!": "Eposta adresinizi girin!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"Please input your code!": "Lütfen size gönderilen kodu girin!",
"Please input your organization name!": "Please input your organization name!",
"Please input your password!": "Lütfen şifrenizi girin!",
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "{type} ile giriş yap",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Logo",
"Logo - Tooltip": "Icons that the application presents to the outside world",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Master password",
@ -456,6 +462,9 @@
"Continue with": "Continue with",
"Email": "Email",
"Email or phone": "Email or phone",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Forgot password?",
@ -465,9 +474,12 @@
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Please input your Email or Phone!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Sign in with {type}",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "The input is not valid Email or phone number!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email cannot be empty",
"Email/phone reset successfully": "Email/phone reset successfully",
"Empty input!": "Empty input!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Homepage",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "Tên bảng của kho lưu trữ chính sách",
"Adapters": "Bộ chuyển đổi",
"Add": "Tạo mới",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Đường dẫn liên kết liên kết",
@ -229,9 +230,12 @@
"Email - Tooltip": "Địa chỉ email hợp lệ",
"Email only": "Email only",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Không thể thêm được",
"Failed to connect to server": "Không thể kết nối đến máy chủ",
"Failed to delete": "Không thể xoá",
@ -268,6 +272,8 @@
"Logging & Auditing": "Logging & Auditing",
"Logo": "Biểu tượng",
"Logo - Tooltip": "Biểu tượng mà ứng dụng hiển thị ra ngoài thế giới",
"Logo dark": "Logo dark",
"Logo dark - Tooltip": "The logo used in dark theme",
"MFA items": "MFA items",
"MFA items - Tooltip": "MFA items - Tooltip",
"Master password": "Mật khẩu chính",
@ -456,6 +462,9 @@
"Continue with": "Tiếp tục với",
"Email": "Email",
"Email or phone": "Email hoặc điện thoại",
"Face ID": "Face ID",
"Face Recognition": "Face Recognition",
"Face recognition failed": "Face recognition failed",
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
"Forgot password?": "Quên mật khẩu?",
@ -465,9 +474,12 @@
"Logging out...": "Đăng xuất ...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "Không có tài khoản?",
"Or sign in with another account": "Hoặc đăng nhập bằng tài khoản khác",
"Phone": "Phone",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "Please ensure sufficient lighting and align your face in the center of the recognition box",
"Please ensure that you have a camera device for facial recognition": "Please ensure that you have a camera device for facial recognition",
"Please input your Email or Phone!": "Vui lòng nhập địa chỉ Email hoặc số điện thoại của bạn!",
"Please input your Email!": "Please input your Email!",
"Please input your LDAP username!": "Please input your LDAP username!",
@ -475,6 +487,8 @@
"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 load the webpage using HTTPS, otherwise the camera cannot be accessed": "Please load the webpage using HTTPS, otherwise the camera cannot be accessed",
"Please provide permission to access the camera": "Please provide permission to access the camera",
"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",
@ -484,6 +498,7 @@
"Sign in with {type}": "Đăng nhập bằng {type}",
"Signing in...": "Đăng nhập...",
"Successfully logged in with WebAuthn credentials": "Đã đăng nhập thành công với thông tin WebAuthn",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
"The input is not valid Email or phone number!": "Đầu vào không phải là địa chỉ Email hoặc số điện thoại hợp lệ!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid phone number!": "The input is not valid phone number!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "Email không được để trống",
"Email/phone reset successfully": "Đặt lại email/điện thoại thành công",
"Empty input!": "Đầu vào trống!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "Gender",
"Gender - Tooltip": "Gender - Tooltip",
"Homepage": "Trang chủ của người dùng",

View File

@ -181,6 +181,7 @@
"Adapter - Tooltip": "策略存储的表名",
"Adapters": "Casbin适配器",
"Add": "添加",
"Add Face Id": "添加人脸",
"Add custom item": "添加自定义项",
"Admin": "管理工具",
"Affiliation URL": "工作单位URL",
@ -229,9 +230,12 @@
"Email - Tooltip": "合法的电子邮件地址",
"Email only": "仅支持邮件",
"Enable": "启用",
"Enable dark logo": "开启暗黑Logo",
"Enable dark logo - Tooltip": "开启暗黑Logo",
"Enabled": "已开启",
"Enabled successfully": "启用成功",
"Enforcers": "Casbin执行器",
"FaceIdData": "人脸数据",
"Failed to add": "添加失败",
"Failed to connect to server": "连接服务器失败",
"Failed to delete": "删除失败",
@ -268,6 +272,8 @@
"Logging & Auditing": "日志 & 审计",
"Logo": "Logo",
"Logo - Tooltip": "应用程序向外展示的图标",
"Logo dark": "暗黑logo",
"Logo dark - Tooltip": "暗黑主题下使用的logo",
"MFA items": "MFA 项",
"MFA items - Tooltip": "MFA 项 - Tooltip",
"Master password": "万能密码",
@ -456,6 +462,9 @@
"Continue with": "使用以下账号继续",
"Email": "Email",
"Email or phone": "Email或手机号",
"Face ID": "Face ID",
"Face Recognition": "人脸识别",
"Face recognition failed": "人脸识别失败",
"Failed to obtain MetaMask authorization": "获取MetaMask授权失败",
"Failed to obtain Web3-Onboard authorization": "获取 Web3-Onboard 授权失败",
"Forgot password?": "忘记密码?",
@ -465,9 +474,12 @@
"Logging out...": "正在退出登录...",
"Login button": "登录按钮",
"MetaMask plugin not detected": "未检测到MetaMask插件",
"Model loading failure": "人脸识别模型加载失败",
"No account?": "没有账号?",
"Or sign in with another account": "或者,登录其他账号",
"Phone": "手机号",
"Please ensure sufficient lighting and align your face in the center of the recognition box": "请保证环境光线充足,并将人脸置于识别框中心位置",
"Please ensure that you have a camera device for facial recognition": "请检查是否有可用的摄像头设备以进行人脸识别",
"Please input your Email or Phone!": "请输入您的Email或手机号!",
"Please input your Email!": "请输入您的Email!",
"Please input your LDAP username!": "请输入您的LDAP用户名!",
@ -475,6 +487,8 @@
"Please input your code!": "请输入您的验证码!",
"Please input your organization name!": "请输入组织的名字!",
"Please input your password!": "请输入您的密码!",
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "请使用HTTPS加载网页否则无法使用摄像头",
"Please provide permission to access the camera": "请打开摄像头访问权限",
"Please select an organization": "请选择一个组织",
"Please select an organization to sign in": "请选择要登录的组织",
"Please type an organization to sign in": "请输入要登录的组织",
@ -484,6 +498,7 @@
"Sign in with {type}": "{type}登录",
"Signing in...": "正在登录...",
"Successfully logged in with WebAuthn credentials": "成功使用WebAuthn证书登录",
"The camera is currently in use by another webpage": "摄像头被占用,无法使用",
"The input is not valid Email or phone number!": "您输入的电子邮箱格式或手机号有误!",
"The input is not valid Email!": "您输入的电子邮箱格式有误!",
"The input is not valid phone number!": "您输入的手机号有误!",
@ -1065,6 +1080,8 @@
"Email cannot be empty": "邮箱不能为空",
"Email/phone reset successfully": "邮箱或手机号重置成功",
"Empty input!": "输入为空!",
"Face ID": "Face ID",
"Face IDs": "Face IDs",
"Gender": "性别",
"Gender - Tooltip": "性别 - Tooltip",
"Homepage": "个人主页",

View File

@ -105,6 +105,7 @@ class AccountTable extends React.Component {
{name: "Multi-factor authentication", label: i18next.t("user:Multi-factor authentication")},
{name: "WebAuthn credentials", label: i18next.t("user:WebAuthn credentials")},
{name: "Managed accounts", label: i18next.t("user:Managed accounts")},
{name: "Face ID", label: i18next.t("user:Face ID")},
];
};

View File

@ -0,0 +1,134 @@
// Copyright 2024 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 React, {Suspense, lazy} from "react";
import {Button, Col, Input, Row, Table} from "antd";
import i18next from "i18next";
import * as Setting from "../Setting";
const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionModal"));
class FaceIdTable extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
openFaceRecognitionModal: false,
};
}
updateTable(table) {
this.props.onUpdateTable(table);
}
updateField(table, index, key, value) {
table[index][key] = value;
this.updateTable(table);
}
deleteRow(table, i) {
table = Setting.deleteRow(table, i);
this.updateTable(table);
}
addFaceId(table, faceIdData) {
const faceId = {
name: Setting.getRandomName(),
faceIdData: faceIdData,
};
if (table === undefined || table === null) {
table = [];
}
table = Setting.addRow(table, faceId);
this.updateTable(table);
}
renderTable(table) {
const columns = [
{
title: i18next.t("general:Name"),
dataIndex: "name",
key: "name",
width: "200px",
render: (text, record, index) => {
return (
<Input defaultValue={text} onChange={e => {
this.updateField(table, index, "name", e.target.value);
}} />
);
},
},
{
title: i18next.t("general:FaceIdData"),
dataIndex: "faceIdData",
key: "faceIdData",
render: (text, record, index) => {
const front = text.slice(0, 3).join(", ");
const back = text.slice(-3).join(", ");
return "[" + front + " ... " + back + "]";
},
},
{
title: i18next.t("general:Action"),
key: "action",
width: "100px",
render: (text, record, index) => {
return (
<Button style={{marginTop: "5px", marginBottom: "5px", marginRight: "5px"}} type="primary" danger onClick={() => {this.deleteRow(table, index);}}>
{i18next.t("general:Delete")}
</Button>
);
},
},
];
return (
<Table scroll={{x: "max-content"}} columns={columns} dataSource={this.props.table} size="middle" bordered pagination={false}
title={() => (
<div>
{i18next.t("user:Face IDs")}&nbsp;&nbsp;&nbsp;&nbsp;
<Button disabled={this.props.table?.length >= 5} style={{marginRight: "5px"}} type="primary" size="small" onClick={() => this.setState({openFaceRecognitionModal: true})}>
{i18next.t("general:Add Face Id")}
</Button>
<Suspense fallback={null}>
<FaceRecognitionModal
visible={this.state.openFaceRecognitionModal}
onOk={(faceIdData) => {
this.addFaceId(table, faceIdData);
this.setState({openFaceRecognitionModal: false});
}}
onCancel={() => this.setState({openFaceRecognitionModal: false})}
/>
</Suspense>
</div>
)}
/>
);
}
render() {
return (
<div>
<Row style={{marginTop: "20px"}}>
<Col span={24}>
{
this.renderTable(this.props.table)
}
</Col>
</Row>
</div>
);
}
}
export default FaceIdTable;

View File

@ -13,7 +13,7 @@
// limitations under the License.
import React from "react";
import {DeleteOutlined, DownOutlined, UpOutlined} from "@ant-design/icons";
import {DeleteOutlined, DownOutlined, LinkOutlined, UpOutlined} from "@ant-design/icons";
import {Button, Col, Input, Row, Select, Table, Tooltip} from "antd";
import * as Setting from "../Setting";
import i18next from "i18next";
@ -98,14 +98,27 @@ class ManagedAccountTable extends React.Component {
);
},
},
{
title: i18next.t("general:Signin URL"),
dataIndex: "signinUrl",
key: "signinUrl",
// width: "420px",
render: (text, record, index) => {
return (
<Input prefix={<LinkOutlined />} value={text} onChange={e => {
this.updateField(table, index, "signinUrl", e.target.value);
}} />
);
},
},
{
title: i18next.t("signup:Username"),
dataIndex: "username",
key: "username",
width: "420px",
width: "200px",
render: (text, record, index) => {
return (
<Input defaultValue={text} onChange={e => {
<Input value={text} onChange={e => {
this.updateField(table, index, "username", e.target.value);
}} />
);
@ -115,10 +128,10 @@ class ManagedAccountTable extends React.Component {
title: i18next.t("general:Password"),
dataIndex: "password",
key: "password",
width: "420px",
width: "200px",
render: (text, record, index) => {
return (
<Input defaultValue={text} onChange={e => {
<Input.Password value={text} onChange={e => {
this.updateField(table, index, "password", e.target.value);
}} />
);

View File

@ -71,6 +71,7 @@ class SigninMethodTable extends React.Component {
{name: "Verification code", displayName: i18next.t("login:Verification code")},
{name: "WebAuthn", displayName: i18next.t("login:WebAuthn")},
{name: "LDAP", displayName: i18next.t("login:LDAP")},
{name: "Face ID", displayName: i18next.t("login:Face ID")},
];
const columns = [
{

View File

@ -3718,6 +3718,18 @@
"@svgr/plugin-svgo" "^5.5.0"
loader-utils "^2.0.0"
"@tensorflow/tfjs-core@1.7.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-core/-/tfjs-core-1.7.0.tgz#9207c8f2481c52a6a40135a6aaf21a9bb0339bdf"
integrity sha512-uwQdiklNjqBnHPeseOdG0sGxrI3+d6lybaKu2+ou3ajVeKdPEwpWbgqA6iHjq1iylnOGkgkbbnQ6r2lwkiIIHw==
dependencies:
"@types/offscreencanvas" "~2019.3.0"
"@types/seedrandom" "2.4.27"
"@types/webgl-ext" "0.0.30"
"@types/webgl2" "0.0.4"
node-fetch "~2.1.2"
seedrandom "2.4.3"
"@testing-library/dom@*":
version "9.3.1"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-9.3.1.tgz#8094f560e9389fb973fe957af41bf766937a9ee9"
@ -4026,6 +4038,11 @@
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"
integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==
"@types/offscreencanvas@~2019.3.0":
version "2019.3.0"
resolved "https://registry.yarnpkg.com/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz#3336428ec7e9180cf4566dfea5da04eb586a6553"
integrity sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
@ -4089,6 +4106,11 @@
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5"
integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==
"@types/seedrandom@2.4.27":
version "2.4.27"
resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.27.tgz#9db563937dd86915f69092bc43259d2f48578e41"
integrity sha512-YvMLqFak/7rt//lPBtEHv3M4sRNA+HGxrhFZ+DQs9K2IkYJbNwVIb8avtJfhDiuaUBX/AW0jnjv48FV8h3u9bQ==
"@types/semver@^7.3.12":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a"
@ -4168,6 +4190,16 @@
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311"
integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==
"@types/webgl-ext@0.0.30":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/webgl-ext/-/webgl-ext-0.0.30.tgz#0ce498c16a41a23d15289e0b844d945b25f0fb9d"
integrity sha512-LKVgNmBxN0BbljJrVUwkxwRYqzsAEPcZOe6S2T6ZaBDIrFp0qu4FNlpc5sM1tGbXUYFgdVQIoeLk1Y1UoblyEg==
"@types/webgl2@0.0.4":
version "0.0.4"
resolved "https://registry.yarnpkg.com/@types/webgl2/-/webgl2-0.0.4.tgz#c3b0f9d6b465c66138e84e64cb3bdf8373c2c279"
integrity sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw==
"@types/ws@^7.4.4":
version "7.4.7"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702"
@ -7720,6 +7752,14 @@ eyes@^0.1.8:
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==
face-api.js@^0.22.2:
version "0.22.2"
resolved "https://registry.yarnpkg.com/face-api.js/-/face-api.js-0.22.2.tgz#5accbf7e53b1569685d116a7e18dbc4800770d39"
integrity sha512-9Bbv/yaBRTKCXjiDqzryeKhYxmgSjJ7ukvOvEBy6krA0Ah/vNBlsf7iBNfJljWiPA8Tys1/MnB3lyP2Hfmsuyw==
dependencies:
"@tensorflow/tfjs-core" "1.7.0"
tslib "^1.11.1"
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@ -10493,6 +10533,11 @@ node-fetch@^2.6.12:
dependencies:
whatwg-url "^5.0.0"
node-fetch@~2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5"
integrity sha512-IHLHYskTc2arMYsHZH82PVX8CSKT5lzb7AXeyO06QnjGDKtkv+pv3mEki6S7reB/x1QPo+YPxQRNEVgR5V/w3Q==
node-forge@^1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
@ -13073,6 +13118,11 @@ scrypt-js@3.0.1:
resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312"
integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==
seedrandom@2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-2.4.3.tgz#2438504dad33917314bff18ac4d794f16d6aaecc"
integrity sha512-2CkZ9Wn2dS4mMUWQaXLsOAfGD+irMlLEeSP3cMxpGbgyOOzJGFa+MWCOMTOCMyZinHRPxyOj/S/C57li/1to6Q==
select-hose@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
@ -14211,7 +14261,7 @@ tslib@2.3.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
tslib@^1.8.1, tslib@^1.9.0:
tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==